summary refs log tree commit diff stats
path: root/tests/nimdoc/trunnableexamples.nim
blob: 1886ceeb3b3a2622a1a2f0253d97d9084eaffc87 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
discard """
cmd: "nim doc --doccmd:--hints:off --hints:off $file"
action: "compile"
nimoutFull: true
nimout: '''
foo1
foo2
foo3
foo5
foo7
in examplesInTemplate1
doc in outer
doc in inner1
doc in inner2
foo8
foo9
foo6
'''
joinable: false
"""

#[
pending bug #18077, use instead:
cmd: "nim doc --doccmd:'-d:testFooExternal --hints:off' --hints:off $file"
and merge trunnableexamples2 back here
]#
{.define(testFooExternal).}

proc fun*() =
  runnableExamples:
    block: # `defer` only allowed inside a block
      defer: echo "foo1"

  runnableExamples:
    # `fun*` only allowed at top level
    proc fun*()=echo "foo2"
    fun()
    block:
      defer: echo "foo3"

  runnableExamples:
    # ditto
    proc fun*()=echo "foo5"
    fun()

  runnableExamples("--experimental:codeReordering --warnings:off"):
    # `codeReordering` only allowed at top level
    {.experimental: "codeReordering".}
    proc fun1() = fun2()
    proc fun2() = echo "foo6"
    fun1()

  runnableExamples:
    # only works at top level
    import std/macros
    macro myImport(a: static string): untyped =
      newTree(nnkImportStmt, [newLit a])
    myImport "str" & "utils"
    doAssert declared(isAlphaAscii)
    echo "foo7"

when true: # issue #12746
  # this proc on its own works fine with `nim doc`
  proc goodProc*() =
    runnableExamples:
      try:
        discard
      except CatchableError:
        # just the general except will work
        discard

  # FIXED: this proc fails with `nim doc`
  proc badProc*() =
    runnableExamples:
      try:
        discard
      except IOError:
        # specifying Error is culprit
        discard

when true: # runnableExamples with rdoccmd
  runnableExamples "-d:testFoo -d:testBar":
    doAssert defined(testFoo) and defined(testBar)
    doAssert defined(testFooExternal)
  runnableExamples "-d:testFoo2":
    doAssert defined(testFoo2)
    doAssert not defined(testFoo) # doesn't get confused by other examples

  ## all these syntaxes work too
  runnableExamples("-d:testFoo2"): discard
  runnableExamples(): discard
  runnableExamples: discard
  runnableExamples "-r:off": # issue #10731
    doAssert false ## we compile only (-r:off), so this won't be run
  runnableExamples "-b:js":
    import std/compilesettings
    proc startsWith*(s, prefix: cstring): bool {.noSideEffect, importjs: "#.startsWith(#)".}
    doAssert querySetting(backend) == "js"
  runnableExamples "-b:cpp":
    static: doAssert defined(cpp)
    type std_exception {.importcpp: "std::exception", header: "<exception>".} = object

  proc fun2*() =
    runnableExamples "-d:foo": discard # checks that it also works inside procs

  template fun3Impl(): untyped =
    runnableExamples(rdoccmd="-d:foo"):
      nonexistent
        # bugfix: this shouldn't be semchecked when `runnableExamples`
        # has more than 1 argument
    discard

  proc fun3*[T]() =
    fun3Impl()

  when false: # future work
    # passing non-string-litterals (for reuse)
    const a = "-b:cpp"
    runnableExamples(a): discard

    # passing seq (to run with multiple compilation options)
    runnableExamples(@["-b:cpp", "-b:js"]): discard

when true: # bug #16993
  template examplesInTemplate1*(cond: untyped) =
    ## in examplesInTemplate1
    runnableExamples:
      echo "in examplesInTemplate1"
    discard
  examplesInTemplate1 true
  examplesInTemplate1 true
  examplesInTemplate1 true

when true: # bug #18054
  template outer*(body: untyped) =
    ## outer template doc string.
    runnableExamples:
      echo "doc in outer"
    ##
    template inner1*() =
      ## inner1 template doc string.
      runnableExamples:
        echo "doc in inner1"
      ##

    template inner2*() =
      ## inner2 template doc string.
      runnableExamples:
        echo "doc in inner2"
    body
  outer:
    inner1()
    inner2()

when true: # bug #17835
  template anyItFake*(s, pred: untyped): bool =
    ## Foo
    runnableExamples: discard
    true

  proc anyItFakeMain*(n: seq[int]): bool =
    result = anyItFake(n, it == 0)
      # this was giving: Error: runnableExamples must appear before the first non-comment statement

runnableExamples:
  block: # bug #17279
    when int.sizeof == 8:
      let x = 0xffffffffffffffff
      doAssert x == -1

  # bug #13491
  block:
    proc fun(): int = doAssert false
    doAssertRaises(AssertionDefect, (discard fun()))

  block:
    template foo(body) = discard
    foo (discard)

  block:
    template fn(body: untyped): untyped = true
    doAssert(fn do: nonexistent)
  import std/macros
  macro foo*(x, y) =
    result = newLetStmt(x[0][0], x[0][1])
  foo:
    a = 1
  do: discard

# also check for runnableExamples at module scope
runnableExamples:
  block:
    defer: echo "foo8"

runnableExamples:
  proc fun*()=echo "foo9"
  fun()

# import std/assertions by default
runnableExamples("-d:nimPreviewSlimSystem"):
  doAssert true

# note: there are yet other examples where putting runnableExamples at module
# scope is needed, for example when using an `include` before an `import`, etc.

##[
snippet:

.. code-block:: Nim
    :test:

  doAssert defined(testFooExternal)

]##