| // 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/src/computer/computer_highlights.dart'; |
| import 'package:analysis_server/src/protocol_server.dart'; |
| import 'package:analyzer/dart/analysis/results.dart'; |
| import 'package:test/test.dart'; |
| import 'package:test_reflective_loader/test_reflective_loader.dart'; |
| |
| import '../../abstract_context.dart'; |
| |
| void main() { |
| defineReflectiveSuite(() { |
| defineReflectiveTests(Highlights2ComputerTest); |
| }); |
| } |
| |
| @reflectiveTest |
| class Highlights2ComputerTest extends AbstractContextTest { |
| late String sourcePath; |
| late String content; |
| late List<HighlightRegion> highlights; |
| |
| @override |
| void setUp() { |
| super.setUp(); |
| sourcePath = convertPath('$testPackageLibPath/test.dart'); |
| } |
| |
| Future<void> test_comment() async { |
| await _computeHighlights(''' |
| // A trailing comment |
| '''); |
| _check(HighlightRegionType.COMMENT_END_OF_LINE, '// A trailing comment'); |
| } |
| |
| Future<void> test_comment_trailing() async { |
| await _computeHighlights(''' |
| class A {} |
| // A trailing comment |
| '''); |
| _check(HighlightRegionType.COMMENT_END_OF_LINE, '// A trailing comment'); |
| } |
| |
| Future<void> test_extension() async { |
| await _computeHighlights(''' |
| extension E on String {} |
| '''); |
| _check(HighlightRegionType.KEYWORD, 'extension'); |
| _check(HighlightRegionType.BUILT_IN, 'on'); |
| } |
| |
| Future<void> test_methodInvocation_ofExtensionOverride_unresolved() async { |
| await _computeHighlights(''' |
| extension E on int {} |
| |
| main() { |
| E(0).foo(); |
| } |
| ''', hasErrors: true); |
| _check(HighlightRegionType.IDENTIFIER_DEFAULT, 'foo'); |
| } |
| |
| Future<void> test_nullLiteral() async { |
| await _computeHighlights('var x = null;'); |
| _check(HighlightRegionType.KEYWORD, 'null'); |
| } |
| |
| Future<void> test_string_interpolated() async { |
| await _computeHighlights(r''' |
| class A { |
| String b(String c) => c; |
| } |
| var foo = A(); |
| var bar = A(); |
| var s = 'test1 $foo test2 ${bar.b('test3')}'; |
| '''); |
| _check(HighlightRegionType.LITERAL_STRING, "'test1 "); |
| _check(HighlightRegionType.TOP_LEVEL_GETTER_REFERENCE, 'foo'); |
| _check(HighlightRegionType.LITERAL_STRING, ' test2 '); |
| _check(HighlightRegionType.TOP_LEVEL_GETTER_REFERENCE, 'bar'); |
| _check(HighlightRegionType.INSTANCE_METHOD_REFERENCE, 'b'); |
| _check(HighlightRegionType.LITERAL_STRING, "'test3'"); |
| } |
| |
| Future<void> test_throwExpression() async { |
| await _computeHighlights(''' |
| void main() { |
| throw 'foo'; |
| } |
| '''); |
| _check(HighlightRegionType.KEYWORD, 'throw'); |
| } |
| |
| void _check(HighlightRegionType expectedType, String expectedText) { |
| for (var region in highlights) { |
| if (region.type == expectedType) { |
| var startIndex = region.offset; |
| var endIndex = startIndex + region.length; |
| var highlightedText = content.substring(startIndex, endIndex); |
| if (highlightedText == expectedText) { |
| return; |
| } |
| } |
| } |
| fail('Expected region of type $expectedType with text "$expectedText"'); |
| } |
| |
| Future<void> _computeHighlights( |
| String content, { |
| bool hasErrors = false, |
| }) async { |
| this.content = content; |
| newFile(sourcePath, content: content); |
| var result = |
| await session.getResolvedUnit(sourcePath) as ResolvedUnitResult; |
| |
| if (hasErrors) { |
| expect(result.errors, isNotEmpty); |
| } else { |
| expect(result.errors, isEmpty); |
| } |
| |
| var computer = DartUnitHighlightsComputer(result.unit); |
| highlights = computer.compute(); |
| } |
| } |