diff --git a/changelog.md b/changelog.md index 2604b09b3bea7..94be905dddedb 100644 --- a/changelog.md +++ b/changelog.md @@ -41,7 +41,8 @@ - Added `cmpMem` to `system`. -- `doAssertRaises` now correctly handles foreign exceptions. +- `doAssertRaises` now correctly handles foreign exceptions; + it also allows a catch-all form that includes foreign exceptions. - Added `asyncdispatch.activeDescriptors` that returns the number of currently active async event handles/file descriptors. @@ -116,7 +117,9 @@ with other backends. see #9125. Use `-d:nimLegacyJsRound` for previous behavior. - The `cstring` doesn't support `[]=` operator in JS backend. - nil dereference is not allowed at compile time. `cast[ptr int](nil)[]` is rejected at compile time. +- `nimscript` now handles `except Exception as e` +- The `cstring` doesn't support `[]=` operator in JS backend. ## Compiler changes diff --git a/lib/system/assertions.nim b/lib/system/assertions.nim index 4c25d2a567872..2d83c067dca91 100644 --- a/lib/system/assertions.nim +++ b/lib/system/assertions.nim @@ -109,3 +109,18 @@ template doAssertRaises*(exception: typedesc, code: untyped) = except: raisedForeign() if wrong: raiseAssert(begin & " nothing was raised" & msgEnd) + +template doAssertRaises*(code: untyped) = + ## Raises `AssertionDefect` if specified `code` does not raise anything, + ## including a foreign exception. + ## Example: + ## + ## .. code-block:: nim + ## doAssertRaises: raise newException(ValueError, "Hello World") + var wrong = false + try: + if true: code + wrong = true + except: discard + if wrong: + raiseAssert("nothing was raised by: " & astToStr(code)) diff --git a/tests/stdlib/tassertions.nim b/tests/stdlib/tassertions.nim new file mode 100644 index 0000000000000..100f688b17024 --- /dev/null +++ b/tests/stdlib/tassertions.nim @@ -0,0 +1,29 @@ +discard """ +targets: "c cpp js" +""" + +template main = + doAssertRaises(ValueError): raise newException(ValueError, "foo") + doAssertRaises(ValueError, block: raise newException(ValueError, "foo")) +static: main() +main() + +when defined(cpp) or defined(js): + when defined(cpp): + {.emit:""" + #include + void fn(){throw std::runtime_error("asdf");}""".} + proc fn(){.importcpp.} + else: + {.emit:""" + function fn(){ throw 42;} """.} + proc fn(){.importc.} + + var witness = false + try: + doAssertRaises(ValueError): fn() + except AssertionDefect: + witness = true + doAssert witness + doAssertRaises: fn() + doAssertRaises(block: fn())