blob: 34888f08cf6ec71c0eac63b646a0815e210b288e [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.domain.analysis.notification.overrides;
import 'dart:async';
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/computer/computer_overrides.dart';
import 'package:analysis_server/src/computer/element.dart';
import 'package:analysis_server/src/constants.dart';
import 'package:analysis_server/src/protocol.dart';
import 'package:analysis_services/constants.dart';
import 'package:analysis_testing/reflective_tests.dart';
import 'package:unittest/unittest.dart';
import 'analysis_abstract.dart';
main() {
group('notification.overrides', () {
runReflectiveTests(AnalysisNotificationOverridesTest);
});
}
@ReflectiveTestCase()
class AnalysisNotificationOverridesTest extends AbstractAnalysisTest {
List<Override> overridesList;
Override override;
/**
* Asserts that there is an overridden interface [Element] at the offset of
* [search] in [override].
*/
void assertHasInterfaceElement(String search) {
int offset = findOffset(search);
for (Element element in override.interfaceElements) {
if (element.location.offset == offset) {
return;
}
}
fail(
'Expect to find an overridden interface elements at $offset in '
'${override.interfaceElements.join('\n')}');
}
/**
* Validates that there is an [Override] at the offset of [search].
*
* If [length] is not specified explicitly, then length of an identifier
* from [search] is used.
*/
void assertHasOverride(String search, [int length = -1]) {
int offset = findOffset(search);
if (length == -1) {
length = findIdentifierLength(search);
}
findOverride(offset, length, true);
}
/**
* Asserts that there is an overridden superclass [Element] at the offset of
* [search] in [override].
*/
void assertHasSuperElement(String search) {
int offset = findOffset(search);
Element element = override.superclassElement;
expect(element.location.offset, offset);
}
/**
* Asserts that there are no overridden elements from interfaces.
*/
void assertNoInterfaceElements() {
expect(override.interfaceElements, isNull);
}
/**
* Asserts that there are no overridden elements from the superclass.
*/
void assertNoSuperElement() {
expect(override.superclassElement, isNull);
}
/**
* Finds an [Override] with the given [offset] and [length].
*
* If [exists] is `true`, then fails if such [Override] does not exist.
* Otherwise remembers this it into [override].
*
* If [exists] is `false`, then fails if such [Override] exists.
*/
void findOverride(int offset, int length, [bool exists]) {
for (Override override in overridesList) {
if (override.offset == offset && override.length == length) {
if (exists == false) {
fail(
'Not expected to find (offset=$offset; length=$length) in\n'
'${overridesList.join('\n')}');
}
this.override = override;
return;
}
}
if (exists == true) {
fail(
'Expected to find (offset=$offset; length=$length) in\n'
'${overridesList.join('\n')}');
}
}
Future prepareOverrides() {
addAnalysisSubscription(AnalysisService.OVERRIDES, testFile);
return waitForTasksFinished();
}
void processNotification(Notification notification) {
if (notification.event == ANALYSIS_OVERRIDES) {
String file = notification.getParameter(FILE);
if (file == testFile) {
overridesList = <Override>[];
List<Map<String, Object>> jsonList =
notification.getParameter(OVERRIDES);
for (Map<String, Object> json in jsonList) {
overridesList.add(new Override.fromJson(json));
}
}
}
}
void setUp() {
super.setUp();
createProject();
}
test_afterAnalysis() {
addTestFile('''
class A {
m() {} // in A
}
class B implements A {
m() {} // in B
}
''');
return waitForTasksFinished().then((_) {
return prepareOverrides().then((_) {
assertHasOverride('m() {} // in B');
assertNoSuperElement();
assertHasInterfaceElement('m() {} // in A');
});
});
}
test_interface_method_direct_multiple() {
addTestFile('''
class IA {
m() {} // in IA
}
class IB {
m() {} // in IB
}
class A implements IA, IB {
m() {} // in A
}
''');
return prepareOverrides().then((_) {
assertHasOverride('m() {} // in A');
assertNoSuperElement();
assertHasInterfaceElement('m() {} // in IA');
assertHasInterfaceElement('m() {} // in IB');
});
}
test_interface_method_direct_single() {
addTestFile('''
class A {
m() {} // in A
}
class B implements A {
m() {} // in B
}
''');
return prepareOverrides().then((_) {
assertHasOverride('m() {} // in B');
assertNoSuperElement();
assertHasInterfaceElement('m() {} // in A');
});
}
test_interface_method_indirect_single() {
addTestFile('''
class A {
m() {} // in A
}
class B extends A {
}
class C implements B {
m() {} // in C
}
''');
return prepareOverrides().then((_) {
assertHasOverride('m() {} // in C');
assertNoSuperElement();
assertHasInterfaceElement('m() {} // in A');
});
}
test_super_fieldByField() {
addTestFile('''
class A {
int fff; // in A
}
class B extends A {
int fff; // in B
}
''');
return prepareOverrides().then((_) {
assertHasOverride('fff; // in B');
assertHasSuperElement('fff; // in A');
assertNoInterfaceElements();
});
}
test_super_fieldByGetter() {
addTestFile('''
class A {
int fff; // in A
}
class B extends A {
get fff => 0; // in B
}
''');
return prepareOverrides().then((_) {
assertHasOverride('fff => 0; // in B');
assertHasSuperElement('fff; // in A');
assertNoInterfaceElements();
});
}
test_super_fieldByMethod() {
addTestFile('''
class A {
int fff; // in A
}
class B extends A {
fff() {} // in B
}
''');
return prepareOverrides().then((_) {
assertHasOverride('fff() {} // in B');
assertHasSuperElement('fff; // in A');
assertNoInterfaceElements();
});
}
test_super_fieldBySetter() {
addTestFile('''
class A {
int fff; // in A
}
class B extends A {
set fff(x) {} // in B
}
''');
return prepareOverrides().then((_) {
assertHasOverride('fff(x) {} // in B');
assertHasSuperElement('fff; // in A');
assertNoInterfaceElements();
});
}
test_super_getterByField() {
addTestFile('''
class A {
get fff => 0; // in A
set fff(x) {} // in A
}
class B extends A {
int fff; // in B
}
''');
return prepareOverrides().then((_) {
assertHasOverride('fff; // in B');
assertHasSuperElement('fff => 0; // in A');
assertNoInterfaceElements();
});
}
test_super_getterByGetter() {
addTestFile('''
class A {
get fff => 0; // in A
}
class B extends A {
get fff => 0; // in B
}
''');
return prepareOverrides().then((_) {
assertHasOverride('fff => 0; // in B');
assertHasSuperElement('fff => 0; // in A');
assertNoInterfaceElements();
});
}
test_super_method_direct() {
addTestFile('''
class A {
m() {} // in A
}
class B extends A {
m() {} // in B
}
''');
return prepareOverrides().then((_) {
assertHasOverride('m() {} // in B');
assertHasSuperElement('m() {} // in A');
assertNoInterfaceElements();
});
}
test_super_method_indirect() {
addTestFile('''
class A {
m() {} // in A
}
class B extends A {
}
class C extends B {
m() {} // in C
}
''');
return prepareOverrides().then((_) {
assertHasOverride('m() {} // in C');
assertHasSuperElement('m() {} // in A');
assertNoInterfaceElements();
});
}
test_super_setterBySetter() {
addTestFile('''
class A {
set fff(x) {} // in A
}
class B extends A {
set fff(x) {} // in B
}
''');
return prepareOverrides().then((_) {
assertHasOverride('fff(x) {} // in B');
assertHasSuperElement('fff(x) {} // in A');
assertNoInterfaceElements();
});
}
}