blob: 71569e8569444ae4260049865f5740037c802bc5 [file] [log] [blame]
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library test.operation.queue;
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/operation/operation.dart';
import 'package:analysis_server/src/operation/operation_analysis.dart';
import 'package:analysis_server/src/operation/operation_queue.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:typed_mock/typed_mock.dart';
import 'package:unittest/unittest.dart';
import '../mocks.dart';
main() {
groupSep = ' | ';
defineReflectiveTests(ServerOperationQueueTest);
}
/**
* Return a [ServerOperation] mock with the given priority.
*/
ServerOperation mockOperation(ServerOperationPriority priority) {
ServerOperation operation = new _ServerOperationMock();
when(operation.priority).thenReturn(priority);
return operation;
}
class AnalysisContextMock extends TypedMock implements InternalAnalysisContext {
List<Source> prioritySources = <Source>[];
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
class AnalysisServerMock extends TypedMock implements AnalysisServer {
@override
final ResourceProvider resourceProvider;
@override
final SearchEngine searchEngine;
AnalysisServerMock({this.resourceProvider, this.searchEngine});
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
class ServerContextManagerMock extends TypedMock
implements ServerContextManager {
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
@reflectiveTest
class ServerOperationQueueTest {
ServerOperationQueue queue = new ServerOperationQueue();
void test_clear() {
var operationA = mockOperation(ServerOperationPriority.ANALYSIS);
var operationB = mockOperation(ServerOperationPriority.ANALYSIS_CONTINUE);
queue.add(operationA);
queue.add(operationB);
// there are some operations
expect(queue.isEmpty, false);
// clear - no operations
queue.clear();
expect(queue.isEmpty, true);
}
void test_contextRemoved() {
var contextA = new AnalysisContextMock();
var contextB = new AnalysisContextMock();
var opA1 = new _ServerOperationMock(contextA);
var opA2 = new _ServerOperationMock(contextA);
var opB1 = new _ServerOperationMock(contextB);
var opB2 = new _ServerOperationMock(contextB);
when(opA1.priority)
.thenReturn(ServerOperationPriority.ANALYSIS_NOTIFICATION);
when(opA2.priority)
.thenReturn(ServerOperationPriority.ANALYSIS_NOTIFICATION);
when(opB1.priority)
.thenReturn(ServerOperationPriority.ANALYSIS_NOTIFICATION);
when(opB2.priority)
.thenReturn(ServerOperationPriority.ANALYSIS_NOTIFICATION);
queue.add(opA1);
queue.add(opB1);
queue.add(opA2);
queue.add(opB2);
queue.contextRemoved(contextA);
expect(queue.take(), same(opB1));
expect(queue.take(), same(opB2));
}
void test_isEmpty_false() {
var operation = mockOperation(ServerOperationPriority.ANALYSIS);
queue.add(operation);
expect(queue.isEmpty, isFalse);
}
void test_isEmpty_true() {
expect(queue.isEmpty, isTrue);
}
void test_reschedule() {
var prioritySource = new MockSource();
var analysisContextA = new AnalysisContextMock();
var analysisContextB = new AnalysisContextMock();
var operationA = new PerformAnalysisOperation(analysisContextA, false);
var operationB = new PerformAnalysisOperation(analysisContextB, false);
queue.add(operationA);
queue.add(operationB);
// update priority sources and reschedule
analysisContextB.prioritySources = [prioritySource];
queue.reschedule();
// verify order
expect(queue.take(), operationB);
expect(queue.take(), operationA);
expect(queue.take(), isNull);
}
void test_sourceAboutToChange() {
Source sourceA = new _SourceMock();
Source sourceB = new _SourceMock();
var opA1 = new _SourceSensitiveOperationMock(sourceA);
var opA2 = new _SourceSensitiveOperationMock(sourceA);
var opB1 = new _SourceSensitiveOperationMock(sourceB);
var opB2 = new _SourceSensitiveOperationMock(sourceB);
queue.add(opA1);
queue.add(opB1);
queue.add(opA2);
queue.add(opB2);
queue.sourceAboutToChange(sourceA);
expect(queue.take(), same(opB1));
expect(queue.take(), same(opB2));
}
void test_take_continueAnalysisFirst() {
var analysisContext = new AnalysisContextMock();
var operationA = new PerformAnalysisOperation(analysisContext, false);
var operationB = new PerformAnalysisOperation(analysisContext, true);
queue.add(operationA);
queue.add(operationB);
expect(queue.take(), operationB);
expect(queue.take(), operationA);
expect(queue.take(), isNull);
}
void test_take_empty() {
expect(queue.take(), isNull);
}
void test_take_priorityContextFirst() {
var prioritySource = new MockSource();
var analysisContextA = new AnalysisContextMock();
var analysisContextB = new AnalysisContextMock();
analysisContextB.prioritySources = [prioritySource];
var operationA = new PerformAnalysisOperation(analysisContextA, false);
var operationB = new PerformAnalysisOperation(analysisContextB, false);
queue.add(operationA);
queue.add(operationB);
expect(queue.take(), operationB);
expect(queue.take(), operationA);
expect(queue.take(), isNull);
}
void test_take_useOperationPriorities() {
var operationA = mockOperation(ServerOperationPriority.ANALYSIS);
var operationB = mockOperation(ServerOperationPriority.ANALYSIS_CONTINUE);
var operationC = mockOperation(ServerOperationPriority.PRIORITY_ANALYSIS);
queue.add(operationA);
queue.add(operationB);
queue.add(operationC);
expect(queue.take(), operationC);
expect(queue.take(), operationB);
expect(queue.take(), operationA);
expect(queue.take(), isNull);
}
}
class _ServerOperationMock extends TypedMock implements ServerOperation {
final AnalysisContext context;
_ServerOperationMock([this.context]);
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
class _SourceMock extends TypedMock implements Source {
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
class _SourceSensitiveOperationMock extends TypedMock
implements SourceSensitiveOperation {
final Source source;
_SourceSensitiveOperationMock(this.source);
@override
ServerOperationPriority get priority {
return ServerOperationPriority.ANALYSIS_NOTIFICATION;
}
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
@override
bool shouldBeDiscardedOnSourceChange(Source source) {
return source == this.source;
}
}