+func TestSplitRich(t *testing.T) {
+ testCases := []struct {
+ name string
+ markdown string
+ limit int
+ parts []string
+ }{
+ {
+ name: "short reply stays whole",
+ markdown: "| a | b |",
+ limit: 100,
+ parts: []string{"| a | b |"},
+ },
+ {
+ name: "cut after a blank line keeps a table whole",
+ markdown: "Intro.\n\n| a | b |\n|---|---|\n| 1 | 2 |\n",
+ limit: 30,
+ parts: []string{"Intro.\n\n", "| a | b |\n|---|---|\n| 1 | 2 |\n"},
+ },
+ {
+ name: "blank line in a code block is not a cut",
+ markdown: "Text.\n\n```go\nx\n\ny\n```\n\nEnd.\n",
+ limit: 20,
+ parts: []string{"Text.\n\n", "```go\nx\n\ny\n```\n\n", "End.\n"},
+ },
+ {
+ name: "paragraph with no blank line is cut after a line",
+ markdown: "aaa\nbbb\nccc\n",
+ limit: 9,
+ parts: []string{"aaa\nbbb\n", "ccc\n"},
+ },
+ {
+ name: "long code block is closed and opened again",
+ markdown: "```sh\none\ntwo\nthree\n```\n",
+ limit: 16,
+ parts: []string{"```sh\none\n```\n", "```sh\ntwo\n```\n", "```sh\nthree\n```\n"},
+ },
+ {
+ name: "long line is cut at the limit and not inside a character",
+ markdown: "ab\u00e9cd",
+ limit: 3,
+ parts: []string{"ab", "\u00e9c", "d"},
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ require.Equal(t, tc.parts, splitRich(tc.markdown, tc.limit))
+ })
+ }
+
+ long := strings.Repeat("A paragraph of the reply.\n\n", 2000)
+ parts := splitRich(long, richMessageBytes)
+ require.Len(t, parts, 2)
+ require.Len(t, parts[0], richMessageBytes-richMessageBytes%len("A paragraph of the reply.\n\n"))
+ require.Equal(t, long, strings.Join(parts, ""))
+}
+