Skip to content

Commit 77917ea

Browse files
committed
add create ignore test
1 parent acaac23 commit 77917ea

File tree

4 files changed

+77
-6
lines changed

4 files changed

+77
-6
lines changed

drift_dev/lib/src/lints/custom_lint_plugin.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'package:custom_lint_builder/custom_lint_builder.dart';
22
import 'package:drift_dev/src/lints/drift_backend_error_lint.dart';
3+
import 'package:drift_dev/src/lints/non_null_insert_with_ignore_lint.dart';
34
import 'package:drift_dev/src/lints/offset_without_limit_lint.dart';
45
import 'package:drift_dev/src/lints/unawaited_futures_in_transaction_lint.dart';
56
import 'package:meta/meta.dart';
@@ -11,6 +12,7 @@ class DriftLinter extends PluginBase {
1112
unawaitedFuturesInMigration,
1213
unawaitedFuturesInTransaction,
1314
OffsetWithoutLimit(),
14-
DriftBuildErrors()
15+
DriftBuildErrors(),
16+
NonNullInsertWithIgnore()
1517
];
1618
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import 'package:analyzer/dart/ast/ast.dart';
2+
import 'package:analyzer/error/error.dart' hide LintCode;
3+
import 'package:analyzer/error/listener.dart';
4+
import 'package:custom_lint_builder/custom_lint_builder.dart';
5+
6+
final managerTypeChecker =
7+
TypeChecker.fromName('BaseTableManager', packageName: 'drift');
8+
final insertStatementChecker =
9+
TypeChecker.fromName('InsertStatement', packageName: 'drift');
10+
final insertOrIgnoreChecker =
11+
TypeChecker.fromName('InsertMode', packageName: 'drift');
12+
13+
class NonNullInsertWithIgnore extends DartLintRule {
14+
NonNullInsertWithIgnore() : super(code: _code);
15+
16+
static const _code = LintCode(
17+
name: 'non_null_insert_with_ignore',
18+
problemMessage:
19+
'`insertReturning` and `createReturning` will throw an exception if a row isn\'t actually inserted. Use `createReturningOrNull` or `insertReturningOrNull` if you want to ignore conflicts.',
20+
errorSeverity: ErrorSeverity.WARNING,
21+
);
22+
23+
@override
24+
void run(CustomLintResolver resolver, ErrorReporter reporter,
25+
CustomLintContext context) async {
26+
context.registry.addMethodInvocation(
27+
(node) {
28+
if (node.argumentList.arguments.isEmpty) return;
29+
switch (node.function) {
30+
case SimpleIdentifier func:
31+
if (func.name == "insertReturning" ||
32+
func.name == "createReturning") {
33+
switch (func.parent) {
34+
case MethodInvocation func:
35+
final targetType = func.realTarget?.staticType;
36+
if (targetType != null) {
37+
if (managerTypeChecker.isSuperTypeOf(targetType) ||
38+
insertStatementChecker.isExactlyType(targetType)) {
39+
final namedArgs = func.argumentList.arguments
40+
.whereType<NamedExpression>();
41+
for (final arg in namedArgs) {
42+
if (arg.name.label.name == "mode") {
43+
switch (arg.expression) {
44+
case PrefixedIdentifier mode:
45+
if (mode.identifier.name == "insertOrIgnore") {
46+
print("Found insertOrIgnore");
47+
reporter.atNode(node, _code);
48+
}
49+
}
50+
}
51+
}
52+
}
53+
}
54+
}
55+
}
56+
}
57+
},
58+
);
59+
}
60+
}

drift_dev/test/lint/lint_test.dart

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,8 @@ void main() {
88
test('linter', () async {
99
final workingDir = p.join(p.current, 'test/lint/test_pkg');
1010
expect(
11-
await Process.run('dart', ['pub', 'get'], workingDirectory: workingDir)
12-
.then((v) => v.exitCode),
13-
0);
14-
expect(
15-
await Process.run('custom_lint', ['--fatal-infos', '--fatal-warnings'],
11+
await Process.run('dart',
12+
['run', 'custom_lint', '--fatal-infos', '--fatal-warnings'],
1613
workingDirectory: workingDir)
1714
.then((v) => v.exitCode),
1815
0);

drift_dev/test/lint/test_pkg/lib/db.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,20 @@ class TestDatabase extends _$TestDatabase {
3333
() async {
3434
// expect_lint: unawaited_futures_in_transaction
3535
into(users).insert(UsersCompanion.insert(name: 'name'));
36+
await into(users).insert(UsersCompanion.insert(name: 'name'));
3637
},
3738
);
39+
await into(users).insertReturning(UsersCompanion.insert(name: 'name'),
40+
mode: InsertMode.insertOrIgnore);
41+
// expect_lint: non_null_insert_with_ignore
42+
await managers.users
43+
.createReturning((o) => o(name: "hi"), mode: InsertMode.insertOrIgnore);
44+
await into(users).insertReturningOrNull(UsersCompanion.insert(name: 'name'),
45+
mode: InsertMode.insertOrIgnore);
46+
await managers.users.createReturningOrNull((o) => o(name: "hi"),
47+
mode: InsertMode.insertOrIgnore);
48+
await into(users).insertReturning(UsersCompanion.insert(name: 'name'));
49+
await managers.users.createReturning((o) => o(name: "hi"));
3850
}
3951

4052
@override

0 commit comments

Comments
 (0)