@@ -394,6 +394,180 @@ func TestLearn(t *testing.T) {
394
394
}
395
395
}
396
396
397
+ func TestRecall (t * testing.T ) {
398
+ cases := []struct {
399
+ name string
400
+ learn []learn
401
+ want []brain.Message
402
+ }{
403
+ {
404
+ name : "empty" ,
405
+ learn : nil ,
406
+ want : nil ,
407
+ },
408
+ {
409
+ name : "single" ,
410
+ learn : []learn {
411
+ {
412
+ tag : "kessoku" ,
413
+ user : userhash.Hash {0 : 1 , userhash .Size - 1 : 2 },
414
+ id : "1" ,
415
+ t : 1 ,
416
+ tups : []brain.Tuple {
417
+ {Prefix : strings .Fields ("kita nijika ryo bocchi" ), Suffix : "" },
418
+ {Prefix : strings .Fields ("nijika ryo bocchi" ), Suffix : "kita" },
419
+ {Prefix : strings .Fields ("ryo bocchi" ), Suffix : "nijika" },
420
+ {Prefix : strings .Fields ("bocchi" ), Suffix : "ryo" },
421
+ {Prefix : nil , Suffix : "bocchi" },
422
+ },
423
+ },
424
+ },
425
+ want : []brain.Message {
426
+ {
427
+ ID : "1" ,
428
+ Sender : userhash.Hash {0 : 1 , userhash .Size - 1 : 2 },
429
+ Text : "bocchiryonijikakita" ,
430
+ Timestamp : 1 ,
431
+ },
432
+ },
433
+ },
434
+ {
435
+ name : "several" ,
436
+ learn : []learn {
437
+ {
438
+ tag : "kessoku" ,
439
+ user : userhash.Hash {0 : 1 , userhash .Size - 1 : 2 },
440
+ id : "1" ,
441
+ t : 1 ,
442
+ tups : []brain.Tuple {
443
+ {Prefix : []string {"bocchi" }, Suffix : "" },
444
+ {Prefix : nil , Suffix : "bocchi" },
445
+ },
446
+ },
447
+ {
448
+ tag : "kessoku" ,
449
+ user : userhash.Hash {0 : 3 , userhash .Size - 1 : 4 },
450
+ id : "2" ,
451
+ t : 1 , // n.b. same timestamp
452
+ tups : []brain.Tuple {
453
+ {Prefix : []string {"ryo" }, Suffix : "" },
454
+ {Prefix : nil , Suffix : "ryo" },
455
+ },
456
+ },
457
+ {
458
+ tag : "kessoku" ,
459
+ user : userhash.Hash {0 : 5 , userhash .Size - 1 : 6 },
460
+ id : "0" , // n.b. lexicographically smaller id
461
+ t : 3 ,
462
+ tups : []brain.Tuple {
463
+ {Prefix : []string {"nijika" }, Suffix : "" },
464
+ {Prefix : nil , Suffix : "nijika" },
465
+ },
466
+ },
467
+ {
468
+ tag : "kessoku" ,
469
+ user : userhash.Hash {0 : 7 , userhash .Size - 1 : 8 },
470
+ id : "4" ,
471
+ t : 4 ,
472
+ tups : []brain.Tuple {
473
+ {Prefix : []string {"kita" }, Suffix : "" },
474
+ {Prefix : nil , Suffix : "kita" },
475
+ },
476
+ },
477
+ },
478
+ want : []brain.Message {
479
+ {
480
+ ID : "1" ,
481
+ Sender : userhash.Hash {0 : 1 , userhash .Size - 1 : 2 },
482
+ Text : "bocchi" ,
483
+ Timestamp : 1 ,
484
+ },
485
+ {
486
+ ID : "2" ,
487
+ Sender : userhash.Hash {0 : 3 , userhash .Size - 1 : 4 },
488
+ Text : "ryo" ,
489
+ Timestamp : 1 ,
490
+ },
491
+ {
492
+ ID : "0" ,
493
+ Sender : userhash.Hash {0 : 5 , userhash .Size - 1 : 6 },
494
+ Text : "nijika" ,
495
+ Timestamp : 3 ,
496
+ },
497
+ {
498
+ ID : "4" ,
499
+ Sender : userhash.Hash {0 : 7 , userhash .Size - 1 : 8 },
500
+ Text : "kita" ,
501
+ Timestamp : 4 ,
502
+ },
503
+ },
504
+ },
505
+ {
506
+ name : "tagged" ,
507
+ learn : []learn {
508
+ {
509
+ tag : "sickhack" ,
510
+ user : userhash.Hash {0 : 1 , userhash .Size - 1 : 2 },
511
+ id : "1" ,
512
+ t : 1 ,
513
+ tups : []brain.Tuple {
514
+ {Prefix : strings .Fields ("kita nijika ryo bocchi" ), Suffix : "" },
515
+ {Prefix : strings .Fields ("nijika ryo bocchi" ), Suffix : "kita" },
516
+ {Prefix : strings .Fields ("ryo bocchi" ), Suffix : "nijika" },
517
+ {Prefix : strings .Fields ("bocchi" ), Suffix : "ryo" },
518
+ {Prefix : nil , Suffix : "bocchi" },
519
+ },
520
+ },
521
+ },
522
+ want : nil ,
523
+ },
524
+ }
525
+ for _ , c := range cases {
526
+ t .Run (c .name , func (t * testing.T ) {
527
+ t .Parallel ()
528
+ ctx := context .Background ()
529
+ db := testDB (ctx )
530
+ br , err := sqlbrain .Open (ctx , db )
531
+ if err != nil {
532
+ t .Fatalf ("couldn't open brain: %v" , err )
533
+ }
534
+ for _ , m := range c .learn {
535
+ msg := brain.Message {
536
+ ID : m .id ,
537
+ Sender : m .user ,
538
+ Timestamp : m .t ,
539
+ }
540
+ err := br .Learn (ctx , m .tag , & msg , m .tups )
541
+ if err != nil {
542
+ t .Errorf ("failed to learn %v/%v: %v" , m .tag , m .id , err )
543
+ }
544
+ }
545
+ var page string
546
+ got := make ([]brain.Message , 1 )
547
+ for _ , want := range c .want {
548
+ n , next , err := br .Recall (ctx , "kessoku" , page , got )
549
+ if err != nil {
550
+ t .Errorf ("recall failed on page %s: %v" , page , err )
551
+ }
552
+ if n != 1 {
553
+ t .Errorf ("wrong number of recalled messages for page %s: want 1, got %d" , page , n )
554
+ }
555
+ if got [0 ] != want {
556
+ t .Errorf ("wrong result: want %+v, got %+v" , want , got [0 ])
557
+ }
558
+ page = next
559
+ }
560
+ n , next , err := br .Recall (ctx , "kessoku" , page , got )
561
+ if err != nil {
562
+ t .Errorf ("final recall failed on page %s: %v" , page , err )
563
+ }
564
+ if n != 0 || next != "" {
565
+ t .Errorf ("final recall gave wrong results: want n=0 with empty next, got n=%d next=%s" , n , next )
566
+ }
567
+ })
568
+ }
569
+ }
570
+
397
571
func BenchmarkLearn (b * testing.B ) {
398
572
dir := filepath .ToSlash (b .TempDir ())
399
573
new := func (ctx context.Context , b * testing.B ) brain.Learner {
0 commit comments