OLD | NEW |
| (Empty) |
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 | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 import 'package:analysis_server/src/analysis_server.dart'; | |
6 import 'package:analysis_server/src/context_manager.dart'; | |
7 import 'package:analysis_server/src/operation/operation.dart'; | |
8 import 'package:analysis_server/src/operation/operation_analysis.dart'; | |
9 import 'package:analysis_server/src/operation/operation_queue.dart'; | |
10 import 'package:analysis_server/src/services/search/search_engine.dart'; | |
11 import 'package:analyzer/file_system/file_system.dart'; | |
12 import 'package:analyzer/src/generated/engine.dart'; | |
13 import 'package:analyzer/src/generated/source.dart'; | |
14 import 'package:test/test.dart'; | |
15 import 'package:test_reflective_loader/test_reflective_loader.dart'; | |
16 import 'package:typed_mock/typed_mock.dart'; | |
17 | |
18 import '../mocks.dart'; | |
19 | |
20 main() { | |
21 defineReflectiveSuite(() { | |
22 defineReflectiveTests(ServerOperationQueueTest); | |
23 }); | |
24 } | |
25 | |
26 /** | |
27 * Return a [ServerOperation] mock with the given priority. | |
28 */ | |
29 ServerOperation mockOperation(ServerOperationPriority priority) { | |
30 ServerOperation operation = new _ServerOperationMock(); | |
31 when(operation.priority).thenReturn(priority); | |
32 return operation; | |
33 } | |
34 | |
35 class AnalysisContextMock extends TypedMock implements InternalAnalysisContext { | |
36 List<Source> prioritySources = <Source>[]; | |
37 } | |
38 | |
39 class AnalysisServerMock extends TypedMock implements AnalysisServer { | |
40 @override | |
41 final ResourceProvider resourceProvider; | |
42 | |
43 @override | |
44 final SearchEngine searchEngine; | |
45 | |
46 AnalysisServerMock({this.resourceProvider, this.searchEngine}); | |
47 } | |
48 | |
49 class ServerContextManagerMock extends TypedMock implements ContextManager {} | |
50 | |
51 @reflectiveTest | |
52 class ServerOperationQueueTest { | |
53 ServerOperationQueue queue = new ServerOperationQueue(); | |
54 | |
55 void test_add_withMerge() { | |
56 var opA = new _MergeableOperationMock(); | |
57 var opB = new _MergeableOperationMock(); | |
58 var opC = new _MergeableOperationMock(); | |
59 when(opA.merge(opC)).thenReturn(true); | |
60 when(opA.merge(anyObject)).thenReturn(false); | |
61 when(opB.merge(anyObject)).thenReturn(false); | |
62 when(opC.merge(anyObject)).thenReturn(false); | |
63 queue.add(opA); | |
64 queue.add(opB); | |
65 queue.add(opC); | |
66 expect(queue.take(), same(opA)); | |
67 expect(queue.take(), same(opB)); | |
68 // no opC, it was merged into opA | |
69 expect(queue.isEmpty, isTrue); | |
70 } | |
71 | |
72 void test_clear() { | |
73 var operationA = mockOperation(ServerOperationPriority.ANALYSIS); | |
74 var operationB = mockOperation(ServerOperationPriority.ANALYSIS_CONTINUE); | |
75 queue.add(operationA); | |
76 queue.add(operationB); | |
77 // there are some operations | |
78 expect(queue.isEmpty, false); | |
79 // clear - no operations | |
80 queue.clear(); | |
81 expect(queue.isEmpty, true); | |
82 } | |
83 | |
84 void test_contextRemoved() { | |
85 var contextA = new AnalysisContextMock(); | |
86 var contextB = new AnalysisContextMock(); | |
87 var opA1 = new _ServerOperationMock(contextA); | |
88 var opA2 = new _ServerOperationMock(contextA); | |
89 var opB1 = new _ServerOperationMock(contextB); | |
90 var opB2 = new _ServerOperationMock(contextB); | |
91 when(opA1.priority) | |
92 .thenReturn(ServerOperationPriority.ANALYSIS_NOTIFICATION); | |
93 when(opA2.priority) | |
94 .thenReturn(ServerOperationPriority.ANALYSIS_NOTIFICATION); | |
95 when(opB1.priority) | |
96 .thenReturn(ServerOperationPriority.ANALYSIS_NOTIFICATION); | |
97 when(opB2.priority) | |
98 .thenReturn(ServerOperationPriority.ANALYSIS_NOTIFICATION); | |
99 queue.add(opA1); | |
100 queue.add(opB1); | |
101 queue.add(opA2); | |
102 queue.add(opB2); | |
103 queue.contextRemoved(contextA); | |
104 expect(queue.take(), same(opB1)); | |
105 expect(queue.take(), same(opB2)); | |
106 } | |
107 | |
108 void test_isEmpty_false() { | |
109 var operation = mockOperation(ServerOperationPriority.ANALYSIS); | |
110 queue.add(operation); | |
111 expect(queue.isEmpty, isFalse); | |
112 } | |
113 | |
114 void test_isEmpty_true() { | |
115 expect(queue.isEmpty, isTrue); | |
116 } | |
117 | |
118 void test_peek() { | |
119 var operationA = mockOperation(ServerOperationPriority.ANALYSIS); | |
120 var operationB = mockOperation(ServerOperationPriority.ANALYSIS); | |
121 queue.add(operationA); | |
122 queue.add(operationB); | |
123 expect(queue.peek(), operationA); | |
124 expect(queue.peek(), operationA); | |
125 expect(queue.peek(), operationA); | |
126 } | |
127 | |
128 void test_peek_empty() { | |
129 expect(queue.peek(), isNull); | |
130 } | |
131 | |
132 void test_reschedule() { | |
133 var prioritySource = new MockSource(); | |
134 var analysisContextA = new AnalysisContextMock(); | |
135 var analysisContextB = new AnalysisContextMock(); | |
136 var operationA = new PerformAnalysisOperation(analysisContextA, false); | |
137 var operationB = new PerformAnalysisOperation(analysisContextB, false); | |
138 queue.add(operationA); | |
139 queue.add(operationB); | |
140 // update priority sources and reschedule | |
141 analysisContextB.prioritySources = [prioritySource]; | |
142 queue.reschedule(); | |
143 // verify order | |
144 expect(queue.take(), operationB); | |
145 expect(queue.take(), operationA); | |
146 expect(queue.take(), isNull); | |
147 } | |
148 | |
149 void test_sourceAboutToChange() { | |
150 Source sourceA = new _SourceMock(); | |
151 Source sourceB = new _SourceMock(); | |
152 var opA1 = new _SourceSensitiveOperationMock(sourceA); | |
153 var opA2 = new _SourceSensitiveOperationMock(sourceA); | |
154 var opB1 = new _SourceSensitiveOperationMock(sourceB); | |
155 var opB2 = new _SourceSensitiveOperationMock(sourceB); | |
156 queue.add(opA1); | |
157 queue.add(opB1); | |
158 queue.add(opA2); | |
159 queue.add(opB2); | |
160 queue.sourceAboutToChange(sourceA); | |
161 expect(queue.take(), same(opB1)); | |
162 expect(queue.take(), same(opB2)); | |
163 } | |
164 | |
165 void test_take_continueAnalysisFirst() { | |
166 var analysisContext = new AnalysisContextMock(); | |
167 var operationA = new PerformAnalysisOperation(analysisContext, false); | |
168 var operationB = new PerformAnalysisOperation(analysisContext, true); | |
169 queue.add(operationA); | |
170 queue.add(operationB); | |
171 expect(queue.take(), operationB); | |
172 expect(queue.take(), operationA); | |
173 expect(queue.take(), isNull); | |
174 } | |
175 | |
176 void test_take_empty() { | |
177 expect(queue.take(), isNull); | |
178 } | |
179 | |
180 void test_take_priorityContextFirst() { | |
181 var prioritySource = new MockSource(); | |
182 var analysisContextA = new AnalysisContextMock(); | |
183 var analysisContextB = new AnalysisContextMock(); | |
184 analysisContextB.prioritySources = [prioritySource]; | |
185 var operationA = new PerformAnalysisOperation(analysisContextA, false); | |
186 var operationB = new PerformAnalysisOperation(analysisContextB, false); | |
187 queue.add(operationA); | |
188 queue.add(operationB); | |
189 expect(queue.take(), operationB); | |
190 expect(queue.take(), operationA); | |
191 expect(queue.take(), isNull); | |
192 } | |
193 | |
194 void test_take_useOperationPriorities() { | |
195 var operationA = mockOperation(ServerOperationPriority.ANALYSIS); | |
196 var operationB = mockOperation(ServerOperationPriority.ANALYSIS_CONTINUE); | |
197 var operationC = mockOperation(ServerOperationPriority.PRIORITY_ANALYSIS); | |
198 queue.add(operationA); | |
199 queue.add(operationB); | |
200 queue.add(operationC); | |
201 expect(queue.take(), operationC); | |
202 expect(queue.take(), operationB); | |
203 expect(queue.take(), operationA); | |
204 expect(queue.take(), isNull); | |
205 } | |
206 | |
207 void test_takeIf() { | |
208 var operationA = mockOperation(ServerOperationPriority.ANALYSIS); | |
209 var operationB = mockOperation(ServerOperationPriority.ANALYSIS); | |
210 queue.add(operationA); | |
211 queue.add(operationB); | |
212 expect(queue.takeIf((_) => false), isNull); | |
213 expect(queue.takeIf((operation) => operation == operationB), operationB); | |
214 expect(queue.takeIf((operation) => operation == operationB), isNull); | |
215 expect(queue.takeIf((operation) => operation == operationA), operationA); | |
216 expect(queue.isEmpty, isTrue); | |
217 } | |
218 } | |
219 | |
220 class _MergeableOperationMock extends TypedMock implements MergeableOperation { | |
221 @override | |
222 ServerOperationPriority get priority { | |
223 return ServerOperationPriority.ANALYSIS_NOTIFICATION; | |
224 } | |
225 } | |
226 | |
227 class _ServerOperationMock extends TypedMock implements ServerOperation { | |
228 final AnalysisContext context; | |
229 | |
230 _ServerOperationMock([this.context]); | |
231 } | |
232 | |
233 class _SourceMock extends TypedMock implements Source {} | |
234 | |
235 class _SourceSensitiveOperationMock extends TypedMock | |
236 implements SourceSensitiveOperation { | |
237 final Source source; | |
238 | |
239 _SourceSensitiveOperationMock(this.source); | |
240 | |
241 @override | |
242 ServerOperationPriority get priority { | |
243 return ServerOperationPriority.ANALYSIS_NOTIFICATION; | |
244 } | |
245 | |
246 @override | |
247 bool shouldBeDiscardedOnSourceChange(Source source) { | |
248 return source == this.source; | |
249 } | |
250 } | |
OLD | NEW |