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.
Этот коммит содержится в:
коммит произвёл
Joram Wilander
родитель
940d0bbbc2
Коммит
88eef609ab
@@ -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: "& test",
|
Markdown: "& test",
|
||||||
ExpectedRanges: []Range{{0, 1}, {1, 9}},
|
ExpectedRanges: []Range{{0, 9}},
|
||||||
ExpectedValues: []string{"&", "amp test"},
|
ExpectedValues: []string{"& 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)
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user