blob: 68e12001422bf2c7e4bca724ea4aecb8b0f9bd37 [file] [log] [blame]
// Copyright (c) 2019, 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.
import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
import 'package:analysis_server/src/lsp/constants.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../tool/lsp_spec/matchers.dart';
import 'server_abstract.dart';
void main() {
defineReflectiveSuite(() {
defineReflectiveTests(DocumentHighlightsTest);
});
}
@reflectiveTest
class DocumentHighlightsTest extends AbstractLspAnalysisServerTest {
Future<void> test_functions() => _testMarkedContent('''
[[main]]() {
[[mai^n]]();
}
''');
Future<void> test_invalidLineByOne() async {
// Test that requesting a line that's too high by one returns a valid
// error response instead of throwing.
const content = '// single line';
await initialize();
await openFile(mainFileUri, withoutMarkers(content));
// Lines are zero-based so 1 is invalid.
final pos = Position(line: 1, character: 0);
final request = getDocumentHighlights(mainFileUri, pos);
await expectLater(
request, throwsA(isResponseError(ServerErrorCodes.InvalidFileLineCol)));
}
Future<void> test_localVariable() => _testMarkedContent('''
main() {
var [[f^oo]] = 1;
print([[foo]]);
[[foo]] = 2;
}
''');
Future<void> test_nonDartFile() async {
await initialize();
await openFile(pubspecFileUri, simplePubspecContent);
final highlights =
await getDocumentHighlights(pubspecFileUri, startOfDocPos);
// Non-Dart files should return empty results, not errors.
expect(highlights, isEmpty);
}
Future<void> test_noResult() => _testMarkedContent('''
main() {
// This one is in a ^ comment!
}
''');
Future<void> test_onlySelf() => _testMarkedContent('''
main() {
[[prin^t]]();
}
''');
Future<void> test_shadow_inner() => _testMarkedContent('''
main() {
var foo = 1;
func() {
var [[fo^o]] = 2;
print([[foo]]);
}
}
''');
Future<void> test_shadow_outer() => _testMarkedContent('''
main() {
var [[foo]] = 1;
func() {
var foo = 2;
print(foo);
}
print([[fo^o]]);
}
''');
Future<void> test_topLevelVariable() => _testMarkedContent('''
String [[foo]] = 'bar';
main() {
print([[foo]]);
[[fo^o]] = 2;
}
''');
/// Tests highlights in a Dart file using the provided content.
/// The content should be marked with a ^ where the highlights request should
/// be invoked and with `[[double brackets]]` around each range expected to
/// be highlighted (eg. all references to the symbol under ^).
/// If the content does not include any `[[double brackets]]` then the response
/// is expected to be `null`.
Future<void> _testMarkedContent(String content) async {
final expectedRanges = rangesFromMarkers(content);
await initialize();
await openFile(mainFileUri, withoutMarkers(content));
final pos = positionFromMarker(content);
final highlights = await getDocumentHighlights(mainFileUri, pos);
if (expectedRanges.isEmpty) {
expect(highlights, isNull);
} else {
final highlightRanges = highlights!.map((h) => h.range).toList();
expect(highlightRanges, equals(expectedRanges));
}
}
}