blob: c802067505a104441e76ee26dfe6e79e84bb371a [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:test_reflective_loader/test_reflective_loader.dart';
import '../../../../client/completion_driver_test.dart';
import '../completion_check.dart';
import '../completion_printer.dart' as printer;
void main() {
defineReflectiveSuite(() {
defineReflectiveTests(EnumTest1);
defineReflectiveTests(EnumTest2);
});
}
@reflectiveTest
class EnumTest1 extends AbstractCompletionDriverTest with EnumTestCases {
@override
TestingCompletionProtocol get protocol => TestingCompletionProtocol.version1;
}
@reflectiveTest
class EnumTest2 extends AbstractCompletionDriverTest with EnumTestCases {
@override
TestingCompletionProtocol get protocol => TestingCompletionProtocol.version2;
}
mixin EnumTestCases on AbstractCompletionDriverTest {
@override
Future<void> setUp() async {
await super.setUp();
printerConfiguration = printer.Configuration(
filter: (suggestion) => true,
);
}
Future<void> test_enumConstantName() async {
await _check_locations(
declaration: '''
enum MyEnum { foo01 }
enum OtherEnum { foo02 }
''',
declarationForContextType: 'void useMyEnum(MyEnum _) {}',
codeAtCompletion: 'useMyEnum(foo0^);',
validator: (response, context) {
if (isProtocolVersion2) {
assertResponse('''
replacement
left: 4
suggestions
MyEnum.foo01
kind: enumConstant
''');
} else {
_configureWithMyEnum();
// The response includes much more, such as `MyEnum` itself.
// We don't expect though that the client will show it.
if (context == _Context.local) {
assertResponse('''
replacement
left: 4
suggestions
MyEnum
kind: enum
MyEnum.foo01
kind: enumConstant
''');
}
}
},
);
}
Future<void> test_enumConstantName_imported_withPrefix() async {
newFile('$testPackageLibPath/a.dart', r'''
enum MyEnum { foo01 }
enum OtherEnum { foo02 }
''');
if (isProtocolVersion1) {
await waitForSetWithUri('package:test/a.dart');
}
await computeSuggestions('''
import 'a.dart' as prefix;
void useMyEnum(prefix.MyEnum _) {}
void f() {
useMyEnum(foo0^);
}
''');
if (isProtocolVersion2) {
assertResponse('''
replacement
left: 4
suggestions
prefix.MyEnum.foo01
kind: enumConstant
''');
} else {
_configureWithMyEnum();
// TODO(scheglov) This is wrong.
assertResponse('''
replacement
left: 4
suggestions
MyEnum
kind: enum
MyEnum.foo01
kind: enumConstant
OtherEnum.foo02
kind: enumConstant
''');
}
}
Future<void> test_enumName() async {
await _check_locations(
declaration: 'enum MyEnum { foo01 }',
codeAtCompletion: 'MyEnu^',
referencesDeclaration: false,
validator: (response, context) {
if (isProtocolVersion2) {
// No enum constants.
assertResponse('''
replacement
left: 5
suggestions
MyEnum
kind: enum
''');
} else {
_configureWithMyEnum();
switch (context) {
case _Context.local:
assertResponse('''
replacement
left: 5
suggestions
MyEnum
kind: enum
''');
break;
case _Context.imported:
case _Context.notImported:
assertResponse('''
replacement
left: 5
suggestions
MyEnum
kind: enum
MyEnum.foo01
kind: enumConstant
''');
break;
}
}
},
);
}
Future<void> test_enumName_imported_withPrefix() async {
newFile('$testPackageLibPath/a.dart', r'''
enum MyEnum { foo01 }
''');
if (isProtocolVersion1) {
await waitForSetWithUri('package:test/a.dart');
}
await computeSuggestions('''
import 'a.dart' as prefix;
void f() {
MyEnu^
}
''');
if (isProtocolVersion2) {
assertResponse('''
replacement
left: 5
suggestions
prefix.MyEnum
kind: enum
''');
} else {
_configureWithMyEnum();
// TODO(scheglov) This is wrong.
assertResponse('''
replacement
left: 5
suggestions
MyEnum
kind: enum
MyEnum.foo01
kind: enumConstant
''');
}
}
Future<void> test_importPrefix() async {
newFile('$testPackageLibPath/a.dart', r'''
enum MyEnum { v }
''');
if (isProtocolVersion1) {
await waitForSetWithUri('package:test/a.dart');
}
await computeSuggestions('''
import 'a.dart' as prefix01;
void f() {
prefix0^
}
''');
if (isProtocolVersion2) {
// TODO(scheglov) The kind should be a prefix.
assertResponse('''
replacement
left: 7
suggestions
prefix01
kind: library
''');
} else {
_configureWithMyEnum();
// TODO(scheglov) This is wrong.
assertResponse('''
replacement
left: 7
suggestions
MyEnum
kind: enum
MyEnum.v
kind: enumConstant
''');
}
}
Future<void> test_importPrefix_dot() async {
newFile('$testPackageLibPath/a.dart', r'''
enum MyEnum { v }
''');
if (isProtocolVersion1) {
await waitForSetWithUri('package:test/a.dart');
}
await computeSuggestions('''
import 'a.dart' as prefix;
void f() {
prefix.^
}
''');
// TODO(scheglov) This is wrong.
// Should include constants, as [test_nothing_imported_withPrefix] does.
assertResponse('''
suggestions
MyEnum
kind: enum
''');
}
Future<void> test_nothing() async {
_configureWithMyEnum();
await _check_locations(
declaration: 'enum MyEnum { foo01 }',
declarationForContextType: 'void useMyEnum(MyEnum _) {}',
codeAtCompletion: 'useMyEnum(^);',
validator: (response, context) {
if (isProtocolVersion2) {
assertResponse('''
suggestions
MyEnum
kind: enum
MyEnum.foo01
kind: enumConstant
''');
} else {
switch (context) {
case _Context.local:
case _Context.imported:
assertResponse('''
suggestions
MyEnum
kind: enum
MyEnum.foo01
kind: enumConstant
''');
break;
case _Context.notImported:
assertResponse('''
suggestions
MyEnum
kind: enum
MyEnum.foo01
kind: enumConstant
useMyEnum
kind: functionInvocation
''');
break;
}
}
},
);
}
Future<void> test_nothing_imported_withPrefix() async {
_configureWithMyEnum();
newFile('$testPackageLibPath/a.dart', r'''
enum MyEnum { foo01 }
''');
await computeSuggestions('''
import 'a.dart' as prefix;
void useMyEnum(prefix.MyEnum _) {}
void f() {
useMyEnum(^);
}
''');
if (isProtocolVersion2) {
assertResponse('''
suggestions
prefix.MyEnum
kind: enum
prefix.MyEnum.foo01
kind: enumConstant
''');
} else {
// TODO(scheglov) This is wrong.
assertResponse('''
suggestions
MyEnum
kind: enum
MyEnum.foo01
kind: enumConstant
''');
}
}
Future<void> _check_locations({
required String declaration,
String declarationForContextType = '',
required String codeAtCompletion,
bool referencesDeclaration = true,
required void Function(
CompletionResponseForTesting response,
_Context context,
)
validator,
}) async {
// local
{
await computeSuggestions('''
$declaration
$declarationForContextType
void f() {
$codeAtCompletion
}
''');
validator(response, _Context.local);
}
// imported
{
newFile('$testPackageLibPath/a.dart', '''
$declaration
''');
if (isProtocolVersion1) {
await waitForSetWithUri('package:test/a.dart');
}
await computeSuggestions('''
import 'a.dart';
$declarationForContextType
void f() {
$codeAtCompletion
}
''');
validator(response, _Context.imported);
}
// not imported
{
newFile('$testPackageLibPath/a.dart', '''
$declaration
''');
newFile('$testPackageLibPath/context_type.dart', '''
import 'a.dart';${referencesDeclaration ? '' : ' // ignore: unused_import'}
$declarationForContextType
''');
if (isProtocolVersion1) {
await waitForSetWithUri('package:test/a.dart');
}
await computeSuggestions('''
import 'context_type.dart';
void f() {
$codeAtCompletion
}
''');
validator(response, _Context.notImported);
}
}
void _configureWithMyEnum() {
printerConfiguration.filter = (suggestion) {
final completion = suggestion.completion;
return completion.contains('MyEnum') || completion.contains('foo0');
};
}
}
enum _Context { local, imported, notImported }