Skip to content

Commit

Permalink
Add unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mqus committed Mar 11, 2020
1 parent ac2fc72 commit 657c3ee
Show file tree
Hide file tree
Showing 2 changed files with 368 additions and 0 deletions.
274 changes: 274 additions & 0 deletions floor_generator/test/processor/view_processor_test.dart
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;
}
94 changes: 94 additions & 0 deletions floor_generator/test/value_object/view_test.dart
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));
});
});
}

0 comments on commit 657c3ee

Please sign in to comment.