package main import ( "errors" "testing" ) // The search index (to-be 55 ยง1, AC52): built from the ledger at start, refusing "index not built" meanwhile, kept current // as the module writes, and answering the questions the knowledge base is asked as the in-memory ranking does: the records // the questions are about come first. func TestTheSearchIndexAnswersTheQuestionsAsTheStoreDoes(t *testing.T) { f := newFakeLedger(t) ls := newLedgerStore(f, newFakeStates()) w := newWorld(t, ls, fixture()) w.k.States = newFakeStates() ls.indexAsync = true if _, err := ls.Search(t.Context(), "merge window", 5); !errors.Is(err, ErrIndexNotBuilt) { t.Fatalf("a question before the index was built: %v", err) } if _, err := w.k.Import("import@test", ImportAsk{}, fixture()); err != nil { t.Fatal(err) } if err := ls.BuildIndex(t.Context()); err != nil { t.Fatal(err) } if st := ls.IndexState(); !st.Built || st.Docs < 20 { t.Fatalf("%+v", st) } mem := imported(t, newMemStore()) for _, q := range []string{"merge window", "how is the tool runtime chosen", "what holds about resolved names", "a knowledge base the mesh writes"} { want, _ := mem.k.Store.Search(t.Context(), q, 3) got, err := ls.Search(t.Context(), q, 8) if err != nil { t.Fatal(err) } // The ranking differs (the index weighs by how rare a word is), so the record the store puts first is among the // first few of the index's. found := false for _, h := range got { found = found || (len(want) > 0 && h.Key == want[0].Key) } if len(want) > 0 && !found { t.Errorf("%q: the store puts %v first, the index %v", q, want[0], got) } } // A new version is in the index at once; a withdrawn record is out of it. r, _ := w.k.ReserveNumber("author@g14", KindDecision, "a test record") if hits, _ := ls.Search(t.Context(), "zebra quantum", 5); len(hits) != 0 { t.Fatalf("%v", hits) } p := valid(r.Number) p.Title = "Zebra quantum processors" p.Sections[2].Text = "A zebra quantum processor." if _, err := w.k.Propose("author@g14", p); err != nil { t.Fatal(err) } if hits, _ := ls.Search(t.Context(), "zebra quantum", 5); len(hits) == 0 || hits[0].Key.Number != r.Number { t.Fatalf("a proposed record is not in the index: %v", hits) } if _, err := w.k.WithdrawRecord("author@g14", Key{KindDecision, r.Number}, "not needed"); err != nil { t.Fatal(err) } if hits, _ := ls.Search(t.Context(), "zebra quantum", 5); len(hits) != 0 { t.Fatalf("a withdrawn record is in the index: %v", hits) } }