find_test.mx raw

   1  package find
   2  
   3  import (
   4  	"bytes"
   5  	"testing"
   6  
   7  	"smesh.lol/pkg/nostr/event"
   8  	"smesh.lol/pkg/nostr/signer/p8k"
   9  	"smesh.lol/pkg/store"
  10  )
  11  
  12  func openTmp(t *testing.T) *store.Engine {
  13  	t.Helper()
  14  	eng, err := store.Open(t.TempDir())
  15  	if err != nil {
  16  		t.Fatal(err)
  17  	}
  18  	t.Cleanup(func() { eng.Close() })
  19  	return eng
  20  }
  21  
  22  func makeEvent(t *testing.T, s *p8k.Signer, content string, ts int64) *event.E {
  23  	t.Helper()
  24  	ev := &event.E{
  25  		CreatedAt: ts,
  26  		Kind:      1,
  27  		Content:   []byte(content),
  28  	}
  29  	if err := ev.Sign(s); err != nil {
  30  		t.Fatal(err)
  31  	}
  32  	return ev
  33  }
  34  
  35  func TestSplitWords(t *testing.T) {
  36  	tests := []struct {
  37  		input string
  38  		want  []string
  39  	}{
  40  		{"hello world", []string{"hello", "world"}},
  41  		{"Hi There", []string{"there"}},          // "hi" too short
  42  		{"a bb ccc", []string{"ccc"}},             // min 3 chars
  43  		{"foo123 bar", []string{"foo123", "bar"}}, // alphanumeric
  44  		{"", nil},
  45  	}
  46  	for _, tt := range tests {
  47  		got := SplitWords([]byte(tt.input))
  48  		if len(got) != len(tt.want) {
  49  			t.Errorf("SplitWords(%q): got %d words, want %d", tt.input, len(got), len(tt.want))
  50  			continue
  51  		}
  52  		for i := range got {
  53  			if string(got[i]) != tt.want[i] {
  54  				t.Errorf("SplitWords(%q)[%d] = %q, want %q", tt.input, i, got[i], tt.want[i])
  55  			}
  56  		}
  57  	}
  58  }
  59  
  60  func TestSearchFindsEvent(t *testing.T) {
  61  	eng := openTmp(t)
  62  	s := p8k.MustNew()
  63  	if err := s.Generate(); err != nil {
  64  		t.Fatal(err)
  65  	}
  66  
  67  	ev := makeEvent(t, s, "the quick brown fox jumps", 1700000000)
  68  	if err := eng.SaveEvent(ev); err != nil {
  69  		t.Fatal(err)
  70  	}
  71  
  72  	f := New(eng)
  73  	results := f.Search([]byte("quick brown"), 10)
  74  	if len(results) != 1 {
  75  		t.Fatalf("expected 1 result, got %d", len(results))
  76  	}
  77  	if !bytes.Equal(results[0].ID, ev.ID) {
  78  		t.Error("result ID mismatch")
  79  	}
  80  }
  81  
  82  func TestSearchNoMatch(t *testing.T) {
  83  	eng := openTmp(t)
  84  	s := p8k.MustNew()
  85  	if err := s.Generate(); err != nil {
  86  		t.Fatal(err)
  87  	}
  88  
  89  	if err := eng.SaveEvent(makeEvent(t, s, "hello world foo", 1700000000)); err != nil {
  90  		t.Fatal(err)
  91  	}
  92  
  93  	f := New(eng)
  94  	results := f.Search([]byte("nonexistent"), 10)
  95  	if len(results) != 0 {
  96  		t.Fatalf("expected 0 results, got %d", len(results))
  97  	}
  98  }
  99  
 100  func TestSearchLimit(t *testing.T) {
 101  	eng := openTmp(t)
 102  	s := p8k.MustNew()
 103  	if err := s.Generate(); err != nil {
 104  		t.Fatal(err)
 105  	}
 106  
 107  	for i := 0; i < 5; i++ {
 108  		if err := eng.SaveEvent(makeEvent(t, s, "testing search limit feature", int64(1700000000+i))); err != nil {
 109  			t.Fatal(err)
 110  		}
 111  	}
 112  
 113  	f := New(eng)
 114  	results := f.Search([]byte("testing search"), 2)
 115  	if len(results) != 2 {
 116  		t.Fatalf("expected 2 results, got %d", len(results))
 117  	}
 118  }
 119