blob: fd6a2400687da7540d84f73c6bee40349c31beeb [file] [log] [blame]
// Copyright (c) 2022, 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/services/snippets/dart/snippet_manager.dart';
import 'package:analyzer/src/test_utilities/platform.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../../../abstract_single_unit.dart';
import 'test_support.dart';
void main() {
defineReflectiveSuite(() {
defineReflectiveTests(SnippetRequestTest);
});
}
@reflectiveTest
class SnippetRequestTest extends AbstractSingleUnitTest {
SnippetRequestTest() {
verifyNoTestUnitErrors = false;
}
Future<void> test_expression_constructor() async {
await testRequest(r'''
final a = new [[^]]
''', SnippetContext.inExpressionOrStatement);
}
Future<void> test_expression_constructorName() async {
await testRequest(r'''
class A {
A.foo();
}
final a = new A.[[fo^]]
''', SnippetContext.inExpressionOrStatement);
}
Future<void> test_inAnnotation() async {
await testRequest(r'''
@[[depre^]]
class A {}
''', SnippetContext.inExpressionOrStatement);
}
Future<void> test_inBlock_forBody() async {
await testRequest(r'''
foo() {
for (var i = 0; i < 10; i++) {
[[^]]
}
}
''', SnippetContext.inBlock);
}
Future<void> test_inClass_atEnd() async {
await testRequest(r'''
class A {
foo() {}
[[^]]
}
''', SnippetContext.inClass);
}
Future<void> test_inClass_atEnd_partialIdentifier() async {
await testRequest(r'''
class A {
foo() {}
[[mysnip^]]
}
''', SnippetContext.inClass);
}
Future<void> test_inClass_atStart() async {
await testRequest(r'''
class A {
[[^]]
foo() {}
}
''', SnippetContext.inClass);
}
Future<void> test_inClass_atStart_partialIdentifier() async {
await testRequest(r'''
class A {
[[mysnip^]]
foo() {}
}
''', SnippetContext.inClass);
}
Future<void> test_inClass_betweenMembers() async {
await testRequest(r'''
class A {
foo() {}
[[^]]
bar() {}
}
''', SnippetContext.inClass);
}
Future<void> test_inClass_betweenMembers_partialIdentifier() async {
await testRequest(r'''
class A {
foo() {}
[[mysnip^]]
bar() {}
}
''', SnippetContext.inClass);
}
Future<void> test_inClass_empty() async {
await testRequest(r'''
class A {
[[^]]
}
''', SnippetContext.inClass);
}
Future<void> test_inClass_empty_partialIdentifier() async {
await testRequest(r'''
class A {
[[mysnip^]]
}
''', SnippetContext.inClass);
}
Future<void> test_inComment_dartDoc() async {
await testRequest(r'''
/// [[^]]
class A {}
''', SnippetContext.inComment);
}
Future<void> test_inComment_dartDoc_reference_member() async {
await testRequest(r'''
class A {
/// [ [[A^]] ]
foo() {}
}
''', SnippetContext.inComment);
}
Future<void> test_inComment_dartDoc_reference_topLevel() async {
await testRequest(r'''
/// [ [[A^]] ]
class A {}
''', SnippetContext.inComment);
}
Future<void> test_inComment_multiline_member() async {
await testRequest(r'''
class A {
/*
* [[^]]
*/
foo() {}
}
''', SnippetContext.inComment);
}
Future<void> test_inComment_multiline_topLevel() async {
await testRequest(r'''
/*
* [[^]]
*/
class A {}
''', SnippetContext.inComment);
}
Future<void> test_inComment_singleLine_member() async {
await testRequest(r'''
class A {
// [[^]]
foo () {}
}
''', SnippetContext.inComment);
}
Future<void> test_inComment_singleLine_topLevel() async {
await testRequest(r'''
// [[^]]
class A {}
''', SnippetContext.inComment);
}
Future<void> test_inExpression_functionCall() async {
await testRequest(r'''
foo() {
print([[^]]
}
''', SnippetContext.inExpressionOrStatement);
}
Future<void> test_inExtension() async {
await testRequest(r'''
extension on Object {
[[^]]
}
''', SnippetContext.inClass);
}
Future<void> test_inFunction_atEnd() async {
await testRequest(r'''
foo() {
var a = 1;
[[^]]
}
''', SnippetContext.inBlock);
}
Future<void> test_inFunction_atEnd_partialIdentifier() async {
await testRequest(r'''
foo() {
var a = 1;
[[mysnip^]]
}
''', SnippetContext.inBlock);
}
Future<void> test_inFunction_atStart() async {
await testRequest(r'''
foo() {
[[^]]
var a = 1;
}
''', SnippetContext.inBlock);
}
Future<void> test_inFunction_atStart_partialIdentifier() async {
await testRequest(r'''
foo() {
[[mysnip^]]
var a = 1;
}
''', SnippetContext.inBlock);
}
Future<void> test_inFunction_betweenStatements() async {
await testRequest(r'''
foo() {
var a = 1;
[[^]]
var b = 1;
}
''', SnippetContext.inBlock);
}
Future<void> test_inFunction_betweenStatements_partialIdentifier() async {
await testRequest(r'''
foo() {
var a = 1;
[[mysnip^]]
var b = 1;
}
''', SnippetContext.inBlock);
}
Future<void> test_inFunction_empty() async {
await testRequest(r'''
foo() {
[[^]]
}
''', SnippetContext.inBlock);
}
Future<void> test_inFunction_empty_partialIdentifier() async {
await testRequest(r'''
foo() {
[[mysnip^]]
}
''', SnippetContext.inBlock);
}
Future<void> test_inMethod_atEnd() async {
await testRequest(r'''
class A {
foo() {
var a = 1;
[[^]]
}
}
''', SnippetContext.inBlock);
}
Future<void> test_inMethod_atEnd_partialIdentifier() async {
await testRequest(r'''
class A {
foo() {
var a = 1;
[[mysnip^]]
}
}
''', SnippetContext.inBlock);
}
Future<void> test_inMethod_atStart() async {
await testRequest(r'''
class A {
foo() {
[[^]]
var a = 1;
}
}
''', SnippetContext.inBlock);
}
Future<void> test_inMethod_atStart_partialIdentifier() async {
await testRequest(r'''
class A {
foo() {
[[mysnip^]]
var a = 1;
}
}
''', SnippetContext.inBlock);
}
Future<void> test_inMethod_betweenStatements() async {
await testRequest(r'''
class A {
foo() {
var a = 1;
[[^]]
var b = 1;
}
}
''', SnippetContext.inBlock);
}
Future<void> test_inMethod_betweenStatements_partialIdentifier() async {
await testRequest(r'''
class A {
foo() {
var a = 1;
[[mysnip^]]
var b = 1;
}
}
''', SnippetContext.inBlock);
}
Future<void> test_inMethod_empty() async {
await testRequest(r'''
class A {
foo() {
[[^]]
}
}
''', SnippetContext.inBlock);
}
Future<void> test_inMethod_empty_partialIdentifier() async {
await testRequest(r'''
class A {
foo() {
[[mysnip^]]
}
}
''', SnippetContext.inBlock);
}
Future<void> test_inMixin() async {
await testRequest(r'''
mixin A {
[[^]]
}
''', SnippetContext.inClass);
}
Future<void> test_inStatement_forCondition() async {
await testRequest(r'''
foo() {
for (var i = [[^]]
}
''', SnippetContext.inExpressionOrStatement);
}
Future<void> test_inStatement_variableDeclaration() async {
await testRequest(r'''
foo() {
var a = [[^]]
}
''', SnippetContext.inExpressionOrStatement);
}
Future<void> test_inString() async {
await testRequest(r'''
const a = '[[^]]';
''', SnippetContext.inString);
}
Future<void> test_inString_raw() async {
await testRequest(r'''
const a = r'[[^]]';
''', SnippetContext.inString);
}
Future<void> test_inString_unterminated() async {
await testRequest(r'''
const a = r'[[^]]
''', SnippetContext.inString);
}
Future<void> test_topLevel_atEnd() async {
await testRequest(r'''
class A {}
[[^]]
''', SnippetContext.atTopLevel);
}
Future<void> test_topLevel_atEnd_partialIdentifier() async {
await testRequest(r'''
class A {}
[[mysnip^]]
''', SnippetContext.atTopLevel);
}
Future<void> test_topLevel_atStart() async {
await testRequest(r'''
[[^]]
class A {}
''', SnippetContext.atTopLevel);
}
Future<void> test_topLevel_atStart_partialIdentifier() async {
await testRequest(r'''
[[mysnip^]]
class A {}
''', SnippetContext.atTopLevel);
}
Future<void> test_topLevel_betweenClasses() async {
await testRequest(r'''
class A {}
[[^]]
class B {}
''', SnippetContext.atTopLevel);
}
Future<void> test_topLevel_betweenClasses_partialIdentifier() async {
await testRequest(r'''
class A {}
[[mysnip^]]
class B {}
''', SnippetContext.atTopLevel);
}
Future<void> test_topLevel_empty() async {
await testRequest('[[^]]', SnippetContext.atTopLevel);
}
Future<void> test_topLevel_empty_partialIdentifier() async {
await testRequest('[[mysnip^]]', SnippetContext.atTopLevel);
}
/// Checks that [code] produces a context of [expectedContext] where the
/// character '^' in [code] represents the supplied offset and the range
/// surrounded `[[` by brackets `]]` is the expected replacement range.
///
/// `^`, `[[` and `]]` will be removed from the code before resolving.
Future<void> testRequest(String code, SnippetContext expectedContext) async {
code = normalizeNewlinesForPlatform(code);
final offset = offsetFromMarker(code);
final expectedReplacementRange = rangeFromMarkers(code);
await resolveTestCode(withoutMarkers(code));
final request = DartSnippetRequest(
unit: testAnalysisResult,
offset: offset,
);
expect(request.filePath, testFile);
expect(request.offset, offset);
expect(request.context, expectedContext);
expect(request.replacementRange, expectedReplacementRange);
}
}