Skip to content

Commit

Permalink
Support four backticks in doc-test parser (#194)
Browse files Browse the repository at this point in the history
  • Loading branch information
mlange-42 authored Feb 3, 2025
1 parent 0977e0c commit 5e625fc
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 11 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## [[unpublished]](https://github.com/mlange-42/modo/compare/v0.10.1...main)

### Other

* Doc-tests parser supports quadruple backticks (#194)

## [[v0.10.1]](https://github.com/mlange-42/modo/compare/v0.10.0...v0.10.1)

### Documentation
Expand Down
20 changes: 11 additions & 9 deletions document/doctest.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"os"
"path"
"path/filepath"
"sort"
"strings"
)

Expand Down Expand Up @@ -121,7 +122,7 @@ func extractTestsText(text string, elems []string, strict bool) (string, []*docT
scanner := bufio.NewScanner(strings.NewReader(text))
outText := strings.Builder{}

fenced := false
fenced := fenceNone
blocks := map[string]*docTest{}
var blockLines []string
var globalLines []string
Expand All @@ -133,8 +134,8 @@ func extractTestsText(text string, elems []string, strict bool) (string, []*docT
origLine := scanner.Text()

isStart := false
isFence := strings.HasPrefix(origLine, codeFence3)
if isFence && !fenced {
currFence := getFenceType(origLine)
if currFence != fenceNone && fenced == fenceNone {
var ok bool
var err error
blockName, excluded, global, ok, err = parseBlockAttr(origLine)
Expand All @@ -146,7 +147,7 @@ func extractTestsText(text string, elems []string, strict bool) (string, []*docT
if !ok {
blockName = ""
}
fenced = true
fenced = currFence
isStart = true
}

Expand All @@ -155,7 +156,7 @@ func extractTestsText(text string, elems []string, strict bool) (string, []*docT
outText.WriteRune('\n')
}

if fenced && !isFence && blockName != "" {
if fenced != fenceNone && currFence != fenced && blockName != "" {
if global {
globalLines = append(globalLines, origLine)
} else {
Expand All @@ -164,11 +165,11 @@ func extractTestsText(text string, elems []string, strict bool) (string, []*docT
}
count++

if isFence && fenced && !isStart {
if fenced != fenceNone && currFence == fenced && !isStart {
if blockName == "" {
excluded = false
global = false
fenced = false
fenced = fenceNone
continue
}
if dt, ok := blocks[blockName]; ok {
Expand All @@ -186,13 +187,13 @@ func extractTestsText(text string, elems []string, strict bool) (string, []*docT
globalLines = globalLines[:0]
excluded = false
global = false
fenced = false
fenced = fenceNone
}
}
if err := scanner.Err(); err != nil {
panic(err)
}
if fenced {
if fenced != fenceNone {
if err := warnOrError(strict, "unbalanced code block in %s", strings.Join(elems, ".")); err != nil {
return "", nil, err
}
Expand All @@ -202,6 +203,7 @@ func extractTestsText(text string, elems []string, strict bool) (string, []*docT
for _, block := range blocks {
tests = append(tests, block)
}
sort.Slice(tests, func(i, j int) bool { return tests[i].Name < tests[j].Name })

return strings.TrimSuffix(outText.String(), "\n"), tests, nil
}
Expand Down
37 changes: 37 additions & 0 deletions document/doctest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,43 @@ func TestExtractDocTests(t *testing.T) {
})
}

func TestExtractDocTests4Ticks(t *testing.T) {
text := "Docstring\n" +
"\n" +
"```mojo {doctest=\"test1\" hide=true global=true}\n" +
"````mojo {doctest=\"test2\"}\n" +
"Test1\n" +
"````\n" +
"```\n" +
"\n" +
"````mojo {doctest=\"test3\" hide=true global=true}\n" +
"```mojo {doctest=\"test4\"}\n" +
"Test2\n" +
"```\n" +
"````\n"

proc := NewProcessor(nil, nil, nil, &Config{})
outText, err := proc.extractTests(text, []string{"pkg", "Struct"}, 1)
assert.Nil(t, err)
assert.Equal(t, 3, len(strings.Split(outText, "\n")))

assert.Equal(t, 2, len(proc.docTests))

assert.Equal(t, &docTest{
Name: "test1",
Path: []string{"pkg", "Struct"},
Code: []string{},
Global: []string{"````mojo {doctest=\"test2\"}", "Test1", "````"},
}, proc.docTests[0])

assert.Equal(t, &docTest{
Name: "test3",
Path: []string{"pkg", "Struct"},
Code: []string{},
Global: []string{"```mojo {doctest=\"test4\"}", "Test2", "```"},
}, proc.docTests[1])
}

func TestExtractTestsMarkdown(t *testing.T) {
inDir := t.TempDir()
outDir := t.TempDir()
Expand Down
2 changes: 0 additions & 2 deletions document/exports.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import (

const exportsMarker = "Exports:"
const exportsPrefix = "- "
const codeFence3 = "```"
const codeFence4 = "````"

type packageExport struct {
Short []string
Expand Down
23 changes: 23 additions & 0 deletions document/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,34 @@ import (
"fmt"
"os"
"path/filepath"
"strings"
"text/template"

"github.com/mlange-42/modo/assets"
)

const codeFence3 = "```"
const codeFence4 = "````"

type fenceType uint8

const (
fenceNone fenceType = iota
fenceThree
fenceFour
)

func getFenceType(line string) fenceType {
isFence4 := strings.HasPrefix(line, codeFence4)
if strings.HasPrefix(line, codeFence3) && !isFence4 {
return fenceThree
}
if isFence4 {
return fenceFour
}
return fenceNone
}

// appends to a slice, but guaranties to return a new one and not alter the original.
func appendNew[T any](sl []T, elems ...T) []T {
sl2 := make([]T, len(sl), len(sl)+len(elems))
Expand Down

0 comments on commit 5e625fc

Please sign in to comment.