summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--lib/pure/unittest.nim13
-rw-r--r--lib/std/exitprocs.nim22
-rw-r--r--lib/system.nim7
-rw-r--r--tests/js/tunittest_error.nim2
-rw-r--r--tests/stdlib/tquit.nim2
-rw-r--r--tests/stdlib/tunittest_error.nim22
6 files changed, 55 insertions, 13 deletions
diff --git a/lib/pure/unittest.nim b/lib/pure/unittest.nim
index bea7d9c44..f3d920d0e 100644
--- a/lib/pure/unittest.nim
+++ b/lib/pure/unittest.nim
@@ -94,6 +94,7 @@
 ##     echo "suite teardown: run once after the tests"
 
 import std/private/since
+import std/exitprocs
 
 import
   macros, strutils, streams, times, sets, sequtils
@@ -498,7 +499,7 @@ template test*(name, body) {.dirty.} =
   ## .. code-block::
   ##
   ##  [OK] roses are red
-  bind shouldRun, checkpoints, formatters, ensureInitialized, testEnded, exceptionTypeName
+  bind shouldRun, checkpoints, formatters, ensureInitialized, testEnded, exceptionTypeName, setProgramResult
 
   ensureInitialized()
 
@@ -524,7 +525,7 @@ template test*(name, body) {.dirty.} =
 
     finally:
       if testStatusIMPL == TestStatus.FAILED:
-        programResult = 1
+        setProgramResult 1
       let testResult = TestResult(
         suiteName: when declared(testSuiteName): testSuiteName else: "",
         testName: name,
@@ -560,12 +561,11 @@ template fail* =
   ##  fail()
   ##
   ## outputs "Checkpoint A" before quitting.
-  bind ensureInitialized
-
+  bind ensureInitialized, setProgramResult
   when declared(testStatusIMPL):
     testStatusIMPL = TestStatus.FAILED
   else:
-    programResult = 1
+    setProgramResult 1
 
   ensureInitialized()
 
@@ -576,8 +576,7 @@ template fail* =
     else:
       formatter.failureOccurred(checkpoints, "")
 
-  when declared(programResult):
-    if abortOnError: quit(programResult)
+  if abortOnError: quit(1)
 
   checkpoints = @[]
 
diff --git a/lib/std/exitprocs.nim b/lib/std/exitprocs.nim
index b2811735c..c6537f7f8 100644
--- a/lib/std/exitprocs.nim
+++ b/lib/std/exitprocs.nim
@@ -63,3 +63,25 @@ proc addExitProc*(cl: proc() {.noconv.}) =
   withLock gFunsLock:
     fun()
     gFuns.add Fun(kind: kNoconv, fun2: cl)
+
+when not defined(nimscript):
+  proc getProgramResult*(): int =
+    when defined(js) and defined(nodejs):
+      asm """
+`result` = process.exitCode;
+"""
+    elif not defined(js):
+      result = programResult
+    else:
+      doAssert false
+
+  proc setProgramResult*(a: int) =
+    # pending https://github.com/nim-lang/Nim/issues/14674
+    when defined(js) and defined(nodejs):
+      asm """
+process.exitCode = `a`;
+"""
+    elif not defined(js):
+      programResult = a
+    else:
+      doAssert false
diff --git a/lib/system.nim b/lib/system.nim
index 822454626..71eed5bee 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -1127,12 +1127,9 @@ const
     ## is the value that should be passed to `quit <#quit,int>`_ to indicate
     ## failure.
 
-when defined(js) and defined(nodejs) and not defined(nimscript):
-  var programResult* {.importc: "process.exitCode".}: int
-  programResult = 0
-elif hostOS != "standalone":
+when not defined(js) and hostOS != "standalone":
   var programResult* {.compilerproc, exportc: "nim_program_result".}: int
-    ## deprecated, prefer ``quit``
+    ## deprecated, prefer `quit` or `exitprocs.getProgramResult`, `exitprocs.setProgramResult`.
 
 import std/private/since
 
diff --git a/tests/js/tunittest_error.nim b/tests/js/tunittest_error.nim
index ab736bf59..781e34338 100644
--- a/tests/js/tunittest_error.nim
+++ b/tests/js/tunittest_error.nim
@@ -3,6 +3,8 @@ discard """
   outputsub: "[FAILED] with exception"
 """
 
+# see also: `tests/stdlib/tunittest_error.nim`
+
 import unittest
 
 proc ddd() =
diff --git a/tests/stdlib/tquit.nim b/tests/stdlib/tquit.nim
index 1f9283ec4..0b4a479dc 100644
--- a/tests/stdlib/tquit.nim
+++ b/tests/stdlib/tquit.nim
@@ -5,7 +5,7 @@ just exiting...
 joinable: false
 """
 
-# Test the new beforeQuit variable:
+# Test `addQuitProc`
 
 proc myExit() {.noconv.} =
   write(stdout, "just exiting...\n")
diff --git a/tests/stdlib/tunittest_error.nim b/tests/stdlib/tunittest_error.nim
new file mode 100644
index 000000000..7f05ec2a9
--- /dev/null
+++ b/tests/stdlib/tunittest_error.nim
@@ -0,0 +1,22 @@
+discard """
+  exitcode: 1
+  outputsub: "failed: 1 == 3"
+  matrix: "-d:case1; -d:case2"
+  targets: "c js"
+  joinable: false
+"""
+
+when defined case1:
+  import unittest
+  suite "Test":
+    test "test require":
+      check 1==2
+      check 1==3
+
+when defined case2:
+  import unittest
+  suite "Test":
+    test "test require":
+      require 1 == 3
+      if true:
+        quit 0 # intentional