mirror of https://github.com/AMT-Cheif/drift.git
275 lines
7.5 KiB
Dart
275 lines
7.5 KiB
Dart
import 'package:drift_dev/src/analysis/driver/state.dart';
|
|
import 'package:drift_dev/src/analysis/resolver/intermediate_state.dart';
|
|
import 'package:drift_dev/src/analysis/results/element.dart';
|
|
import 'package:test/test.dart';
|
|
|
|
import '../test_utils.dart';
|
|
|
|
void main() {
|
|
group('drift files', () {
|
|
test('finds local elements', () async {
|
|
final backend = await TestBackend.inTest({
|
|
'a|lib/main.drift': '''
|
|
CREATE TABLE foo (bar INTEGER);
|
|
|
|
CREATE VIEW my_view AS SELECT whatever FROM unknown_table;
|
|
''',
|
|
});
|
|
|
|
final uri = Uri.parse('package:a/main.drift');
|
|
final state = await backend.driver.findLocalElements(uri);
|
|
final discovered = state.discovery;
|
|
|
|
DriftElementId id(String name) => DriftElementId(uri, name);
|
|
|
|
expect(state, hasNoErrors);
|
|
expect(
|
|
discovered,
|
|
isA<DiscoveredDriftFile>()
|
|
.having((e) => e.imports, 'imports', isEmpty)
|
|
.having(
|
|
(e) => e.locallyDefinedElements,
|
|
'locallyDefinedElements',
|
|
[
|
|
isA<DiscoveredDriftTable>()
|
|
.having((t) => t.ownId, 'ownId', id('foo')),
|
|
isA<DiscoveredDriftView>()
|
|
.having((v) => v.ownId, 'ownId', id('my_view')),
|
|
],
|
|
),
|
|
);
|
|
});
|
|
|
|
test('reports syntax errors', () async {
|
|
final backend = await TestBackend.inTest({
|
|
'a|lib/main.drift': '''
|
|
CREATE TABLE valid_1 (bar INTEGER);
|
|
|
|
CREATE TABLE EXISTS syntax_error ();
|
|
|
|
CREATE TABLE valid_2 (bar INTEGER);
|
|
''',
|
|
});
|
|
|
|
final state = await backend.discoverLocalElements('package:a/main.drift');
|
|
expect(state.errorsDuringDiscovery, [
|
|
isDriftError(contains('Expected a table name')),
|
|
]);
|
|
|
|
// The syntax error should only affect the single statement
|
|
expect(
|
|
state.discovery,
|
|
isA<DiscoveredDriftFile>().having((e) => e.locallyDefinedElements,
|
|
'locallyDefinedElements', hasLength(2)));
|
|
});
|
|
|
|
test('warns about duplicate elements', () async {
|
|
final backend = await TestBackend.inTest({
|
|
'a|lib/main.drift': '''
|
|
CREATE TABLE a (id INTEGER);
|
|
CREATE VIEW a AS VALUES(1,2,3);
|
|
''',
|
|
});
|
|
|
|
final state = await backend.discoverLocalElements('package:a/main.drift');
|
|
expect(state.errorsDuringDiscovery, [
|
|
isDriftError(contains('already defines an element named `a`')),
|
|
]);
|
|
|
|
final result = state.discovery as DiscoveredDriftFile;
|
|
expect(result.locallyDefinedElements, [isA<DiscoveredDriftTable>()]);
|
|
});
|
|
|
|
group('imports', () {
|
|
test('are resolved', () async {
|
|
final backend = await TestBackend.inTest({
|
|
'a|lib/a.drift': "import 'b.drift';",
|
|
'a|lib/b.drift': "CREATE TABLE foo (bar INTEGER);",
|
|
});
|
|
|
|
final state = await backend.discoverLocalElements('package:a/a.drift');
|
|
expect(state, hasNoErrors);
|
|
expect(
|
|
state.discovery,
|
|
isA<DiscoveredDriftFile>().having(
|
|
(e) => e.importDependencies,
|
|
'importDependencies',
|
|
[(uri: Uri.parse('package:a/b.drift'), transitive: true)],
|
|
),
|
|
);
|
|
|
|
expect(
|
|
backend.driver.cache.knownFiles[Uri.parse('package:a/b.drift')],
|
|
isNull,
|
|
reason: 'Discovering local elements should not prepare other files',
|
|
);
|
|
});
|
|
|
|
test('can handle circular imports', () async {
|
|
final backend = await TestBackend.inTest({
|
|
'a|lib/a.drift': "import 'a.drift'; import 'b.drift';",
|
|
'a|lib/b.drift': "import 'a.drift';",
|
|
});
|
|
|
|
final state = await backend.discoverLocalElements('package:a/a.drift');
|
|
expect(state, hasNoErrors);
|
|
});
|
|
});
|
|
});
|
|
|
|
group('dart files', () {
|
|
test('fails for part files', () async {
|
|
final backend = await TestBackend.inTest({
|
|
'a|lib/a.dart': '''
|
|
part of 'b.dart';
|
|
''',
|
|
'a|lib/b.dart': '''
|
|
part 'a.dart';
|
|
''',
|
|
});
|
|
|
|
final uri = Uri.parse('package:a/a.dart');
|
|
final state = await backend.driver.findLocalElements(uri);
|
|
|
|
expect(state, hasNoErrors);
|
|
expect(state.discovery, isA<NotADartLibrary>());
|
|
});
|
|
|
|
test('finds tables', () async {
|
|
final backend = await TestBackend.inTest({
|
|
'a|lib/a.dart': '''
|
|
import 'package:drift/drift.dart';
|
|
|
|
class Users extends Table {
|
|
IntColumn get id => integer()();
|
|
}
|
|
|
|
class Groups extends Table {
|
|
IntColumn get id => integer()();
|
|
|
|
String get tableName => 'my_custom_table';
|
|
}
|
|
''',
|
|
});
|
|
|
|
final uri = Uri.parse('package:a/a.dart');
|
|
final state = await backend.driver.findLocalElements(uri);
|
|
|
|
expect(state, hasNoErrors);
|
|
expect(
|
|
state.discovery,
|
|
isA<DiscoveredDartLibrary>().having(
|
|
(e) => e.locallyDefinedElements,
|
|
'locallyDefinedElements',
|
|
[
|
|
isA<DiscoveredDartTable>()
|
|
.having((t) => t.ownId, 'ownId', DriftElementId(uri, 'users')),
|
|
isA<DiscoveredDartTable>().having((t) => t.ownId, 'ownId',
|
|
DriftElementId(uri, 'my_custom_table')),
|
|
],
|
|
),
|
|
);
|
|
});
|
|
|
|
test('ignores abstract tables', () async {
|
|
final backend = await TestBackend.inTest({
|
|
'a|lib/a.dart': '''
|
|
import 'package:drift/drift.dart';
|
|
|
|
abstract class Users extends Table {
|
|
IntColumn get id => integer()();
|
|
}
|
|
|
|
abstract class BaseRelationTable extends Table {
|
|
Column<int?> get parentId;
|
|
Column<int?> get childId;
|
|
|
|
@override
|
|
Set<Column> get primaryKey => {parentId, childId};
|
|
}
|
|
''',
|
|
});
|
|
|
|
final uri = Uri.parse('package:a/a.dart');
|
|
final state = await backend.driver.findLocalElements(uri);
|
|
|
|
expect(state, hasNoErrors);
|
|
expect(
|
|
state.discovery,
|
|
isA<DiscoveredDartLibrary>().having(
|
|
(e) => e.locallyDefinedElements,
|
|
'locallyDefinedElements',
|
|
[
|
|
isA<DiscoveredDartTable>()
|
|
.having((t) => t.ownId, 'ownId', DriftElementId(uri, 'users')),
|
|
],
|
|
),
|
|
);
|
|
});
|
|
|
|
test('table name errors', () async {
|
|
final backend = await TestBackend.inTest({
|
|
'a|lib/expr.dart': '''
|
|
import 'package:drift/drift.dart';
|
|
|
|
class InvalidExpression extends Table {
|
|
String get tableName => 'foo'.toLowerCase();
|
|
}
|
|
''',
|
|
'a|lib/getter.dart': '''
|
|
import 'package:drift/drift.dart';
|
|
|
|
class InvalidGetter extends Table {
|
|
String get tableName {
|
|
return '';
|
|
}
|
|
}
|
|
''',
|
|
});
|
|
|
|
for (final source in backend.sourceContents.keys) {
|
|
final state = await backend.driver.findLocalElements(Uri.parse(source));
|
|
|
|
expect(
|
|
state.errorsDuringDiscovery,
|
|
[isDriftError(contains('must directly return a string literal'))],
|
|
reason: 'Should report error for $source',
|
|
);
|
|
}
|
|
});
|
|
|
|
test('warns about duplicate elements', () async {
|
|
final backend = await TestBackend.inTest({
|
|
'a|lib/a.dart': '''
|
|
import 'package:drift/drift.dart';
|
|
|
|
class A extends Table {
|
|
IntColumn get id => integer()();
|
|
|
|
String get tableName => 'tbl';
|
|
}
|
|
|
|
class B extends Table {
|
|
IntColumn get id => integer()();
|
|
|
|
String get tableName => 'tbl';
|
|
}
|
|
''',
|
|
});
|
|
|
|
final state =
|
|
await backend.driver.findLocalElements(Uri.parse('package:a/a.dart'));
|
|
|
|
expect(state.errorsDuringDiscovery, [
|
|
isDriftError(contains('already defines an element named `tbl`')),
|
|
]);
|
|
|
|
final result = state.discovery as DiscoveredDartLibrary;
|
|
expect(result.locallyDefinedElements, [
|
|
isA<DiscoveredDartTable>()
|
|
.having((e) => e.dartElement.name, 'dartElement.name', 'A')
|
|
]);
|
|
});
|
|
});
|
|
}
|