package manifest_test import ( "strings" "testing" "git.vakhrushev.me/av/convy/internal/manifest" ) func TestAddEntryKeepsComments(t *testing.T) { source := `# The suite manifest. [language] version = 1 # ─── Topics ─── # # A topic is a set of rules about one focus of development. [topics.live] config = "configuration" time = "time" [topics.retired] # Empty. Retired names land here together with a reason and a date. ` got, err := manifest.AddEntry([]byte(source), "topics.live", "logging", "logging: levels, structure") if err != nil { t.Fatal(err) } out := string(got) for _, want := range []string{ "# ─── Topics ───", "# A topic is a set of rules about one focus of development.", "# Empty. Retired names land here together with a reason and a date.", `logging = "logging: levels, structure"`, } { if !strings.Contains(out, want) { t.Errorf("the result lost %q:\n%s", want, out) } } } // A table whose keys are already sorted keeps its order; one ordered by hand // gets the entry appended, so that a grouping by directory survives. func TestAddEntryRespectsExistingOrder(t *testing.T) { sorted := `[topics.live] config = "c" time = "t" ` got, err := manifest.AddEntry([]byte(sorted), "topics.live", "logging", "l") if err != nil { t.Fatal(err) } wantSorted := "[topics.live]\nconfig = \"c\"\nlogging = \"l\"\ntime = \"t\"\n" if string(got) != wantSorted { t.Errorf("a sorted table was not kept sorted:\n%s", got) } grouped := `[prefixes.live] TIME = "conventions/arch/time.md" CONF = "conventions/arch/config.md" GTIM = "conventions/lang/go/time.md" ` got, err = manifest.AddEntry([]byte(grouped), "prefixes.live", "GCFG", "conventions/lang/go/config.md") if err != nil { t.Fatal(err) } if !strings.HasSuffix(strings.TrimRight(string(got), "\n"), `GCFG = "conventions/lang/go/config.md"`) { t.Errorf("a hand-ordered table did not get the entry appended:\n%s", got) } } func TestAddEntryIntoEmptyTable(t *testing.T) { source := `[topics.live] # Nothing yet. [topics.retired] ` got, err := manifest.AddEntry([]byte(source), "topics.live", "time", "time") if err != nil { t.Fatal(err) } want := "[topics.live]\n# Nothing yet.\ntime = \"time\"\n\n[topics.retired]\n" if string(got) != want { t.Errorf("insertion into an empty table went wrong:\n%q", got) } } // A comment block separated from an empty table by a blank line explains the // table header standing below it, not the one above. Filing an entry after such // a block puts it under the wrong explanation. func TestAddEntryIntoEmptyTableStopsBeforeTheNextComment(t *testing.T) { source := `[topics.live] # Retired names land here together with a reason and a date. [topics.retired] ` got, err := manifest.AddEntry([]byte(source), "topics.live", "time", "time") if err != nil { t.Fatal(err) } want := "[topics.live]\ntime = \"time\"\n\n# Retired names land here together with a reason and a date.\n\n[topics.retired]\n" if string(got) != want { t.Errorf("the entry was filed under the wrong comment:\n%q", got) } } func TestAddEntryRejectsDuplicateAndMissingTable(t *testing.T) { source := "[topics.live]\ntime = \"t\"\n" if _, err := manifest.AddEntry([]byte(source), "topics.live", "time", "t"); err == nil { t.Error("a duplicate key was accepted") } if _, err := manifest.AddEntry([]byte(source), "prefixes.live", "TIME", "x.md"); err == nil { t.Error("a missing table was accepted") } } func TestAddEntryQuotesWhatIsNotBare(t *testing.T) { source := "[topics.live]\n" got, err := manifest.AddEntry([]byte(source), "topics.live", "web ui", `a "quoted" thing`) if err != nil { t.Fatal(err) } if !strings.Contains(string(got), `"web ui" = "a \"quoted\" thing"`) { t.Errorf("key or value was not escaped:\n%s", got) } }