blob: 987e624d0a3648c621006a774553ebe368a20300 [file] [log] [blame]
// Copyright (c) 2021, 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 '../rule_test_support.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(PreferConstConstructorsTest);
});
}
@reflectiveTest
class PreferConstConstructorsTest extends LintRuleTest {
@override
bool get addMetaPackageDep => true;
@override
String get lintRule => 'prefer_const_constructors';
test_canBeConst_argumentIsAdjacentStrings() async {
await assertDiagnostics(r'''
class A {
const A(String s);
}
var a = A('adjacent' 'string');
''', [
lint(41, 22),
]);
}
test_canBeConst_argumentIsListLiteral() async {
await assertDiagnostics(r'''
class A {
const A(List<int> l);
}
var a = A([]);
''', [
lint(44, 5),
]);
}
test_canBeConst_argumentIsMap_nonLiteral() async {
await assertNoDiagnostics(r'''
class A {
const A(Map<int, int> m);
}
A f(Map<int, int> m) => A(m);
''');
}
test_canBeConst_argumentIsMapLiteral_containsNonLiteral() async {
await assertNoDiagnostics(r'''
class A {
const A(Map<int, int> m);
}
A f(int x) => A({x: x});
''');
}
test_canBeConst_argumentIsMapLiteral_instantiated() async {
await assertDiagnostics(r'''
class A {
const A(Map<int, int> m);
}
var a = A({});
''', [
lint(48, 5),
]);
}
test_canBeConst_explicitTypeArgument_dynamic() async {
await assertDiagnostics(r'''
class A<T> {
const A();
}
var a = A<dynamic>();
''', [
lint(36, 12),
]);
}
test_canBeConst_explicitTypeArgument_string() async {
await assertDiagnostics(r'''
class A<T> {
const A();
}
var a = A<String>();
''', [
lint(36, 11),
]);
}
test_canBeConst_implicitTypeArgument() async {
await assertNoDiagnostics(r'''
class A<T, U> {
const A();
}
A<T, int> f<T>() => A();
''');
}
test_canBeConst_implicitTypeArgument_downwardInference() async {
await assertDiagnostics(r'''
class A<T> {
const A();
}
A<int> f() => A();
''', [
lint(42, 3),
]);
}
test_canBeConst_implicitTypeArgument_inConditional() async {
await assertNoDiagnostics(r'''
class A<T, U> {
const A();
}
class B<T, U> extends A<T, U> {}
A<T, int> f<T>(bool b) => b ? A() : B();
''');
}
test_canBeConst_intLiteralArgument() async {
await assertDiagnostics(r'''
class A {
const A(int x);
}
var a = A(5);
''', [
lint(38, 4),
]);
}
test_canBeConst_optionalNamedParameter() async {
await assertDiagnostics(r'''
class A {
const A({A? parent});
}
var a = A();
''', [
lint(44, 3),
]);
}
test_canBeConst_optionalNamedParameter_nested() async {
await assertDiagnostics(r'''
class A {
const A({A? parent});
const A.a();
}
var a = A(
parent: A.a(),
);
''', [
lint(59, 21),
lint(72, 5),
]);
}
test_canBeConst_optionalNamedParameter_newKeyword() async {
await assertDiagnostics(r'''
class A {
const A({A? parent});
}
var a = new A();
''', [
lint(44, 7),
]);
}
test_cannotBeConst_argumentIsAdjacentStrings_withInterpolation() async {
await assertNoDiagnostics(r'''
class A {
const A(String s);
}
A f(int i) => A('adjacent' '$i');
''');
}
test_cannotBeConst_argumentIsExtensionTypeMethodCall() async {
await assertNoDiagnostics(r'''
final class A {
final Ex f;
const A(this.f);
void foo() {
var a = A(-f);
}
}
extension type const Ex(int i) implements int {
Ex operator -() => Ex(-i);
}
''');
}
test_cannotBeConst_argumentIsListLiteral_nonLiteralElement() async {
await assertNoDiagnostics(r'''
class A {
const A(List<int> l);
}
A f(int i) => A([i]);
''');
}
test_cannotBeConst_argumentIsLocalVariable() async {
await assertNoDiagnostics(r'''
class A {
const A(String s);
}
void f() {
final s = '';
var a = A(s);
}
''');
}
test_cannotBeConst_argumentIsNonLiteral() async {
await assertNoDiagnostics(r'''
class A {
const A(String s);
}
A f(String s) => A(s);
''');
}
test_cannotBeConst_argumentIsNonLiteralList() async {
await assertNoDiagnostics(r'''
class A {
const A(List<int> l);
}
A f(List<int> l) => A(l);
''');
}
test_cannotBeConst_explicitTypeArgument_typeVariable() async {
await assertNoDiagnostics(r'''
class A<T> {
const A();
}
void f<U>() => A<U>();
''');
}
test_cannotBeConst_nonConstArgument() async {
await assertNoDiagnostics(r'''
class A {
final int x;
const A(this.x);
}
A f(int x) => A(x);
''');
}
test_cannotBeConst_notConstConstructor() async {
await assertNoDiagnostics(r'''
class A {
A();
}
var a = A();
''');
}
test_cannotBeConst_stringLiteralArgument_withInterpolation() async {
await assertNoDiagnostics(r'''
class A {
const A(String s);
static A m1(int i) => A('$i');
}
''');
}
test_deferred_arg() async {
newFile('$testPackageLibPath/a.dart', '''
class A {
const A();
}
const aa = A();
''');
await assertNoDiagnostics(r'''
import 'a.dart' deferred as a;
class B {
const B(Object a);
}
main() {
var b = B(a.aa);
}
''');
}
test_deferredConstructorCall() async {
newFile('$testPackageLibPath/a.dart', '''
class A {
const A();
}
''');
await assertNoDiagnostics(r'''
import 'a.dart' deferred as a;
void f() {
var aa = a.A();
}
''');
}
test_extensionType_constPrimaryConstructor() async {
await assertDiagnostics(r'''
extension type const E(int i) {}
var e = E(1);
''', [
lint(42, 4),
]);
}
test_extensionType_nonConstPrimaryConstructor() async {
await assertNoDiagnostics(r'''
extension type E(int i) {}
var e = E(1);
''');
}
test_extraPositionalArgument() async {
await assertDiagnostics(r'''
import 'package:meta/meta.dart';
class K {
@literal
const K();
}
K k() {
var kk = K();
return kk;
}
''', [
// No lint
error(WarningCode.NON_CONST_CALL_TO_LITERAL_CONSTRUCTOR, 90, 3),
]);
}
test_isConst_intLiteralArgument() async {
await assertNoDiagnostics(r'''
class A {
final int x;
const A(this.x);
}
A f() => const A(5);
''');
}
test_isConstCall_optionalNamedParameter() async {
await assertNoDiagnostics(r'''
class A {
const A({A? parent});
}
var a = const A();
''');
}
test_objectConstructorCall() async {
await assertNoDiagnostics(r'''
var x = Object();
''');
}
}