-
Notifications
You must be signed in to change notification settings - Fork 192
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
368 additions
and
0 deletions.
There are no files selected for viewing
274 changes: 274 additions & 0 deletions
274
floor_generator/test/processor/view_processor_test.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,274 @@ | ||
import 'package:analyzer/dart/element/element.dart'; | ||
import 'package:build_test/build_test.dart'; | ||
import 'package:floor_generator/processor/view_processor.dart'; | ||
import 'package:floor_generator/processor/field_processor.dart'; | ||
import 'package:floor_generator/value_object/view.dart'; | ||
|
||
import 'package:source_gen/source_gen.dart'; | ||
import 'package:test/test.dart'; | ||
|
||
void main() { | ||
test('Process view', () async { | ||
final classElement = await _createClassElement(''' | ||
@DatabaseView("SELECT * from otherentity") | ||
class Person { | ||
final int id; | ||
final String name; | ||
Person(this.id, this.name); | ||
} | ||
'''); | ||
|
||
final actual = ViewProcessor(classElement).process(); | ||
|
||
const name = 'Person'; | ||
final fields = classElement.fields | ||
.map((fieldElement) => FieldProcessor(fieldElement).process()) | ||
.toList(); | ||
const query = 'SELECT * from otherentity'; | ||
const constructor = "Person(row['id'] as int, row['name'] as String)"; | ||
final expected = View( | ||
classElement, | ||
name, | ||
fields, | ||
query, | ||
constructor, | ||
); | ||
expect(actual, equals(expected)); | ||
}); | ||
|
||
test('Process view with dedicated name', () async { | ||
final classElement = await _createClassElement(''' | ||
@DatabaseView("SELECT * from otherentity",viewName: "personview") | ||
class Person { | ||
final int id; | ||
final String name; | ||
Person(this.id, this.name); | ||
} | ||
'''); | ||
|
||
final actual = ViewProcessor(classElement).process(); | ||
|
||
const name = 'personview'; | ||
final fields = classElement.fields | ||
.map((fieldElement) => FieldProcessor(fieldElement).process()) | ||
.toList(); | ||
const query = 'SELECT * from otherentity'; | ||
const constructor = "Person(row['id'] as int, row['name'] as String)"; | ||
final expected = View( | ||
classElement, | ||
name, | ||
fields, | ||
query, | ||
constructor, | ||
); | ||
expect(actual, equals(expected)); | ||
}); | ||
|
||
test('Ignore hashCode field', () async { | ||
final classElement = await _createClassElement(''' | ||
@DatabaseView("SELECT * from otherentity") | ||
class Person { | ||
final int id; | ||
final String name; | ||
Person(this.id, this.name); | ||
@override | ||
int get hashCode => id.hashCode ^ name.hashCode; | ||
} | ||
'''); | ||
|
||
final actual = ViewProcessor(classElement).process(); | ||
|
||
expect(actual.fields.length, equals(2)); | ||
}); | ||
|
||
test('Ignore static field', () async { | ||
final classElement = await _createClassElement(''' | ||
@DatabaseView("SELECT * from otherentity") | ||
class Person { | ||
final int id; | ||
final String name; | ||
Person(this.id, this.name); | ||
static String foo = 'foo'; | ||
} | ||
'''); | ||
|
||
final actual = ViewProcessor(classElement).process(); | ||
|
||
expect(actual.fields.length, equals(2)); | ||
}); | ||
|
||
group('Constructors', () { | ||
test('generate simple constructor', () async { | ||
final classElement = await _createClassElement(''' | ||
@DatabaseView("SELECT * from otherentity") | ||
class Person { | ||
final int id; | ||
final String name; | ||
Person(this.id, this.name); | ||
} | ||
'''); | ||
|
||
final actual = ViewProcessor(classElement).process().constructor; | ||
|
||
const expected = "Person(row['id'] as int, row['name'] as String)"; | ||
expect(actual, equals(expected)); | ||
}); | ||
|
||
test('generate constructor with named argument', () async { | ||
final classElement = await _createClassElement(''' | ||
@DatabaseView("SELECT * from otherentity") | ||
class Person { | ||
final int id; | ||
final String name; | ||
final String bar; | ||
Person(this.id, this.name, {this.bar}); | ||
} | ||
'''); | ||
|
||
final actual = ViewProcessor(classElement).process().constructor; | ||
|
||
const expected = | ||
"Person(row['id'] as int, row['name'] as String, bar: row['bar'] as String)"; | ||
expect(actual, equals(expected)); | ||
}); | ||
|
||
test('generate constructor with named arguments', () async { | ||
final classElement = await _createClassElement(''' | ||
@DatabaseView("SELECT * from otherentity") | ||
class Person { | ||
final int id; | ||
final String name; | ||
final String bar; | ||
Person({this.id, this.name, this.bar}); | ||
} | ||
'''); | ||
|
||
final actual = ViewProcessor(classElement).process().constructor; | ||
|
||
const expected = | ||
"Person(id: row['id'] as int, name: row['name'] as String, bar: row['bar'] as String)"; | ||
expect(actual, equals(expected)); | ||
}); | ||
|
||
test('generate constructor with optional argument', () async { | ||
final classElement = await _createClassElement(''' | ||
@DatabaseView("SELECT * from otherentity") | ||
class Person { | ||
final int id; | ||
final String name; | ||
final String bar; | ||
Person(this.id, this.name, [this.bar]); | ||
} | ||
'''); | ||
|
||
final actual = ViewProcessor(classElement).process().constructor; | ||
|
||
const expected = | ||
"Person(row['id'] as int, row['name'] as String, row['bar'] as String)"; | ||
expect(actual, equals(expected)); | ||
}); | ||
|
||
test('generate constructor with optional arguments', () async { | ||
final classElement = await _createClassElement(''' | ||
@DatabaseView("SELECT * from otherentity") | ||
class Person { | ||
final int id; | ||
final String name; | ||
final String bar; | ||
Person([this.id, this.name, this.bar]); | ||
} | ||
'''); | ||
|
||
final actual = ViewProcessor(classElement).process().constructor; | ||
|
||
const expected = | ||
"Person(row['id'] as int, row['name'] as String, row['bar'] as String)"; | ||
expect(actual, equals(expected)); | ||
}); | ||
}); | ||
|
||
group('@Ignore', () { | ||
test('ignore field not present in constructor', () async { | ||
final classElement = await _createClassElement(''' | ||
@DatabaseView("SELECT * from otherentity") | ||
class Person { | ||
final int id; | ||
final String name; | ||
@ignore | ||
String foo; | ||
Person(this.id, this.name); | ||
} | ||
'''); | ||
|
||
final actual = ViewProcessor(classElement) | ||
.process() | ||
.fields | ||
.map((field) => field.name); | ||
|
||
const expected = 'foo'; | ||
expect(actual, isNot(contains(expected))); | ||
}); | ||
|
||
test('ignore field present in constructor', () async { | ||
final classElement = await _createClassElement(''' | ||
@DatabaseView("SELECT * from otherentity") | ||
class Person { | ||
final int id; | ||
final String name; | ||
@ignore | ||
String foo; | ||
Person(this.id, this.name, [this.foo = 'foo']); | ||
} | ||
'''); | ||
|
||
final actual = ViewProcessor(classElement).process().constructor; | ||
|
||
const expected = "Person(row['id'] as int, row['name'] as String)"; | ||
expect(actual, equals(expected)); | ||
}); | ||
}); | ||
} | ||
|
||
Future<ClassElement> _createClassElement(final String clazz) async { | ||
final library = await resolveSource(''' | ||
library test; | ||
import 'package:floor_annotation/floor_annotation.dart'; | ||
$clazz | ||
''', (resolver) async { | ||
return LibraryReader(await resolver.findLibraryByName('test')); | ||
}); | ||
|
||
return library.classes.first; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import 'package:floor_generator/misc/constants.dart'; | ||
import 'package:floor_generator/value_object/view.dart'; | ||
import 'package:floor_generator/value_object/field.dart'; | ||
import 'package:mockito/mockito.dart'; | ||
import 'package:test/test.dart'; | ||
|
||
import '../mocks.dart'; | ||
|
||
void main() { | ||
final mockClassElement = MockClassElement(); | ||
final mockFieldElement = MockFieldElement(); | ||
final mockDartType = MockDartType(); | ||
|
||
final field = Field( | ||
mockFieldElement, | ||
'field1Name', | ||
'field1ColumnName', | ||
false, | ||
SqlType.INTEGER, | ||
); | ||
final nullableField = Field( | ||
mockFieldElement, | ||
'field2Name', | ||
'field2ColumnName', | ||
true, | ||
SqlType.TEXT, | ||
); | ||
final allFields = [field, nullableField]; | ||
|
||
tearDown(() { | ||
clearInteractions(mockClassElement); | ||
clearInteractions(mockFieldElement); | ||
clearInteractions(mockDartType); | ||
reset(mockClassElement); | ||
reset(mockFieldElement); | ||
reset(mockDartType); | ||
}); | ||
|
||
group('statement', () { | ||
test('Create view statement with simple query', () { | ||
final view = View( | ||
mockClassElement, | ||
'entityName', | ||
allFields, | ||
'select * from x', | ||
'', | ||
); | ||
|
||
final actual = view.getCreateViewStatement(); | ||
|
||
final expected = | ||
'CREATE VIEW IF NOT EXISTS `${view.name}` AS ${view.query}'; | ||
expect(actual, equals(expected)); | ||
}); | ||
}); | ||
|
||
group('Value mapping', () { | ||
final view = View( | ||
mockClassElement, | ||
'entityName', | ||
[nullableField], | ||
'select * from x', | ||
'', | ||
); | ||
const fieldElementDisplayName = 'foo'; | ||
|
||
setUp(() { | ||
when(mockFieldElement.displayName).thenReturn(fieldElementDisplayName); | ||
when(mockFieldElement.type).thenReturn(mockDartType); | ||
}); | ||
|
||
test('Get value mapping', () { | ||
when(mockDartType.isDartCoreBool).thenReturn(false); | ||
|
||
final actual = view.getValueMapping(); | ||
|
||
final expected = '<String, dynamic>{' | ||
"'${nullableField.columnName}': item.$fieldElementDisplayName" | ||
'}'; | ||
expect(actual, equals(expected)); | ||
}); | ||
|
||
test('Get boolean value mapping', () { | ||
when(mockDartType.isDartCoreBool).thenReturn(true); | ||
|
||
final actual = view.getValueMapping(); | ||
|
||
final expected = '<String, dynamic>{' | ||
"'${nullableField.columnName}': item.$fieldElementDisplayName ? 1 : 0" | ||
'}'; | ||
expect(actual, equals(expected)); | ||
}); | ||
}); | ||
} |