diff --git a/generator/lib/src/code_chunks.dart b/generator/lib/src/code_chunks.dart index fa4e0b320..1607cc603 100644 --- a/generator/lib/src/code_chunks.dart +++ b/generator/lib/src/code_chunks.dart @@ -1,31 +1,18 @@ +import "dart:convert"; import "package:objectbox/src/modelinfo/index.dart"; import "package:objectbox/src/bindings/constants.dart" show OBXPropertyType; import "package:source_gen/source_gen.dart" show InvalidGenerationSourceError; class CodeChunks { + // TODO ModelInfo, once per DB static String modelInfoLoader() => """ - Map _allOBXModelEntities; - - void _loadOBXModelEntities() { - _allOBXModelEntities = {}; - ModelInfo modelInfo = ModelInfo.fromMap(||MODEL-JSON||); - modelInfo.entities.forEach((e) => _allOBXModelEntities[e.id.uid] = e); - } - - ModelEntity _getOBXModelEntity(int entityUid) { - if (_allOBXModelEntities == null) _loadOBXModelEntities(); - if (!_allOBXModelEntities.containsKey(entityUid)) { - throw Exception("entity uid missing in objectbox-model.json: \$entityUid"); - } - return _allOBXModelEntities[entityUid]; - } """; static String instanceBuildersReaders(ModelEntity readEntity) { String name = readEntity.name; return """ ModelEntity _${name}_OBXModelGetter() { - return _getOBXModelEntity(${readEntity.id.uid}); + return ModelEntity.fromMap(${JsonEncoder().convert(readEntity.toMap())}); } $name _${name}_OBXBuilder(Map members) { diff --git a/generator/lib/src/generator.dart b/generator/lib/src/generator.dart index 9412781d4..8a3d0a87c 100644 --- a/generator/lib/src/generator.dart +++ b/generator/lib/src/generator.dart @@ -128,9 +128,6 @@ class EntityGenerator extends GeneratorForAnnotation { final modelJson = JsonEncoder.withIndent(" ").convert(allModels.toMap()); await File(ALL_MODELS_JSON).writeAsString(modelJson); - // add model-json to the generated code - ret = ret.replaceFirst('||MODEL-JSON||', modelJson); - readEntity = allModels.findEntityByName(element.name); if (readEntity == null) return ret; diff --git a/generator/test/cases/multiple_entities/a.dart_testcase b/generator/test/cases/multiple_entities/a.dart_testcase new file mode 100644 index 000000000..661c75649 --- /dev/null +++ b/generator/test/cases/multiple_entities/a.dart_testcase @@ -0,0 +1,8 @@ +import "package:objectbox/objectbox.dart"; +part "a.g.dart"; + +@Entity(uid: 1) +class A { + @Id(uid: 11) + int id; +} diff --git a/generator/test/cases/multiple_entities/a.g.dart_expected b/generator/test/cases/multiple_entities/a.g.dart_expected new file mode 100644 index 000000000..30cf492dc --- /dev/null +++ b/generator/test/cases/multiple_entities/a.g.dart_expected @@ -0,0 +1,34 @@ +// ************************************************************************** +// EntityGenerator +// ************************************************************************** + +ModelEntity _A_OBXModelGetter() { + return ModelEntity.fromMap({ + "id": "1:1", + "lastPropertyId": "1:11", + "name": "A", + "properties": [ + {"id": "1:11", "name": "id", "type": 6, "flags": 1} + ] + }); +} + +A _A_OBXBuilder(Map members) { + A r = A(); + r.id = members["id"]; + return r; +} + +Map _A_OBXReader(A inst) { + Map r = {}; + r["id"] = inst.id; + return r; +} + +const A_OBXDefs = + EntityDefinition(_A_OBXModelGetter, _A_OBXReader, _A_OBXBuilder); + +class A_ { + static final id = + QueryIntegerProperty(entityId: 1, propertyId: 1, obxType: 6); +} diff --git a/generator/test/cases/multiple_entities/b.dart_testcase b/generator/test/cases/multiple_entities/b.dart_testcase new file mode 100644 index 000000000..775d016ea --- /dev/null +++ b/generator/test/cases/multiple_entities/b.dart_testcase @@ -0,0 +1,8 @@ +import "package:objectbox/objectbox.dart"; +part "b.g.dart"; + +@Entity(uid: 2) +class B { + @Id(uid: 21) + int id; +} diff --git a/generator/test/cases/multiple_entities/b.g.dart_expected b/generator/test/cases/multiple_entities/b.g.dart_expected new file mode 100644 index 000000000..eaa6a8a05 --- /dev/null +++ b/generator/test/cases/multiple_entities/b.g.dart_expected @@ -0,0 +1,34 @@ +// ************************************************************************** +// EntityGenerator +// ************************************************************************** + +ModelEntity _B_OBXModelGetter() { + return ModelEntity.fromMap({ + "id": "2:2", + "lastPropertyId": "1:21", + "name": "B", + "properties": [ + {"id": "1:21", "name": "id", "type": 6, "flags": 1} + ] + }); +} + +B _B_OBXBuilder(Map members) { + B r = B(); + r.id = members["id"]; + return r; +} + +Map _B_OBXReader(B inst) { + Map r = {}; + r["id"] = inst.id; + return r; +} + +const B_OBXDefs = + EntityDefinition(_B_OBXModelGetter, _B_OBXReader, _B_OBXBuilder); + +class B_ { + static final id = + QueryIntegerProperty(entityId: 2, propertyId: 1, obxType: 6); +} diff --git a/generator/test/cases/multiple_entities/objectbox-model.json_expected b/generator/test/cases/multiple_entities/objectbox-model.json_expected new file mode 100644 index 000000000..cf873ba05 --- /dev/null +++ b/generator/test/cases/multiple_entities/objectbox-model.json_expected @@ -0,0 +1,44 @@ +{ + "_note1": "KEEP THIS FILE! Check it into a version control system (VCS) like git.", + "_note2": "ObjectBox manages crucial IDs for your object model. See docs for details.", + "_note3": "If you have VCS merge conflicts, you must resolve them according to ObjectBox docs.", + "entities": [ + { + "id": "1:1", + "lastPropertyId": "1:11", + "name": "A", + "properties": [ + { + "id": "1:11", + "name": "id", + "type": 6, + "flags": 1 + } + ] + }, + { + "id": "2:2", + "lastPropertyId": "1:21", + "name": "B", + "properties": [ + { + "id": "1:21", + "name": "id", + "type": 6, + "flags": 1 + } + ] + } + ], + "lastEntityId": "2:2", + "lastIndexId": "0:0", + "lastRelationId": "0:0", + "lastSequenceId": "0:0", + "modelVersion": 5, + "modelVersionParserMinimum": 5, + "retiredEntityUids": [], + "retiredIndexUids": [], + "retiredPropertyUids": [], + "retiredRelationUids": [], + "version": 1 +} \ No newline at end of file diff --git a/generator/test/cases/single_entity/single_entity.dart_testcase b/generator/test/cases/single_entity/single_entity.dart_testcase index d5632877f..c81d711da 100644 --- a/generator/test/cases/single_entity/single_entity.dart_testcase +++ b/generator/test/cases/single_entity/single_entity.dart_testcase @@ -1,11 +1,18 @@ import "package:objectbox/objectbox.dart"; part "single_entity.g.dart"; +/// A dummy annotation to verify the code is generated properly even with annotations unknown to ObjectBox generator. +class TestingUnknownAnnotation { + const TestingUnknownAnnotation(); +} + @Entity(uid: 1234) +@TestingUnknownAnnotation() class SingleEntity { @Id(uid: 5678) int id; @Property(uid: 4321) + @TestingUnknownAnnotation() String texta; } diff --git a/generator/test/cases/single_entity/single_entity.g.dart_expected b/generator/test/cases/single_entity/single_entity.g.dart_expected index 39a21dbd3..b216d223c 100644 --- a/generator/test/cases/single_entity/single_entity.g.dart_expected +++ b/generator/test/cases/single_entity/single_entity.g.dart_expected @@ -2,53 +2,16 @@ // EntityGenerator // ************************************************************************** -Map _allOBXModelEntities; - -void _loadOBXModelEntities() { - _allOBXModelEntities = {}; - ModelInfo modelInfo = ModelInfo.fromMap({ - "_note1": - "KEEP THIS FILE! Check it into a version control system (VCS) like git.", - "_note2": - "ObjectBox manages crucial IDs for your object model. See docs for details.", - "_note3": - "If you have VCS merge conflicts, you must resolve them according to ObjectBox docs.", - "entities": [ - { - "id": "1:1234", - "lastPropertyId": "2:4321", - "name": "SingleEntity", - "properties": [ - {"id": "1:5678", "name": "id", "type": 6, "flags": 1}, - {"id": "2:4321", "name": "texta", "type": 9} - ] - } - ], - "lastEntityId": "1:1234", - "lastIndexId": "0:0", - "lastRelationId": "0:0", - "lastSequenceId": "0:0", - "modelVersion": 5, - "modelVersionParserMinimum": 5, - "retiredEntityUids": [], - "retiredIndexUids": [], - "retiredPropertyUids": [], - "retiredRelationUids": [], - "version": 1 - }); - modelInfo.entities.forEach((e) => _allOBXModelEntities[e.id.uid] = e); -} - -ModelEntity _getOBXModelEntity(int entityUid) { - if (_allOBXModelEntities == null) _loadOBXModelEntities(); - if (!_allOBXModelEntities.containsKey(entityUid)) { - throw Exception("entity uid missing in objectbox-model.json: $entityUid"); - } - return _allOBXModelEntities[entityUid]; -} - ModelEntity _SingleEntity_OBXModelGetter() { - return _getOBXModelEntity(1234); + return ModelEntity.fromMap({ + "id": "1:1234", + "lastPropertyId": "2:4321", + "name": "SingleEntity", + "properties": [ + {"id": "1:5678", "name": "id", "type": 6, "flags": 1}, + {"id": "2:4321", "name": "texta", "type": 9} + ] + }); } SingleEntity _SingleEntity_OBXBuilder(Map members) { diff --git a/generator/test/generator_test.dart b/generator/test/generator_test.dart index 331314227..5db3abad2 100644 --- a/generator/test/generator_test.dart +++ b/generator/test/generator_test.dart @@ -1,14 +1,42 @@ import "dart:io"; import "package:test/test.dart"; +import 'package:glob/glob.dart' show Glob; +import 'package:path/path.dart'; import "helpers.dart"; +Map getArgs() { + final result = Map(); + + // accept GENERATOR environment variable as a list of arguments, e.g. GENERATOR=update-expected,target:single_entity + final env = Platform.environment['GENERATOR'] ?? ""; + + env.split(",").forEach((part) { + final kvPair = part.split(":"); + if (kvPair.length < 2) { + result[part] = ""; + } else { + result[kvPair[0]] = kvPair.sublist(1).join(":"); // join() just in case there were multiple ":" + } + }); + + return result; +} + void main() async { group("generator", () { tearDown(() { File("objectbox-model.json").deleteSync(); }); - testGeneratorOutput("single_entity"); + final args = getArgs(); + final updateExpected = args["update-expected"] != null; + + for (var testCase in Glob("test/cases/*").listSync()) { + final name = basename(testCase.path); + if (args["target"] == null || args["target"] == name) { + testGeneratorOutput(name, updateExpected); + } + } }); } diff --git a/generator/test/helpers.dart b/generator/test/helpers.dart index f500eff9e..5d0ccceee 100644 --- a/generator/test/helpers.dart +++ b/generator/test/helpers.dart @@ -12,9 +12,9 @@ import "package:build/src/analyzer/resolver.dart"; import "package:build_resolvers/src/resolver.dart"; class _InMemoryAssetWriter implements AssetWriter { - String output; + Map output; - _InMemoryAssetWriter(); + _InMemoryAssetWriter() : output = Map(); @override Future writeAsBytes(AssetId id, List bytes) async { @@ -23,23 +23,15 @@ class _InMemoryAssetWriter implements AssetWriter { @override Future writeAsString(AssetId id, String contents, {Encoding encoding = utf8}) async { - if (output != null) throw Exception("output was set already"); - output = contents; + if (output[id] != null) throw Exception("output was set already"); + output[id] = contents; } } class _SingleFileAssetReader extends AssetReader { - AssetId id; - - _SingleFileAssetReader(this.id) { - if (id.package != "objectbox_generator") { - throw Exception("asset package needs to be 'objectbox_generator', but got '${id.package}'"); - } - } - Future canRead(AssetId id) async => true; //this.id == id; - Stream findAssets(Glob glob, {String package}) => Stream.fromIterable([id]); + Stream findAssets(Glob glob, {String package}) => throw UnimplementedError(); @override Future> readAsBytes(AssetId id) async => utf8.encode(await readAsString(id)); @@ -59,24 +51,45 @@ class _SingleFileAssetReader extends AssetReader { } } -Future _buildGeneratorOutput(String caseName) async { - AssetId assetId = AssetId("objectbox_generator", "test/cases/$caseName/$caseName.dart"); +Future> _buildGeneratorOutput(String caseName) async { + final entities = List(); + for (var entity in Glob("test/cases/$caseName/*.dart_testcase").listSync()) { + final path = entity.path.substring(0, entity.path.length - "_testcase".length); + entities.add(AssetId("objectbox_generator", path)); + } + var writer = _InMemoryAssetWriter(); - var reader = _SingleFileAssetReader(assetId); + var reader = _SingleFileAssetReader(); Resolvers resolvers = AnalyzerResolvers(); - await runBuilder(objectboxModelFactory(BuilderOptions.empty), [assetId], reader, writer, resolvers); + await runBuilder(objectboxModelFactory(BuilderOptions.empty), entities, reader, writer, resolvers); return writer.output; } -void testGeneratorOutput(String caseName) { +void checkExpectedContents(String path, String contents, bool updateExpected) async { + final expectedFile = File(path); + final expectedContents = await expectedFile.readAsString(); + + if (updateExpected) { + if (expectedContents != contents) { + print("Updating $path"); + } + await expectedFile.writeAsString(contents); + } else { + expect(contents, equals(expectedContents)); + } +} + +void testGeneratorOutput(String caseName, bool updateExpected) { test(caseName, () async { - String built = await _buildGeneratorOutput(caseName); - String expected = await File("test/cases/$caseName/$caseName.g.dart_expected").readAsString(); - expect(built, equals(expected)); + Map built = await _buildGeneratorOutput(caseName); + + built.forEach((assetId, generatedCode) async { + final expectedPath = assetId.path.replaceAll(".objectbox_model.g.part", ".g.dart_expected"); + checkExpectedContents(expectedPath, generatedCode, updateExpected); + }); String jsonBuilt = await File("objectbox-model.json").readAsString(); - String jsonExpected = await File("test/cases/$caseName/objectbox-model.json_expected").readAsString(); - expect(jsonBuilt, equals(jsonExpected)); + checkExpectedContents("test/cases/$caseName/objectbox-model.json_expected", jsonBuilt, updateExpected); }); } diff --git a/lib/integration_test.dart b/lib/integration_test.dart index b4d378edd..620a5b47b 100644 --- a/lib/integration_test.dart +++ b/lib/integration_test.dart @@ -19,8 +19,8 @@ class IntegrationTest { static model() { // create a model with a single entity and a single property final modelInfo = ModelInfo.createDefault(); - final property = ModelProperty(IdUid.create(1, int64_max - 1), "id", OBXPropertyType.Long, 0, null); - final entity = ModelEntity(IdUid.create(1, int64_max), null, "entity", [], modelInfo); + final property = ModelProperty(IdUid(1, int64_max - 1), "id", OBXPropertyType.Long, 0, null); + final entity = ModelEntity(IdUid(1, int64_max), null, "entity", [], modelInfo); property.entity = entity; entity.properties.add(property); entity.lastPropertyId = property.id; diff --git a/lib/src/modelinfo/iduid.dart b/lib/src/modelinfo/iduid.dart index 35d916f70..17f4a20f3 100644 --- a/lib/src/modelinfo/iduid.dart +++ b/lib/src/modelinfo/iduid.dart @@ -1,7 +1,12 @@ class IdUid { int _id, _uid; - IdUid(String str) { + IdUid(int newId, int newUid) { + id = newId; + uid = newUid; + } + + IdUid.fromString(String str) { if (str == null || str == "" || str == "0:0") { _id = 0; _uid = 0; @@ -14,11 +19,6 @@ class IdUid { uid = int.parse(spl[1]); } - IdUid.create(int newId, int newUid) { - id = newId; - uid = newUid; - } - IdUid.empty() : this._id = 0, this._uid = 0; diff --git a/lib/src/modelinfo/modelentity.dart b/lib/src/modelinfo/modelentity.dart index 426e095eb..8c9b9a5a7 100644 --- a/lib/src/modelinfo/modelentity.dart +++ b/lib/src/modelinfo/modelentity.dart @@ -1,3 +1,4 @@ +import '../util.dart'; import "iduid.dart"; import "modelinfo.dart"; import "modelproperty.dart"; @@ -8,15 +9,21 @@ class ModelEntity { String name; List properties; String idPropName; - ModelInfo model; + ModelInfo _model; - ModelEntity(this.id, this.lastPropertyId, this.name, this.properties, this.model) { + ModelInfo get model => (_model == null) ? throw Exception("model is null") : _model; + + set model(ModelInfo model) { + this._model = model; + } + + ModelEntity(this.id, this.lastPropertyId, this.name, this.properties, this._model) { validate(); } - ModelEntity.fromMap(Map data, this.model) { - id = IdUid(data["id"]); - lastPropertyId = IdUid(data["lastPropertyId"]); + ModelEntity.fromMap(Map data) { + id = IdUid.fromString(data["id"]); + lastPropertyId = IdUid.fromString(data["lastPropertyId"]); name = data["name"]; properties = data["properties"].map((p) => ModelProperty.fromMap(p, this)).toList(); validate(); @@ -25,11 +32,11 @@ class ModelEntity { void validate() { if (name == null || name.isEmpty) throw Exception("name is not defined"); if (properties == null) throw Exception("properties is null"); - if (model == null) throw Exception("model is null"); if (properties.isEmpty) { if (lastPropertyId != null) throw Exception("lastPropertyId is not null although there are no properties"); } else { + if (lastPropertyId == null) throw Exception("lastPropertyId is null"); var entity = this; bool lastPropertyIdFound = false; @@ -50,16 +57,16 @@ class ModelEntity { } }); - if (properties.isNotEmpty && !lastPropertyIdFound) { + if (!lastPropertyIdFound && !listContains(model.retiredPropertyUids, lastPropertyId.uid)) { throw Exception("lastPropertyId ${lastPropertyId.toString()} does not match any property"); } - } - for (int i = 0; i < properties.length; ++i) { - final ModelProperty p = properties[i]; - if ((p.flags & OBXPropertyFlag.ID) != 0) { - idPropName = p.name; - break; + for (int i = 0; i < properties.length; ++i) { + final ModelProperty p = properties[i]; + if ((p.flags & OBXPropertyFlag.ID) != 0) { + idPropName = p.name; + break; + } } } } @@ -98,7 +105,7 @@ class ModelEntity { if (uid != 0 && model.containsUid(uid)) throw Exception("uid already exists: $uid"); int uniqueUid = uid == 0 ? model.generateUid() : uid; - var property = ModelProperty(IdUid.create(id, uniqueUid), name, 0, 0, this); + var property = ModelProperty(IdUid(id, uniqueUid), name, 0, 0, this); properties.add(property); lastPropertyId = property.id; return property; diff --git a/lib/src/modelinfo/modelinfo.dart b/lib/src/modelinfo/modelinfo.dart index 86befd60f..e8f996bd5 100644 --- a/lib/src/modelinfo/modelinfo.dart +++ b/lib/src/modelinfo/modelinfo.dart @@ -1,5 +1,6 @@ import "dart:math"; +import '../util.dart'; import "modelentity.dart"; import "iduid.dart"; @@ -18,6 +19,20 @@ class ModelInfo { List retiredEntityUids, retiredIndexUids, retiredPropertyUids, retiredRelationUids; int modelVersion, modelVersionParserMinimum, version; + ModelInfo( + {this.entities, + this.lastEntityId, + this.lastIndexId, + this.lastRelationId, + this.lastSequenceId, + this.retiredEntityUids, + this.retiredIndexUids, + this.retiredPropertyUids, + this.retiredRelationUids, + this.modelVersion, + this.modelVersionParserMinimum, + this.version}); + ModelInfo.createDefault() : entities = [], lastEntityId = IdUid.empty(), @@ -33,11 +48,11 @@ class ModelInfo { version = 1; ModelInfo.fromMap(Map data) { - entities = data["entities"].map((e) => ModelEntity.fromMap(e, this)).toList(); - lastEntityId = IdUid(data["lastEntityId"]); - lastIndexId = IdUid(data["lastIndexId"]); - lastRelationId = IdUid(data["lastRelationId"]); - lastSequenceId = IdUid(data["lastSequenceId"]); + entities = data["entities"].map((e) => ModelEntity.fromMap(e)..model = this).toList(); + lastEntityId = IdUid.fromString(data["lastEntityId"]); + lastIndexId = IdUid.fromString(data["lastIndexId"]); + lastRelationId = IdUid.fromString(data["lastRelationId"]); + lastSequenceId = IdUid.fromString(data["lastSequenceId"]); modelVersion = data["modelVersion"]; modelVersionParserMinimum = data["modelVersionParserMinimum"]; retiredEntityUids = data["retiredEntityUids"].map((x) => x as int).toList(); @@ -63,6 +78,7 @@ class ModelInfo { if (retiredIndexUids == null) throw Exception("retiredIndexUids is null"); if (retiredPropertyUids == null) throw Exception("retiredPropertyUids is null"); if (retiredRelationUids == null) throw Exception("retiredRelationUids is null"); + if (lastEntityId == null) throw Exception("lastEntityId is null"); var model = this; bool lastEntityIdFound = false; @@ -83,7 +99,7 @@ class ModelInfo { } }); - if (entities.isNotEmpty && !lastEntityIdFound) { + if (!lastEntityIdFound && !listContains(model.retiredEntityUids, lastEntityId.uid)) { throw Exception("lastEntityId ${lastEntityId.toString()} does not match any entity"); } } @@ -139,7 +155,7 @@ class ModelInfo { if (uid != 0 && containsUid(uid)) throw Exception("uid already exists: $uid"); int uniqueUid = uid == 0 ? generateUid() : uid; - var entity = ModelEntity(IdUid.create(id, uniqueUid), null, name, [], this); + var entity = ModelEntity(IdUid(id, uniqueUid), null, name, [], this); entities.add(entity); lastEntityId = entity.id; return entity; @@ -158,16 +174,16 @@ class ModelInfo { throw Exception("internal error: could not generate a unique UID"); } - bool containsUid(int searched) { - if (lastEntityId.uid == searched) return true; - if (lastIndexId.uid == searched) return true; - if (lastRelationId.uid == searched) return true; - if (lastSequenceId.uid == searched) return true; - if (entities.indexWhere((e) => e.containsUid(searched)) != -1) return true; - if (retiredEntityUids.indexWhere((x) => x == searched) != -1) return true; - if (retiredIndexUids.indexWhere((x) => x == searched) != -1) return true; - if (retiredPropertyUids.indexWhere((x) => x == searched) != -1) return true; - if (retiredRelationUids.indexWhere((x) => x == searched) != -1) return true; + bool containsUid(int uid) { + if (lastEntityId.uid == uid) return true; + if (lastIndexId.uid == uid) return true; + if (lastRelationId.uid == uid) return true; + if (lastSequenceId.uid == uid) return true; + if (entities.indexWhere((e) => e.containsUid(uid)) != -1) return true; + if (listContains(retiredEntityUids, uid)) return true; + if (listContains(retiredIndexUids, uid)) return true; + if (listContains(retiredPropertyUids, uid)) return true; + if (listContains(retiredRelationUids, uid)) return true; return false; } } diff --git a/lib/src/modelinfo/modelproperty.dart b/lib/src/modelinfo/modelproperty.dart index 106d90a48..dc35b9a35 100644 --- a/lib/src/modelinfo/modelproperty.dart +++ b/lib/src/modelinfo/modelproperty.dart @@ -12,7 +12,7 @@ class ModelProperty { } ModelProperty.fromMap(Map data, this.entity) { - id = IdUid(data["id"]); + id = IdUid.fromString(data["id"]); name = data["name"]; type = data["type"]; flags = data.containsKey("flags") ? data["flags"] : 0; diff --git a/lib/src/util.dart b/lib/src/util.dart new file mode 100644 index 000000000..04ce2742d --- /dev/null +++ b/lib/src/util.dart @@ -0,0 +1,2 @@ + +bool listContains(List list, T item) => list.indexWhere((x) => x == item) != -1; diff --git a/test/entity.dart b/test/entity.dart index ffe9f80f9..cf37cbc5e 100644 --- a/test/entity.dart +++ b/test/entity.dart @@ -2,9 +2,16 @@ import "package:objectbox/objectbox.dart"; part 'entity.g.dart'; +/// A dummy annotation to verify the code is generated properly even with annotations unknown to ObjectBox generator. +class TestingUnknownAnnotation { + const TestingUnknownAnnotation(); +} + @Entity() +@TestingUnknownAnnotation() class TestEntity { @Id() + @TestingUnknownAnnotation() int id; // implicitly determined types