OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 test.src.context.context_test; | 5 library test.src.context.context_test; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 | 8 |
9 import 'package:analyzer/src/cancelable_future.dart'; | 9 import 'package:analyzer/src/cancelable_future.dart'; |
10 import 'package:analyzer/src/context/cache.dart'; | 10 import 'package:analyzer/src/context/cache.dart'; |
(...skipping 16 matching lines...) Expand all Loading... |
27 ChangeNotice, | 27 ChangeNotice, |
28 ChangeSet, | 28 ChangeSet, |
29 IncrementalAnalysisCache, | 29 IncrementalAnalysisCache, |
30 TimestampedData; | 30 TimestampedData; |
31 import 'package:analyzer/src/generated/error.dart'; | 31 import 'package:analyzer/src/generated/error.dart'; |
32 import 'package:analyzer/src/generated/html.dart' as ht; | 32 import 'package:analyzer/src/generated/html.dart' as ht; |
33 import 'package:analyzer/src/generated/java_engine.dart'; | 33 import 'package:analyzer/src/generated/java_engine.dart'; |
34 import 'package:analyzer/src/generated/resolver.dart'; | 34 import 'package:analyzer/src/generated/resolver.dart'; |
35 import 'package:analyzer/src/generated/scanner.dart'; | 35 import 'package:analyzer/src/generated/scanner.dart'; |
36 import 'package:analyzer/src/generated/source.dart'; | 36 import 'package:analyzer/src/generated/source.dart'; |
| 37 import 'package:analyzer/src/task/dart.dart'; |
37 import 'package:analyzer/task/dart.dart'; | 38 import 'package:analyzer/task/dart.dart'; |
| 39 import 'package:analyzer/task/model.dart'; |
38 import 'package:html/dom.dart' show Document; | 40 import 'package:html/dom.dart' show Document; |
39 import 'package:path/path.dart' as pathos; | |
40 import 'package:unittest/unittest.dart'; | 41 import 'package:unittest/unittest.dart'; |
41 import 'package:watcher/src/utils.dart'; | 42 import 'package:watcher/src/utils.dart'; |
42 | 43 |
43 import '../../generated/engine_test.dart'; | 44 import '../../generated/engine_test.dart'; |
44 import '../../generated/test_support.dart'; | 45 import '../../generated/test_support.dart'; |
45 import '../../reflective_tests.dart'; | 46 import '../../reflective_tests.dart'; |
46 import 'abstract_context.dart'; | 47 import 'abstract_context.dart'; |
47 | 48 |
48 main() { | 49 main() { |
49 groupSep = ' | '; | 50 groupSep = ' | '; |
50 runReflectiveTests(AnalysisContextImplTest); | 51 runReflectiveTests(AnalysisContextImplTest); |
| 52 runReflectiveTests(LimitedInvalidateTest); |
51 } | 53 } |
52 | 54 |
53 @reflectiveTest | 55 @reflectiveTest |
54 class AnalysisContextImplTest extends AbstractContextTest { | 56 class AnalysisContextImplTest extends AbstractContextTest { |
55 void fail_applyChanges_empty() { | 57 void fail_applyChanges_empty() { |
56 context.applyChanges(new ChangeSet()); | 58 context.applyChanges(new ChangeSet()); |
57 expect(context.performAnalysisTask().changeNotices, isNull); | 59 expect(context.performAnalysisTask().changeNotices, isNull); |
58 // This test appears to be flaky. If it is named "test_" it fails, if it's | 60 // This test appears to be flaky. If it is named "test_" it fails, if it's |
59 // named "fail_" it doesn't fail. I'm guessing that it's dependent on | 61 // named "fail_" it doesn't fail. I'm guessing that it's dependent on |
60 // whether some other test is run. | 62 // whether some other test is run. |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 // prepare errors | 118 // prepare errors |
117 _analyzeAll_assertFinished(); | 119 _analyzeAll_assertFinished(); |
118 List<AnalysisError> errors = context.getErrors(source).errors; | 120 List<AnalysisError> errors = context.getErrors(source).errors; |
119 // validate errors | 121 // validate errors |
120 expect(errors, hasLength(1)); | 122 expect(errors, hasLength(1)); |
121 AnalysisError error = errors[0]; | 123 AnalysisError error = errors[0]; |
122 expect(error.source, same(source)); | 124 expect(error.source, same(source)); |
123 expect(error.errorCode, ScannerErrorCode.UNABLE_GET_CONTENT); | 125 expect(error.errorCode, ScannerErrorCode.UNABLE_GET_CONTENT); |
124 } | 126 } |
125 | 127 |
126 void test_performAnalysisTask_importedLibraryAdd_html() { | |
127 Source htmlSource = addSource("/page.html", r''' | |
128 <html><body><script type="application/dart"> | |
129 import '/libB.dart'; | |
130 main() {print('hello dart');} | |
131 </script></body></html>'''); | |
132 _analyzeAll_assertFinished(); | |
133 context.computeErrors(htmlSource); | |
134 expect(_hasAnalysisErrorWithErrorSeverity(context.getErrors(htmlSource)), | |
135 isTrue, reason: "htmlSource has an error"); | |
136 // add libB.dart and analyze | |
137 Source libBSource = addSource("/libB.dart", "library libB;"); | |
138 _analyzeAll_assertFinished(); | |
139 expect( | |
140 context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull, | |
141 reason: "libB resolved 2"); | |
142 // TODO (danrubel) commented out to fix red bots | |
143 // context.computeErrors(htmlSource); | |
144 // AnalysisErrorInfo errors = _context.getErrors(htmlSource); | |
145 // expect( | |
146 // !_hasAnalysisErrorWithErrorSeverity(errors), | |
147 // isTrue, | |
148 // reason: "htmlSource doesn't have errors"); | |
149 } | |
150 | |
151 void fail_performAnalysisTask_importedLibraryDelete_html() { | 128 void fail_performAnalysisTask_importedLibraryDelete_html() { |
152 // NOTE: This was failing before converting to the new task model. | 129 // NOTE: This was failing before converting to the new task model. |
153 Source htmlSource = addSource("/page.html", r''' | 130 Source htmlSource = addSource("/page.html", r''' |
154 <html><body><script type="application/dart"> | 131 <html><body><script type="application/dart"> |
155 import 'libB.dart'; | 132 import 'libB.dart'; |
156 main() {print('hello dart');} | 133 main() {print('hello dart');} |
157 </script></body></html>'''); | 134 </script></body></html>'''); |
158 Source libBSource = addSource("/libB.dart", "library libB;"); | 135 Source libBSource = addSource("/libB.dart", "library libB;"); |
159 _analyzeAll_assertFinished(); | 136 _analyzeAll_assertFinished(); |
160 context.computeErrors(htmlSource); | 137 context.computeErrors(htmlSource); |
(...skipping 1482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1643 expect( | 1620 expect( |
1644 context.getResolvedCompilationUnit2(libASource, libASource), isNotNull, | 1621 context.getResolvedCompilationUnit2(libASource, libASource), isNotNull, |
1645 reason: "libA resolved 2"); | 1622 reason: "libA resolved 2"); |
1646 expect( | 1623 expect( |
1647 context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull, | 1624 context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull, |
1648 reason: "libB resolved 2"); | 1625 reason: "libB resolved 2"); |
1649 expect(_hasAnalysisErrorWithErrorSeverity(context.getErrors(libASource)), | 1626 expect(_hasAnalysisErrorWithErrorSeverity(context.getErrors(libASource)), |
1650 isFalse, reason: "libA doesn't have errors"); | 1627 isFalse, reason: "libA doesn't have errors"); |
1651 } | 1628 } |
1652 | 1629 |
| 1630 void test_performAnalysisTask_importedLibraryAdd_html() { |
| 1631 Source htmlSource = addSource("/page.html", r''' |
| 1632 <html><body><script type="application/dart"> |
| 1633 import '/libB.dart'; |
| 1634 main() {print('hello dart');} |
| 1635 </script></body></html>'''); |
| 1636 _analyzeAll_assertFinished(); |
| 1637 context.computeErrors(htmlSource); |
| 1638 expect(_hasAnalysisErrorWithErrorSeverity(context.getErrors(htmlSource)), |
| 1639 isTrue, reason: "htmlSource has an error"); |
| 1640 // add libB.dart and analyze |
| 1641 Source libBSource = addSource("/libB.dart", "library libB;"); |
| 1642 _analyzeAll_assertFinished(); |
| 1643 expect( |
| 1644 context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull, |
| 1645 reason: "libB resolved 2"); |
| 1646 // TODO (danrubel) commented out to fix red bots |
| 1647 // context.computeErrors(htmlSource); |
| 1648 // AnalysisErrorInfo errors = _context.getErrors(htmlSource); |
| 1649 // expect( |
| 1650 // !_hasAnalysisErrorWithErrorSeverity(errors), |
| 1651 // isTrue, |
| 1652 // reason: "htmlSource doesn't have errors"); |
| 1653 } |
| 1654 |
1653 void test_performAnalysisTask_importedLibraryDelete() { | 1655 void test_performAnalysisTask_importedLibraryDelete() { |
1654 Source libASource = | 1656 Source libASource = |
1655 addSource("/libA.dart", "library libA; import 'libB.dart';"); | 1657 addSource("/libA.dart", "library libA; import 'libB.dart';"); |
1656 Source libBSource = addSource("/libB.dart", "library libB;"); | 1658 Source libBSource = addSource("/libB.dart", "library libB;"); |
1657 _analyzeAll_assertFinished(); | 1659 _analyzeAll_assertFinished(); |
1658 expect( | 1660 expect( |
1659 context.getResolvedCompilationUnit2(libASource, libASource), isNotNull, | 1661 context.getResolvedCompilationUnit2(libASource, libASource), isNotNull, |
1660 reason: "libA resolved 1"); | 1662 reason: "libA resolved 1"); |
1661 expect( | 1663 expect( |
1662 context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull, | 1664 context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull, |
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2046 List<AnalysisError> errors = errorInfo.errors; | 2048 List<AnalysisError> errors = errorInfo.errors; |
2047 for (AnalysisError analysisError in errors) { | 2049 for (AnalysisError analysisError in errors) { |
2048 if (analysisError.errorCode.errorSeverity == ErrorSeverity.ERROR) { | 2050 if (analysisError.errorCode.errorSeverity == ErrorSeverity.ERROR) { |
2049 return true; | 2051 return true; |
2050 } | 2052 } |
2051 } | 2053 } |
2052 return false; | 2054 return false; |
2053 } | 2055 } |
2054 } | 2056 } |
2055 | 2057 |
| 2058 @reflectiveTest |
| 2059 class LimitedInvalidateTest extends AbstractContextTest { |
| 2060 @override |
| 2061 void setUp() { |
| 2062 AnalysisEngine.instance.limitInvalidationInTaskModel = true; |
| 2063 super.setUp(); |
| 2064 } |
| 2065 |
| 2066 @override |
| 2067 void tearDown() { |
| 2068 AnalysisEngine.instance.limitInvalidationInTaskModel = false; |
| 2069 super.tearDown(); |
| 2070 } |
| 2071 |
| 2072 void test_unusedName() { |
| 2073 Source sourceA = addSource("/a.dart", r''' |
| 2074 library lib_a; |
| 2075 class A {} |
| 2076 class B {} |
| 2077 class C {} |
| 2078 '''); |
| 2079 Source sourceB = addSource("/b.dart", r''' |
| 2080 library lib_b; |
| 2081 import 'a.dart'; |
| 2082 main() { |
| 2083 new A(); |
| 2084 new C(); |
| 2085 } |
| 2086 '''); |
| 2087 _performPendingAnalysisTasks(); |
| 2088 // Update A. |
| 2089 context.setContents(sourceA, r''' |
| 2090 library lib_a; |
| 2091 class A {} |
| 2092 class B2 {} |
| 2093 class C {} |
| 2094 '''); |
| 2095 // Only a.dart is invalidated. |
| 2096 // Because b.dart does not use B, so it is valid. |
| 2097 _assertInvalid(sourceA, LIBRARY_ERRORS_READY); |
| 2098 _assertValid(sourceB, LIBRARY_ERRORS_READY); |
| 2099 } |
| 2100 |
| 2101 void test_usedName_directUser() { |
| 2102 Source sourceA = addSource("/a.dart", r''' |
| 2103 library lib_a; |
| 2104 class A {} |
| 2105 class B {} |
| 2106 class C {} |
| 2107 '''); |
| 2108 Source sourceB = addSource("/b.dart", r''' |
| 2109 library lib_b; |
| 2110 import 'a.dart'; |
| 2111 main() { |
| 2112 new A(); |
| 2113 new C2(); |
| 2114 } |
| 2115 '''); |
| 2116 _performPendingAnalysisTasks(); |
| 2117 expect(context.getErrors(sourceB).errors, hasLength(1)); |
| 2118 // Update a.dart, invalidates b.dart because it references "C2". |
| 2119 context.setContents(sourceA, r''' |
| 2120 library lib_a; |
| 2121 class A {} |
| 2122 class B {} |
| 2123 class C2 {} |
| 2124 '''); |
| 2125 _assertInvalid(sourceA, LIBRARY_ERRORS_READY); |
| 2126 _assertInvalid(sourceB, LIBRARY_ERRORS_READY); |
| 2127 // Now b.dart is analyzed and the error is fixed. |
| 2128 _performPendingAnalysisTasks(); |
| 2129 expect(context.getErrors(sourceB).errors, hasLength(0)); |
| 2130 // Update a.dart, invalidates b.dart because it references "C". |
| 2131 context.setContents(sourceA, r''' |
| 2132 library lib_a; |
| 2133 class A {} |
| 2134 class B {} |
| 2135 class C {} |
| 2136 '''); |
| 2137 _assertInvalid(sourceA, LIBRARY_ERRORS_READY); |
| 2138 _assertInvalid(sourceB, LIBRARY_ERRORS_READY); |
| 2139 _performPendingAnalysisTasks(); |
| 2140 // Now b.dart is analyzed and it again has the error. |
| 2141 expect(context.getErrors(sourceB).errors, hasLength(1)); |
| 2142 } |
| 2143 |
| 2144 void test_usedName_indirectUser() { |
| 2145 Source sourceA = addSource("/a.dart", r''' |
| 2146 library lib_a; |
| 2147 class A { |
| 2148 m() {} |
| 2149 } |
| 2150 '''); |
| 2151 Source sourceB = addSource("/b.dart", r''' |
| 2152 library lib_b; |
| 2153 import 'a.dart'; |
| 2154 class B extends A {} |
| 2155 '''); |
| 2156 Source sourceC = addSource("/c.dart", r''' |
| 2157 library lib_c; |
| 2158 import 'b.dart'; |
| 2159 class C extends B { |
| 2160 main() { |
| 2161 m(); |
| 2162 } |
| 2163 } |
| 2164 '''); |
| 2165 // No errors, "A.m" exists. |
| 2166 _performPendingAnalysisTasks(); |
| 2167 expect(context.getErrors(sourceC).errors, hasLength(0)); |
| 2168 // Replace "A.m" with "A.m2", invalidate both b.dart and c.dart files. |
| 2169 context.setContents(sourceA, r''' |
| 2170 library lib_a; |
| 2171 class A { |
| 2172 m2() {} |
| 2173 } |
| 2174 '''); |
| 2175 _assertInvalid(sourceA, LIBRARY_ERRORS_READY); |
| 2176 _assertInvalid(sourceB, LIBRARY_ERRORS_READY); |
| 2177 _assertInvalid(sourceC, LIBRARY_ERRORS_READY); |
| 2178 // There is an error in c.dart, "A.m" does not exist. |
| 2179 _performPendingAnalysisTasks(); |
| 2180 expect(context.getErrors(sourceB).errors, hasLength(0)); |
| 2181 expect(context.getErrors(sourceC).errors, hasLength(1)); |
| 2182 // Restore "A.m", invalidate both b.dart and c.dart files. |
| 2183 context.setContents(sourceA, r''' |
| 2184 library lib_a; |
| 2185 class A { |
| 2186 m() {} |
| 2187 } |
| 2188 '''); |
| 2189 _assertInvalid(sourceA, LIBRARY_ERRORS_READY); |
| 2190 _assertInvalid(sourceB, LIBRARY_ERRORS_READY); |
| 2191 _assertInvalid(sourceC, LIBRARY_ERRORS_READY); |
| 2192 // No errors, "A.m" exists. |
| 2193 _performPendingAnalysisTasks(); |
| 2194 expect(context.getErrors(sourceC).errors, hasLength(0)); |
| 2195 } |
| 2196 |
| 2197 void _assertInvalid(AnalysisTarget target, ResultDescriptor descriptor) { |
| 2198 CacheState state = analysisCache.getState(target, descriptor); |
| 2199 expect(state, CacheState.INVALID); |
| 2200 } |
| 2201 |
| 2202 void _assertValid(AnalysisTarget target, ResultDescriptor descriptor) { |
| 2203 CacheState state = analysisCache.getState(target, descriptor); |
| 2204 expect(state, CacheState.VALID); |
| 2205 } |
| 2206 |
| 2207 void _performPendingAnalysisTasks([int maxTasks = 512]) { |
| 2208 for (int i = 0; context.performAnalysisTask().hasMoreWork; i++) { |
| 2209 if (i > maxTasks) { |
| 2210 fail('Analysis did not terminate.'); |
| 2211 } |
| 2212 } |
| 2213 } |
| 2214 } |
| 2215 |
2056 class _AnalysisContextImplTest_test_applyChanges_removeContainer | 2216 class _AnalysisContextImplTest_test_applyChanges_removeContainer |
2057 implements SourceContainer { | 2217 implements SourceContainer { |
2058 Source libB; | 2218 Source libB; |
2059 _AnalysisContextImplTest_test_applyChanges_removeContainer(this.libB); | 2219 _AnalysisContextImplTest_test_applyChanges_removeContainer(this.libB); |
2060 @override | 2220 @override |
2061 bool contains(Source source) => source == libB; | 2221 bool contains(Source source) => source == libB; |
2062 } | 2222 } |
OLD | NEW |