Merge pull request #15 from TripleDogDare/trailing-whitespace-error
commit 00b11e2440469dc9e046ead7442d6c13901ac97d · parent 8c1550b905 · parent aefd8a6e14
· browse this tree
Eric Myhre, 2022-12-09 21:55:03 UTC
Trailing whitespace error
diff --git a/read.go b/read.go index 6179b08..77658dc 100644 --- a/read.go +++ b/read.go @@ -77,21 +77,22 @@ func Parse(data []byte) (*Document, error) { inCodeBlock = !inCodeBlock goto next } - // If we're in a code block, just fly by. if inCodeBlock { + // If we're in a code block, just fly by. goto next } - // If we were expecting a code block just now, we didn't get it. if expectCodeBlock { - // ... Log a complaint? I don't think halting with a parse error would be helpful. - // But definitely don't wait around for arbitrarily distant code blocks. - expectCodeBlock = false + // If we were expecting a code block just now, we didn't get it. + return &doc, fmt.Errorf("invalid markdown comment on line %d. Missing code block for hunk %s", i+1, hunkInProgress.Name) } // Look for testmark block indicators. if bytes.HasPrefix(line, sigilTestmark) { // If this line, after the sigil prefix, doesn't begin with "(" and end with ")", it's not a well-formed markdown comment, and you should probably be told about that. remainder := line[len(sigilTestmark):] if len(remainder) < 2 || remainder[0] != '(' || remainder[len(remainder)-1] != ')' { + if unicode.IsSpace(rune(remainder[len(remainder)-1])) { + return &doc, fmt.Errorf("invalid markdown comment on line %d (should look like %q; remove trailing whitespace)", i+1, "[testmark]:# (data-name-here)") + } return &doc, fmt.Errorf("invalid markdown comment on line %d (should look like %q, mind the parens)", i+1, "[testmark]:# (data-name-here)") } remainder = remainder[1 : len(remainder)-1] diff --git a/read_test.go b/read_test.go index 62de99f..d12a758 100644 --- a/read_test.go +++ b/read_test.go @@ -2,6 +2,7 @@ package testmark_test import ( "bytes" + "fmt" "io/ioutil" "path/filepath" "regexp" @@ -56,6 +57,48 @@ func TestParseCRLF(t *testing.T) { readFixturesExample(t, doc) } +func TestParseSimple(t *testing.T) { + buf := bytes.NewBuffer([]byte{}) + fmt.Fprintln(buf, "[testmark]:# (simple)") + fmt.Fprintln(buf, "```") + fmt.Fprintln(buf, "Hello, World!") + fmt.Fprintln(buf, "```") + doc, err := testmark.Parse(buf.Bytes()) + if err != nil { + t.Fatal(err) + } + hunk := doc.HunksByName["simple"] + assert(t, hunk.Body, "Hello, World!\n") +} + +func TestParseTrailingWhitespace(t *testing.T) { + buf := bytes.NewBuffer([]byte{}) + fmt.Fprintln(buf, "[testmark]:# (trailing/whitespace) ") + fmt.Fprintln(buf, "```") + fmt.Fprintln(buf, "foo") + fmt.Fprintln(buf, "```") + doc, err := testmark.Parse(buf.Bytes()) + assert(t, err.Error(), `invalid markdown comment on line 1 (should look like "[testmark]:# (data-name-here)"; remove trailing whitespace)`) + _, exists := doc.HunksByName["trailing/whitespace"] + if exists { + t.Errorf("hunk should not exist") + } +} + +func TestParseTrailingExtraLineBreak(t *testing.T) { + buf := bytes.NewBuffer([]byte("[testmark]:# (extra/newline)\n\n")) + fmt.Fprintln(buf, "```") + fmt.Fprintln(buf, "foo") + fmt.Fprintln(buf, "```") + doc, err := testmark.Parse(buf.Bytes()) + assert(t, err.Error(), `invalid markdown comment on line 2. Missing code block for hunk extra/newline`) + hunk, exists := doc.HunksByName["extra/newline"] + if exists { + t.Errorf("testmark should ignore these") + } + assert(t, hunk.Body, "") +} + func TestDuplicateHunk(t *testing.T) { testdata, err := filepath.Abs("testdata") if err != nil {