package matcher_test import ( "fmt" "testing" "git.max-richter.dev/max/marka/parser/matcher" "git.max-richter.dev/max/marka/registry" "git.max-richter.dev/max/marka/template" "git.max-richter.dev/max/marka/testdata" ) func TestFuzzyFindAll(t *testing.T) { recipeMd := testdata.Read(t, "baguette/input.md") tests := []struct { Needle string Start, End, StartIndex int }{ {StartIndex: 0, Needle: "# Ingredients\n", Start: 77, End: 91}, {StartIndex: 0, Needle: "# Ingrdients\n", Start: 77, End: 91}, {StartIndex: 0, Needle: "# Inrdients\n", Start: 77, End: 91}, {StartIndex: 0, Needle: "---\n", Start: 0, End: 4}, {StartIndex: 4, Needle: "---\n", Start: 29, End: 33}, {StartIndex: 0, Needle: "# Steps\n", Start: 116, End: 124}, {StartIndex: 0, Needle: "# Stps\n", Start: 116, End: 124}, {StartIndex: 0, Needle: "# Step\n", Start: 116, End: 124}, } for _, test := range tests { start, end := matcher.FuzzyFind(string(recipeMd), test.StartIndex, test.Needle, 0.3) // allow 50% error if start != test.Start || end != test.End { t.Errorf("Start or end do not match: Needle=%q Start=%d/%d End=%d/%d", test.Needle, test.Start, start, test.End, end) } } } func TestFuzzyBlockMatch(t *testing.T) { recipeMd := testdata.Read(t, "baguette/input.md") schemaMd, err := registry.GetTemplate("Recipe") if err != nil { t.Errorf("Failed to load template: %s", err.Error()) t.FailNow() } blocks, err := template.CompileTemplate(schemaMd) if err != nil { t.Errorf("Failed to compile template: %s", err.Error()) t.FailNow() } matches := matcher.MatchBlocksFuzzy(string(recipeMd), blocks, 0.3) expected := []struct { value string }{ { value: "@type: Recipe\nauthor.name: Max Richter", }, { value: "Baguette", }, { value: "\nMy favourite baguette recipe", }, { value: "", }, { value: "- Flour\n- Water\n- Salt", }, { value: "1. Mix Flour Water and Salt\n2. Bake the bread\n", }, } for i, m := range matches { if i > len(expected)-1 { t.Errorf("No expected result for match: %d -> %q", i, m.GetContent()) t.FailNow() } if expected[i].value != m.GetContent() { t.Errorf("Match %d did not match expected: %q", i, m.GetContent()) } fmt.Printf("match: %s->%q\n", m.Block.Path, m.GetContent()) } } func TestFuzzyBlockMatchSalad(t *testing.T) { recipeMd := testdata.Read(t, "recipe_salad/input.md") schemaMd, err := registry.GetTemplate("Recipe") if err != nil { t.Errorf("Failed to load template: %s", err.Error()) t.FailNow() } blocks, err := template.CompileTemplate(schemaMd) if err != nil { t.Errorf("Failed to compile template: %s", err.Error()) t.FailNow() } matches := matcher.MatchBlocksFuzzy(string(recipeMd), blocks, 0.3) expected := []struct { value string }{ { value: "@type: Recipe\nauthor.name: Alex Chef\ncookTime: PT0M\nimage: https://example.com/salad.jpg\nprepTime: PT10M\nrecipeYield: 2 servings", }, { value: "Simple Salad", }, { value: "#healthy #salad", }, { value: "A quick green salad.", }, { value: "- 100 g lettuce\n- 5 cherry tomatoes\n- 1 tbsp olive oil\n- Pinch of salt", }, { value: "1. Wash and dry the lettuce.\n2. Halve the cherry tomatoes.\n3. Toss with olive oil and salt.\n", }, } for i, m := range matches { if i > len(expected)-1 { t.Errorf("No expected result for match: %d -> %q", i, m.GetContent()) t.FailNow() } if expected[i].value != m.GetContent() { t.Errorf("Match %d did not match expected: %q", i, m.GetContent()) } fmt.Printf("match: %s->%q\n", m.Block.Path, m.GetContent()) } }