diff options
Diffstat (limited to 'tests/js')
68 files changed, 1448 insertions, 471 deletions
diff --git a/tests/js/readme.md b/tests/js/readme.md new file mode 100644 index 000000000..7fcc722fa --- /dev/null +++ b/tests/js/readme.md @@ -0,0 +1,5 @@ +## notes +Prefer moving tests to a non-js directory so that they get tested across all backends automatically. +Ideally, tests/js should be reserved to code that only makes sense in js. + +Note also that tests for a js specific module (e.g.: `std/jsbigints`) belong to `tests/stdlib`, (e.g.: `tests/stdlib/tjsbigints.nim`) diff --git a/tests/js/t11166.nim b/tests/js/t11166.nim index 8dd77925c..e98ccda10 100644 --- a/tests/js/t11166.nim +++ b/tests/js/t11166.nim @@ -1,4 +1,20 @@ +discard """ + output: ''' +test1 +test2 +''' +""" + import jsffi +type + C = object + props: int + +var c: C + when compiles(c.props): - echo "test" + echo "test1" + +when not compiles(d.props): + echo "test2" diff --git a/tests/js/t11354.nim b/tests/js/t11354.nim new file mode 100644 index 000000000..8dee90de0 --- /dev/null +++ b/tests/js/t11354.nim @@ -0,0 +1,20 @@ +discard """ + output: ''' +0 +@[@[0, 1]] +''' +""" + +type + TrackySeq[T] = object + s: seq[T] + pos: int + +proc foobar(ls: var TrackySeq[seq[int]], i: int): var seq[int] = + echo ls.pos # removing this, or making the return explicit works + ls.s[i] + +var foo: TrackySeq[seq[int]] +foo.s.add(@[0]) +foo.foobar(0).add(1) +echo foo.s \ No newline at end of file diff --git a/tests/js/t11697.nim b/tests/js/t11697.nim new file mode 100644 index 000000000..967752586 --- /dev/null +++ b/tests/js/t11697.nim @@ -0,0 +1,5 @@ +import tables + +var xs: Table[int, Table[int, int]] + +doAssertRaises(KeyError): reset xs[0] diff --git a/tests/js/t12303.nim b/tests/js/t12303.nim new file mode 100644 index 000000000..270d82ced --- /dev/null +++ b/tests/js/t12303.nim @@ -0,0 +1,16 @@ +discard """ + output: "{ b: 2 }" +""" + +import jsconsole, jsffi + +type + A = ref object + b: B + + B = object + b: int + +var a = cast[A](js{}) +a.b = B(b: 2) +console.log a.b diff --git a/tests/js/t12672.nim b/tests/js/t12672.nim new file mode 100644 index 000000000..a658fbcbe --- /dev/null +++ b/tests/js/t12672.nim @@ -0,0 +1,12 @@ +discard """ + output: "" +""" + +proc foo = + var x: seq[seq[int]] + for row in x.mitems: + let i = 1 + echo row + inc row[i-1] + +foo() diff --git a/tests/js/t14153.nim b/tests/js/t14153.nim new file mode 100644 index 000000000..350bbd83b --- /dev/null +++ b/tests/js/t14153.nim @@ -0,0 +1,22 @@ +discard """ + output: ''' +index 5 not in 0 .. 2 +index 5 not in 0 .. 2 +''' +""" + +var x = @[1, 2, 3] + +try: + echo x[5] +except IndexError: + echo getCurrentExceptionMsg() +except: + doAssert false + +try: + x[5] = 8 +except IndexError: + echo getCurrentExceptionMsg() +except: + doAssert false diff --git a/tests/js/t14570.nim b/tests/js/t14570.nim new file mode 100644 index 000000000..100c2651d --- /dev/null +++ b/tests/js/t14570.nim @@ -0,0 +1,11 @@ +discard """ + output: ''' +18 +''' +""" + +type A = range[15 .. 30] + +let a: A = 18 + +echo ord(a) diff --git a/tests/js/t17177.nim b/tests/js/t17177.nim new file mode 100644 index 000000000..fc362cec1 --- /dev/null +++ b/tests/js/t17177.nim @@ -0,0 +1,10 @@ +import std/asyncjs + +proc fn1(n: int): Future[int] {.async.} = return n +proc main2() = + proc fn2(n: int): Future[int] {.async.} = return n +proc main3(a: auto) = + proc fn3(n: int): Future[int] {.async.} = return n +proc main4() {.async.} = + proc fn4(n: int): Future[int] {.async.} = return n + discard diff --git a/tests/js/t20233.nim b/tests/js/t20233.nim new file mode 100644 index 000000000..401d14122 --- /dev/null +++ b/tests/js/t20233.nim @@ -0,0 +1,7 @@ +discard """ + output: "yes" +""" +case 1.0 +of 1.0..2.0, 4.0: echo "yes" +of 3.0: discard +else: echo "no" \ No newline at end of file diff --git a/tests/js/t20235.nim b/tests/js/t20235.nim new file mode 100644 index 000000000..3a69c2bd6 --- /dev/null +++ b/tests/js/t20235.nim @@ -0,0 +1,11 @@ +discard """ + action: "run" + output: "0 4" +""" + +proc main = + var s = "" + s.setLen(4) + echo s[0].ord, " ", s.len + +main() diff --git a/tests/js/t21209.nim b/tests/js/t21209.nim new file mode 100644 index 000000000..4de34f035 --- /dev/null +++ b/tests/js/t21209.nim @@ -0,0 +1,6 @@ +discard """ + action: "compile" + cmd: "nim check --warning[UnusedImport]:off $file" +""" + +import std/times diff --git a/tests/js/t21209.nims b/tests/js/t21209.nims new file mode 100644 index 000000000..318e28f97 --- /dev/null +++ b/tests/js/t21209.nims @@ -0,0 +1 @@ +--b:js \ No newline at end of file diff --git a/tests/js/t21247.nim b/tests/js/t21247.nim new file mode 100644 index 000000000..5b38787b3 --- /dev/null +++ b/tests/js/t21247.nim @@ -0,0 +1,15 @@ +import std/typetraits + +type + QueryParams* = distinct seq[(string, string)] + +converter toBase*(params: var QueryParams): var seq[(string, string)] = + params.distinctBase + +proc foo(): QueryParams = + # Issue was that the implicit converter call didn't say that it took the + # address of the parameter it was converting. This led to the parameter not being + # passed as a fat pointer which toBase expected + result.add(("hello", "world")) + +assert foo().distinctBase() == @[("hello", "world")] diff --git a/tests/js/t21439.nim b/tests/js/t21439.nim new file mode 100644 index 000000000..3caeb090a --- /dev/null +++ b/tests/js/t21439.nim @@ -0,0 +1,11 @@ +proc test(a: openArray[string]): proc = + let a = @a + result = proc = + for i in a: + discard i + + +const a = ["t1", "t2"] + +discard test(a) + diff --git a/tests/js/t7109.nim b/tests/js/t7109.nim new file mode 100644 index 000000000..a1a3b718e --- /dev/null +++ b/tests/js/t7109.nim @@ -0,0 +1,8 @@ +iterator iter*(): int {.closure.} = + yield 3 + +var x = iter +doAssert x() == 3 + +let fIt = iterator(): int = yield 70 +doAssert fIt() == 70 diff --git a/tests/js/t7127.nim b/tests/js/t7127.nim new file mode 100644 index 000000000..364aedd4a --- /dev/null +++ b/tests/js/t7127.nim @@ -0,0 +1,2 @@ +doAssertRaises(DivByZeroDefect): discard 1 mod 0 +doAssertRaises(DivByZeroDefect): discard 1 div 0 \ No newline at end of file diff --git a/tests/js/t7224.nim b/tests/js/t7224.nim index be9d0ae9c..77fef10a7 100644 --- a/tests/js/t7224.nim +++ b/tests/js/t7224.nim @@ -1,10 +1,11 @@ discard """ cmd: "nim $target $options --stackTrace:on --lineTrace:on $file" outputsub: ''' -t7224.aaa, line: 21 -t7224.bbb, line: 18 -t7224.ccc, line: 15 -t7224.ddd, line: 12 +t7224.nim(25) at module t7224 +t7224.nim(22) at t7224.aaa +t7224.nim(19) at t7224.bbb +t7224.nim(16) at t7224.ccc +t7224.nim(13) at t7224.ddd ''' """ diff --git a/tests/js/t8231.nim b/tests/js/t8231.nim new file mode 100644 index 000000000..b0625a621 --- /dev/null +++ b/tests/js/t8231.nim @@ -0,0 +1,3 @@ +import strutils + +doAssert formatSize(2462056448, '.', bpIEC, false) == "2.293GiB" \ No newline at end of file diff --git a/tests/js/t8821.nim b/tests/js/t8821.nim new file mode 100644 index 000000000..38c88efa8 --- /dev/null +++ b/tests/js/t8821.nim @@ -0,0 +1,9 @@ + +proc isInt32(i: int): bool = + case i + of 1 .. 70000: + return true + else: + return false + +doAssert isInt32(1) == true \ No newline at end of file diff --git a/tests/js/t9410.nim b/tests/js/t9410.nim index 78c329a24..042520dc5 100644 --- a/tests/js/t9410.nim +++ b/tests/js/t9410.nim @@ -447,10 +447,10 @@ template tests = doAssert seqOfSeqs == @[@[10, 2], @[30, 4]] when false: - block: # openarray + block: # openArray # Error: internal error: genAddr: nkStmtListExpr var calls = 0 - proc getvarint(x: var openarray[int]): var int = + proc getvarint(x: var openArray[int]): var int = calls += 1 if true: x[1] diff --git a/tests/js/taddr.nim b/tests/js/taddr.nim deleted file mode 100644 index d8ff4c11b..000000000 --- a/tests/js/taddr.nim +++ /dev/null @@ -1,79 +0,0 @@ -discard """ - action: run -""" - -type T = object - x: int - s: string - -var obj: T -var fieldAddr = addr(obj.x) -var objAddr = addr(obj) - -# Integer tests -var field = fieldAddr[] -doAssert field == 0 - -var objDeref = objAddr[] -doAssert objDeref.x == 0 - -# Change value -obj.x = 42 - -doAssert field == 0 -doAssert objDeref.x == 0 - -field = fieldAddr[] -objDeref = objAddr[] - -doAssert field == 42 -doAssert objDeref.x == 42 - -# String tests -obj.s = "lorem ipsum dolor sit amet" -var indexAddr = addr(obj.s[2]) - -doAssert indexAddr[] == 'r' - -indexAddr[] = 'd' - -doAssert indexAddr[] == 'd' - -doAssert obj.s == "lodem ipsum dolor sit amet" - -# Bug #2148 -var x: array[2, int] -var y = addr x[1] - -y[] = 12 -doAssert(x[1] == 12) - -type - Foo = object - bar: int - -var foo: array[2, Foo] -var z = addr foo[1] - -z[].bar = 12345 -doAssert(foo[1].bar == 12345) - -var t : tuple[a, b: int] -var pt = addr t[1] -pt[] = 123 -doAssert(t.b == 123) - -#block: # Test "untyped" pointer. -proc testPtr(p: pointer, a: int) = - doAssert(a == 5) - (cast[ptr int](p))[] = 124 -var i = 123 -testPtr(addr i, 5) -doAssert(i == 124) - -var someGlobal = 5 -proc getSomeGlobalPtr(): ptr int = addr someGlobal -let someGlobalPtr = getSomeGlobalPtr() -doAssert(someGlobalPtr[] == 5) -someGlobalPtr[] = 10 -doAssert(someGlobal == 10) diff --git a/tests/js/tarrayboundscheck.nim b/tests/js/tarrayboundscheck.nim index f0eaeb89d..d8bf8de97 100644 --- a/tests/js/tarrayboundscheck.nim +++ b/tests/js/tarrayboundscheck.nim @@ -39,6 +39,12 @@ proc test_arrayboundscheck() = echo "month out of bounds: ", idx except: echo "idx out of bounds: ", i + + # #13966 + var negativeIndexed: array[-2..2, int] = [0, 1, 2, 3, 4] + negativeIndexed[-1] = 2 + negativeIndexed[1] = 2 + doAssert negativeIndexed == [0, 2, 2, 2, 4] test_arrayboundscheck() {.pop.} \ No newline at end of file diff --git a/tests/js/tasync.nim b/tests/js/tasync.nim deleted file mode 100644 index 318237651..000000000 --- a/tests/js/tasync.nim +++ /dev/null @@ -1,33 +0,0 @@ -discard """ - output: ''' -x -e -''' -""" - -import asyncjs - -# demonstrate forward definition -# for js -proc y(e: int): Future[string] {.async.} - -proc e: int {.discardable.} = - echo "e" - return 2 - -proc x(e: int): Future[void] {.async.} = - var s = await y(e) - if e > 2: - return - echo s - e() - -proc y(e: int): Future[string] {.async.} = - if e > 0: - return await y(0) - else: - return "x" - - -discard x(2) - diff --git a/tests/js/tasyncjs.nim b/tests/js/tasyncjs.nim new file mode 100644 index 000000000..f3b273c44 --- /dev/null +++ b/tests/js/tasyncjs.nim @@ -0,0 +1,107 @@ +discard """ + output: ''' +x +e +done +''' +""" + +#[ +xxx move this to tests/stdlib/tasyncjs.nim +]# + +import std/asyncjs + +block: + # demonstrate forward definition for js + proc y(e: int): Future[string] {.async.} + + proc e: int {.discardable.} = + echo "e" + return 2 + + proc x(e: int): Future[void] {.async.} = + var s = await y(e) + if e > 2: + return + echo s + e() + + proc y(e: int): Future[string] {.async.} = + if e > 0: + return await y(0) + else: + return "x" + + discard x(2) + +import std/sugar +from std/strutils import contains + +var witness: seq[string] + +proc fn(n: int): Future[int] {.async.} = + if n >= 7: + raise newException(ValueError, "foobar: " & $n) + if n > 0: + var ret = 1 + await fn(n-1) + witness.add $(n, ret) + return ret + else: + return 10 + +proc asyncFact(n: int): Future[int] {.async.} = + if n > 0: result = n * await asyncFact(n-1) + else: result = 1 + +proc asyncIdentity(n: int): Future[int] {.async.} = + if n > 0: result = 1 + await asyncIdentity(n-1) + else: result = 0 + +proc main() {.async.} = + block: # then + let x = await fn(4) + .then((a: int) => a.float) + .then((a: float) => $a) + doAssert x == "14.0" + doAssert witness == @["(1, 11)", "(2, 12)", "(3, 13)", "(4, 14)"] + + doAssert (await fn(2)) == 12 + + let x2 = await fn(4).then((a: int) => (discard)).then(() => 13) + doAssert x2 == 13 + + let x4 = await asyncFact(3).then(asyncIdentity).then(asyncIdentity).then((a:int) => a * 7).then(asyncIdentity) + doAssert x4 == 3 * 2 * 7 + + block: # bug #17177 + proc asyncIdentityNested(n: int): Future[int] {.async.} = return n + let x5 = await asyncFact(3).then(asyncIdentityNested) + doAssert x5 == 3 * 2 + + when false: # xxx pending bug #17254 + let x6 = await asyncFact(3).then((a:int) {.async.} => a * 11) + doAssert x6 == 3 * 2 * 11 + + block: # catch + var reason: Error + await fn(6).then((a: int) => (witness.add $a)).catch((r: Error) => (reason = r)) + doAssert reason == nil + + await fn(7).then((a: int) => (discard)).catch((r: Error) => (reason = r)) + doAssert reason != nil + doAssert reason.name == "Error" + doAssert "foobar: 7" in $reason.message + echo "done" # justified here to make sure we're running this, since it's inside `async` + +block asyncPragmaInType: + type Handler = proc () {.async.} + proc foo() {.async.} = discard + var x: Handler = foo + +block: # 13341 + proc f {.async.} = + proc g: int = + result = 123 + +discard main() diff --git a/tests/js/tasyncjs_bad.nim b/tests/js/tasyncjs_bad.nim new file mode 100644 index 000000000..b1e5a7bc3 --- /dev/null +++ b/tests/js/tasyncjs_bad.nim @@ -0,0 +1,22 @@ +discard """ + exitCode: 1 + outputsub: "Error: unhandled exception: foobar: 13" +""" + +# note: this needs `--unhandled-rejections=strict`, see D20210217T215950 + +import std/asyncjs +from std/sugar import `=>` + +proc fn(n: int): Future[int] {.async.} = + if n >= 7: raise newException(ValueError, "foobar: " & $n) + else: result = n + +proc main() {.async.} = + let x1 = await fn(6) + doAssert x1 == 6 + await fn(7).catch((a: Error) => (discard)) + let x3 = await fn(13) + doAssert false # shouldn't go here, should fail before + +discard main() diff --git a/tests/js/tasync_pragma.nim b/tests/js/tasyncjs_pragma.nim index 916769fad..2b6f32e92 100644 --- a/tests/js/tasync_pragma.nim +++ b/tests/js/tasyncjs_pragma.nim @@ -5,6 +5,8 @@ t ''' """ +# xxx merge into tasyncjs.nim + import asyncjs, macros macro f*(a: untyped): untyped = diff --git a/tests/js/tbasics.nim b/tests/js/tbasics.nim index b297bb037..ef84f8bb5 100644 --- a/tests/js/tbasics.nim +++ b/tests/js/tbasics.nim @@ -54,7 +54,7 @@ for x in someGlobal: doAssert(x == 0) proc tdefault = var x = default(int) doAssert(x == 0) - proc inner(v: openarray[string]) = + proc inner(v: openArray[string]) = doAssert(v.len == 0) inner(default(seq[string])) diff --git a/tests/js/tbigint_backend.nim b/tests/js/tbigint_backend.nim new file mode 100644 index 000000000..8f2f6c4f4 --- /dev/null +++ b/tests/js/tbigint_backend.nim @@ -0,0 +1,57 @@ +import std/private/jsutils + + +type JsBigIntImpl {.importc: "bigint".} = int +type JsBigInt = distinct JsBigIntImpl + +doAssert JsBigInt isnot int +func big*(integer: SomeInteger): JsBigInt {.importjs: "BigInt(#)".} +func big*(integer: cstring): JsBigInt {.importjs: "BigInt(#)".} +func `<=`*(x, y: JsBigInt): bool {.importjs: "(# $1 #)".} +func `==`*(x, y: JsBigInt): bool {.importjs: "(# === #)".} +func inc*(x: var JsBigInt) {.importjs: "[#][0][0]++".} +func inc2*(x: var JsBigInt) {.importjs: "#++".} +func toCstring*(this: JsBigInt): cstring {.importjs: "#.toString()".} +func `$`*(this: JsBigInt): string = + $toCstring(this) + +block: + doAssert defined(nimHasJsBigIntBackend) + let z1 = big"10" + let z2 = big"15" + doAssert z1 == big"10" + doAssert z1 == z1 + doAssert z1 != z2 + var s: seq[cstring] + for i in z1 .. z2: + s.add $i + doAssert s == @["10".cstring, "11", "12", "13", "14", "15"] + block: + var a=big"3" + a.inc + doAssert a == big"4" + block: + var z: JsBigInt + doAssert $z == "0" + doAssert z.jsTypeOf == "bigint" # would fail without codegen change + doAssert z != big(1) + doAssert z == big"0" # ditto + + # ditto below + block: + let z: JsBigInt = big"1" + doAssert $z == "1" + doAssert z.jsTypeOf == "bigint" + doAssert z == big"1" + + block: + let z = JsBigInt.default + doAssert $z == "0" + doAssert z.jsTypeOf == "bigint" + doAssert z == big"0" + + block: + var a: seq[JsBigInt] + a.setLen 3 + doAssert a[^1].jsTypeOf == "bigint" + doAssert a[^1] == big"0" diff --git a/tests/js/tbyvar.nim b/tests/js/tbyvar.nim index 705d62574..93724a2f1 100644 --- a/tests/js/tbyvar.nim +++ b/tests/js/tbyvar.nim @@ -1,15 +1,16 @@ discard """ - output: '''foo 12 + output: ''' +foo 12 bar 12 2 foo 12 bar 12 2 12.5 -(nums: @[5, 5, 10, 5, 5, 5, 5, 5, 5, 5]) -(nums: @[5, 5, 50, 5, 5, 5, 5, 5, 5, 5]) -(nums: @[5, 5, 45, 5, 5, 5, 5, 5, 5, 5]) -(nums: @[5, 5, 9, 5, 5, 5, 5, 5, 5, 5]) +(nums: @[5.0, 5.0, 10.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0]) +(nums: @[5.0, 5.0, 50.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0]) +(nums: @[5.0, 5.0, 45.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0]) +(nums: @[5.0, 5.0, 9.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0]) asd ''' """ @@ -38,9 +39,9 @@ proc main = main() -# Test: pass var seq to var openarray +# Test: pass var seq to var openArray var s = @[2, 1] -proc foo(a: var openarray[int]) = a[0] = 123 +proc foo(a: var openArray[int]) = a[0] = 123 proc bar(s: var seq[int], a: int) = doAssert(a == 5) diff --git a/tests/js/tclosures.nim b/tests/js/tclosures.nim index 3137123bf..4f1c28de3 100644 --- a/tests/js/tclosures.nim +++ b/tests/js/tclosures.nim @@ -22,7 +22,7 @@ asm """ function print (text) { console.log (text); } """ -proc consoleprint (str:cstring): void {.importc: "print", noDecl.} +proc consoleprint (str:cstring): void {.importc: "print", nodecl.} proc print* (a: varargs[string, `$`]) = consoleprint "$1: $2" % [consolePrefix, join(a, " ")] type CallbackProc {.importc.} = proc () : cstring diff --git a/tests/js/tcodegendeclproc.nim b/tests/js/tcodegendeclproc.nim index 3acf0bc13..33064bdf1 100644 --- a/tests/js/tcodegendeclproc.nim +++ b/tests/js/tcodegendeclproc.nim @@ -3,7 +3,7 @@ discard """ -1 8 ''' - ccodecheck: "'console.log(-1); function fac_' \\d+ '(n_' \\d+ ')'" + ccodecheck: "'console.log(-1); function fac__tcodegendeclproc_u1(n_p0)'" """ proc fac(n: int): int {.codegenDecl: "console.log(-1); function $2($3)".} = return n diff --git a/tests/js/tconsole.nim b/tests/js/tconsole.nim index b2eecc656..88c71ea18 100644 --- a/tests/js/tconsole.nim +++ b/tests/js/tconsole.nim @@ -3,7 +3,6 @@ discard """ Hello, console 1 2 3 ''' - disabled: "freebsd" """ # This file tests the JavaScript console diff --git a/tests/js/tcsymbol.nim b/tests/js/tcsymbol.nim new file mode 100644 index 000000000..07e52b9b6 --- /dev/null +++ b/tests/js/tcsymbol.nim @@ -0,0 +1,6 @@ +discard """ + matrix: "--cc:gcc; --cc:tcc" +""" + +doAssert not defined(gcc) +doAssert not defined(tcc) \ No newline at end of file diff --git a/tests/js/tdanger.nim b/tests/js/tdanger.nim new file mode 100644 index 000000000..9088859a8 --- /dev/null +++ b/tests/js/tdanger.nim @@ -0,0 +1,17 @@ +discard """ + matrix: ";--d:danger" +""" + +block: + proc foo() = + var name = int64(12) + var x = uint32(name) + var m = x + 12 + + var y = int32(name) + var n = y + 1 + + doAssert m == uint32(n + 11) + + + foo() diff --git a/tests/js/tdiscard.nim b/tests/js/tdiscard.nim new file mode 100644 index 000000000..9aa6ea1b1 --- /dev/null +++ b/tests/js/tdiscard.nim @@ -0,0 +1,3 @@ +import dom + +discard Node() \ No newline at end of file diff --git a/tests/js/tdollar_float.nim b/tests/js/tdollar_float.nim new file mode 100644 index 000000000..4fd8e3cba --- /dev/null +++ b/tests/js/tdollar_float.nim @@ -0,0 +1,62 @@ +#[ +merge into tests/system/tdollars.nim once https://github.com/nim-lang/Nim/pull/14122 +is merged +]# + +import unittest + +block: # https://github.com/timotheecour/Nim/issues/133 + # simple test + var a: float = 2 + check $a == "2.0" + + # systematic tests + template fun(a2: static float) = + const a: float = a2 # needed pending https://github.com/timotheecour/Nim/issues/132 + var b = a + check $b == $a + + fun 2 + fun 2.0 + fun 2.1 + fun 1_000 + fun 1_000.1 + fun 1_000_000_000.1 + fun 1_000_000_000_000.1 + + # negatives + fun -2.0 + fun -2.1 + + # 0 + fun 0 + fun -0 + fun 0.0 + + block: + var a = -0.0 + check $a in ["-0.0", "0.0"] + + # exponents + block: + var a = 5e20 + check $a in ["5e20", "500000000000000000000.0"] + + fun 3.4e1'f32 + fun 3.4e-1'f32 + fun -3.4e-1'f32 + fun 3.4e-1'f32 + fun 3e-1'f32 + + block: + var a = 3.4e38'f32 + check $a in ["3.4e+38", "3.4e+038"] + # on windows, printf (used in VM) prints as 3.4e+038 + # but js prints as 3.4e+38 + # on osx, both print as 3.4e+38 + # see https://github.com/timotheecour/Nim/issues/138 + + when false: # edge cases + fun -0.0 # see https://github.com/timotheecour/Nim/issues/136 + fun 5e20 + fun 3.4e38'f32 diff --git a/tests/js/temptyseq.nim b/tests/js/temptyseq.nim new file mode 100644 index 000000000..6489cf817 --- /dev/null +++ b/tests/js/temptyseq.nim @@ -0,0 +1,8 @@ +# #12671 + +proc foo = + var x: seq[int] + doAssertRaises(IndexDefect): + inc x[0] + +foo() diff --git a/tests/js/tfieldchecks.nim b/tests/js/tfieldchecks.nim index 77759a75a..a0679a349 100644 --- a/tests/js/tfieldchecks.nim +++ b/tests/js/tfieldchecks.nim @@ -24,15 +24,15 @@ var obj = X(f0: "foo", f1: C, f3: 3.14) block: echo obj.f0 echo obj.f1 - doAssertRaises(FieldError): echo obj.f2 + doAssertRaises(FieldDefect): echo obj.f2 echo obj.f3 block: let a0 = addr(obj.f0) echo a0[] - # let a1 = unsafeAddr(obj.f1) + # let a1 = addr(obj.f1) # echo a1[] - doAssertRaises(FieldError): + doAssertRaises(FieldDefect): let a2 = addr(obj.f2) echo a2[] let a3 = addr(obj.f3) diff --git a/tests/js/tglobal.nim b/tests/js/tglobal.nim new file mode 100644 index 000000000..38f5eec34 --- /dev/null +++ b/tests/js/tglobal.nim @@ -0,0 +1,30 @@ +block global: + proc getState(): int = + var state0 {.global.}: int + inc state0 + result = state0 + + for i in 0 ..< 3: + doAssert getState() == i + 1 + + for i in 0 ..< 3: + once: + doAssert i == 0 + + +block threadvar: + proc getThreadState0(): int = + var state0 {.threadvar.}: int + inc state0 + result = state0 + + for i in 0 ..< 3: + doAssert getThreadState0() == i + 1 + + proc getThreadState1(): int = + var state1 {.threadvar.}: int + inc state1 + result = state1 + + for i in 0 ..< 3: + doAssert getThreadState1() == i + 1 diff --git a/tests/js/tindexdefect.nim b/tests/js/tindexdefect.nim new file mode 100644 index 000000000..37994ec2e --- /dev/null +++ b/tests/js/tindexdefect.nim @@ -0,0 +1,9 @@ +discard """ + outputsub: "unhandled exception: index 10000 not in 0 .. 0 [IndexDefect]" + exitcode: 1 + joinable: false +""" + +var s = ['a'] +let z = s[10000] == 'a' +echo z \ No newline at end of file diff --git a/tests/js/tjsffi.nim b/tests/js/tjsffi.nim index af33cee8a..f27ea5546 100644 --- a/tests/js/tjsffi.nim +++ b/tests/js/tjsffi.nim @@ -1,291 +1,197 @@ discard """ +matrix: "--legacy:jsnolambdalifting;" output: ''' -true -true -true -true -true -true -true -true -true -true -true -true -true -true -true -true 3 2 12 Event { name: 'click: test' } Event { name: 'reloaded: test' } Event { name: 'updates: test' } -true -true -true -true -true -true -true ''' """ import jsffi, jsconsole # Tests for JsObject -# Test JsObject []= and [] -block: - proc test(): bool = - let obj = newJsObject() - var working = true - obj["a"] = 11 - obj["b"] = "test" - obj["c"] = "test".cstring - working = working and obj["a"].to(int) == 11 - working = working and obj["c"].to(cstring) == "test".cstring - working - echo test() +block: # Test JsObject []= and [] + let obj = newJsObject() + obj["a"] = 11 + obj["b"] = "test" + obj["c"] = "test".cstring + doAssert obj["a"].to(int) == 11 + doAssert obj["c"].to(cstring) == "test".cstring -# Test JsObject .= and . -block: - proc test(): bool = - let obj = newJsObject() - var working = true - obj.a = 11 - obj.b = "test" - obj.c = "test".cstring - obj.`$!&` = 42 - obj.`while` = 99 - working = working and obj.a.to(int) == 11 - working = working and obj.b.to(string) == "test" - working = working and obj.c.to(cstring) == "test".cstring - working = working and obj.`$!&`.to(int) == 42 - working = working and obj.`while`.to(int) == 99 - working - echo test() +block: # Test JsObject .= and . + let obj = newJsObject() + obj.a = 11 + obj.b = "test" + obj.c = "test".cstring + obj.`$!&` = 42 + obj.`while` = 99 + doAssert obj.a.to(int) == 11 + doAssert obj.b.to(string) == "test" + doAssert obj.c.to(cstring) == "test".cstring + doAssert obj.`$!&`.to(int) == 42 + doAssert obj.`while`.to(int) == 99 -# Test JsObject .() -block: - proc test(): bool = - let obj = newJsObject() - obj.`?!$` = proc(x, y, z: int, t: cstring): cstring = t & $(x + y + z) - obj.`?!$`(1, 2, 3, "Result is: ").to(cstring) == cstring"Result is: 6" - echo test() +block: # Test JsObject .() + let obj = newJsObject() + obj.`?!$` = proc(x, y, z: int, t: cstring): cstring = t & $(x + y + z) + doAssert obj.`?!$`(1, 2, 3, "Result is: ").to(cstring) == cstring"Result is: 6" -# Test JsObject []() -block: - proc test(): bool = - let obj = newJsObject() - obj.a = proc(x, y, z: int, t: string): string = t & $(x + y + z) - let call = obj["a"].to(proc(x, y, z: int, t: string): string) - call(1, 2, 3, "Result is: ") == "Result is: 6" - echo test() +block: # Test JsObject []() + let obj = newJsObject() + obj.a = proc(x, y, z: int, t: string): string = t & $(x + y + z) + let call = obj["a"].to(proc(x, y, z: int, t: string): string) + doAssert call(1, 2, 3, "Result is: ") == "Result is: 6" # Test JsObject Iterators -block: - proc testPairs(): bool = - let obj = newJsObject() - var working = true - obj.a = 10 - obj.b = 20 - obj.c = 30 - for k, v in obj.pairs: - case $k - of "a": - working = working and v.to(int) == 10 - of "b": - working = working and v.to(int) == 20 - of "c": - working = working and v.to(int) == 30 - else: - return false - working - proc testItems(): bool = - let obj = newJsObject() - var working = true - obj.a = 10 - obj.b = 20 - obj.c = 30 - for v in obj.items: - working = working and v.to(int) in [10, 20, 30] - working - proc testKeys(): bool = - let obj = newJsObject() - var working = true - obj.a = 10 - obj.b = 20 - obj.c = 30 - for v in obj.keys: - working = working and $v in ["a", "b", "c"] - working - proc test(): bool = testPairs() and testItems() and testKeys() - echo test() +block: # testPairs + let obj = newJsObject() + obj.a = 10 + obj.b = 20 + obj.c = 30 + for k, v in obj.pairs: + case $k + of "a": + doAssert v.to(int) == 10 + of "b": + doAssert v.to(int) == 20 + of "c": + doAssert v.to(int) == 30 + else: + doAssert false +block: # testItems + let obj = newJsObject() + obj.a = 10 + obj.b = 20 + obj.c = 30 + for v in obj.items: + doAssert v.to(int) in [10, 20, 30] +block: # testKeys + let obj = newJsObject() + obj.a = 10 + obj.b = 20 + obj.c = 30 + for v in obj.keys: + doAssert $v in ["a", "b", "c"] -# Test JsObject equality -block: - proc test(): bool = - {. emit: "var comparison = {a: 22, b: 'test'};" .} - var comparison {. importjs, nodecl .}: JsObject - let obj = newJsObject() - obj.a = 22 - obj.b = "test".cstring - obj.a == comparison.a and obj.b == comparison.b - echo test() +block: # Test JsObject equality + {. emit: "var comparison = {a: 22, b: 'test'};" .} + var comparison {. importjs, nodecl .}: JsObject + let obj = newJsObject() + obj.a = 22 + obj.b = "test".cstring + doAssert obj.a == comparison.a and obj.b == comparison.b -# Test JsObject literal -block: - proc test(): bool = - {. emit: "var comparison = {a: 22, b: 'test'};" .} - var comparison {. importjs, nodecl .}: JsObject - let obj = JsObject{ a: 22, b: "test".cstring } - obj.a == comparison.a and obj.b == comparison.b - echo test() +block: # Test JsObject literal + {. emit: "var comparison = {a: 22, b: 'test'};" .} + var comparison {. importjs, nodecl .}: JsObject + let obj = JsObject{ a: 22, b: "test".cstring } + doAssert obj.a == comparison.a and obj.b == comparison.b # Tests for JsAssoc -# Test JsAssoc []= and [] -block: - proc test(): bool = - let obj = newJsAssoc[int, int]() - var working = true - obj[1] = 11 - working = working and not compiles(obj["a"] = 11) - working = working and not compiles(obj["a"]) - working = working and not compiles(obj[2] = "test") - working = working and not compiles(obj[3] = "test".cstring) - working = working and obj[1] == 11 - working - echo test() +block: # Test JsAssoc []= and [] + let obj = newJsAssoc[int, int]() + obj[1] = 11 + doAssert not compiles(obj["a"] = 11) + doAssert not compiles(obj["a"]) + doAssert not compiles(obj[2] = "test") + doAssert not compiles(obj[3] = "test".cstring) + doAssert obj[1] == 11 -# Test JsAssoc .= and . -block: - proc test(): bool = - let obj = newJsAssoc[cstring, int]() - var working = true - obj.a = 11 - obj.`$!&` = 42 - working = working and not compiles(obj.b = "test") - working = working and not compiles(obj.c = "test".cstring) - working = working and obj.a == 11 - working = working and obj.`$!&` == 42 - working - echo test() +block: # Test JsAssoc .= and . + let obj = newJsAssoc[cstring, int]() + var working = true + obj.a = 11 + obj.`$!&` = 42 + doAssert not compiles(obj.b = "test") + doAssert not compiles(obj.c = "test".cstring) + doAssert obj.a == 11 + doAssert obj.`$!&` == 42 -# Test JsAssoc .() -block: - proc test(): bool = - let obj = newJsAssoc[cstring, proc(e: int): int]() - obj.a = proc(e: int): int = e * e - obj.a(10) == 100 - echo test() +block: # Test JsAssoc .() + let obj = newJsAssoc[cstring, proc(e: int): int]() + obj.a = proc(e: int): int = e * e + doAssert obj.a(10) == 100 -# Test JsAssoc []() -block: - proc test(): bool = - let obj = newJsAssoc[cstring, proc(e: int): int]() - obj.a = proc(e: int): int = e * e - let call = obj["a"] - call(10) == 100 - echo test() +block: # Test JsAssoc []() + let obj = newJsAssoc[cstring, proc(e: int): int]() + obj.a = proc(e: int): int = e * e + let call = obj["a"] + doAssert call(10) == 100 # Test JsAssoc Iterators -block: - proc testPairs(): bool = - let obj = newJsAssoc[cstring, int]() - var working = true - obj.a = 10 - obj.b = 20 - obj.c = 30 - for k, v in obj.pairs: - case $k - of "a": - working = working and v == 10 - of "b": - working = working and v == 20 - of "c": - working = working and v == 30 - else: - return false - working - proc testItems(): bool = - let obj = newJsAssoc[cstring, int]() - var working = true - obj.a = 10 - obj.b = 20 - obj.c = 30 - for v in obj.items: - working = working and v in [10, 20, 30] - working - proc testKeys(): bool = - let obj = newJsAssoc[cstring, int]() - var working = true - obj.a = 10 - obj.b = 20 - obj.c = 30 - for v in obj.keys: - working = working and v in [cstring"a", cstring"b", cstring"c"] - working - proc test(): bool = testPairs() and testItems() and testKeys() - echo test() +block: # testPairs + let obj = newJsAssoc[cstring, int]() + obj.a = 10 + obj.b = 20 + obj.c = 30 + for k, v in obj.pairs: + case $k + of "a": + doAssert v == 10 + of "b": + doAssert v == 20 + of "c": + doAssert v == 30 + else: + doAssert false +block: # testItems + let obj = newJsAssoc[cstring, int]() + obj.a = 10 + obj.b = 20 + obj.c = 30 + for v in obj.items: + doAssert v in [10, 20, 30] +block: # testKeys + let obj = newJsAssoc[cstring, int]() + obj.a = 10 + obj.b = 20 + obj.c = 30 + for v in obj.keys: + doAssert v in [cstring"a", cstring"b", cstring"c"] -# Test JsAssoc equality -block: - proc test(): bool = - {. emit: "var comparison = {a: 22, b: 55};" .} - var comparison {. importjs, nodecl .}: JsAssoc[cstring, int] - let obj = newJsAssoc[cstring, int]() - obj.a = 22 - obj.b = 55 - obj.a == comparison.a and obj.b == comparison.b - echo test() +block: # Test JsAssoc equality + {. emit: "var comparison = {a: 22, b: 55};" .} + var comparison {. importjs, nodecl .}: JsAssoc[cstring, int] + let obj = newJsAssoc[cstring, int]() + obj.a = 22 + obj.b = 55 + doAssert obj.a == comparison.a and obj.b == comparison.b -# Test JsAssoc literal -block: - proc test(): bool = - {. emit: "var comparison = {a: 22, b: 55};" .} - var comparison {. importjs, nodecl .}: JsAssoc[cstring, int] - let obj = JsAssoc[cstring, int]{ a: 22, b: 55 } - var working = true - working = working and - compiles(JsAssoc[int, int]{ 1: 22, 2: 55 }) - working = working and - comparison.a == obj.a and comparison.b == obj.b - working = working and - not compiles(JsAssoc[cstring, int]{ a: "test" }) - working - echo test() +block: # Test JsAssoc literal + {. emit: "var comparison = {a: 22, b: 55};" .} + var comparison {. importjs, nodecl .}: JsAssoc[cstring, int] + let obj = JsAssoc[cstring, int]{ a: 22, b: 55 } + doAssert compiles(JsAssoc[int, int]{ 1: 22, 2: 55 }) + doAssert comparison.a == obj.a and comparison.b == obj.b + doAssert not compiles(JsAssoc[cstring, int]{ a: "test" }) # Tests for macros on non-JsRoot objects -# Test lit -block: +block: # Test lit type TestObject = object a: int b: cstring - proc test(): bool = - {. emit: "var comparison = {a: 1};" .} - var comparison {. importjs, nodecl .}: TestObject - let obj = TestObject{ a: 1 } - obj == comparison - echo test() + {. emit: "var comparison = {a: 1};" .} + var comparison {. importjs, nodecl .}: TestObject + let obj = TestObject{ a: 1 } + doAssert obj == comparison -# Test bindMethod -block: +block: # Test bindMethod type TestObject = object a: int - onWhatever: proc(e: int): int + onWhatever: proc(e: int): int {.nimcall.} proc handleWhatever(this: TestObject, e: int): int = e + this.a - proc test(): bool = + block: let obj = TestObject(a: 9, onWhatever: bindMethod(handleWhatever)) - obj.onWhatever(1) == 10 - echo test() + doAssert obj.onWhatever(1) == 10 block: {.emit: "function jsProc(n) { return n; }" .} proc jsProc(x: int32): JsObject {.importjs: "jsProc(#)".} - - proc test() = + block: var x = jsProc(1) var y = jsProc(2) console.log x + y @@ -294,8 +200,6 @@ block: x += jsProc(10) console.log x - test() - block: {.emit: """ @@ -314,7 +218,7 @@ block: on("click") do (e: Event): console.log e - jslib.on("reloaded") do: + jslib.on("reloaded") do (): console.log jsarguments[0] # this test case is different from the above, because @@ -323,11 +227,48 @@ block: console.log jsarguments[0] block: + doAssert jsUndefined == jsNull + doAssert jsUndefined == nil + doAssert jsNull == nil + doAssert jsUndefined.isNil + doAssert jsNull.isNil + doAssert jsNull.isNull + doAssert jsUndefined.isUndefined + +block: # test ** + var a = toJs(0) + var b = toJs(0) + doAssert to(a ** b, int) == 1 + a = toJs(1) + b = toJs(1) + doAssert to(a ** b, int) == 1 + a = toJs(-1) + b = toJs(-1) + doAssert to(a ** b, int) == -1 + a = toJs(6) + b = toJs(6) + doAssert to(a ** b, int) == 46656 + a = toJs(5.5) + b = toJs(3) + doAssert to(a ** b, float) == 166.375 + a = toJs(5) + b = toJs(3.0) + doAssert to(a ** b, float) == 125.0 + a = toJs(7.0) + b = toJS(6.0) + doAssert to(a ** b, float) == 117649.0 + a = toJs(8) + b = toJS(-2) + doAssert to(a ** b, float) == 0.015625 + + a = toJs(1) + b = toJs(1) + doAssert to(`**`(a + a, b), int) == 2 + + doAssert to(`**`(toJs(1) + toJs(1), toJs(2)), int) == 4 - echo jsUndefined == jsNull - echo jsUndefined == nil - echo jsNull == nil - echo jsUndefined.isNil - echo jsNull.isNil - echo jsNull.isNull - echo jsUndefined.isUndefined +block: # issue #21208 + type MyEnum = enum baz + var obj: JsObject + {.emit: "`obj` = {bar: {baz: 123}};".} + discard obj.bar.baz diff --git a/tests/js/tjsffi_old.nim b/tests/js/tjsffi_old.nim index 1f149694b..378003f4e 100644 --- a/tests/js/tjsffi_old.nim +++ b/tests/js/tjsffi_old.nim @@ -35,6 +35,9 @@ true ## same as tjsffi, but this test uses the old names: importc and ## importcpp. This test is for backwards compatibility. +# xxx instead of maintaining this near-duplicate test file, just have tests +# that check that importc, importcpp, importjs work and remove this file. + import jsffi, jsconsole # Tests for JsObject @@ -276,8 +279,8 @@ block: block: type TestObject = object a: int - onWhatever: proc(e: int): int - proc handleWhatever(this: TestObject, e: int): int = + onWhatever: proc(e: int): int {.nimcall.} + proc handleWhatever(this: TestObject, e: int): int {.nimcall.} = e + this.a proc test(): bool = let obj = TestObject(a: 9, onWhatever: bindMethod(handleWhatever)) @@ -318,7 +321,7 @@ block: on("click") do (e: Event): console.log e - jslib.on("reloaded") do: + jslib.on("reloaded") do (): console.log jsarguments[0] # this test case is different from the above, because diff --git a/tests/js/tjshello.nim b/tests/js/tjshello.nim index 19e0b90ae..8e090b3d2 100644 --- a/tests/js/tjshello.nim +++ b/tests/js/tjshello.nim @@ -1,4 +1,5 @@ discard """ + cmd: "nim $target $options --stackTrace:off --lineTrace:off $file" output: "Hello World" maxcodesize: 1000 ccodecheck: "!@'function'" @@ -7,4 +8,3 @@ discard """ import jsconsole console.log "Hello World" - diff --git a/tests/js/tjshello_stacktrace.nim b/tests/js/tjshello_stacktrace.nim new file mode 100644 index 000000000..d5e1c36eb --- /dev/null +++ b/tests/js/tjshello_stacktrace.nim @@ -0,0 +1,9 @@ +discard """ + output: "Hello World" + maxcodesize: 4500 + ccodecheck: "!@'function'" +""" + +import jsconsole + +console.log "Hello World" diff --git a/tests/js/tjsnimscombined.nim b/tests/js/tjsnimscombined.nim new file mode 100644 index 000000000..4d3e6c453 --- /dev/null +++ b/tests/js/tjsnimscombined.nim @@ -0,0 +1 @@ +import std/jsffi diff --git a/tests/js/tjsnimscombined.nims b/tests/js/tjsnimscombined.nims new file mode 100644 index 000000000..01b93d3fa --- /dev/null +++ b/tests/js/tjsnimscombined.nims @@ -0,0 +1 @@ +# test the condition where both `js` and `nimscript` are defined (nimscript receives priority) diff --git a/tests/js/tlent.nim b/tests/js/tlent.nim new file mode 100644 index 000000000..2546e5b1d --- /dev/null +++ b/tests/js/tlent.nim @@ -0,0 +1,33 @@ +discard """ + output: ''' +hmm +100 +hmm +100 +''' +""" + +# #16800 + +type A = object + b: int +var t = A(b: 100) +block: + proc getValues: lent int = + echo "hmm" + result = t.b + echo getValues() +block: + proc getValues: lent int = + echo "hmm" + t.b + echo getValues() + +when false: # still an issue, #16908 + template main = + iterator fn[T](a:T): lent T = yield a + let a = @[10] + for b in fn(a): echo b + + static: main() + main() diff --git a/tests/js/tmangle.nim b/tests/js/tmangle.nim index c97bf7029..caaa15fa1 100644 --- a/tests/js/tmangle.nim +++ b/tests/js/tmangle.nim @@ -62,8 +62,8 @@ block: result = result and obj1.`&&`.addr[] == "bar".cstring result = result and obj2.`if` == 0 result = result and obj2.`for` == 0 - result = result and obj2.`==`.isNil() - result = result and obj2.`&&`.isNil() + result = result and obj2.`==`.isNil + result = result and obj2.`&&`.isNil echo test() # Test codegen for fields with uppercase letters: diff --git a/tests/js/tmodify_cstring.nim b/tests/js/tmodify_cstring.nim new file mode 100644 index 000000000..82f8ccb23 --- /dev/null +++ b/tests/js/tmodify_cstring.nim @@ -0,0 +1,6 @@ +discard """ + errormsg: "cstring doesn't support `[]=` operator" +""" + +var x = cstring"abcd" +x[0] = 'x' diff --git a/tests/js/tnativeexc.nim b/tests/js/tnativeexc.nim index ea371c1cd..8b2b43e8f 100644 --- a/tests/js/tnativeexc.nim +++ b/tests/js/tnativeexc.nim @@ -18,7 +18,7 @@ try: except JsEvalError: doAssert false except JsSyntaxError as se: - doAssert se.message == "Unexpected token ; in JSON at position 0" + doAssert se.message == "Unexpected token ';', \";;\" is not valid JSON" except JsError as e: doAssert false diff --git a/tests/js/tneginthash.nim b/tests/js/tneginthash.nim new file mode 100644 index 000000000..c082405c9 --- /dev/null +++ b/tests/js/tneginthash.nim @@ -0,0 +1,21 @@ +# issue #19929 + +import std/[tables, hashes] + +type Foo = object + a: int + +proc hash(f: Foo): Hash = + var h: Hash = 0 + h = h !& hash(f.a) + result = !$h + +proc transpose[T, S](data: array[T, S]): Table[S, T] = + for i, x in data: + result[x] = i + +const xs = [Foo(a: 5), Foo(a: -5)] +const x = transpose(xs) + +doAssert x[Foo(a: -5)] == 1 +doAssert x[Foo(a: 5)] == 0 diff --git a/tests/js/tnilstrs.nim b/tests/js/tnilstrs.nim index c0048cb24..6c1e4e401 100644 --- a/tests/js/tnilstrs.nim +++ b/tests/js/tnilstrs.nim @@ -14,4 +14,12 @@ block: var x = "foo".cstring var y: string add(y, x) - doAssert y == "foo" \ No newline at end of file + doAssert y == "foo" + +block: + type Foo = object + a: string + var foo = Foo(a: "foo") + var y = move foo.a + doAssert foo.a.len == 0 + doAssert y == "foo" diff --git a/tests/js/tos.nim b/tests/js/tos.nim new file mode 100644 index 000000000..40fb52bcf --- /dev/null +++ b/tests/js/tos.nim @@ -0,0 +1,21 @@ +# xxx consider merging this in tests/stdlib/tos.nim for increased coverage (with selecting disabling) + +static: doAssert defined(nodejs) + +import os + +block: + doAssert "./foo//./bar/".normalizedPath == "foo/bar" + doAssert relativePath(".//foo/bar", "foo") == "bar" + doAssert "/".isAbsolute + doAssert not "".isAbsolute + doAssert not ".".isAbsolute + doAssert not "foo".isAbsolute + doAssert relativePath("", "bar") == "" + doAssert normalizedPath(".///foo//./") == "foo" + + when nimvm: discard + else: + let cwd = getCurrentDir() + doAssert cwd.isAbsolute + doAssert relativePath(getCurrentDir() / "foo", "bar") == ".." / "foo" diff --git a/tests/js/trepr.nim b/tests/js/trepr.nim index 366d247c5..a562ad63b 100644 --- a/tests/js/trepr.nim +++ b/tests/js/trepr.nim @@ -1,6 +1,4 @@ -discard """ - action: run -""" +# xxx consider merging with `tests/stdlib/trepr.nim` to increase overall test coverage block ints: let @@ -137,15 +135,13 @@ block tuples: when defined js: doAssert(repr(ot) == """ [Field0 = true, -Field1 = 120] -""") +Field1 = 120]""") doAssert(repr(t) == """ [Field0 = 42, Field1 = 12.34, Field2 = "tuple", Field3 = [Field0 = true, -Field1 = 120]] -""") +Field1 = 120]]""") block objects: type @@ -162,14 +158,12 @@ block objects: doAssert(repr(oo) == """ [a = true, -b = 120] -""") +b = 120]""") doAssert(repr(o) == """ [a = 42, b = 12.34, c = [a = true, -b = 120]] -""") +b = 120]]""") block arrays: type @@ -183,15 +177,14 @@ block arrays: c = [o, o, o] d = ["hi", "array", "!"] - doAssert(repr(a) == "[0.0, 1.0, 2.0]\n") - doAssert(repr(b) == "[[0.0, 1.0, 2.0], [0.0, 1.0, 2.0], [0.0, 1.0, 2.0]]\n") + doAssert(repr(a) == "[0.0, 1.0, 2.0]") + doAssert(repr(b) == "[[0.0, 1.0, 2.0], [0.0, 1.0, 2.0], [0.0, 1.0, 2.0]]") doAssert(repr(c) == """ [[x = 42, y = [0.0, 1.0, 2.0]], [x = 42, y = [0.0, 1.0, 2.0]], [x = 42, -y = [0.0, 1.0, 2.0]]] -""") - doAssert(repr(d) == "[\"hi\", \"array\", \"!\"]\n") +y = [0.0, 1.0, 2.0]]]""") + doAssert(repr(d) == "[\"hi\", \"array\", \"!\"]") block seqs: type @@ -205,15 +198,14 @@ block seqs: c = @[o, o, o] d = @["hi", "array", "!"] - doAssert(repr(a) == "@[0.0, 1.0, 2.0]\n") - doAssert(repr(b) == "@[@[0.0, 1.0, 2.0], @[0.0, 1.0, 2.0], @[0.0, 1.0, 2.0]]\n") + doAssert(repr(a) == "@[0.0, 1.0, 2.0]") + doAssert(repr(b) == "@[@[0.0, 1.0, 2.0], @[0.0, 1.0, 2.0], @[0.0, 1.0, 2.0]]") doAssert(repr(c) == """ @[[x = 42, y = @[0.0, 1.0, 2.0]], [x = 42, y = @[0.0, 1.0, 2.0]], [x = 42, -y = @[0.0, 1.0, 2.0]]] -""") - doAssert(repr(d) == "@[\"hi\", \"array\", \"!\"]\n") +y = @[0.0, 1.0, 2.0]]]""") + doAssert(repr(d) == "@[\"hi\", \"array\", \"!\"]") block ptrs: type @@ -226,13 +218,12 @@ block ptrs: c = addr a[2] d = AObj() - doAssert(repr(a) == "[12.0, 13.0, 14.0]\n") - doAssert(repr(b) == "ref 0 --> 12.0\n") - doAssert(repr(c) == "ref 2 --> 14.0\n") + doAssert(repr(a) == "[12.0, 13.0, 14.0]") + doAssert(repr(b) == "ref 0 --> 12.0") + doAssert(repr(c) == "ref 2 --> 14.0") doAssert(repr(d) == """ [x = nil, -y = 0] -""") +y = 0]""") block ptrs: type @@ -248,8 +239,7 @@ block ptrs: [x = ref 0 --> [[x = nil, y = 0], [x = nil, y = 0]], -y = 0] -""") +y = 0]""") block procs: proc test(): int = @@ -258,9 +248,9 @@ block procs: ptest = test nilproc: proc(): int - doAssert(repr(test) == "0\n") - doAssert(repr(ptest) == "0\n") - doAssert(repr(nilproc) == "nil\n") + doAssert(repr(test) == "0") + doAssert(repr(ptest) == "0") + doAssert(repr(nilproc) == "nil") block bunch: type @@ -293,7 +283,7 @@ block bunch: result[] = b var - aa: A + aa = default(A) bb: B = B(a: "inner", b: @['o', 'b', 'j']) cc: A = A(a: 12, b: 1, c: 1.2, d: '\0', e: eC, f: "hello", g: {'A'}, h: {2'i16}, @@ -308,22 +298,21 @@ b = 0, c = 0.0, d = '\0', e = eA, -f = nil, +f = "", g = {}, h = {}, -i = [nil, nil, nil], -j = nil, -k = 0, -l = [a = nil, -b = nil], +i = ["", "", ""], +j = @[], +k = -12, +l = [a = "", +b = @[]], m = nil, n = nil, -o = [Field0 = [a = nil, -b = nil], -Field1 = nil], +o = [Field0 = [a = "", +b = @[]], +Field1 = ""], p = nil, -q = nil] -""") +q = nil]""") doAssert(repr(cc) == """ [a = 12, b = 1, @@ -346,8 +335,7 @@ o = [Field0 = [a = "inner", b = @['o', 'b', 'j']], Field1 = "tuple!"], p = 0, -q = "cstringtest"] -""") +q = "cstringtest"]""") block another: type @@ -358,9 +346,9 @@ block another: Size3 = enum s3e=0, s3f=2000000000 - doAssert(repr([s1a, s1b]) == "[s1a, s1b]\n") - doAssert(repr([s2c, s2d]) == "[s2c, s2d]\n") - doAssert(repr([s3e, s3f]) == "[s3e, s3f]\n") + doAssert(repr([s1a, s1b]) == "[s1a, s1b]") + doAssert(repr([s2c, s2d]) == "[s2c, s2d]") + doAssert(repr([s3e, s3f]) == "[s3e, s3f]") block another2: @@ -395,15 +383,13 @@ block another2: y = 13, z = 45, s = ["abc", "xyz"], -e = en6] -""") +e = en6]""") doAssert(repr(q) == """ ref 0 --> [x = 0, y = 13, z = 45, s = ["abc", "xyz"], -e = en6] -""") +e = en6]""") doAssert(repr(s) == """ @[ref 0 --> [x = 0, y = 13, @@ -421,8 +407,7 @@ e = en6], ref 3 --> [x = 0, y = 13, z = 45, s = ["abc", "xyz"], -e = en6]] -""") +e = en6]]""") doAssert(repr(en4) == "en4") doAssert(repr({'a'..'p'}) == "{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p'}") diff --git a/tests/js/treprinifexpr.nim b/tests/js/treprinifexpr.nim new file mode 100644 index 000000000..09ded18b9 --- /dev/null +++ b/tests/js/treprinifexpr.nim @@ -0,0 +1,18 @@ +type + Enum = enum A + +let + enumVal = A + tmp = if true: $enumVal else: $enumVal + +let + intVal = 12 + tmp2 = if true: repr(intVal) else: $enumVal + +let + strVal = "123" + tmp3 = if true: repr(strVal) else: $strVal + +let + floatVal = 12.4 + tmp4 = if true: repr(floatVal) else: $floatVal \ No newline at end of file diff --git a/tests/js/tseqops.nim b/tests/js/tseqops.nim index af664222c..8cfb50886 100644 --- a/tests/js/tseqops.nim +++ b/tests/js/tseqops.nim @@ -1,11 +1,3 @@ -discard """ - output: '''(x: 0, y: 0) -(x: 5, y: 0) -@[(x: "2", y: 4), (x: "4", y: 5), (x: "4", y: 5)] -@[(a: "3", b: 3), (a: "1", b: 1), (a: "2", b: 2)] -''' -""" - # bug #4139 type @@ -17,8 +9,8 @@ proc onLoad() = var foo = TestO(x: 0, y: 0) test.add(foo) foo.x = 5 - echo(test[0]) - echo foo + doAssert $test[0] == "(x: 0, y: 0)" + doAssert $foo == "(x: 5, y: 0)" onLoad() @@ -34,7 +26,7 @@ proc foo(x: var seq[MyObj]) = var s = @[MyObj(x: "2", y: 4), MyObj(x: "4", y: 5)] foo(s) -echo s +doAssert $s == """@[(x: "2", y: 4), (x: "4", y: 5), (x: "4", y: 5)]""" # bug #5933 import sequtils @@ -48,4 +40,9 @@ var test = @[Test(a: "1", b: 1), Test(a: "2", b: 2)] test.insert(@[Test(a: "3", b: 3)], 0) -echo test +doAssert $test == """@[(a: "3", b: 3), (a: "1", b: 1), (a: "2", b: 2)]""" + +proc hello(): array[5, int] = discard +var x = @(hello()) +x.add(2) +doAssert x == @[0, 0, 0, 0, 0, 2] diff --git a/tests/js/tsourcemap.nim b/tests/js/tsourcemap.nim new file mode 100644 index 000000000..d358e4a57 --- /dev/null +++ b/tests/js/tsourcemap.nim @@ -0,0 +1,96 @@ +discard """ + action: "run" + targets: "js" + cmd: "nim js -r -d:nodejs $options --sourceMap:on $file" +""" +import std/[os, json, strutils, sequtils, algorithm, assertions, paths, compilesettings] + +# Implements a very basic sourcemap parser and then runs it on itself. +# Allows to check for basic problems such as bad counts and lines missing (e.g. issue #21052) + +type + SourceMap = object + version: int + sources: seq[string] + names: seq[string] + mappings: string + file: string + + Line = object + line, column: int + file: string + +const + flag = 1 shl 5 + signBit = 0b1 + fourBits = 0b1111 + fiveBits = 0b11111 + mask = (1 shl 5) - 1 + alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" + +var b64Table: seq[int] = 0.repeat(max(alphabet.mapIt(it.ord)) + 1) +for i, b in alphabet.pairs: + b64Table[b.ord] = i + +# From https://github.com/juancarlospaco/nodejs/blob/main/src/nodejs/jsfs.nim +proc importFs*() {.importjs: "var fs = require(\"fs\");".} +proc readFileSync*(path: cstring): cstring {.importjs: "(fs.$1(#).toString())".} +importFS() +# Read in needed files +let + jsFileName = string(querySetting(outDir).Path / "tsourcemap.js".Path) + mapFileName = jsFileName & ".map" + + data = parseJson($mapFileName.cstring.readFileSync()).to(SourceMap) + jsFile = $readFileSync(jsFileName.cstring) + +proc decodeVLQ(inp: string): seq[int] = + var + shift, value: int + for v in inp.mapIt(b64Table[it.ord]): + value += (v and mask) shl shift + if (v and flag) > 0: + shift += 5 + continue + result &= (value shr 1) * (if (value and 1) > 0: -1 else: 1) + shift = 0 + value = 0 + + +# Keep track of state +var + line = 0 + source = 0 + name = 0 + column = 0 + jsLine = 1 + lines: seq[Line] + +for gline in data.mappings.split(';'): + jsLine += 1 + var jsColumn = 0 + for item in gline.strip().split(','): + let value = item.decodeVLQ() + doAssert value.len in [0, 1, 4, 5] + if value.len == 0: + continue + jsColumn += value[0] + if value.len >= 4: + source += value[1] + line += value[2] + column += value[3] + lines &= Line(line: line, column: column, file: data.sources[source]) + +let jsLines = jsFile.splitLines().len +# There needs to be a mapping for every line in the JS +# If there isn't then the JS lines wont match up with Nim lines. +# Except we don't care about the final line since that doesn't need to line up +doAssert data.mappings.count(';') == jsLines - 1 + +# Check we can find this file somewhere in the source map +var foundSelf = false +for line in lines: + if "tsourcemap.nim" in line.file: + foundSelf = true + doAssert line.line in 0..<jsLines, "Lines is out of bounds for file" +doAssert foundSelf, "Couldn't find tsourcemap.nim in source map" diff --git a/tests/js/tstdlib_imports.nim b/tests/js/tstdlib_imports.nim new file mode 100644 index 000000000..db851ba28 --- /dev/null +++ b/tests/js/tstdlib_imports.nim @@ -0,0 +1,80 @@ +discard """ + action: compile +""" + +{.warning[UnusedImport]: off.} + +when defined(nimPreviewSlimSystem): + import std/[ + syncio, assertions, formatfloat, objectdollar, widestrs + ] + +import std/[ + # Core: + bitops, typetraits, lenientops, macros, volatile, typeinfo, + # fails due to FFI: rlocks + # fails due to cstring cast/copyMem: endians + # works but uses FFI: cpuinfo, locks + + # Algorithms: + algorithm, enumutils, sequtils, setutils, + + # Collections: + critbits, deques, heapqueue, intsets, lists, options, sets, + tables, packedsets, + + # Strings: + cstrutils, editdistance, wordwrap, parseutils, ropes, + pegs, strformat, strmisc, strscans, strtabs, + strutils, unicode, unidecode, + # fails due to FFI: encodings + + # Time handling: + monotimes, times, + + # Generic operator system services: + os, streams, + # fails intentionally: dynlib, marshal, memfiles + # fails due to FFI: osproc, terminal + # fails due to osproc import: distros + + # Math libraries: + complex, math, random, rationals, stats, sums, sysrand, + # works but uses FFI: fenv + + # Internet protocols: + cookies, httpcore, mimetypes, uri, + # fails due to FFI: asyncdispatch, asyncfile, asyncftpclient, asynchttpserver, + # asyncnet, cgi, httpclient, nativesockets, net, selectors + # works but no need to test: asyncstreams, asyncfutures + + # Threading: + # fails due to FFI: threadpool + + # Parsers: + htmlparser, json, lexbase, parsecfg, parsecsv, parsesql, parsexml, + parseopt, jsonutils, + + # XML processing: + xmltree, xmlparser, + + # Generators: + htmlgen, + + # Hashing: + base64, hashes, + # fails due to cstring cast/endians import: oids + # fails due to copyMem/endians import: sha1 + + # Miscellaneous: + colors, logging, sugar, unittest, varints, enumerate, with, + # fails due to FFI: browsers, coro + # works but uses FFI: segfaults + + # Modules for JS backend: + asyncjs, dom, jsconsole, jscore, jsffi, jsbigints, + + # Unlisted in lib.html: + decls, compilesettings, wrapnils, exitprocs, effecttraits, + genasts, importutils, isolation, jsfetch, jsformdata, jsheaders +] diff --git a/tests/js/tstdlib_various.nim b/tests/js/tstdlib_various.nim new file mode 100644 index 000000000..1e584f735 --- /dev/null +++ b/tests/js/tstdlib_various.nim @@ -0,0 +1,174 @@ +discard """ +output: ''' +abc +def +definition +prefix +xyz +def +definition +Hi Andreas! How do you feel, Rumpf? + +@[0, 2, 1] +@[1, 0, 2] +@[1, 2, 0] +@[2, 0, 1] +@[2, 1, 0] +@[2, 0, 1] +@[1, 2, 0] +@[1, 0, 2] +@[0, 2, 1] +@[0, 1, 2] +[5] +[4, 5] +[3, 4, 5] +[2, 3, 4, 5] +[2, 3, 4, 5, 6] +[1, 2, 3, 4, 5, 6] +''' +""" + +import + critbits, sets, strutils, tables, random, algorithm, ropes, + lists, htmlgen, xmltree, strtabs + + +block tcritbits: + var r: CritBitTree[void] + r.incl "abc" + r.incl "xyz" + r.incl "def" + r.incl "definition" + r.incl "prefix" + doAssert r.contains"def" + #r.del "def" + + for w in r.items: + echo w + for w in r.itemsWithPrefix("de"): + echo w + + + +block testequivalence: + doAssert(toHashSet(@[1,2,3]) <= toHashSet(@[1,2,3,4]), "equivalent or subset") + doAssert(toHashSet(@[1,2,3]) <= toHashSet(@[1,2,3]), "equivalent or subset") + doAssert((not(toHashSet(@[1,2,3]) <= toHashSet(@[1,2]))), "equivalent or subset") + doAssert(toHashSet(@[1,2,3]) <= toHashSet(@[1,2,3,4]), "strict subset") + doAssert((not(toHashSet(@[1,2,3]) < toHashSet(@[1,2,3]))), "strict subset") + doAssert((not(toHashSet(@[1,2,3]) < toHashSet(@[1,2]))), "strict subset") + doAssert((not(toHashSet(@[1,2,3]) == toHashSet(@[1,2,3,4]))), "==") + doAssert(toHashSet(@[1,2,3]) == toHashSet(@[1,2,3]), "==") + doAssert((not(toHashSet(@[1,2,3]) == toHashSet(@[1,2]))), "==") + + + +block tformat: + echo("Hi $1! How do you feel, $2?\n" % ["Andreas", "Rumpf"]) + + + +block tnilecho: + var x = @["1", "", "3"] + doAssert $x == """@["1", "", "3"]""" + + + +block torderedtable: + var t = initOrderedTable[int,string]() + + # this tests issue #5917 + var data = newSeq[int]() + for i in 0..<1000: + var x = rand(1000) + if x notin t: data.add(x) + t[x] = "meh" + + # this checks that keys are re-inserted + # in order when table is enlarged. + var i = 0 + for k, v in t: + doAssert(k == data[i]) + doAssert(v == "meh") + inc(i) + + + +block tpermutations: + var v = @[0, 1, 2] + while v.nextPermutation(): + echo v + while v.prevPermutation(): + echo v + + +block tropes: + var + r1 = rope("") + r2 = rope("123") + doAssert r1.len == 0 + doAssert r2.len == 3 + doAssert $r1 == "" + doAssert $r2 == "123" + + r1.add("123") + r2.add("456") + doAssert r1.len == 3 + doAssert r2.len == 6 + doAssert $r1 == "123" + doAssert $r2 == "123456" + doAssert $r1[1] == "2" + doAssert $r2[2] == "3" + + +block tsinglylinkedring: + var r = initSinglyLinkedRing[int]() + r.prepend(5) + echo r + r.prepend(4) + echo r + r.prepend(3) + echo r + r.prepend(2) + echo r + r.append(6) + echo r + r.prepend(1) + echo r + +block tsplit: + var s = "" + for w in split("|abc|xy|z", {'|'}): + s.add("#") + s.add(w) + + doAssert s == "##abc#xy#z" + +block tsplit2: + var s = "" + for w in split("|abc|xy|z", {'|'}): + s.add("#") + s.add(w) + + doAssert "true".split("") == @["true"] + +block txmlgen: + var nim = "Nim" + doAssert h1(a(href="http://force7.de/nim", nim)) == + "<h1><a href=\"http://force7.de/nim\">Nim</a></h1>" + +block txmltree: + var x = <>a(href="nim.de", newText("www.nim-test.de")) + + doAssert($x == "<a href=\"nim.de\">www.nim-test.de</a>") + doAssert(newText("foo").innerText == "foo") + doAssert(newEntity("bar").innerText == "bar") + doAssert(newComment("baz").innerText == "") + + let y = newXmlTree("x", [ + newText("foo"), + newXmlTree("y", [ + newText("bar") + ]) + ]) + doAssert(y.innerText == "foobar") diff --git a/tests/js/tstreams.nim b/tests/js/tstreams.nim new file mode 100644 index 000000000..43c26e01a --- /dev/null +++ b/tests/js/tstreams.nim @@ -0,0 +1,22 @@ +discard """ + output: ''' +I +AM +GROOT +''' +""" + +import streams + +var s = newStringStream("I\nAM\nGROOT") +doAssert s.peekStr(1) == "I" +doAssert s.peekChar() == 'I' +for line in s.lines: + echo line +s.close + +var s2 = newStringStream("abc") +doAssert s2.readAll == "abc" +s2.write("def") +doAssert s2.data == "abcdef" +s2.close diff --git a/tests/js/ttempgen.nim b/tests/js/ttempgen.nim new file mode 100644 index 000000000..badc66c1b --- /dev/null +++ b/tests/js/ttempgen.nim @@ -0,0 +1,79 @@ +discard """ + output: ''' +foo +''' +""" + +block: # #12672 + var a = @[1] + let i = 1 + inc a[i-1] + + var b: seq[int] + doAssertRaises(IndexDefect): inc b[0] + doAssertRaises(IndexDefect): inc b[i-1] + + var x: seq[seq[int]] + doAssertRaises(IndexDefect): # not TypeError + inc x[0][i-1] + +block: # #14087 + type Obj = object + str: string + + var s = @[Obj(str: "abc"), Obj(str: "def")] + s[1].str.add("ghi") + s[s.len - 1].str.add("jkl") + s[^1].str.add("mno") + s[s.high].str.add("pqr") + + let slen = s.len + s[slen - 1].str.add("stu") + + let shigh = s.high + s[shigh].str.add("vwx") + + proc foo(): int = + echo "foo" + shigh + s[foo()].str.add("yz") + doAssert s[1].str == "defghijklmnopqrstuvwxyz" + +block: # #14117 + type + A = object + case kind: bool + of true: + sons: seq[int] + else: discard + + var a = A(kind: true) + doAssert a.sons.len == 0 + a.sons.add(1) + doAssert a.sons.len == 1 + +import tables + +block: # #13966 + var t: Table[int8, array[int8, seq[tuple[]]]] + + t[0] = default(array[int8, seq[tuple[]]]) + t[0][0].add () + +block: # #11783 + proc fun(): string = + discard + + var ret: string + ret.add fun() + doAssert ret == "" + +block: # #12256 + var x: bool + + doAssert x == false + + reset x + + doAssert x == false + doAssert x != true diff --git a/tests/js/ttypedarray.nim b/tests/js/ttypedarray.nim new file mode 100644 index 000000000..4807cb103 --- /dev/null +++ b/tests/js/ttypedarray.nim @@ -0,0 +1,26 @@ +discard """ + matrix: "--jsbigint64:off -d:nimStringHash2; --jsbigint64:on" +""" + +import std/private/jsutils + +proc main()= + template fn(a): untyped = jsConstructorName(a) + doAssert fn(array[2, int8].default) == "Int8Array" + doAssert fn(array[2, uint8].default) == "Uint8Array" + doAssert fn(array[2, byte].default) == "Uint8Array" + doAssert fn(array[2, char].default) == "Uint8Array" + whenJsNoBigInt64: discard + do: + doAssert fn(array[2, uint64].default) == "BigUint64Array" + doAssert fn([1'u8]) == "Uint8Array" + doAssert fn([1'u16]) == "Uint16Array" + doAssert fn([byte(1)]) == "Uint8Array" + doAssert fn([1.0'f32]) == "Float32Array" + doAssert fn(array[2, float32].default) == "Float32Array" + doAssert fn(array[2, float].default) == "Float64Array" + doAssert fn(array[2, float64].default) == "Float64Array" + doAssert fn([1.0]) == "Float64Array" + doAssert fn([1.0'f64]) == "Float64Array" + +main() diff --git a/tests/js/tunion.nim b/tests/js/tunion.nim new file mode 100644 index 000000000..e185495ad --- /dev/null +++ b/tests/js/tunion.nim @@ -0,0 +1,7 @@ +discard """ + errormsg: "`{.union.}` is not implemented for js backend." +""" + +type Foo {.union.} = object + as_bytes: array[8, int8] + data: int64 diff --git a/tests/js/tunittest_error.nim b/tests/js/tunittest_error.nim new file mode 100644 index 000000000..781e34338 --- /dev/null +++ b/tests/js/tunittest_error.nim @@ -0,0 +1,24 @@ +discard """ + exitcode: 1 + outputsub: "[FAILED] with exception" +""" + +# see also: `tests/stdlib/tunittest_error.nim` + +import unittest + +proc ddd() = + raise newException(IOError, "didn't do stuff") + +proc ccc() = + ddd() + +proc bbb() = + ccc() + +proc aaa() = + bbb() + +test "with exception": + check 3 == 3 + aaa() diff --git a/tests/js/tunittest_error2.nim b/tests/js/tunittest_error2.nim new file mode 100644 index 000000000..9c5af7529 --- /dev/null +++ b/tests/js/tunittest_error2.nim @@ -0,0 +1,16 @@ +discard """ + exitcode: 1 + outputsub: ''' +[<foreign exception>] +[FAILED] Bad test + ''' + matrix: "-d:nodejs" + targets: "js" + joinable: false +""" + +# bug #16978 +import unittest +test "Bad test": + var x: cstring = nil + let y = x[0] diff --git a/tests/js/tunittests.nim b/tests/js/tunittests.nim deleted file mode 100644 index 7c2e70563..000000000 --- a/tests/js/tunittests.nim +++ /dev/null @@ -1,11 +0,0 @@ -discard """ - output: ''' -[Suite] Bacon - [OK] >:)''' -""" - -import unittest - -suite "Bacon": - test ">:)": - check(true == true) diff --git a/tests/js/twritestacktrace.nim b/tests/js/twritestacktrace.nim new file mode 100644 index 000000000..2fe2b1987 --- /dev/null +++ b/tests/js/twritestacktrace.nim @@ -0,0 +1,12 @@ +discard """ + cmd: "nim js --panics:on $file" + output: '''Traceback (most recent call last) +twritestacktrace.nim(12) at module twritestacktrace +twritestacktrace.nim(10) at twritestacktrace.hello +''' +""" + +proc hello() = + writeStackTrace() + +hello() |