| 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 test.analysis.updateContent; | 5 library test.analysis.updateContent; |
| 6 | 6 |
| 7 import 'package:analysis_server/src/constants.dart'; | 7 import 'package:analysis_server/src/constants.dart'; |
| 8 import 'package:analysis_server/src/protocol.dart'; | 8 import 'package:analysis_server/src/protocol.dart'; |
| 9 import 'package:analysis_server/src/services/index/index.dart'; | 9 import 'package:analysis_server/src/services/index/index.dart'; |
| 10 import 'package:analyzer/file_system/file_system.dart'; |
| 10 import 'package:analyzer/src/generated/ast.dart'; | 11 import 'package:analyzer/src/generated/ast.dart'; |
| 12 import 'package:analyzer/src/generated/engine.dart'; |
| 13 import 'package:analyzer/src/generated/source.dart'; |
| 11 import 'package:typed_mock/typed_mock.dart'; | 14 import 'package:typed_mock/typed_mock.dart'; |
| 12 import 'package:unittest/unittest.dart'; | 15 import 'package:unittest/unittest.dart'; |
| 13 | 16 |
| 14 import '../analysis_abstract.dart'; | 17 import '../analysis_abstract.dart'; |
| 15 import '../reflective_tests.dart'; | 18 import '../reflective_tests.dart'; |
| 16 | 19 |
| 17 main() { | 20 main() { |
| 18 groupSep = ' | '; | 21 groupSep = ' | '; |
| 19 runReflectiveTests(UpdateContentTest); | 22 runReflectiveTests(UpdateContentTest); |
| 20 } | 23 } |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 // It will schedule an indexing operation. | 100 // It will schedule an indexing operation. |
| 98 await server.test_onOperationPerformed; | 101 await server.test_onOperationPerformed; |
| 99 // Update the file and remove an overlay. | 102 // Update the file and remove an overlay. |
| 100 resourceProvider.updateFile(testFile, 'main() { print(2); }'); | 103 resourceProvider.updateFile(testFile, 'main() { print(2); }'); |
| 101 server.updateContent('2', {testFile: new RemoveContentOverlay()}); | 104 server.updateContent('2', {testFile: new RemoveContentOverlay()}); |
| 102 // Validate that at the end the unit was indexed. | 105 // Validate that at the end the unit was indexed. |
| 103 await server.onAnalysisComplete; | 106 await server.onAnalysisComplete; |
| 104 verify(server.index.indexUnit(anyObject, testUnitMatcher)).times(2); | 107 verify(server.index.indexUnit(anyObject, testUnitMatcher)).times(2); |
| 105 } | 108 } |
| 106 | 109 |
| 107 test_multiple_contexts() { | 110 test_multiple_contexts() async { |
| 108 String fooPath = '/project1/foo.dart'; | 111 String fooPath = '/project1/foo.dart'; |
| 109 resourceProvider.newFile(fooPath, ''' | 112 resourceProvider.newFile(fooPath, ''' |
| 110 library foo; | 113 library foo; |
| 111 import '../project2/baz.dart'; | 114 import '../project2/baz.dart'; |
| 112 main() { f(); }'''); | 115 main() { f(); }'''); |
| 113 String barPath = '/project2/bar.dart'; | 116 String barPath = '/project2/bar.dart'; |
| 114 resourceProvider.newFile(barPath, ''' | 117 resourceProvider.newFile(barPath, ''' |
| 115 library bar; | 118 library bar; |
| 116 import 'baz.dart'; | 119 import 'baz.dart'; |
| 117 main() { f(); }'''); | 120 main() { f(); }'''); |
| 118 String bazPath = '/project2/baz.dart'; | 121 String bazPath = '/project2/baz.dart'; |
| 119 resourceProvider.newFile(bazPath, ''' | 122 resourceProvider.newFile(bazPath, ''' |
| 120 library baz; | 123 library baz; |
| 121 f(int i) {} | 124 f(int i) {} |
| 122 '''); | 125 '''); |
| 123 Request request = new AnalysisSetAnalysisRootsParams( | 126 Request request = new AnalysisSetAnalysisRootsParams( |
| 124 ['/project1', '/project2'], []).toRequest('0'); | 127 ['/project1', '/project2'], []).toRequest('0'); |
| 125 handleSuccessfulRequest(request); | 128 handleSuccessfulRequest(request); |
| 126 return waitForTasksFinished().then((_) { | 129 { |
| 130 await server.onAnalysisComplete; |
| 127 // Files foo.dart and bar.dart should both have errors, since they both | 131 // Files foo.dart and bar.dart should both have errors, since they both |
| 128 // call f() with the wrong number of arguments. | 132 // call f() with the wrong number of arguments. |
| 129 expect(filesErrors[fooPath], hasLength(1)); | 133 expect(filesErrors[fooPath], hasLength(1)); |
| 130 expect(filesErrors[barPath], hasLength(1)); | 134 expect(filesErrors[barPath], hasLength(1)); |
| 131 // Overlay the content of baz.dart to eliminate the errors. | 135 // Overlay the content of baz.dart to eliminate the errors. |
| 132 server.updateContent('1', { | 136 server.updateContent('1', { |
| 133 bazPath: new AddContentOverlay(''' | 137 bazPath: new AddContentOverlay(''' |
| 134 library baz; | 138 library baz; |
| 135 f() {} | 139 f() {} |
| 136 ''') | 140 ''') |
| 137 }); | 141 }); |
| 138 return waitForTasksFinished(); | 142 } |
| 139 }).then((_) { | 143 { |
| 144 await server.onAnalysisComplete; |
| 140 // The overlay should have been propagated to both contexts, causing both | 145 // The overlay should have been propagated to both contexts, causing both |
| 141 // foo.dart and bar.dart to be reanalyzed and found to be free of errors. | 146 // foo.dart and bar.dart to be reanalyzed and found to be free of errors. |
| 142 expect(filesErrors[fooPath], isEmpty); | 147 expect(filesErrors[fooPath], isEmpty); |
| 143 expect(filesErrors[barPath], isEmpty); | 148 expect(filesErrors[barPath], isEmpty); |
| 144 }); | 149 } |
| 150 } |
| 151 |
| 152 test_overlayOnly() async { |
| 153 String filePath = '/User/project1/test.dart'; |
| 154 Folder folder1 = resourceProvider.newFolder('/User/project1'); |
| 155 Folder folder2 = resourceProvider.newFolder('/User/project2'); |
| 156 Request request = new AnalysisSetAnalysisRootsParams( |
| 157 [folder1.path, folder2.path], []).toRequest('0'); |
| 158 handleSuccessfulRequest(request); |
| 159 // exactly 2 contexts |
| 160 expect(server.folderMap, hasLength(2)); |
| 161 AnalysisContext context1 = server.folderMap[folder1]; |
| 162 AnalysisContext context2 = server.folderMap[folder2]; |
| 163 // no sources |
| 164 expect(_getUserSources(context1), isEmpty); |
| 165 expect(_getUserSources(context2), isEmpty); |
| 166 // add an overlay - new Source in context1 |
| 167 server.updateContent('1', {filePath: new AddContentOverlay('')}); |
| 168 { |
| 169 List<Source> sources = _getUserSources(context1); |
| 170 expect(sources, hasLength(1)); |
| 171 expect(sources[0].fullName, filePath); |
| 172 } |
| 173 expect(_getUserSources(context2), isEmpty); |
| 174 // remove the overlay - no sources |
| 175 server.updateContent('2', {filePath: new RemoveContentOverlay()}); |
| 176 expect(_getUserSources(context1), isEmpty); |
| 177 expect(_getUserSources(context2), isEmpty); |
| 145 } | 178 } |
| 146 | 179 |
| 147 test_sendNoticesAfterNopChange() async { | 180 test_sendNoticesAfterNopChange() async { |
| 148 createProject(); | 181 createProject(); |
| 149 addTestFile(''); | 182 addTestFile(''); |
| 150 await server.onAnalysisComplete; | 183 await server.onAnalysisComplete; |
| 151 // add an overlay | 184 // add an overlay |
| 152 server.updateContent( | 185 server.updateContent( |
| 153 '1', {testFile: new AddContentOverlay('main() {} main() {}')}); | 186 '1', {testFile: new AddContentOverlay('main() {} main() {}')}); |
| 154 await server.onAnalysisComplete; | 187 await server.onAnalysisComplete; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 173 // clear errors and make a no-op change | 206 // clear errors and make a no-op change |
| 174 filesErrors.clear(); | 207 filesErrors.clear(); |
| 175 server.test_flushResolvedUnit(testFile); | 208 server.test_flushResolvedUnit(testFile); |
| 176 server.updateContent('2', { | 209 server.updateContent('2', { |
| 177 testFile: new ChangeContentOverlay([new SourceEdit(0, 4, 'main')]) | 210 testFile: new ChangeContentOverlay([new SourceEdit(0, 4, 'main')]) |
| 178 }); | 211 }); |
| 179 await server.onAnalysisComplete; | 212 await server.onAnalysisComplete; |
| 180 // errors should have been resent | 213 // errors should have been resent |
| 181 expect(filesErrors, isNotEmpty); | 214 expect(filesErrors, isNotEmpty); |
| 182 } | 215 } |
| 216 |
| 217 List<Source> _getUserSources(AnalysisContext context) { |
| 218 List<Source> sources = <Source>[]; |
| 219 context.sources.forEach((source) { |
| 220 if (source.fullName.startsWith('/User/')) { |
| 221 sources.add(source); |
| 222 } |
| 223 }); |
| 224 return sources; |
| 225 } |
| 183 } | 226 } |
| 184 | 227 |
| 185 class _ArgumentMatcher_CompilationUnit extends ArgumentMatcher { | 228 class _ArgumentMatcher_CompilationUnit extends ArgumentMatcher { |
| 186 final String file; | 229 final String file; |
| 187 | 230 |
| 188 _ArgumentMatcher_CompilationUnit(this.file); | 231 _ArgumentMatcher_CompilationUnit(this.file); |
| 189 | 232 |
| 190 @override | 233 @override |
| 191 bool matches(arg) { | 234 bool matches(arg) { |
| 192 return arg is CompilationUnit && arg.element.source.fullName == file; | 235 return arg is CompilationUnit && arg.element.source.fullName == file; |
| 193 } | 236 } |
| 194 } | 237 } |
| 195 | 238 |
| 196 class _MockIndex extends TypedMock implements Index { | 239 class _MockIndex extends TypedMock implements Index { |
| 197 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); | 240 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); |
| 198 } | 241 } |
| OLD | NEW |