trunnableexamples.nim 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. discard """
  2. cmd: "nim doc --doccmd:--hints:off --hints:off $file"
  3. action: "compile"
  4. nimoutFull: true
  5. nimout: '''
  6. foo1
  7. foo2
  8. foo3
  9. foo5
  10. foo6
  11. foo7
  12. in examplesInTemplate1
  13. doc in outer
  14. doc in inner1
  15. doc in inner2
  16. foo8
  17. foo9
  18. '''
  19. joinable: false
  20. """
  21. #[
  22. pending bug #18077, use instead:
  23. cmd: "nim doc --doccmd:'-d:testFooExternal --hints:off' --hints:off $file"
  24. and merge trunnableexamples2 back here
  25. ]#
  26. {.define(testFooExternal).}
  27. proc fun*() =
  28. runnableExamples:
  29. block: # `defer` only allowed inside a block
  30. defer: echo "foo1"
  31. runnableExamples:
  32. # `fun*` only allowed at top level
  33. proc fun*()=echo "foo2"
  34. fun()
  35. block:
  36. defer: echo "foo3"
  37. runnableExamples:
  38. # ditto
  39. proc fun*()=echo "foo5"
  40. fun()
  41. runnableExamples:
  42. # `codeReordering` only allowed at top level
  43. {.experimental: "codeReordering".}
  44. proc fun1() = fun2()
  45. proc fun2() = echo "foo6"
  46. fun1()
  47. runnableExamples:
  48. # only works at top level
  49. import std/macros
  50. macro myImport(a: static string): untyped =
  51. newTree(nnkImportStmt, [newLit a])
  52. myImport "str" & "utils"
  53. doAssert declared(isAlphaAscii)
  54. echo "foo7"
  55. when true: # issue #12746
  56. # this proc on its own works fine with `nim doc`
  57. proc goodProc*() =
  58. runnableExamples:
  59. try:
  60. discard
  61. except:
  62. # just the general except will work
  63. discard
  64. # FIXED: this proc fails with `nim doc`
  65. proc badProc*() =
  66. runnableExamples:
  67. try:
  68. discard
  69. except IOError:
  70. # specifying Error is culprit
  71. discard
  72. when true: # runnableExamples with rdoccmd
  73. runnableExamples "-d:testFoo -d:testBar":
  74. doAssert defined(testFoo) and defined(testBar)
  75. doAssert defined(testFooExternal)
  76. runnableExamples "-d:testFoo2":
  77. doAssert defined(testFoo2)
  78. doAssert not defined(testFoo) # doesn't get confused by other examples
  79. ## all these syntaxes work too
  80. runnableExamples("-d:testFoo2"): discard
  81. runnableExamples(): discard
  82. runnableExamples: discard
  83. runnableExamples "-r:off": # issue #10731
  84. doAssert false ## we compile only (-r:off), so this won't be run
  85. runnableExamples "-b:js":
  86. import std/compilesettings
  87. proc startsWith*(s, prefix: cstring): bool {.noSideEffect, importjs: "#.startsWith(#)".}
  88. doAssert querySetting(backend) == "js"
  89. runnableExamples "-b:cpp":
  90. static: doAssert defined(cpp)
  91. type std_exception {.importcpp: "std::exception", header: "<exception>".} = object
  92. proc fun2*() =
  93. runnableExamples "-d:foo": discard # checks that it also works inside procs
  94. template fun3Impl(): untyped =
  95. runnableExamples(rdoccmd="-d:foo"):
  96. nonexistent
  97. # bugfix: this shouldn't be semchecked when `runnableExamples`
  98. # has more than 1 argument
  99. discard
  100. proc fun3*[T]() =
  101. fun3Impl()
  102. when false: # future work
  103. # passing non-string-litterals (for reuse)
  104. const a = "-b:cpp"
  105. runnableExamples(a): discard
  106. # passing seq (to run with multiple compilation options)
  107. runnableExamples(@["-b:cpp", "-b:js"]): discard
  108. when true: # bug #16993
  109. template examplesInTemplate1*(cond: untyped) =
  110. ## in examplesInTemplate1
  111. runnableExamples:
  112. echo "in examplesInTemplate1"
  113. discard
  114. examplesInTemplate1 true
  115. examplesInTemplate1 true
  116. examplesInTemplate1 true
  117. when true: # bug #18054
  118. template outer*(body: untyped) =
  119. ## outer template doc string.
  120. runnableExamples:
  121. echo "doc in outer"
  122. ##
  123. template inner1*() =
  124. ## inner1 template doc string.
  125. runnableExamples:
  126. echo "doc in inner1"
  127. ##
  128. template inner2*() =
  129. ## inner2 template doc string.
  130. runnableExamples:
  131. echo "doc in inner2"
  132. body
  133. outer:
  134. inner1()
  135. inner2()
  136. when true: # bug #17835
  137. template anyItFake*(s, pred: untyped): bool =
  138. ## Foo
  139. runnableExamples: discard
  140. true
  141. proc anyItFakeMain*(n: seq[int]): bool =
  142. result = anyItFake(n, it == 0)
  143. # this was giving: Error: runnableExamples must appear before the first non-comment statement
  144. runnableExamples:
  145. block: # bug #17279
  146. when int.sizeof == 8:
  147. let x = 0xffffffffffffffff
  148. doAssert x == -1
  149. # bug #13491
  150. block:
  151. proc fun(): int = doAssert false
  152. doAssertRaises(AssertionDefect, (discard fun()))
  153. block:
  154. template foo(body) = discard
  155. foo (discard)
  156. block:
  157. template fn(body: untyped): untyped = true
  158. doAssert(fn do: nonexistent)
  159. import std/macros
  160. macro foo*(x, y) =
  161. result = newLetStmt(x[0][0], x[0][1])
  162. foo:
  163. a = 1
  164. do: discard
  165. # also check for runnableExamples at module scope
  166. runnableExamples:
  167. block:
  168. defer: echo "foo8"
  169. runnableExamples:
  170. proc fun*()=echo "foo9"
  171. fun()
  172. # note: there are yet other examples where putting runnableExamples at module
  173. # scope is needed, for example when using an `include` before an `import`, etc.
  174. ##[
  175. snippet:
  176. .. code-block:: Nim
  177. :test:
  178. doAssert defined(testFooExternal)
  179. ]##