markup_test.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. package markup_test
  2. import (
  3. . "gitote/gitote/pkg/markup"
  4. "gitote/gitote/pkg/setting"
  5. "strings"
  6. "testing"
  7. . "github.com/smartystreets/goconvey/convey"
  8. )
  9. func Test_IsReadmeFile(t *testing.T) {
  10. Convey("Detect README file extension", t, func() {
  11. testCases := []struct {
  12. ext string
  13. match bool
  14. }{
  15. {"readme", true},
  16. {"README", true},
  17. {"readme.md", true},
  18. {"readme.markdown", true},
  19. {"readme.mdown", true},
  20. {"readme.mkd", true},
  21. {"readme.org", true},
  22. {"readme.rst", true},
  23. {"readme.asciidoc", true},
  24. {"readme_ZH", true},
  25. }
  26. for _, tc := range testCases {
  27. So(IsReadmeFile(tc.ext), ShouldEqual, tc.match)
  28. }
  29. })
  30. }
  31. func Test_FindAllMentions(t *testing.T) {
  32. Convey("Find all mention patterns", t, func() {
  33. testCases := []struct {
  34. content string
  35. matches string
  36. }{
  37. {"@Yoginth, what do you think?", "Yoginth"},
  38. {"@Yoginth what do you think?", "Yoginth"},
  39. {"Hi @Yoginth, sounds good to me", "Yoginth"},
  40. {"cc/ @Yoginth @User", "Yoginth,User"},
  41. }
  42. for _, tc := range testCases {
  43. So(strings.Join(FindAllMentions(tc.content), ","), ShouldEqual, tc.matches)
  44. }
  45. })
  46. }
  47. func Test_RenderIssueIndexPattern(t *testing.T) {
  48. Convey("Rendering an issue reference", t, func() {
  49. var (
  50. urlPrefix = "/prefix"
  51. metas map[string]string = nil
  52. )
  53. setting.AppSubURLDepth = 0
  54. Convey("To the internal issue tracker", func() {
  55. Convey("It should not render anything when there are no mentions", func() {
  56. testCases := []string{
  57. "",
  58. "this is a test",
  59. "test 123 123 1234",
  60. "#",
  61. "# # #",
  62. "# 123",
  63. "#abcd",
  64. "##1234",
  65. "test#1234",
  66. "#1234test",
  67. " test #1234test",
  68. }
  69. for i := 0; i < len(testCases); i++ {
  70. So(string(RenderIssueIndexPattern([]byte(testCases[i]), urlPrefix, metas)), ShouldEqual, testCases[i])
  71. }
  72. })
  73. Convey("It should render freestanding mentions", func() {
  74. testCases := []string{
  75. "#1234 test", "<a href=\"/prefix/issues/1234\">#1234</a> test",
  76. "test #1234 issue", "test <a href=\"/prefix/issues/1234\">#1234</a> issue",
  77. "test issue #1234", "test issue <a href=\"/prefix/issues/1234\">#1234</a>",
  78. "#5 test", "<a href=\"/prefix/issues/5\">#5</a> test",
  79. "test #5 issue", "test <a href=\"/prefix/issues/5\">#5</a> issue",
  80. "test issue #5", "test issue <a href=\"/prefix/issues/5\">#5</a>",
  81. }
  82. for i := 0; i < len(testCases); i += 2 {
  83. So(string(RenderIssueIndexPattern([]byte(testCases[i]), urlPrefix, metas)), ShouldEqual, testCases[i+1])
  84. }
  85. })
  86. Convey("It should not render issue mention without leading space", func() {
  87. input := []byte("test#54321 issue")
  88. expected := "test#54321 issue"
  89. So(string(RenderIssueIndexPattern(input, urlPrefix, metas)), ShouldEqual, expected)
  90. })
  91. Convey("It should not render issue mention without trailing space", func() {
  92. input := []byte("test #54321issue")
  93. expected := "test #54321issue"
  94. So(string(RenderIssueIndexPattern(input, urlPrefix, metas)), ShouldEqual, expected)
  95. })
  96. Convey("It should render issue mention in parentheses", func() {
  97. testCases := []string{
  98. "(#54321 issue)", "(<a href=\"/prefix/issues/54321\">#54321</a> issue)",
  99. "test (#54321) issue", "test (<a href=\"/prefix/issues/54321\">#54321</a>) issue",
  100. "test (#54321 extra) issue", "test (<a href=\"/prefix/issues/54321\">#54321</a> extra) issue",
  101. "test (#54321 issue)", "test (<a href=\"/prefix/issues/54321\">#54321</a> issue)",
  102. "test (#54321)", "test (<a href=\"/prefix/issues/54321\">#54321</a>)",
  103. }
  104. for i := 0; i < len(testCases); i += 2 {
  105. So(string(RenderIssueIndexPattern([]byte(testCases[i]), urlPrefix, metas)), ShouldEqual, testCases[i+1])
  106. }
  107. })
  108. Convey("It should render issue mention in square brackets", func() {
  109. testCases := []string{
  110. "[#54321 issue]", "[<a href=\"/prefix/issues/54321\">#54321</a> issue]",
  111. "test [#54321] issue", "test [<a href=\"/prefix/issues/54321\">#54321</a>] issue",
  112. "test [#54321 extra] issue", "test [<a href=\"/prefix/issues/54321\">#54321</a> extra] issue",
  113. "test [#54321 issue]", "test [<a href=\"/prefix/issues/54321\">#54321</a> issue]",
  114. "test [#54321]", "test [<a href=\"/prefix/issues/54321\">#54321</a>]",
  115. }
  116. for i := 0; i < len(testCases); i += 2 {
  117. So(string(RenderIssueIndexPattern([]byte(testCases[i]), urlPrefix, metas)), ShouldEqual, testCases[i+1])
  118. }
  119. })
  120. Convey("It should render multiple issue mentions in the same line", func() {
  121. testCases := []string{
  122. "#54321 #1243", "<a href=\"/prefix/issues/54321\">#54321</a> <a href=\"/prefix/issues/1243\">#1243</a>",
  123. "test #54321 #1243", "test <a href=\"/prefix/issues/54321\">#54321</a> <a href=\"/prefix/issues/1243\">#1243</a>",
  124. "(#54321 #1243)", "(<a href=\"/prefix/issues/54321\">#54321</a> <a href=\"/prefix/issues/1243\">#1243</a>)",
  125. "(#54321)(#1243)", "(<a href=\"/prefix/issues/54321\">#54321</a>)(<a href=\"/prefix/issues/1243\">#1243</a>)",
  126. "text #54321 test #1243 issue", "text <a href=\"/prefix/issues/54321\">#54321</a> test <a href=\"/prefix/issues/1243\">#1243</a> issue",
  127. "#1 (#4321) test", "<a href=\"/prefix/issues/1\">#1</a> (<a href=\"/prefix/issues/4321\">#4321</a>) test",
  128. }
  129. for i := 0; i < len(testCases); i += 2 {
  130. So(string(RenderIssueIndexPattern([]byte(testCases[i]), urlPrefix, metas)), ShouldEqual, testCases[i+1])
  131. }
  132. })
  133. })
  134. Convey("To an external issue tracker with numeric style", func() {
  135. metas = make(map[string]string)
  136. metas["format"] = "https://someurl.com/{user}/{repo}/{index}"
  137. metas["user"] = "someuser"
  138. metas["repo"] = "somerepo"
  139. metas["style"] = ISSUE_NAME_STYLE_NUMERIC
  140. Convey("should not render anything when there are no mentions", func() {
  141. testCases := []string{
  142. "this is a test",
  143. "test 123 123 1234",
  144. "#",
  145. "# # #",
  146. "# 123",
  147. "#abcd",
  148. }
  149. for i := 0; i < len(testCases); i++ {
  150. So(string(RenderIssueIndexPattern([]byte(testCases[i]), urlPrefix, metas)), ShouldEqual, testCases[i])
  151. }
  152. })
  153. Convey("It should render freestanding issue mentions", func() {
  154. testCases := []string{
  155. "#1234 test", "<a href=\"https://someurl.com/someuser/somerepo/1234\">#1234</a> test",
  156. "test #1234 issue", "test <a href=\"https://someurl.com/someuser/somerepo/1234\">#1234</a> issue",
  157. "test issue #1234", "test issue <a href=\"https://someurl.com/someuser/somerepo/1234\">#1234</a>",
  158. "#5 test", "<a href=\"https://someurl.com/someuser/somerepo/5\">#5</a> test",
  159. "test #5 issue", "test <a href=\"https://someurl.com/someuser/somerepo/5\">#5</a> issue",
  160. "test issue #5", "test issue <a href=\"https://someurl.com/someuser/somerepo/5\">#5</a>",
  161. }
  162. for i := 0; i < len(testCases); i += 2 {
  163. So(string(RenderIssueIndexPattern([]byte(testCases[i]), urlPrefix, metas)), ShouldEqual, testCases[i+1])
  164. }
  165. })
  166. Convey("It should not render issue mention without leading space", func() {
  167. input := []byte("test#54321 issue")
  168. expected := "test#54321 issue"
  169. So(string(RenderIssueIndexPattern(input, urlPrefix, metas)), ShouldEqual, expected)
  170. })
  171. Convey("It should not render issue mention without trailing space", func() {
  172. input := []byte("test #54321issue")
  173. expected := "test #54321issue"
  174. So(string(RenderIssueIndexPattern(input, urlPrefix, metas)), ShouldEqual, expected)
  175. })
  176. Convey("It should render issue mention in parentheses", func() {
  177. testCases := []string{
  178. "(#54321 issue)", "(<a href=\"https://someurl.com/someuser/somerepo/54321\">#54321</a> issue)",
  179. "test (#54321) issue", "test (<a href=\"https://someurl.com/someuser/somerepo/54321\">#54321</a>) issue",
  180. "test (#54321 extra) issue", "test (<a href=\"https://someurl.com/someuser/somerepo/54321\">#54321</a> extra) issue",
  181. "test (#54321 issue)", "test (<a href=\"https://someurl.com/someuser/somerepo/54321\">#54321</a> issue)",
  182. "test (#54321)", "test (<a href=\"https://someurl.com/someuser/somerepo/54321\">#54321</a>)",
  183. }
  184. for i := 0; i < len(testCases); i += 2 {
  185. So(string(RenderIssueIndexPattern([]byte(testCases[i]), urlPrefix, metas)), ShouldEqual, testCases[i+1])
  186. }
  187. })
  188. Convey("It should render multiple issue mentions in the same line", func() {
  189. testCases := []string{
  190. "#54321 #1243", "<a href=\"https://someurl.com/someuser/somerepo/54321\">#54321</a> <a href=\"https://someurl.com/someuser/somerepo/1243\">#1243</a>",
  191. "test #54321 #1243", "test <a href=\"https://someurl.com/someuser/somerepo/54321\">#54321</a> <a href=\"https://someurl.com/someuser/somerepo/1243\">#1243</a>",
  192. "(#54321 #1243)", "(<a href=\"https://someurl.com/someuser/somerepo/54321\">#54321</a> <a href=\"https://someurl.com/someuser/somerepo/1243\">#1243</a>)",
  193. "(#54321)(#1243)", "(<a href=\"https://someurl.com/someuser/somerepo/54321\">#54321</a>)(<a href=\"https://someurl.com/someuser/somerepo/1243\">#1243</a>)",
  194. "text #54321 test #1243 issue", "text <a href=\"https://someurl.com/someuser/somerepo/54321\">#54321</a> test <a href=\"https://someurl.com/someuser/somerepo/1243\">#1243</a> issue",
  195. "#1 (#4321) test", "<a href=\"https://someurl.com/someuser/somerepo/1\">#1</a> (<a href=\"https://someurl.com/someuser/somerepo/4321\">#4321</a>) test",
  196. }
  197. for i := 0; i < len(testCases); i += 2 {
  198. So(string(RenderIssueIndexPattern([]byte(testCases[i]), urlPrefix, metas)), ShouldEqual, testCases[i+1])
  199. }
  200. })
  201. })
  202. Convey("To an external issue tracker with alphanumeric style", func() {
  203. metas = make(map[string]string)
  204. metas["format"] = "https://someurl.com/{user}/{repo}/?b={index}"
  205. metas["user"] = "someuser"
  206. metas["repo"] = "somerepo"
  207. metas["style"] = ISSUE_NAME_STYLE_ALPHANUMERIC
  208. Convey("It should not render anything when there are no mentions", func() {
  209. testCases := []string{
  210. "",
  211. "this is a test",
  212. "test 123 123 1234",
  213. "#",
  214. "##1234",
  215. "# 123",
  216. "#abcd",
  217. "test #123",
  218. "abc-1234", // issue prefix must be capital
  219. "ABc-1234", // issue prefix must be _all_ capital
  220. "ABCDEFGHIJK-1234", // the limit is 10 characters in the prefix
  221. "ABC1234", // dash is required
  222. "test ABC- test", // number is required
  223. "test -1234 test", // prefix is required
  224. "testABC-123 test", // leading space is required
  225. "test ABC-123test", // trailing space is required
  226. "ABC-0123", // no leading zero
  227. }
  228. for i := 0; i < len(testCases); i += 2 {
  229. So(string(RenderIssueIndexPattern([]byte(testCases[i]), urlPrefix, metas)), ShouldEqual, testCases[i])
  230. }
  231. })
  232. Convey("It should render freestanding issue mention", func() {
  233. testCases := []string{
  234. "OTT-1234 test", "<a href=\"https://someurl.com/someuser/somerepo/?b=OTT-1234\">OTT-1234</a> test",
  235. "test T-12 issue", "test <a href=\"https://someurl.com/someuser/somerepo/?b=T-12\">T-12</a> issue",
  236. "test issue ABCDEFGHIJ-1234567890", "test issue <a href=\"https://someurl.com/someuser/somerepo/?b=ABCDEFGHIJ-1234567890\">ABCDEFGHIJ-1234567890</a>",
  237. "A-1 test", "<a href=\"https://someurl.com/someuser/somerepo/?b=A-1\">A-1</a> test",
  238. "test ZED-1 issue", "test <a href=\"https://someurl.com/someuser/somerepo/?b=ZED-1\">ZED-1</a> issue",
  239. "test issue DEED-7154", "test issue <a href=\"https://someurl.com/someuser/somerepo/?b=DEED-7154\">DEED-7154</a>",
  240. }
  241. for i := 0; i < len(testCases); i += 2 {
  242. So(string(RenderIssueIndexPattern([]byte(testCases[i]), urlPrefix, metas)), ShouldEqual, testCases[i+1])
  243. }
  244. })
  245. Convey("It should render issue mention in parentheses", func() {
  246. testCases := []string{
  247. "(ABG-124 issue)", "(<a href=\"https://someurl.com/someuser/somerepo/?b=ABG-124\">ABG-124</a> issue)",
  248. "test (ABG-124) issue", "test (<a href=\"https://someurl.com/someuser/somerepo/?b=ABG-124\">ABG-124</a>) issue",
  249. "test (ABG-124 extra) issue", "test (<a href=\"https://someurl.com/someuser/somerepo/?b=ABG-124\">ABG-124</a> extra) issue",
  250. "test (ABG-124 issue)", "test (<a href=\"https://someurl.com/someuser/somerepo/?b=ABG-124\">ABG-124</a> issue)",
  251. "test (ABG-124)", "test (<a href=\"https://someurl.com/someuser/somerepo/?b=ABG-124\">ABG-124</a>)",
  252. }
  253. for i := 0; i < len(testCases); i += 2 {
  254. So(string(RenderIssueIndexPattern([]byte(testCases[i]), urlPrefix, metas)), ShouldEqual, testCases[i+1])
  255. }
  256. })
  257. Convey("It should render issue mention in square brackets", func() {
  258. testCases := []string{
  259. "[ABG-124] issue", "[<a href=\"https://someurl.com/someuser/somerepo/?b=ABG-124\">ABG-124</a>] issue",
  260. "test [ABG-124] issue", "test [<a href=\"https://someurl.com/someuser/somerepo/?b=ABG-124\">ABG-124</a>] issue",
  261. "test [ABG-124 extra] issue", "test [<a href=\"https://someurl.com/someuser/somerepo/?b=ABG-124\">ABG-124</a> extra] issue",
  262. "test [ABG-124 issue]", "test [<a href=\"https://someurl.com/someuser/somerepo/?b=ABG-124\">ABG-124</a> issue]",
  263. "test [ABG-124]", "test [<a href=\"https://someurl.com/someuser/somerepo/?b=ABG-124\">ABG-124</a>]",
  264. }
  265. for i := 0; i < len(testCases); i += 2 {
  266. So(string(RenderIssueIndexPattern([]byte(testCases[i]), urlPrefix, metas)), ShouldEqual, testCases[i+1])
  267. }
  268. })
  269. Convey("It should render multiple issue mentions in the same line", func() {
  270. testCases := []string{
  271. "ABG-124 OTT-4321", "<a href=\"https://someurl.com/someuser/somerepo/?b=ABG-124\">ABG-124</a> <a href=\"https://someurl.com/someuser/somerepo/?b=OTT-4321\">OTT-4321</a>",
  272. "test ABG-124 OTT-4321", "test <a href=\"https://someurl.com/someuser/somerepo/?b=ABG-124\">ABG-124</a> <a href=\"https://someurl.com/someuser/somerepo/?b=OTT-4321\">OTT-4321</a>",
  273. "(ABG-124 OTT-4321)", "(<a href=\"https://someurl.com/someuser/somerepo/?b=ABG-124\">ABG-124</a> <a href=\"https://someurl.com/someuser/somerepo/?b=OTT-4321\">OTT-4321</a>)",
  274. "(ABG-124)(OTT-4321)", "(<a href=\"https://someurl.com/someuser/somerepo/?b=ABG-124\">ABG-124</a>)(<a href=\"https://someurl.com/someuser/somerepo/?b=OTT-4321\">OTT-4321</a>)",
  275. "text ABG-124 test OTT-4321 issue", "text <a href=\"https://someurl.com/someuser/somerepo/?b=ABG-124\">ABG-124</a> test <a href=\"https://someurl.com/someuser/somerepo/?b=OTT-4321\">OTT-4321</a> issue",
  276. "A-1 (RRE-345) test", "<a href=\"https://someurl.com/someuser/somerepo/?b=A-1\">A-1</a> (<a href=\"https://someurl.com/someuser/somerepo/?b=RRE-345\">RRE-345</a>) test",
  277. }
  278. for i := 0; i < len(testCases); i += 2 {
  279. So(string(RenderIssueIndexPattern([]byte(testCases[i]), urlPrefix, metas)), ShouldEqual, testCases[i+1])
  280. }
  281. })
  282. })
  283. })
  284. }