| OLD | NEW |
| 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 dev_compiler.src.testing; | 5 library dev_compiler.src.testing; |
| 6 | 6 |
| 7 import 'dart:mirrors'; | 7 import 'dart:mirrors'; |
| 8 import 'package:analyzer/file_system/file_system.dart'; | 8 import 'package:analyzer/file_system/file_system.dart'; |
| 9 import 'package:analyzer/file_system/memory_file_system.dart'; | 9 import 'package:analyzer/file_system/memory_file_system.dart'; |
| 10 import 'package:analyzer/src/generated/ast.dart'; | 10 import 'package:analyzer/src/generated/ast.dart'; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 import 'package:dev_compiler/strong_mode.dart'; | 21 import 'package:dev_compiler/strong_mode.dart'; |
| 22 import 'package:dev_compiler/src/analysis_context.dart'; | 22 import 'package:dev_compiler/src/analysis_context.dart'; |
| 23 | 23 |
| 24 import 'package:dev_compiler/src/server/dependency_graph.dart' | 24 import 'package:dev_compiler/src/server/dependency_graph.dart' |
| 25 show runtimeFilesForServerMode; | 25 show runtimeFilesForServerMode; |
| 26 import 'package:dev_compiler/src/info.dart'; | 26 import 'package:dev_compiler/src/info.dart'; |
| 27 import 'package:dev_compiler/src/options.dart'; | 27 import 'package:dev_compiler/src/options.dart'; |
| 28 import 'package:dev_compiler/src/utils.dart'; | 28 import 'package:dev_compiler/src/utils.dart'; |
| 29 | 29 |
| 30 /// Shared analysis context used for compilation. | 30 /// Shared analysis context used for compilation. |
| 31 final realSdkContext = createAnalysisContextWithSources(new StrongModeOptions(), | 31 final realSdkContext = createAnalysisContextWithSources( |
| 32 new StrongModeOptions(), |
| 32 new SourceResolverOptions( | 33 new SourceResolverOptions( |
| 33 dartSdkPath: getSdkDir().path, | 34 dartSdkPath: getSdkDir().path, |
| 34 customUrlMappings: { | 35 customUrlMappings: { |
| 35 'package:expect/expect.dart': _testCodegenPath('expect.dart'), | 36 'package:expect/expect.dart': _testCodegenPath('expect.dart'), |
| 36 'package:async_helper/async_helper.dart': | 37 'package:async_helper/async_helper.dart': |
| 37 _testCodegenPath('async_helper.dart'), | 38 _testCodegenPath('async_helper.dart'), |
| 38 'package:unittest/unittest.dart': _testCodegenPath('unittest.dart'), | 39 'package:unittest/unittest.dart': _testCodegenPath('unittest.dart'), |
| 39 'package:dom/dom.dart': _testCodegenPath('sunflower', 'dom.dart') | 40 'package:dom/dom.dart': _testCodegenPath('sunflower', 'dom.dart') |
| 40 }))..analysisOptions = (new AnalysisOptionsImpl()..cacheSize = 512); | 41 }))..analysisOptions = (new AnalysisOptionsImpl()..cacheSize = 512); |
| 41 | 42 |
| 42 String _testCodegenPath(String p1, [String p2]) => | 43 String _testCodegenPath(String p1, [String p2]) => |
| 43 path.join(testDirectory, 'codegen', p1, p2); | 44 path.join(testDirectory, 'codegen', p1, p2); |
| 44 | 45 |
| 45 final String testDirectory = | 46 final String testDirectory = |
| 46 path.dirname((reflectClass(_TestUtils).owner as LibraryMirror).uri.path); | 47 path.dirname((reflectClass(_TestUtils).owner as LibraryMirror).uri.path); |
| 47 | 48 |
| 48 class _TestUtils {} | 49 class _TestUtils {} |
| 49 | 50 |
| 50 /// Run the checker on a program with files contents as indicated in | 51 /// Run the checker on a program with files contents as indicated in |
| (...skipping 13 matching lines...) Expand all Loading... |
| 64 /// conversion, you can describe the test as follows: | 65 /// conversion, you can describe the test as follows: |
| 65 /// | 66 /// |
| 66 /// testChecker({ | 67 /// testChecker({ |
| 67 /// '/main.dart': ''' | 68 /// '/main.dart': ''' |
| 68 /// testMethod() { | 69 /// testMethod() { |
| 69 /// dynamic x = /*warning:Box*/3; | 70 /// dynamic x = /*warning:Box*/3; |
| 70 /// } | 71 /// } |
| 71 /// ''' | 72 /// ''' |
| 72 /// }); | 73 /// }); |
| 73 /// | 74 /// |
| 74 void testChecker(Map<String, String> testFiles, {String sdkDir, | 75 void testChecker(Map<String, String> testFiles, |
| 75 customUrlMappings: const {}, relaxedCasts: true, | 76 {String sdkDir, |
| 77 customUrlMappings: const {}, |
| 78 relaxedCasts: true, |
| 76 inferDownwards: StrongModeOptions.inferDownwardsDefault, | 79 inferDownwards: StrongModeOptions.inferDownwardsDefault, |
| 77 inferFromOverrides: StrongModeOptions.inferFromOverridesDefault, | 80 inferFromOverrides: StrongModeOptions.inferFromOverridesDefault, |
| 78 inferTransitively: StrongModeOptions.inferTransitivelyDefault, | 81 inferTransitively: StrongModeOptions.inferTransitivelyDefault, |
| 79 nonnullableTypes: StrongModeOptions.NONNULLABLE_TYPES}) { | 82 nonnullableTypes: StrongModeOptions.NONNULLABLE_TYPES}) { |
| 80 expect(testFiles.containsKey('/main.dart'), isTrue, | 83 expect(testFiles.containsKey('/main.dart'), isTrue, |
| 81 reason: '`/main.dart` is missing in testFiles'); | 84 reason: '`/main.dart` is missing in testFiles'); |
| 82 | 85 |
| 83 var provider = createTestResourceProvider(testFiles); | 86 var provider = createTestResourceProvider(testFiles); |
| 84 var uriResolver = new TestUriResolver(provider); | 87 var uriResolver = new TestUriResolver(provider); |
| 85 var context = AnalysisEngine.instance.createAnalysisContext(); | 88 var context = AnalysisEngine.instance.createAnalysisContext(); |
| 86 context.sourceFactory = createSourceFactory(new SourceResolverOptions( | 89 context.sourceFactory = createSourceFactory(new SourceResolverOptions( |
| 87 customUrlMappings: customUrlMappings, | 90 customUrlMappings: customUrlMappings, |
| 88 useMockSdk: sdkDir == null, | 91 useMockSdk: sdkDir == null, |
| 89 dartSdkPath: sdkDir), fileResolvers: [uriResolver]); | 92 dartSdkPath: sdkDir), fileResolvers: [uriResolver]); |
| 90 | 93 |
| 91 var checker = new StrongChecker(context, new StrongModeOptions( | 94 var checker = new StrongChecker( |
| 92 relaxedCasts: relaxedCasts, | 95 context, |
| 93 inferDownwards: inferDownwards, | 96 new StrongModeOptions( |
| 94 inferFromOverrides: inferFromOverrides, | 97 relaxedCasts: relaxedCasts, |
| 95 inferTransitively: inferTransitively, | 98 inferDownwards: inferDownwards, |
| 96 nonnullableTypes: nonnullableTypes, | 99 inferFromOverrides: inferFromOverrides, |
| 97 hints: true)); | 100 inferTransitively: inferTransitively, |
| 101 nonnullableTypes: nonnullableTypes, |
| 102 hints: true)); |
| 98 | 103 |
| 99 // Run the checker on /main.dart. | 104 // Run the checker on /main.dart. |
| 100 var mainSource = uriResolver.resolveAbsolute(new Uri.file('/main.dart')); | 105 var mainSource = uriResolver.resolveAbsolute(new Uri.file('/main.dart')); |
| 101 var initialLibrary = context.resolveCompilationUnit2(mainSource, mainSource); | 106 var initialLibrary = context.resolveCompilationUnit2(mainSource, mainSource); |
| 102 | 107 |
| 103 // Extract expectations from the comments in the test files, and | 108 // Extract expectations from the comments in the test files, and |
| 104 // check that all errors we emit are included in the expected map. | 109 // check that all errors we emit are included in the expected map. |
| 105 var allLibraries = reachableLibraries(initialLibrary.element.library); | 110 var allLibraries = reachableLibraries(initialLibrary.element.library); |
| 106 for (var lib in allLibraries) { | 111 for (var lib in allLibraries) { |
| 107 for (var unit in lib.units) { | 112 for (var unit in lib.units) { |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 errors.map(_ErrorExpectation.parse).where((x) => x != null); | 194 errors.map(_ErrorExpectation.parse).where((x) => x != null); |
| 190 | 195 |
| 191 for (var e in expectations) _expectError(node, e); | 196 for (var e in expectations) _expectError(node, e); |
| 192 } | 197 } |
| 193 } | 198 } |
| 194 } | 199 } |
| 195 return super.visitNode(node); | 200 return super.visitNode(node); |
| 196 } | 201 } |
| 197 | 202 |
| 198 void _expectError(AstNode node, _ErrorExpectation expected) { | 203 void _expectError(AstNode node, _ErrorExpectation expected) { |
| 199 | |
| 200 // See if we can find the expected error in our actual errors | 204 // See if we can find the expected error in our actual errors |
| 201 for (var actual in _actualErrors) { | 205 for (var actual in _actualErrors) { |
| 202 if (actual.offset == node.offset && actual.length == node.length) { | 206 if (actual.offset == node.offset && actual.length == node.length) { |
| 203 var actualMsg = _formatActualError(actual); | 207 var actualMsg = _formatActualError(actual); |
| 204 expect(_actualErrorLevel(actual), expected.level, | 208 expect(_actualErrorLevel(actual), expected.level, |
| 205 reason: 'expected different error code at:\n\n$actualMsg'); | 209 reason: 'expected different error code at:\n\n$actualMsg'); |
| 206 expect(errorCodeName(actual.errorCode), expected.typeName, | 210 expect(errorCodeName(actual.errorCode), expected.typeName, |
| 207 reason: 'expected different error type at:\n\n$actualMsg'); | 211 reason: 'expected different error type at:\n\n$actualMsg'); |
| 208 | 212 |
| 209 // We found it. Stop the search. | 213 // We found it. Stop the search. |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 268 expect(tokens[1], "should", reason: 'invalid error descriptor'); | 272 expect(tokens[1], "should", reason: 'invalid error descriptor'); |
| 269 expect(tokens[2], "be", reason: 'invalid error descriptor'); | 273 expect(tokens[2], "be", reason: 'invalid error descriptor'); |
| 270 if (tokens[0] == "pass") return null; | 274 if (tokens[0] == "pass") return null; |
| 271 // TODO(leafp) For now, we just use whatever the current expectation is, | 275 // TODO(leafp) For now, we just use whatever the current expectation is, |
| 272 // eventually we could do more automated reporting here. | 276 // eventually we could do more automated reporting here. |
| 273 return _parse(tokens[0]); | 277 return _parse(tokens[0]); |
| 274 } | 278 } |
| 275 | 279 |
| 276 String toString() => '$level $typeName'; | 280 String toString() => '$level $typeName'; |
| 277 } | 281 } |
| OLD | NEW |