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

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
« no previous file with comments | « lib/src/report.dart ('k') | lib/src/utils.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/config.dart'; 23 import 'package:dev_compiler/config.dart';
24 import 'package:dev_compiler/devc.dart' show compile; 24 import 'package:dev_compiler/devc.dart' show Compiler;
25 25
26 /// Run the checker on a program with files contents as indicated in 26 /// Run the checker on a program with files contents as indicated in
27 /// [testFiles]. 27 /// [testFiles].
28 /// 28 ///
29 /// This function makes several assumptions to make it easier to describe error 29 /// This function makes several assumptions to make it easier to describe error
30 /// expectations: 30 /// expectations:
31 /// 31 ///
32 /// * a file named `/main.dart` exists in [testFiles]. 32 /// * a file named `/main.dart` exists in [testFiles].
33 /// * all expected failures are listed in the source code using comments 33 /// * all expected failures are listed in the source code using comments
34 /// immediately in front of the AST node that should contain the error. 34 /// immediately in front of the AST node that should contain the error.
(...skipping 14 matching lines...) Expand all
49 /// 49 ///
50 CheckerResults testChecker(Map<String, String> testFiles, 50 CheckerResults testChecker(Map<String, String> testFiles,
51 {bool allowConstCasts: true, String sdkDir, CheckerReporter reporter, 51 {bool allowConstCasts: true, String sdkDir, CheckerReporter reporter,
52 covariantGenerics: true, relaxedCasts: true, inferFromOverrides: true, 52 covariantGenerics: true, relaxedCasts: true, inferFromOverrides: true,
53 inferStaticsFromIdentifiers: false, inferInNonStableOrder: false, 53 inferStaticsFromIdentifiers: false, inferInNonStableOrder: false,
54 nonnullableTypes: TypeOptions.NONNULLABLE_TYPES}) { 54 nonnullableTypes: TypeOptions.NONNULLABLE_TYPES}) {
55 expect(testFiles.containsKey('/main.dart'), isTrue, 55 expect(testFiles.containsKey('/main.dart'), isTrue,
56 reason: '`/main.dart` is missing in testFiles'); 56 reason: '`/main.dart` is missing in testFiles');
57 57
58 // Create a resolver that can load test files from memory. 58 // Create a resolver that can load test files from memory.
59 var testUriResolver = new _TestUriResolver(testFiles); 59 var testUriResolver = new TestUriResolver(testFiles);
60 var options = new CompilerOptions( 60 var options = new CompilerOptions(
61 allowConstCasts: allowConstCasts, 61 allowConstCasts: allowConstCasts,
62 covariantGenerics: covariantGenerics, 62 covariantGenerics: covariantGenerics,
63 relaxedCasts: relaxedCasts, 63 relaxedCasts: relaxedCasts,
64 inferFromOverrides: inferFromOverrides, 64 inferFromOverrides: inferFromOverrides,
65 inferStaticsFromIdentifiers: inferStaticsFromIdentifiers, 65 inferStaticsFromIdentifiers: inferStaticsFromIdentifiers,
66 inferInNonStableOrder: inferInNonStableOrder, 66 inferInNonStableOrder: inferInNonStableOrder,
67 nonnullableTypes: nonnullableTypes); 67 nonnullableTypes: nonnullableTypes,
68 useMockSdk: sdkDir == null,
69 dartSdkPath: sdkDir,
70 entryPointFile: '/main.dart');
68 var resolver = sdkDir == null 71 var resolver = sdkDir == null
69 ? new TypeResolver.fromMock(mockSdkSources, options, 72 ? new TypeResolver.fromMock(mockSdkSources, options,
70 otherResolvers: [testUriResolver]) 73 otherResolvers: [testUriResolver])
71 : new TypeResolver.fromDir(sdkDir, options, 74 : new TypeResolver.fromDir(sdkDir, options,
72 otherResolvers: [testUriResolver]); 75 otherResolvers: [testUriResolver]);
73 76
74 // Run the checker on /main.dart. 77 // Run the checker on /main.dart.
75 var mainFile = new Uri.file('/main.dart'); 78 var mainFile = new Uri.file('/main.dart');
76 var checkExpectations = reporter == null; 79 var checkExpectations = reporter == null;
77 if (reporter == null) reporter = new TestReporter(); 80 if (reporter == null) reporter = new TestReporter();
78 var results = compile('/main.dart', resolver, options, reporter); 81 var results = new Compiler(options, resolver, reporter).run();
79 82
80 // Extract expectations from the comments in the test files. 83 // Extract expectations from the comments in the test files.
81 var expectedErrors = <AstNode, List<_ErrorExpectation>>{}; 84 var expectedErrors = <AstNode, List<_ErrorExpectation>>{};
82 var visitor = new _ErrorMarkerVisitor(expectedErrors); 85 var visitor = new _ErrorMarkerVisitor(expectedErrors);
83 var initialLibrary = 86 var initialLibrary =
84 resolver.context.getLibraryElement(testUriResolver.files[mainFile]); 87 resolver.context.getLibraryElement(testUriResolver.files[mainFile]);
85 for (var lib in reachableLibraries(initialLibrary)) { 88 for (var lib in reachableLibraries(initialLibrary)) {
86 for (var unit in lib.units) { 89 for (var unit in lib.units) {
87 unit.unit.accept(visitor); 90 unit.unit.accept(visitor);
88 } 91 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 } 172 }
170 173
171 String _messageWithSpan(StaticInfo info) { 174 String _messageWithSpan(StaticInfo info) {
172 var span = _spanFor(info.node); 175 var span = _spanFor(info.node);
173 var level = info.level.name.toLowerCase(); 176 var level = info.level.name.toLowerCase();
174 return '$level: ${span.message(info.message, color: colorOf(level))}'; 177 return '$level: ${span.message(info.message, color: colorOf(level))}';
175 } 178 }
176 179
177 SourceSpan _spanFor(AstNode node) { 180 SourceSpan _spanFor(AstNode node) {
178 var root = node.root as CompilationUnit; 181 var root = node.root as CompilationUnit;
179 _TestSource source = (root.element as CompilationUnitElementImpl).source; 182 TestSource source = (root.element as CompilationUnitElementImpl).source;
180 return source.spanFor(node); 183 return source.spanFor(node);
181 } 184 }
182 185
183 /// Visitor that extracts expected errors from comments. 186 /// Visitor that extracts expected errors from comments.
184 class _ErrorMarkerVisitor extends UnifyingAstVisitor { 187 class _ErrorMarkerVisitor extends UnifyingAstVisitor {
185 Map<AstNode, List<_ErrorExpectation>> expectedErrors; 188 Map<AstNode, List<_ErrorExpectation>> expectedErrors;
186 189
187 _ErrorMarkerVisitor(this.expectedErrors); 190 _ErrorMarkerVisitor(this.expectedErrors);
188 191
189 visitNode(AstNode node) { 192 visitNode(AstNode node) {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 if (tokens[0] == "pass") return null; 255 if (tokens[0] == "pass") return null;
253 // TODO(leafp) For now, we just use whatever the current expectation is, 256 // TODO(leafp) For now, we just use whatever the current expectation is,
254 // eventually we could do more automated reporting here. 257 // eventually we could do more automated reporting here.
255 return _parse(tokens[0]); 258 return _parse(tokens[0]);
256 } 259 }
257 260
258 String toString() => '$level $type'; 261 String toString() => '$level $type';
259 } 262 }
260 263
261 /// Uri resolver that can load test files from memory. 264 /// Uri resolver that can load test files from memory.
262 class _TestUriResolver extends UriResolver { 265 class TestUriResolver extends UriResolver {
263 final Map<Uri, _TestSource> files = <Uri, _TestSource>{}; 266 final Map<Uri, TestSource> files = <Uri, TestSource>{};
264 267
265 _TestUriResolver(Map<String, String> allFiles) { 268 TestUriResolver(Map<String, String> allFiles) {
266 allFiles.forEach((key, value) { 269 allFiles.forEach((key, value) {
267 var uri = key.startsWith('package:') ? Uri.parse(key) : new Uri.file(key); 270 var uri = key.startsWith('package:') ? Uri.parse(key) : new Uri.file(key);
268 files[uri] = new _TestSource(uri, value); 271 files[uri] = new TestSource(uri, value);
269 }); 272 });
270 } 273 }
271 274
272 Source resolveAbsolute(Uri uri) { 275 Source resolveAbsolute(Uri uri) {
273 if (uri.scheme != 'file' && uri.scheme != 'package') return null; 276 if (uri.scheme != 'file' && uri.scheme != 'package') return null;
274 return files[uri]; 277 return files.putIfAbsent(uri, () => new TestSource(uri, null));
275 } 278 }
276 } 279 }
277 280
281 class TestContents implements TimestampedData<String> {
282 int modificationTime;
283 String data;
284
285 TestContents(this.modificationTime, this.data);
286 }
287
278 /// An in memory source file. 288 /// An in memory source file.
279 class _TestSource implements Source { 289 class TestSource implements Source {
280 final Uri uri; 290 final Uri uri;
281 final TimestampedData<String> contents; 291 TestContents contents;
282 final SourceFile _file; 292 final SourceFile _file;
283 final UriKind uriKind; 293 final UriKind uriKind;
294 bool _exists;
284 295
285 _TestSource(uri, contents) 296 TestSource(uri, contents)
286 : uri = uri, 297 : uri = uri,
287 contents = new TimestampedData<String>(0, contents), 298 _exists = contents != null,
288 _file = new SourceFile(contents, url: uri), 299 contents = new TestContents(1, contents),
300 _file = contents != null ? new SourceFile(contents, url: uri) : null,
289 uriKind = uri.scheme == 'file' ? UriKind.FILE_URI : UriKind.PACKAGE_URI; 301 uriKind = uri.scheme == 'file' ? UriKind.FILE_URI : UriKind.PACKAGE_URI;
290 302
291 bool exists() => true; 303 bool exists() => _exists;
292 304
293 Source get source => this; 305 Source get source => this;
294 306
295 String _encoding; 307 String _encoding;
296 String get encoding => _encoding != null ? _encoding : (_encoding = '$uri'); 308 String get encoding => _encoding != null ? _encoding : (_encoding = '$uri');
297 309
298 String get fullName => uri.path; 310 String get fullName => uri.path;
299 311
300 int get modificationStamp => 0; 312 int get modificationStamp => contents.modificationTime;
301 String get shortName => path.basename(uri.path); 313 String get shortName => path.basename(uri.path);
302 314
303 operator ==(other) => other is _TestSource && uri == other.uri; 315 operator ==(other) => other is TestSource && uri == other.uri;
304 int get hashCode => uri.hashCode; 316 int get hashCode => uri.hashCode;
305 bool get isInSystemLibrary => false; 317 bool get isInSystemLibrary => false;
306 318
307 Uri resolveRelativeUri(Uri relativeUri) => uri.resolveUri(relativeUri); 319 Uri resolveRelativeUri(Uri relativeUri) => uri.resolveUri(relativeUri);
308 320
309 SourceSpan spanFor(AstNode node) { 321 SourceSpan spanFor(AstNode node) {
310 final begin = node is AnnotatedNode 322 final begin = node is AnnotatedNode
311 ? node.firstTokenAfterCommentAndMetadata.offset 323 ? node.firstTokenAfterCommentAndMetadata.offset
312 : node.offset; 324 : node.offset;
313 return _file.span(begin, node.end); 325 return _file.span(begin, node.end);
314 } 326 }
315 327
316 String toString() => '[$runtimeType: $uri]'; 328 String toString() => '[$runtimeType: $uri]';
317 } 329 }
OLDNEW
« no previous file with comments | « lib/src/report.dart ('k') | lib/src/utils.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698