tdochelpers.nim 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. discard """
  2. output: '''
  3. [Suite] Integration with Nim
  4. '''
  5. """
  6. # tests for dochelpers.nim module
  7. import ../../lib/packages/docutils/[rstast, rst, dochelpers]
  8. import unittest
  9. import std/assertions
  10. proc testMsgHandler(filename: string, line, col: int, msgkind: MsgKind,
  11. arg: string) =
  12. doAssert msgkind == mwBrokenLink
  13. proc fromRst(text: string): LangSymbol =
  14. let r = rstParse(text, "-input-", LineRstInit, ColRstInit,
  15. {roNimFile},
  16. msgHandler=testMsgHandler)
  17. assert r.node.kind == rnRstRef
  18. result = toLangSymbol(r.node)
  19. proc fromMd(text: string): LangSymbol =
  20. let r = rstParse(text, "-input-", LineRstInit, ColRstInit,
  21. {roPreferMarkdown, roSupportMarkdown, roNimFile},
  22. msgHandler=testMsgHandler)
  23. assert r.node.kind == rnPandocRef
  24. assert r.node.len == 2
  25. # this son is the target:
  26. assert r.node.sons[1].kind == rnInner
  27. result = toLangSymbol(r.node.sons[1])
  28. suite "Integration with Nim":
  29. test "simple symbol parsing (shortest form)":
  30. let expected = LangSymbol(symKind: "", name: "g")
  31. check "g_".fromRst == expected
  32. check "[g]".fromMd == expected
  33. # test also alternative syntax variants of Pandoc Markdown:
  34. check "[g][]".fromMd == expected
  35. check "[this symbol][g]".fromMd == expected
  36. test "simple symbol parsing (group of words)":
  37. #let input1 = "`Y`_".rstParseTest
  38. let expected1 = LangSymbol(symKind: "", name: "Y")
  39. check "`Y`_".fromRst == expected1
  40. check "[Y]".fromMd == expected1
  41. # this means not a statement 'type', it's a backticked identifier `type`:
  42. let expected2 = LangSymbol(symKind: "", name: "type")
  43. check "`type`_".fromRst == expected2
  44. check "[type]".fromMd == expected2
  45. let expected3 = LangSymbol(symKind: "", name: "[]")
  46. check "`[]`_".fromRst == expected3
  47. # Markdown syntax for this case is NOT [[]]
  48. check "[`[]`]".fromMd == expected3
  49. let expected4 = LangSymbol(symKind: "", name: "Xyz")
  50. check "`X Y Z`_".fromRst == expected4
  51. check "[X Y Z]".fromMd == expected4
  52. test "simple proc parsing":
  53. let expected = LangSymbol(symKind: "proc", name: "f")
  54. check "`proc f`_".fromRst == expected
  55. check "[proc f]".fromMd == expected
  56. test "another backticked name":
  57. let expected = LangSymbol(symKind: "template", name: "type")
  58. check """`template \`type\``_""".fromRst == expected
  59. # no backslash in Markdown:
  60. check """[template `type`]""".fromMd == expected
  61. test "simple proc parsing with parameters":
  62. let expected = LangSymbol(symKind: "proc", name: "f",
  63. parametersProvided: true)
  64. check "`proc f*()`_".fromRst == expected
  65. check "`proc f()`_".fromRst == expected
  66. check "[proc f*()]".fromMd == expected
  67. check "[proc f()]".fromMd == expected
  68. test "symbol parsing with 1 parameter":
  69. let expected = LangSymbol(symKind: "", name: "f",
  70. parameters: @[("G[int]", "")],
  71. parametersProvided: true)
  72. check "`f(G[int])`_".fromRst == expected
  73. check "[f(G[int])]".fromMd == expected
  74. test "more proc parsing":
  75. let input1 = "`proc f[T](x:G[T]):M[T]`_".fromRst
  76. let input2 = "`proc f[ T ] ( x: G [T] ): M[T]`_".fromRst
  77. let input3 = "`proc f*[T](x: G[T]): M[T]`_".fromRst
  78. let expected = LangSymbol(symKind: "proc",
  79. name: "f",
  80. generics: "[T]",
  81. parameters: @[("x", "G[T]")],
  82. parametersProvided: true,
  83. outType: "M[T]")
  84. check(input1 == expected)
  85. check(input2 == expected)
  86. check(input3 == expected)
  87. test "advanced proc parsing with Nim identifier normalization":
  88. let inputRst = """`proc binarySearch*[T, K](a: openarray[T]; key: K;
  89. cmp: proc (x: T; y: K): int)`_"""
  90. let inputMd = """[proc binarySearch*[T, K](a: openarray[T]; key: K;
  91. cmp: proc (x: T; y: K): int)]"""
  92. let expected = LangSymbol(symKind: "proc",
  93. name: "binarysearch",
  94. generics: "[T,K]",
  95. parameters: @[
  96. ("a", "openarray[T]"),
  97. ("key", "K"),
  98. ("cmp", "proc(x:T;y:K):int")],
  99. parametersProvided: true,
  100. outType: "")
  101. check(inputRst.fromRst == expected)
  102. check(inputMd.fromMd == expected)
  103. test "the same without proc":
  104. let input = """`binarySearch*[T, K](a: openarray[T]; key: K;
  105. cmp: proc (x: T; y: K): int {.closure.})`_"""
  106. let expected = LangSymbol(symKind: "",
  107. name: "binarysearch",
  108. generics: "[T,K]",
  109. parameters: @[
  110. ("a", "openarray[T]"),
  111. ("key", "K"),
  112. ("cmp", "proc(x:T;y:K):int")],
  113. parametersProvided: true,
  114. outType: "")
  115. check(input.fromRst == expected)
  116. let inputMd = """[binarySearch*[T, K](a: openarray[T]; key: K;
  117. cmp: proc (x: T; y: K): int {.closure.})]"""
  118. check(inputMd.fromMd == expected)
  119. test "operator $ with and without backticks":
  120. let input1 = """`func \`$\`*[T](a: \`open Array\`[T]): string`_"""
  121. let input1md = "[func `$`*[T](a: `open Array`[T]): string]"
  122. let input2 = """`func $*[T](a: \`open Array\`[T]): string`_"""
  123. let input2md = "[func $*[T](a: `open Array`[T]): string]"
  124. let expected = LangSymbol(symKind: "func",
  125. name: "$",
  126. generics: "[T]",
  127. parameters: @[("a", "openarray[T]")],
  128. parametersProvided: true,
  129. outType: "string")
  130. check input1.fromRst == expected
  131. check input2.fromRst == expected
  132. check input1md.fromMd == expected
  133. check input2md.fromMd == expected
  134. test "operator [] with and without backticks":
  135. let input1 = """`func \`[]\`[T](a: \`open Array\`[T], idx: int): T`_"""
  136. let input1md = "[func `[]`[T](a: `open Array`[T], idx: int): T]"
  137. let input2 = """`func [][T](a: \`open Array\`[T], idx: int): T`_"""
  138. let input2md = "[func [][T](a: `open Array`[T], idx: int): T]"
  139. let expected = LangSymbol(symKind: "func",
  140. name: "[]",
  141. generics: "[T]",
  142. parameters: @[("a", "openarray[T]"),
  143. ("idx", "int")],
  144. parametersProvided: true,
  145. outType: "T")
  146. check input1.fromRst == expected
  147. check input2.fromRst == expected
  148. check input1md.fromMd == expected
  149. check input2md.fromMd == expected
  150. test "postfix symbol specifier #1":
  151. let input = "`walkDir iterator`_"
  152. let inputMd = "[walkDir iterator]"
  153. let expected = LangSymbol(symKind: "iterator",
  154. name: "walkdir")
  155. check input.fromRst == expected
  156. check inputMd.fromMd == expected
  157. test "postfix symbol specifier #2":
  158. let input1 = """`\`[]\`[T](a: \`open Array\`[T], idx: int): T func`_"""
  159. let input1md = "[`[]`[T](a: `open Array`[T], idx: int): T func]"
  160. let input2 = """`[][T](a: \`open Array\`[T], idx: int): T func`_"""
  161. # note again that ` is needed between 1st and second [
  162. let input2md = "[`[]`[T](a: `open Array`[T], idx: int): T func]"
  163. let expected = LangSymbol(symKind: "func",
  164. name: "[]",
  165. generics: "[T]",
  166. parameters: @[("a", "openarray[T]"),
  167. ("idx", "int")],
  168. parametersProvided: true,
  169. outType: "T")
  170. check input1.fromRst == expected
  171. check input2.fromRst == expected
  172. check input1md.fromMd == expected
  173. check input2md.fromMd == expected
  174. test "type of type":
  175. let inputRst = "`CopyFlag enum`_"
  176. let inputMd = "[CopyFlag enum]"
  177. let expected = LangSymbol(symKind: "type",
  178. symTypeKind: "enum",
  179. name: "Copyflag")
  180. check inputRst.fromRst == expected
  181. check inputMd.fromMd == expected