Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(206)

Side by Side Diff: lib/src/testing.dart

Issue 973433003: Initial cut for a development server (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library ddc.src.testing; 5 library ddc.src.testing;
6 6
7 import 'package:analyzer/src/generated/ast.dart'; 7 import 'package:analyzer/src/generated/ast.dart';
8 import 'package:analyzer/src/generated/element.dart'; 8 import 'package:analyzer/src/generated/element.dart';
9 import 'package:analyzer/src/generated/engine.dart' show TimestampedData; 9 import 'package:analyzer/src/generated/engine.dart' show TimestampedData;
10 import 'package:analyzer/src/generated/source.dart'; 10 import 'package:analyzer/src/generated/source.dart';
11 import 'package:logging/logging.dart'; 11 import 'package:logging/logging.dart';
12 import 'package:path/path.dart' as path; 12 import 'package:path/path.dart' as path;
13 import 'package:source_span/source_span.dart'; 13 import 'package:source_span/source_span.dart';
14 import 'package:unittest/unittest.dart'; 14 import 'package:unittest/unittest.dart';
15 15
16 import 'package:dev_compiler/src/checker/dart_sdk.dart' 16 import 'package:dev_compiler/src/checker/dart_sdk.dart'
17 show mockSdkSources, dartSdkDirectory; 17 show mockSdkSources, dartSdkDirectory;
18 import 'package:dev_compiler/src/checker/resolver.dart' show TypeResolver; 18 import 'package:dev_compiler/src/checker/resolver.dart' show TypeResolver;
19 import 'package:dev_compiler/src/utils.dart'; 19 import 'package:dev_compiler/src/utils.dart';
20 import 'package:dev_compiler/src/info.dart'; 20 import 'package:dev_compiler/src/info.dart';
21 import 'package:dev_compiler/src/options.dart'; 21 import 'package:dev_compiler/src/options.dart';
22 import 'package:dev_compiler/src/report.dart'; 22 import 'package:dev_compiler/src/report.dart';
23 import 'package:dev_compiler/devc.dart' show compile; 23 import 'package:dev_compiler/devc.dart' show Compiler;
24 24
25 /// Run the checker on a program with files contents as indicated in 25 /// Run the checker on a program with files contents as indicated in
26 /// [testFiles]. 26 /// [testFiles].
27 /// 27 ///
28 /// This function makes several assumptions to make it easier to describe error 28 /// This function makes several assumptions to make it easier to describe error
29 /// expectations: 29 /// expectations:
30 /// 30 ///
31 /// * a file named `/main.dart` exists in [testFiles]. 31 /// * a file named `/main.dart` exists in [testFiles].
32 /// * all expected failures are listed in the source code using comments 32 /// * all expected failures are listed in the source code using comments
33 /// immediately in front of the AST node that should contain the error. 33 /// immediately in front of the AST node that should contain the error.
(...skipping 13 matching lines...) Expand all
47 /// }); 47 /// });
48 /// 48 ///
49 CheckerResults testChecker(Map<String, String> testFiles, 49 CheckerResults testChecker(Map<String, String> testFiles,
50 {bool allowConstCasts: true, String sdkDir, CheckerReporter reporter, 50 {bool allowConstCasts: true, String sdkDir, CheckerReporter reporter,
51 covariantGenerics: true, relaxedCasts: true, inferFromOverrides: true, 51 covariantGenerics: true, relaxedCasts: true, inferFromOverrides: true,
52 inferStaticsFromIdentifiers: false, inferInNonStableOrder: false}) { 52 inferStaticsFromIdentifiers: false, inferInNonStableOrder: false}) {
53 expect(testFiles.containsKey('/main.dart'), isTrue, 53 expect(testFiles.containsKey('/main.dart'), isTrue,
54 reason: '`/main.dart` is missing in testFiles'); 54 reason: '`/main.dart` is missing in testFiles');
55 55
56 // Create a resolver that can load test files from memory. 56 // Create a resolver that can load test files from memory.
57 var testUriResolver = new _TestUriResolver(testFiles); 57 var testUriResolver = new TestUriResolver(testFiles);
58 var options = new CompilerOptions( 58 var options = new CompilerOptions(
59 allowConstCasts: allowConstCasts, 59 allowConstCasts: allowConstCasts,
60 covariantGenerics: covariantGenerics, 60 covariantGenerics: covariantGenerics,
61 relaxedCasts: relaxedCasts, 61 relaxedCasts: relaxedCasts,
62 inferFromOverrides: inferFromOverrides, 62 inferFromOverrides: inferFromOverrides,
63 inferStaticsFromIdentifiers: inferStaticsFromIdentifiers, 63 inferStaticsFromIdentifiers: inferStaticsFromIdentifiers,
64 inferInNonStableOrder: inferInNonStableOrder); 64 inferInNonStableOrder: inferInNonStableOrder,
65 useMockSdk: sdkDir == null,
66 dartSdkPath: sdkDir,
67 entryPointFile: '/main.dart');
65 var resolver = sdkDir == null 68 var resolver = sdkDir == null
66 ? new TypeResolver.fromMock(mockSdkSources, options, 69 ? new TypeResolver.fromMock(mockSdkSources, options,
67 otherResolvers: [testUriResolver]) 70 otherResolvers: [testUriResolver])
68 : new TypeResolver.fromDir(sdkDir, options, 71 : new TypeResolver.fromDir(sdkDir, options,
69 otherResolvers: [testUriResolver]); 72 otherResolvers: [testUriResolver]);
70 73
71 // Run the checker on /main.dart. 74 // Run the checker on /main.dart.
72 var mainFile = new Uri.file('/main.dart'); 75 var mainFile = new Uri.file('/main.dart');
73 var checkExpectations = reporter == null; 76 var checkExpectations = reporter == null;
74 if (reporter == null) reporter = new TestReporter(); 77 if (reporter == null) reporter = new TestReporter();
75 var results = compile('/main.dart', resolver, options, reporter); 78 var results = new Compiler(options, resolver, reporter).runOnce();
76 79
77 // Extract expectations from the comments in the test files. 80 // Extract expectations from the comments in the test files.
78 var expectedErrors = <AstNode, List<_ErrorExpectation>>{}; 81 var expectedErrors = <AstNode, List<_ErrorExpectation>>{};
79 var visitor = new _ErrorMarkerVisitor(expectedErrors); 82 var visitor = new _ErrorMarkerVisitor(expectedErrors);
80 var initialLibrary = 83 var initialLibrary =
81 resolver.context.getLibraryElement(testUriResolver.files[mainFile]); 84 resolver.context.getLibraryElement(testUriResolver.files[mainFile]);
82 for (var lib in reachableLibraries(initialLibrary)) { 85 for (var lib in reachableLibraries(initialLibrary)) {
83 for (var unit in lib.units) { 86 for (var unit in lib.units) {
84 unit.unit.accept(visitor); 87 unit.unit.accept(visitor);
85 } 88 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 } 169 }
167 170
168 String _messageWithSpan(StaticInfo info) { 171 String _messageWithSpan(StaticInfo info) {
169 var span = _spanFor(info.node); 172 var span = _spanFor(info.node);
170 var level = info.level.name.toLowerCase(); 173 var level = info.level.name.toLowerCase();
171 return '$level: ${span.message(info.message, color: colorOf(level))}'; 174 return '$level: ${span.message(info.message, color: colorOf(level))}';
172 } 175 }
173 176
174 SourceSpan _spanFor(AstNode node) { 177 SourceSpan _spanFor(AstNode node) {
175 var root = node.root as CompilationUnit; 178 var root = node.root as CompilationUnit;
176 _TestSource source = (root.element as CompilationUnitElementImpl).source; 179 TestSource source = (root.element as CompilationUnitElementImpl).source;
177 return source.spanFor(node); 180 return source.spanFor(node);
178 } 181 }
179 182
180 /// Visitor that extracts expected errors from comments. 183 /// Visitor that extracts expected errors from comments.
181 class _ErrorMarkerVisitor extends UnifyingAstVisitor { 184 class _ErrorMarkerVisitor extends UnifyingAstVisitor {
182 Map<AstNode, List<_ErrorExpectation>> expectedErrors; 185 Map<AstNode, List<_ErrorExpectation>> expectedErrors;
183 186
184 _ErrorMarkerVisitor(this.expectedErrors); 187 _ErrorMarkerVisitor(this.expectedErrors);
185 188
186 visitNode(AstNode node) { 189 visitNode(AstNode node) {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 if (tokens[0] == "pass") return null; 252 if (tokens[0] == "pass") return null;
250 // TODO(leafp) For now, we just use whatever the current expectation is, 253 // TODO(leafp) For now, we just use whatever the current expectation is,
251 // eventually we could do more automated reporting here. 254 // eventually we could do more automated reporting here.
252 return _parse(tokens[0]); 255 return _parse(tokens[0]);
253 } 256 }
254 257
255 String toString() => '$level $type'; 258 String toString() => '$level $type';
256 } 259 }
257 260
258 /// Uri resolver that can load test files from memory. 261 /// Uri resolver that can load test files from memory.
259 class _TestUriResolver extends UriResolver { 262 class TestUriResolver extends UriResolver {
260 final Map<Uri, _TestSource> files = <Uri, _TestSource>{}; 263 final Map<Uri, TestSource> files = <Uri, TestSource>{};
261 264
262 _TestUriResolver(Map<String, String> allFiles) { 265 TestUriResolver(Map<String, String> allFiles) {
263 allFiles.forEach((key, value) { 266 allFiles.forEach((key, value) {
264 var uri = key.startsWith('package:') ? Uri.parse(key) : new Uri.file(key); 267 var uri = key.startsWith('package:') ? Uri.parse(key) : new Uri.file(key);
265 files[uri] = new _TestSource(uri, value); 268 files[uri] = new TestSource(uri, value);
266 }); 269 });
267 } 270 }
268 271
269 Source resolveAbsolute(Uri uri) { 272 Source resolveAbsolute(Uri uri) {
270 if (uri.scheme != 'file' && uri.scheme != 'package') return null; 273 if (uri.scheme != 'file' && uri.scheme != 'package') return null;
271 return files[uri]; 274 return files.putIfAbsent(uri, () => new TestSource(uri, null));
272 } 275 }
273 } 276 }
274 277
278 class TestContents implements TimestampedData<String> {
279 int modificationTime;
280 String data;
281
282 TestContents(this.modificationTime, this.data);
283 }
284
275 /// An in memory source file. 285 /// An in memory source file.
276 class _TestSource implements Source { 286 class TestSource implements Source {
277 final Uri uri; 287 final Uri uri;
278 final TimestampedData<String> contents; 288 TestContents contents;
279 final SourceFile _file; 289 final SourceFile _file;
280 final UriKind uriKind; 290 final UriKind uriKind;
291 bool _exists;
281 292
282 _TestSource(uri, contents) 293 TestSource(uri, contents)
283 : uri = uri, 294 : uri = uri,
284 contents = new TimestampedData<String>(0, contents), 295 _exists = contents != null,
285 _file = new SourceFile(contents, url: uri), 296 contents = new TestContents(1, contents),
297 _file = contents != null ? new SourceFile(contents, url: uri) : null,
286 uriKind = uri.scheme == 'file' ? UriKind.FILE_URI : UriKind.PACKAGE_URI; 298 uriKind = uri.scheme == 'file' ? UriKind.FILE_URI : UriKind.PACKAGE_URI;
287 299
288 bool exists() => true; 300 bool exists() => _exists;
289 301
290 Source get source => this; 302 Source get source => this;
291 303
292 String _encoding; 304 String _encoding;
293 String get encoding => _encoding != null ? _encoding : (_encoding = '$uri'); 305 String get encoding => _encoding != null ? _encoding : (_encoding = '$uri');
294 306
295 String get fullName => uri.path; 307 String get fullName => uri.path;
296 308
297 int get modificationStamp => 0; 309 int get modificationStamp => contents.modificationTime;
298 String get shortName => path.basename(uri.path); 310 String get shortName => path.basename(uri.path);
299 311
300 operator ==(other) => other is _TestSource && uri == other.uri; 312 operator ==(other) => other is TestSource && uri == other.uri;
301 int get hashCode => uri.hashCode; 313 int get hashCode => uri.hashCode;
302 bool get isInSystemLibrary => false; 314 bool get isInSystemLibrary => false;
303 315
304 Uri resolveRelativeUri(Uri relativeUri) => uri.resolveUri(relativeUri); 316 Uri resolveRelativeUri(Uri relativeUri) => uri.resolveUri(relativeUri);
305 317
306 SourceSpan spanFor(AstNode node) { 318 SourceSpan spanFor(AstNode node) {
307 final begin = node is AnnotatedNode 319 final begin = node is AnnotatedNode
308 ? node.firstTokenAfterCommentAndMetadata.offset 320 ? node.firstTokenAfterCommentAndMetadata.offset
309 : node.offset; 321 : node.offset;
310 return _file.span(begin, node.end); 322 return _file.span(begin, node.end);
311 } 323 }
312 324
313 String toString() => '[$runtimeType: $uri]'; 325 String toString() => '[$runtimeType: $uri]';
314 } 326 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698