mirror of
https://github.com/dart-lang/sdk
synced 2024-11-05 18:22:09 +00:00
Adds support for layout tests.
Review URL: https://chromiumcodereview.appspot.com//10683009 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@9207 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
parent
7be8e8fc12
commit
25a24b69a5
8 changed files with 221 additions and 10 deletions
28
tests/utils/png_layout_test.dart
Normal file
28
tests/utils/png_layout_test.dart
Normal file
|
@ -0,0 +1,28 @@
|
|||
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
/**
|
||||
* Tests the layout test functionality of test.dart. There is a .png image with
|
||||
* the same name as this file. The existence of the .png file indicates to the
|
||||
* test framework that we want to compare the final state of this application
|
||||
* against an image file.
|
||||
*/
|
||||
#library("layouttest");
|
||||
|
||||
#import('dart:html');
|
||||
|
||||
main() {
|
||||
var div1Style = _style('blue', 20, 10, 40, 10);
|
||||
var div2Style = _style('red', 25, 30, 40, 10);
|
||||
var div1 = new Element.html('<div style="$div1Style"></div>');
|
||||
var div2 = new Element.html('<div style="$div2Style"></div>');
|
||||
document.body.elements.add(div1);
|
||||
document.body.elements.add(div2);
|
||||
}
|
||||
|
||||
_style(String color, int top, int left, int width, int height) {
|
||||
return ('background-color:$color; position:absolute; '
|
||||
'top:${top}px; left:${left}px; '
|
||||
'width:${width}px; height:${height}px;');
|
||||
}
|
BIN
tests/utils/png_layout_test.png
Normal file
BIN
tests/utils/png_layout_test.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.8 KiB |
28
tests/utils/txt_layout_test.dart
Normal file
28
tests/utils/txt_layout_test.dart
Normal file
|
@ -0,0 +1,28 @@
|
|||
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
/**
|
||||
* Tests the layout test functionality of test.dart. There is a .txt image with
|
||||
* the same name as this file. The existence of the .txt file indicates to the
|
||||
* test framework that we want to compare the final state of this application
|
||||
* against a text file (with a text representation of the DOM tree).
|
||||
*/
|
||||
#library("layouttest");
|
||||
|
||||
#import('dart:html');
|
||||
|
||||
main() {
|
||||
var div1Style = _style('blue', 20, 10, 40, 10);
|
||||
var div2Style = _style('red', 25, 30, 40, 10);
|
||||
var div1 = new Element.html('<div style="$div1Style"></div>');
|
||||
var div2 = new Element.html('<div style="$div2Style"></div>');
|
||||
document.body.elements.add(div1);
|
||||
document.body.elements.add(div2);
|
||||
}
|
||||
|
||||
_style(String color, int top, int left, int width, int height) {
|
||||
return ('background-color:$color; position:absolute; '
|
||||
'top:${top}px; left:${left}px; '
|
||||
'width:${width}px; height:${height}px;');
|
||||
}
|
11
tests/utils/txt_layout_test.txt
Normal file
11
tests/utils/txt_layout_test.txt
Normal file
|
@ -0,0 +1,11 @@
|
|||
Content-Type: text/plain
|
||||
layer at (0,0) size 800x600
|
||||
RenderView at (0,0) size 800x600
|
||||
layer at (0,0) size 800x8
|
||||
RenderBlock {HTML} at (0,0) size 800x8
|
||||
RenderBody {BODY} at (8,8) size 784x0
|
||||
layer at (10,20) size 40x10
|
||||
RenderBlock (positioned) {DIV} at (10,20) size 40x10 [bgcolor=#0000FF]
|
||||
layer at (30,25) size 40x10
|
||||
RenderBlock (positioned) {DIV} at (30,25) size 40x10 [bgcolor=#FF0000]
|
||||
#EOF
|
|
@ -12,9 +12,8 @@ markdown_test: Skip
|
|||
|
||||
[ $compiler == frog ]
|
||||
dummy_compiler_test: Fail
|
||||
|
||||
[ $compiler == frog ]
|
||||
utf8_test: Crash
|
||||
*_layout_test: Skip
|
||||
|
||||
[ $compiler == dart2js ]
|
||||
utf8_test: Fail # compiler cancelled: Unhandled non-BMP character: U+10412
|
||||
|
@ -40,3 +39,6 @@ dummy_compiler_test: Fail # Issue 3529.
|
|||
|
||||
[ $compiler == frog && $runtime == none ]
|
||||
*: Skip
|
||||
|
||||
[ $runtime == vm ]
|
||||
*_layout_test: Skip
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
String GetHtmlContents(String title,
|
||||
String getHtmlContents(String title,
|
||||
String controllerScript,
|
||||
String scriptType,
|
||||
String sourceScript) =>
|
||||
|
@ -27,13 +27,29 @@ String GetHtmlContents(String title,
|
|||
</html>
|
||||
""";
|
||||
|
||||
String WrapDartTestInLibrary(Path test) =>
|
||||
String getHtmlLayoutContents(String scriptType, String sourceScript) =>
|
||||
"""
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
if (navigator.webkitStartDart) navigator.webkitStartDart();
|
||||
</script>
|
||||
<script type="$scriptType" src="$sourceScript"></script>
|
||||
</body>
|
||||
</html>
|
||||
""";
|
||||
|
||||
String wrapDartTestInLibrary(Path test) =>
|
||||
"""
|
||||
#library('libraryWrapper');
|
||||
#source('$test');
|
||||
""";
|
||||
|
||||
String DartTestWrapper(Path dartHome, Path library) =>
|
||||
String dartTestWrapper(Path dartHome, Path library) =>
|
||||
"""
|
||||
#library('test');
|
||||
|
||||
|
|
|
@ -543,14 +543,14 @@ class StandardTestSuite implements TestSuite {
|
|||
dartLibraryFilename = new Path('test_as_library.dart');
|
||||
File file = new File('$tempDir/$dartLibraryFilename');
|
||||
RandomAccessFile dartLibrary = file.openSync(FileMode.WRITE);
|
||||
dartLibrary.writeStringSync(WrapDartTestInLibrary(filePath));
|
||||
dartLibrary.writeStringSync(wrapDartTestInLibrary(filePath));
|
||||
dartLibrary.closeSync();
|
||||
}
|
||||
|
||||
File file = new File(dartWrapperFilename);
|
||||
RandomAccessFile dartWrapper = file.openSync(FileMode.WRITE);
|
||||
dartWrapper.writeStringSync(
|
||||
DartTestWrapper(dartDir, dartLibraryFilename));
|
||||
dartTestWrapper(dartDir, dartLibraryFilename));
|
||||
dartWrapper.closeSync();
|
||||
} else {
|
||||
dartWrapperFilename = filename;
|
||||
|
@ -578,11 +578,26 @@ class StandardTestSuite implements TestSuite {
|
|||
// with 'C:' adding 'file:///' solves the problem.
|
||||
filePrefix = 'file:///';
|
||||
}
|
||||
htmlTest.writeStringSync(GetHtmlContents(
|
||||
String content = null;
|
||||
Path dir = filePath.directoryPath;
|
||||
String nameNoExt = filePath.filenameWithoutExtension;
|
||||
Path pngPath = dir.append('$nameNoExt.png');
|
||||
Path txtPath = dir.append('$nameNoExt.txt');
|
||||
Path expectedOutput = null;
|
||||
if (new File.fromPath(pngPath).existsSync()) {
|
||||
expectedOutput = pngPath;
|
||||
content = getHtmlLayoutContents(scriptType, '$filePrefix$scriptPath');
|
||||
} else if (new File.fromPath(txtPath).existsSync()) {
|
||||
expectedOutput = txtPath;
|
||||
content = getHtmlLayoutContents(scriptType, '$filePrefix$scriptPath');
|
||||
} else {
|
||||
content = getHtmlContents(
|
||||
filename,
|
||||
'$filePrefix${dartDir.append("lib/unittest/test_controller.js")}',
|
||||
scriptType,
|
||||
'$filePrefix$scriptPath'));
|
||||
'$filePrefix$scriptPath');
|
||||
}
|
||||
htmlTest.writeStringSync(content);
|
||||
htmlTest.closeSync();
|
||||
|
||||
// Construct the command(s) that compile all the inputs needed by the
|
||||
|
@ -633,6 +648,9 @@ class StandardTestSuite implements TestSuite {
|
|||
args.add('--dart-flags=${Strings.join(dartFlags, " ")}');
|
||||
}
|
||||
args.add(htmlPath);
|
||||
if (expectedOutput != null) {
|
||||
args.add('--out-expectation=$expectedOutput');
|
||||
}
|
||||
}
|
||||
commands.add(new Command('python', args));
|
||||
|
||||
|
@ -829,6 +847,59 @@ class StandardTestSuite implements TestSuite {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Special options for individual tests are currently specified in various
|
||||
* ways: with comments directly in test files, by using certain imports, or by
|
||||
* creating additional files in the test directories.
|
||||
*
|
||||
* Here is a list of options that are used by 'test.dart' today:
|
||||
* - Flags can be passed to the vm or dartium process that runs the test by
|
||||
* adding a comment to the test file:
|
||||
*
|
||||
* // VMOptions=--flag1 --flag2
|
||||
*
|
||||
* - Flags can be passed to the dart script that contains the test also
|
||||
* using comments, as follows:
|
||||
*
|
||||
* // DartOptions=--flag1 --flag2
|
||||
*
|
||||
* - For tests that depend on compiling other files with dart2js (e.g.
|
||||
* isolate tests that use multiple source scripts), you can specify
|
||||
* additional files to compile using a comment too, as follows:
|
||||
*
|
||||
* // OtherScripts=file1.dart file2.dart
|
||||
*
|
||||
* - You can indicate whether a test is treated as a web-only test by
|
||||
* using an explicit import to the dart:html library:
|
||||
*
|
||||
* #import('dart:html');
|
||||
*
|
||||
* Most tests are not web tests, but can (and will be) wrapped within
|
||||
* another script file to test them also on browser environments (e.g.
|
||||
* language and corelib tests are run this way). We deduce that if this
|
||||
* import is specified, the test was intended to be a web test and no
|
||||
* wrapping is necessary.
|
||||
*
|
||||
* - You can convert DRT web-tests into layout-web-tests by specifying a
|
||||
* test expectation file. An expectation file is located in the same
|
||||
* location as the test, it has the same file name, except for the extension
|
||||
* (which can be either .txt or .png).
|
||||
*
|
||||
* When there are no expectation files, 'test.dart' assumes tests fail if
|
||||
* the process return a non-zero exit code (in the case of web tests, we
|
||||
* check for PASS/FAIL indications in the test output).
|
||||
*
|
||||
* When there is an expectation file, tests are run differently: the test
|
||||
* code is run to the end of the event loop and 'test.dart' takes a snapshot
|
||||
* of what is rendered in the page at that moment. This snapshot is
|
||||
* represented either in text form, if the expectation ends in .txt, or as
|
||||
* an image, if the expectation ends in .png. 'test.dart' will compare the
|
||||
* snapshot to the expectation file. When tests fail, 'test.dart' saves the
|
||||
* new snapshot into a file so it can be visualized or copied over.
|
||||
* Expectations can be recorded for the first time by creating an empty file
|
||||
* with the right name (touch test_name_test.png), running the test, and
|
||||
* executing the copy command printed by the test script.
|
||||
*/
|
||||
Map readOptionsFromFile(Path filePath) {
|
||||
RegExp testOptionsRegExp = const RegExp(@"// VMOptions=(.*)");
|
||||
RegExp dartOptionsRegExp = const RegExp(@"// DartOptions=(.*)");
|
||||
|
|
|
@ -13,6 +13,7 @@ import subprocess
|
|||
import sys
|
||||
|
||||
DART_FLAGS_PREFIX = '--dart-flags='
|
||||
OUT_EXPECTATION_PREFIX = '--out-expectation='
|
||||
|
||||
def main(argv):
|
||||
drt_path = argv[1]
|
||||
|
@ -21,18 +22,72 @@ def main(argv):
|
|||
cmd = [drt_path]
|
||||
|
||||
env = None
|
||||
test_file = None
|
||||
out_expected_file = None
|
||||
is_png = False
|
||||
|
||||
# parse arguments, filtering out flags, and selecting the input test file
|
||||
for arg in command_line:
|
||||
if arg.startswith(DART_FLAGS_PREFIX):
|
||||
env = dict(os.environ.items())
|
||||
env['DART_FLAGS'] = arg[len(DART_FLAGS_PREFIX):]
|
||||
elif arg.startswith(OUT_EXPECTATION_PREFIX):
|
||||
out_expected_file = arg[len(OUT_EXPECTATION_PREFIX):]
|
||||
if out_expected_file.endswith('.png'):
|
||||
cmd.append('--pixel-tests')
|
||||
cmd.append('--notree')
|
||||
is_png = True
|
||||
elif not out_expected_file.endswith('.txt'):
|
||||
raise Exception(
|
||||
'Bad file expectation (%s), ' % out_expected_file
|
||||
+ 'please specify either a .txt or a .png file')
|
||||
elif arg.endswith('.html'):
|
||||
test_file = arg
|
||||
cmd.append(arg)
|
||||
else:
|
||||
cmd.append(arg)
|
||||
|
||||
p = subprocess.Popen(cmd, env=env)
|
||||
|
||||
p = subprocess.Popen(cmd, env=env, stdout=subprocess.PIPE)
|
||||
p.wait()
|
||||
if p.returncode != 0:
|
||||
raise Exception('Failed to run command. return code=%s' % p.returncode)
|
||||
|
||||
if out_expected_file:
|
||||
# Compare output to the given expectation file.
|
||||
output = None
|
||||
expectation = None
|
||||
with p.stdout as res:
|
||||
if is_png:
|
||||
# DRT prints the image to STDOUT, but includes 5 header lines.
|
||||
for i in range(4): res.readline()
|
||||
output = res.read()
|
||||
if os.path.exists(out_expected_file):
|
||||
with open(out_expected_file, 'r') as f:
|
||||
expectation = f.read()
|
||||
else:
|
||||
# Instructions on how to create the expectation will be printed below
|
||||
# (outout != expectation)
|
||||
print 'File %s was not found' % out_expected_file
|
||||
expectation = None
|
||||
|
||||
# Report test status using the format test.dart expects to see from DRT.
|
||||
print 'Content-Type: text/plain'
|
||||
if expectation == output:
|
||||
print 'PASS'
|
||||
print 'Expectation matches'
|
||||
else:
|
||||
# Generate a temporary file in the same place as the .html file:
|
||||
out_file = test_file[:test_file.rfind('.html')] + out_expected_file[-4:]
|
||||
with open(out_file, 'w') as f:
|
||||
f.write(output)
|
||||
print 'FAIL'
|
||||
print 'Expectation didn\'t match. Update expectations by running:\n'
|
||||
print 'cp %s %s\n' % (out_file, out_expected_file)
|
||||
print '#EOF'
|
||||
else:
|
||||
# Pipe through the output for non-layout tests.
|
||||
sys.stdout.write(p.stdout.read())
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
|
|
Loading…
Reference in a new issue