trunner.nim 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. discard """
  2. targets: "c cpp"
  3. joinable: false
  4. """
  5. ## tests that don't quite fit the mold and are easier to handle via `execCmdEx`
  6. ## A few others could be added to here to simplify code.
  7. ## Note: this test is a bit slow but tests a lot of things; please don't disable.
  8. import std/[strformat,os,osproc,unittest]
  9. from std/sequtils import toSeq,mapIt
  10. from std/algorithm import sorted
  11. import stdtest/[specialpaths, unittest_light]
  12. from std/private/globs import nativeToUnixPath
  13. import "$lib/../compiler/nimpaths"
  14. const
  15. nim = getCurrentCompilerExe()
  16. mode =
  17. when defined(c): "c"
  18. elif defined(cpp): "cpp"
  19. else: static: doAssert false
  20. nimcache = buildDir / "nimcacheTrunner"
  21. # instead of `querySetting(nimcacheDir)`, avoids stomping on other parallel tests
  22. proc runCmd(file, options = ""): auto =
  23. let fileabs = testsDir / file.unixToNativePath
  24. doAssert fileabs.fileExists, fileabs
  25. let cmd = fmt"{nim} {mode} {options} --hints:off {fileabs}"
  26. result = execCmdEx(cmd)
  27. when false: echo result[0] & "\n" & result[1] # for debugging
  28. when defined(nimTrunnerFfi):
  29. block: # mevalffi
  30. when defined(openbsd):
  31. #[
  32. openbsd defines `#define stderr (&__sF[2])` which makes it cumbersome
  33. for dlopen'ing inside `importcSymbol`. Instead of adding special rules
  34. inside `importcSymbol` to handle this, we disable just the part that's
  35. not working and will provide a more general, clean fix in future PR.
  36. ]#
  37. var opt = "-d:nimEvalffiStderrWorkaround"
  38. let prefix = ""
  39. else:
  40. var opt = ""
  41. let prefix = """
  42. hello world stderr
  43. hi stderr
  44. """
  45. let (output, exitCode) = runCmd("vm/mevalffi.nim", fmt"{opt} --experimental:compiletimeFFI")
  46. let expected = fmt"""
  47. {prefix}foo
  48. foo:100
  49. foo:101
  50. foo:102:103
  51. foo:102:103:104
  52. foo:0.03:asdf:103:105
  53. ret=[s1:foobar s2:foobar age:25 pi:3.14]
  54. """
  55. doAssert output == expected, output
  56. doAssert exitCode == 0
  57. else: # don't run twice the same test
  58. import std/[strutils]
  59. template check2(msg) = doAssert msg in output, output
  60. block: # tests with various options `nim doc --project --index --docroot`
  61. # regression tests for issues and PRS: #14376 #13223 #6583 ##13647
  62. let file = testsDir / "nimdoc/sub/mmain.nim"
  63. let mainFname = "mmain.html"
  64. let htmldocsDirCustom = nimcache / "htmldocsCustom"
  65. let docroot = testsDir / "nimdoc"
  66. let options = [
  67. 0: "--project",
  68. 1: "--project --docroot",
  69. 2: "",
  70. 3: fmt"--outDir:{htmldocsDirCustom}",
  71. 4: fmt"--docroot:{docroot}",
  72. 5: "--project --useNimcache",
  73. 6: "--index:off",
  74. ]
  75. for i in 0..<options.len:
  76. let htmldocsDir = case i
  77. of 3: htmldocsDirCustom
  78. of 5: nimcache / htmldocsDirname
  79. else: file.parentDir / htmldocsDirname
  80. var cmd = fmt"{nim} doc --index:on --listFullPaths --hint:successX:on --nimcache:{nimcache} {options[i]} {file}"
  81. removeDir(htmldocsDir)
  82. let (outp, exitCode) = execCmdEx(cmd)
  83. check exitCode == 0
  84. let ret = toSeq(walkDirRec(htmldocsDir, relative=true)).mapIt(it.nativeToUnixPath).sorted.join("\n")
  85. let context = $(i, ret, cmd)
  86. var expected = ""
  87. case i
  88. of 0,5:
  89. let htmlFile = htmldocsDir/"mmain.html"
  90. check htmlFile in outp # sanity check for `hintSuccessX`
  91. assertEquals ret, fmt"""
  92. {dotdotMangle}/imp.html
  93. {dotdotMangle}/imp.idx
  94. {docHackJsFname}
  95. imp.html
  96. imp.idx
  97. imp2.html
  98. imp2.idx
  99. mmain.html
  100. mmain.idx
  101. {nimdocOutCss}
  102. {theindexFname}""", context
  103. of 1: assertEquals ret, fmt"""
  104. {docHackJsFname}
  105. {nimdocOutCss}
  106. tests/nimdoc/imp.html
  107. tests/nimdoc/imp.idx
  108. tests/nimdoc/sub/imp.html
  109. tests/nimdoc/sub/imp.idx
  110. tests/nimdoc/sub/imp2.html
  111. tests/nimdoc/sub/imp2.idx
  112. tests/nimdoc/sub/mmain.html
  113. tests/nimdoc/sub/mmain.idx
  114. {theindexFname}"""
  115. of 2, 3: assertEquals ret, fmt"""
  116. {docHackJsFname}
  117. mmain.html
  118. mmain.idx
  119. {nimdocOutCss}""", context
  120. of 4: assertEquals ret, fmt"""
  121. {docHackJsFname}
  122. {nimdocOutCss}
  123. sub/mmain.html
  124. sub/mmain.idx""", context
  125. of 6: assertEquals ret, fmt"""
  126. mmain.html
  127. {nimdocOutCss}""", context
  128. else: doAssert false
  129. block: # mstatic_assert
  130. let (output, exitCode) = runCmd("ccgbugs/mstatic_assert.nim", "-d:caseBad")
  131. check2 "sizeof(bool) == 2"
  132. check exitCode != 0
  133. block: # ABI checks
  134. let file = "misc/msizeof5.nim"
  135. block:
  136. let (output, exitCode) = runCmd(file, "-d:checkAbi")
  137. doAssert exitCode == 0, output
  138. block:
  139. let (output, exitCode) = runCmd(file, "-d:checkAbi -d:caseBad")
  140. # on platforms that support _StaticAssert natively, errors will show full context, eg:
  141. # error: static_assert failed due to requirement 'sizeof(unsigned char) == 8'
  142. # "backend & Nim disagree on size for: BadImportcType{int64} [declared in mabi_check.nim(1, 6)]"
  143. check2 "sizeof(unsigned char) == 8"
  144. check2 "sizeof(struct Foo2) == 1"
  145. check2 "sizeof(Foo5) == 16"
  146. check2 "sizeof(Foo5) == 3"
  147. check2 "sizeof(struct Foo6) == "
  148. check exitCode != 0
  149. import streams
  150. block: # stdin input
  151. let nimcmd = fmt"""{nim} r --hints:off - -firstparam "-second param" """
  152. let expected = """@["-firstparam", "-second param"]"""
  153. block:
  154. let p = startProcess(nimcmd, options = {poEvalCommand})
  155. p.inputStream.write("import os; echo commandLineParams()")
  156. p.inputStream.close
  157. var output = p.outputStream.readAll
  158. let error = p.errorStream.readAll
  159. doAssert p.waitForExit == 0
  160. doAssert error.len == 0, $error
  161. output.stripLineEnd
  162. check output == expected
  163. p.errorStream.close
  164. p.outputStream.close
  165. block:
  166. when defined posix:
  167. # xxx on windows, `poEvalCommand` should imply `/cmd`, (which should
  168. # make this work), but currently doesn't
  169. let cmd = fmt"""echo "import os; echo commandLineParams()" | {nimcmd}"""
  170. var (output, exitCode) = execCmdEx(cmd)
  171. output.stripLineEnd
  172. check output == expected
  173. doAssert exitCode == 0
  174. block: # nim doc --backend:$backend --doccmd:$cmd
  175. # test for https://github.com/nim-lang/Nim/issues/13129
  176. # test for https://github.com/nim-lang/Nim/issues/13891
  177. let file = testsDir / "nimdoc/m13129.nim"
  178. for backend in fmt"{mode} js".split:
  179. # pending #14343 this fails on windows: --doccmd:"-d:m13129Foo2 --hints:off"
  180. let cmd = fmt"""{nim} doc -b:{backend} --nimcache:{nimcache} -d:m13129Foo1 "--doccmd:-d:m13129Foo2 --hints:off" --usenimcache --hints:off {file}"""
  181. check execCmdEx(cmd) == (&"ok1:{backend}\nok2: backend: {backend}\n", 0)
  182. # checks that --usenimcache works with `nim doc`
  183. check fileExists(nimcache / "htmldocs/m13129.html")
  184. block: # mak sure --backend works with `nim r`
  185. let cmd = fmt"{nim} r --backend:{mode} --hints:off --nimcache:{nimcache} {file}"
  186. check execCmdEx(cmd) == ("ok3\n", 0)
  187. block: # further issues with `--backend`
  188. let file = testsDir / "misc/mbackend.nim"
  189. var cmd = fmt"{nim} doc -b:cpp --hints:off --nimcache:{nimcache} {file}"
  190. check execCmdEx(cmd) == ("", 0)
  191. cmd = fmt"{nim} check -b:c -b:cpp --hints:off --nimcache:{nimcache} {file}"
  192. check execCmdEx(cmd) == ("", 0)
  193. # issue https://github.com/timotheecour/Nim/issues/175
  194. cmd = fmt"{nim} c -b:js -b:cpp --hints:off --nimcache:{nimcache} {file}"
  195. check execCmdEx(cmd) == ("", 0)
  196. block: # some importc tests
  197. # issue #14314
  198. let file = testsDir / "misc/mimportc.nim"
  199. let cmd = fmt"{nim} r -b:cpp --hints:off --nimcache:{nimcache} --warningAsError:ProveInit {file}"
  200. check execCmdEx(cmd) == ("witness\n", 0)