Merge consecutive text nodes when inspecting markdown (#9112)

* Fix assertion order

expected/actual were in wrong order, resulting in misleading output in
case of failing tests

* Merge consesutive markdown text nodes

This ensures that parser quirks such as "hello!" being parsed as
two separate nodes ("hello" and "!") are not exposed to code inspecting
a markdown strings.
Этот коммит содержится в:
Adrian
2018-07-16 17:12:31 +02:00
коммит произвёл Joram Wilander
родитель 940d0bbbc2
Коммит 88eef609ab
3 изменённых файлов: 57 добавлений и 23 удалений

Просмотреть файл

@@ -476,6 +476,40 @@ func ParseInlines(markdown string, ranges []Range, referenceDefinitions []*Refer
return newInlineParser(markdown, ranges, referenceDefinitions).Parse() return newInlineParser(markdown, ranges, referenceDefinitions).Parse()
} }
func MergeInlineText(inlines []Inline) []Inline {
var ret []Inline
for i, v := range inlines {
// always add first node
if i == 0 {
ret = append(ret, v)
continue
}
// not a text node? nothing to merge
text, ok := v.(*Text)
if !ok {
ret = append(ret, v)
continue
}
// previous node is not a text node? nothing to merge
prevText, ok := ret[len(ret)-1].(*Text)
if !ok {
ret = append(ret, v)
continue
}
// previous node is not right before this one
if prevText.Range.End != text.Range.Position {
ret = append(ret, v)
continue
}
// we have two consecutive text nodes
ret[len(ret)-1] = &Text{
Text: prevText.Text + text.Text,
Range: Range{prevText.Range.Position, text.Range.End},
}
}
return ret
}
func Unescape(markdown string) string { func Unescape(markdown string) string {
ret := "" ret := ""

Просмотреть файл

@@ -13,7 +13,7 @@ func Inspect(markdown string, f func(interface{}) bool) {
} }
switch v := block.(type) { switch v := block.(type) {
case *Paragraph: case *Paragraph:
for _, inline := range v.ParseInlines(referenceDefinitions) { for _, inline := range MergeInlineText(v.ParseInlines(referenceDefinitions)) {
InspectInline(inline, func(inline Inline) bool { InspectInline(inline, func(inline Inline) bool {
return f(inline) return f(inline)
}) })

Просмотреть файл

@@ -22,8 +22,8 @@ func TestTextRanges(t *testing.T) {
}, },
"simple2": { "simple2": {
Markdown: "hello!", Markdown: "hello!",
ExpectedRanges: []Range{{0, 5}, {5, 6}}, ExpectedRanges: []Range{{0, 6}},
ExpectedValues: []string{"hello", "!"}, ExpectedValues: []string{"hello!"},
}, },
"multiline": { "multiline": {
Markdown: "hello world\nfoobar", Markdown: "hello world\nfoobar",
@@ -37,13 +37,13 @@ func TestTextRanges(t *testing.T) {
}, },
"notcode": { "notcode": {
Markdown: "hello ` world", Markdown: "hello ` world",
ExpectedRanges: []Range{{0, 6}, {6, 7}, {7, 13}}, ExpectedRanges: []Range{{0, 13}},
ExpectedValues: []string{"hello ", "`", " world"}, ExpectedValues: []string{"hello ` world"},
}, },
"escape": { "escape": {
Markdown: "\\*hello\\*", Markdown: "\\*hello\\*",
ExpectedRanges: []Range{{1, 2}, {2, 7}, {8, 9}}, ExpectedRanges: []Range{{1, 7}, {8, 9}},
ExpectedValues: []string{"*", "hello", "*"}, ExpectedValues: []string{"*hello", "*"},
}, },
"escapeescape": { "escapeescape": {
Markdown: "\\\\", Markdown: "\\\\",
@@ -52,28 +52,28 @@ func TestTextRanges(t *testing.T) {
}, },
"notescape": { "notescape": {
Markdown: "foo\\x", Markdown: "foo\\x",
ExpectedRanges: []Range{{0, 3}, {3, 4}, {4, 5}}, ExpectedRanges: []Range{{0, 5}},
ExpectedValues: []string{"foo", "\\", "x"}, ExpectedValues: []string{"foo\\x"},
}, },
"notlink": { "notlink": {
Markdown: "[foo", Markdown: "[foo",
ExpectedRanges: []Range{{0, 1}, {1, 4}}, ExpectedRanges: []Range{{0, 4}},
ExpectedValues: []string{"[", "foo"}, ExpectedValues: []string{"[foo"},
}, },
"notlinkend": { "notlinkend": {
Markdown: "[foo]", Markdown: "[foo]",
ExpectedRanges: []Range{{0, 1}, {1, 4}, {4, 5}}, ExpectedRanges: []Range{{0, 5}},
ExpectedValues: []string{"[", "foo", "]"}, ExpectedValues: []string{"[foo]"},
}, },
"notimage": { "notimage": {
Markdown: "![foo", Markdown: "![foo",
ExpectedRanges: []Range{{0, 2}, {2, 5}}, ExpectedRanges: []Range{{0, 5}},
ExpectedValues: []string{"![", "foo"}, ExpectedValues: []string{"![foo"},
}, },
"notimage2": { "notimage2": {
Markdown: "!foo", Markdown: "!foo",
ExpectedRanges: []Range{{0, 1}, {1, 4}}, ExpectedRanges: []Range{{0, 4}},
ExpectedValues: []string{"!", "foo"}, ExpectedValues: []string{"!foo"},
}, },
"charref": { "charref": {
Markdown: ""test", Markdown: ""test",
@@ -82,13 +82,13 @@ func TestTextRanges(t *testing.T) {
}, },
"notcharref": { "notcharref": {
Markdown: "&amp test", Markdown: "&amp test",
ExpectedRanges: []Range{{0, 1}, {1, 9}}, ExpectedRanges: []Range{{0, 9}},
ExpectedValues: []string{"&", "amp test"}, ExpectedValues: []string{"&amp test"},
}, },
"notcharref2": { "notcharref2": {
Markdown: "&mattermost;", Markdown: "&mattermost;",
ExpectedRanges: []Range{{0, 1}, {1, 12}}, ExpectedRanges: []Range{{0, 12}},
ExpectedValues: []string{"&", "mattermost;"}, ExpectedValues: []string{"&mattermost;"},
}, },
} { } {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
@@ -101,8 +101,8 @@ func TestTextRanges(t *testing.T) {
} }
return true return true
}) })
assert.Equal(t, ranges, tc.ExpectedRanges) assert.Equal(t, tc.ExpectedRanges, ranges)
assert.Equal(t, values, tc.ExpectedValues) assert.Equal(t, tc.ExpectedValues, values)
}) })
} }