package search import ( "reflect" "slices" "testing" ) func TestParse(t *testing.T) { term := func(field Field, value string) Term { return Term{ Field: field, Value: value, } } text := func(value string) Term { return term(FieldText, value) } not := func(term Term) Term { term.Negated = true return term } none := []string{} cases := []struct { input string terms []Term unknown []string }{ {"", nil, none}, {" ", nil, none}, {"cloud hosting", []Term{text("cloud"), text("hosting")}, none}, {`"road repairs" leeds`, []Term{text("road repairs"), text("leeds")}, none}, {`title:"road repairs"`, []Term{term(FieldTitle, "road repairs")}, none}, {"TITLE:road Buyer:leeds", []Term{term(FieldTitle, "road"), term(FieldBuyer, "leeds")}, none}, {"buyer_id:GB-1 cpv:72", []Term{term(FieldBuyerID, "GB-1"), term(FieldCPV, "72")}, none}, {"!cloud !cpv:food", []Term{not(text("cloud")), not(term(FieldCPV, "food"))}, none}, {`!title:"a b"`, []Term{not(term(FieldTitle, "a b"))}, none}, {"12:00", []Term{text("12:00")}, none}, {`"unclosed phrase`, []Term{text("unclosed phrase")}, none}, {`title: !!! "" ! cloud`, []Term{text("cloud")}, none}, {"foo:bar cloud Foo:baz foo:x baz:", []Term{text("cloud")}, []string{"foo", "Foo", "baz"}}, {"buyer_id:", nil, none}, } for _, tc := range cases { got := Parse(tc.input) if !reflect.DeepEqual(got.Terms, tc.terms) { t.Errorf("%q: terms %+v, want %+v", tc.input, got.Terms, tc.terms) } if !slices.Equal(got.UnknownPrompts, tc.unknown) { t.Errorf( "%q: unknown %q, want %q", tc.input, got.UnknownPrompts, tc.unknown, ) } if got.UnknownPrompts == nil { t.Errorf("%q: UnknownPrompts is nil", tc.input) } if got.MatchesAll() != (len(tc.terms) == 0) { t.Errorf("%q: MatchesAll %v", tc.input, got.MatchesAll()) } } } func TestTermWordsAndCPVCode(t *testing.T) { cases := []struct { value string words []string code string isCPV bool }{ {"road-repairs", []string{"road", "repairs"}, "", false}, {"Café's", []string{"Café", "s"}, "", false}, {"72", []string{"72"}, "72", true}, {"72210000-5", []string{"72210000", "5"}, "72210000", true}, {"72-55", []string{"72", "55"}, "", false}, {"72a", []string{"72a"}, "", false}, } for _, tc := range cases { term := Term{ Field: FieldCPV, Value: tc.value, } if got := term.Words(); !slices.Equal(got, tc.words) { t.Errorf("%q: words %q, want %q", tc.value, got, tc.words) } code, ok := term.CPVCode() if code != tc.code || ok != tc.isCPV { t.Errorf( "%q: CPVCode %q %v, want %q %v", tc.value, code, ok, tc.code, tc.isCPV, ) } } } // Every known prompt has help, and every prompt with help is known. func TestPromptsHaveHelp(t *testing.T) { if len(Prompts) != len(prompts) { t.Errorf("%d prompts with help, %d known", len(Prompts), len(prompts)) } for _, prompt := range Prompts { if _, ok := prompts[prompt.Name]; !ok || prompt.Help == "" { t.Errorf("prompt %q: known %v, help %q", prompt.Name, ok, prompt.Help) } } }