@@ -203,7 +203,7 @@ void main() {
203203 }
204204 ''' ;
205205
206- final result = await testEnv.run (source, expectNoOutput : true );
206+ final result = await testEnv.run (source, ignoreOutput : true );
207207
208208 expect (result.builderResult.succeeded, false );
209209 expect (
@@ -271,6 +271,190 @@ void main() {
271271 ''' );
272272 });
273273
274+ test ('Finds backlink source if type is unique' , () async {
275+ final source = r'''
276+ library example;
277+ import 'package:objectbox/objectbox.dart';
278+
279+ @Entity()
280+ class Example {
281+ @Id()
282+ int id = 0;
283+
284+ final relA = ToMany<A>();
285+ final relB = ToOne<B>();
286+ }
287+
288+ // Name related classes to be lexically before Example so they are
289+ // processed first.
290+
291+ @Entity()
292+ class A {
293+ @Id()
294+ int id = 0;
295+
296+ @Backlink()
297+ final backRel = ToMany<Example>();
298+ }
299+
300+ @Entity()
301+ class B {
302+ @Id()
303+ int id = 0;
304+
305+ @Backlink()
306+ final backRel = ToMany<Example>();
307+ }
308+ ''' ;
309+
310+ final testEnv = GeneratorTestEnv ();
311+ await testEnv.run (source);
312+
313+ final entityA = testEnv.model.entities.firstWhere ((e) => e.name == 'A' );
314+ var backlinkSourceA = entityA.backlinks.first.source;
315+ expect (backlinkSourceA, isA <BacklinkSourceRelation >());
316+ expect ((backlinkSourceA as BacklinkSourceRelation ).srcRel.name, 'relA' );
317+
318+ final entityB = testEnv.model.entities.firstWhere ((e) => e.name == 'B' );
319+ var backlinkSourceB = entityB.backlinks.first.source;
320+ expect (backlinkSourceB, isA <BacklinkSourceProperty >());
321+ expect (
322+ (backlinkSourceB as BacklinkSourceProperty ).srcProp.relationField,
323+ 'relB' ,
324+ );
325+ });
326+
327+ test ('Errors if backlink source is not unique' , () async {
328+ final source = r'''
329+ library example;
330+ import 'package:objectbox/objectbox.dart';
331+
332+ @Entity()
333+ class Example {
334+ @Id()
335+ int id = 0;
336+
337+ final relA1 = ToOne<A>();
338+ final relA2 = ToOne<A>();
339+ final relA3 = ToMany<A>();
340+ }
341+
342+ @Entity()
343+ class A {
344+ @Id()
345+ int id = 0;
346+
347+ @Backlink()
348+ final backRel = ToMany<Example>();
349+ }
350+ ''' ;
351+
352+ final testEnv = GeneratorTestEnv ();
353+ final result = await testEnv.run (source, ignoreOutput: true );
354+
355+ expect (result.builderResult.succeeded, false );
356+ expect (
357+ result.logs,
358+ contains (
359+ isA <LogRecord >()
360+ .having ((r) => r.level, 'level' , Level .SEVERE )
361+ .having (
362+ (r) => r.message,
363+ 'message' ,
364+ contains ('Can\' t determine backlink source for "A.backRel"' ),
365+ ),
366+ ),
367+ );
368+ });
369+
370+ test ('Errors if backlink source does not exist' , () async {
371+ final source = r'''
372+ library example;
373+ import 'package:objectbox/objectbox.dart';
374+
375+ @Entity()
376+ class Example {
377+ @Id()
378+ int id = 0;
379+ }
380+
381+ @Entity()
382+ class A {
383+ @Id()
384+ int id = 0;
385+
386+ @Backlink()
387+ final backRel = ToMany<Example>();
388+ }
389+ ''' ;
390+
391+ final testEnv = GeneratorTestEnv ();
392+ final result = await testEnv.run (source, ignoreOutput: true );
393+
394+ expect (result.builderResult.succeeded, false );
395+ expect (
396+ result.logs,
397+ contains (
398+ isA <LogRecord >()
399+ .having ((r) => r.level, 'level' , Level .SEVERE )
400+ .having (
401+ (r) => r.message,
402+ 'message' ,
403+ contains (
404+ 'Failed to find backlink source for "A.backRel" in "Example"' ,
405+ ),
406+ ),
407+ ),
408+ );
409+ });
410+
411+ test (
412+ 'Does not pick implicit backlink source if explicit one does not exist' ,
413+ () async {
414+ final source = r'''
415+ library example;
416+ import 'package:objectbox/objectbox.dart';
417+
418+ @Entity()
419+ class Example {
420+ @Id()
421+ int id = 0;
422+
423+ final relA1 = ToOne<A>();
424+ final relA2 = ToMany<A>();
425+ }
426+
427+ @Entity()
428+ class A {
429+ @Id()
430+ int id = 0;
431+
432+ @Backlink('doesnotexist')
433+ final backRel = ToMany<Example>();
434+ }
435+ ''' ;
436+
437+ final testEnv = GeneratorTestEnv ();
438+ final result = await testEnv.run (source, ignoreOutput: true );
439+
440+ expect (result.builderResult.succeeded, false );
441+ expect (
442+ result.logs,
443+ contains (
444+ isA <LogRecord >()
445+ .having ((r) => r.level, 'level' , Level .SEVERE )
446+ .having (
447+ (r) => r.message,
448+ 'message' ,
449+ contains (
450+ 'Failed to find backlink source for "A.backRel" in "Example"' ,
451+ ),
452+ ),
453+ ),
454+ );
455+ },
456+ );
457+
274458 test ('@TargetIdProperty ToOne annotation' , () async {
275459 final source = r'''
276460 library example;
@@ -298,6 +482,44 @@ void main() {
298482 expect (renamedRelationProperty! .type, OBXPropertyType .Relation );
299483 });
300484
485+ test ('Explicit backlink to renamed ToOne target ID property' , () async {
486+ final source = r'''
487+ library example;
488+ import 'package:objectbox/objectbox.dart';
489+
490+ @Entity()
491+ class Example {
492+ @Id()
493+ int id = 0;
494+
495+ @TargetIdProperty('customerRef')
496+ final customer = ToOne<Customer>();
497+ }
498+
499+ @Entity()
500+ class Customer {
501+ @Id()
502+ int id = 0;
503+
504+ @Backlink('customer')
505+ final backRel = ToMany<Example>();
506+ }
507+ ''' ;
508+
509+ final testEnv = GeneratorTestEnv ();
510+ await testEnv.run (source);
511+
512+ final customerEntity = testEnv.model.entities.firstWhere (
513+ (e) => e.name == 'Customer' ,
514+ );
515+ var backlinkSource = customerEntity.backlinks.first.source;
516+ expect (backlinkSource, isA <BacklinkSourceProperty >());
517+ expect (
518+ (backlinkSource as BacklinkSourceProperty ).srcProp.relationField,
519+ 'customer' ,
520+ );
521+ });
522+
301523 test ('ToOne target ID property name conflict' , () async {
302524 // Note: unlike in Java, for Dart it's also not supported to "expose" the
303525 // target ID (relation) property.
@@ -315,7 +537,7 @@ void main() {
315537 ''' ;
316538
317539 final testEnv = GeneratorTestEnv ();
318- final result = await testEnv.run (source, expectNoOutput : true );
540+ final result = await testEnv.run (source, ignoreOutput : true );
319541
320542 expect (result.builderResult.succeeded, false );
321543 expect (
@@ -350,7 +572,7 @@ void main() {
350572 ''' ;
351573
352574 final testEnv = GeneratorTestEnv ();
353- final result = await testEnv.run (source, expectNoOutput : true );
575+ final result = await testEnv.run (source, ignoreOutput : true );
354576
355577 expect (result.builderResult.succeeded, false );
356578 expect (
0 commit comments