diff options
Diffstat (limited to 'tests/system')
43 files changed, 1404 insertions, 54 deletions
diff --git a/tests/system/t10307.nim b/tests/system/t10307.nim new file mode 100644 index 000000000..b5a93c5c6 --- /dev/null +++ b/tests/system/t10307.nim @@ -0,0 +1,24 @@ +discard """ + cmd: "nim c --mm:refc -d:useGcAssert $file" + output: '''running someProc(true) +res: yes +yes +running someProc(false) +res: + +''' +""" + +proc someProc(x:bool):cstring = + var res:string = "" + if x: + res = "yes" + echo "res: ", res + GC_ref(res) + result = res + +echo "running someProc(true)" +echo someProc(true) + +echo "running someProc(false)" +echo someProc(false) diff --git a/tests/system/t20938.nim b/tests/system/t20938.nim new file mode 100644 index 000000000..7341cbb91 --- /dev/null +++ b/tests/system/t20938.nim @@ -0,0 +1,12 @@ +discard """ + cmd: "nim c --mm:refc $file" + action: "compile" +""" + +template foo(x: typed) = + discard x + +foo: + var x = "hello" + x.shallowCopy("test") + true diff --git a/tests/system/talloc.nim b/tests/system/talloc.nim index 9b970fda0..a81fef481 100644 --- a/tests/system/talloc.nim +++ b/tests/system/talloc.nim @@ -1,8 +1,4 @@ -discard """ -disabled: "appveyor" -""" - -# appveyor is "out of memory" +# was: appveyor is "out of memory" var x: ptr int diff --git a/tests/system/talloc2.nim b/tests/system/talloc2.nim index a321fe741..9d1687f34 100644 --- a/tests/system/talloc2.nim +++ b/tests/system/talloc2.nim @@ -1,10 +1,11 @@ discard """ disabled: "windows" +disabled: "openbsd" joinable: false disabled: 32bit """ # no point to test this on system with smaller address space -# appveyor is "out of memory" +# was: appveyor is "out of memory" const nmax = 2*1024*1024*1024 diff --git a/tests/system/tatomics1.nim b/tests/system/tatomics1.nim new file mode 100644 index 000000000..217fd07fa --- /dev/null +++ b/tests/system/tatomics1.nim @@ -0,0 +1,9 @@ +discard """ + targets: "c cpp js" +""" + +var x = 10 +atomicInc(x) +doAssert x == 11 +atomicDec(x) +doAssert x == 10 diff --git a/tests/system/tcomparisons.nim b/tests/system/tcomparisons.nim new file mode 100644 index 000000000..a661b14a1 --- /dev/null +++ b/tests/system/tcomparisons.nim @@ -0,0 +1,51 @@ +discard """ + targets: "c cpp js" +""" + +template main = + block: # proc equality + var prc: proc(): int {.closure.} + prc = nil + doAssert prc == nil + doAssert prc.isNil + prc = proc(): int = + result = 123 + doAssert prc != nil + doAssert not prc.isNil + doAssert prc == prc + let prc2 = prc + doAssert prc == prc2 + doAssert prc2 != nil + doAssert not prc2.isNil + doAssert not prc.isNil + prc = proc(): int = + result = 456 + doAssert prc != nil + doAssert not prc.isNil + doAssert prc != prc2 + block: # iterator equality + when nimvm: discard # vm does not support closure iterators + else: + when not defined(js): # js also does not support closure iterators + var iter: iterator(): int {.closure.} + iter = nil + doAssert iter == nil + doAssert iter.isNil + iter = iterator(): int = + yield 123 + doAssert iter != nil + doAssert not iter.isNil + doAssert iter == iter + let iter2 = iter + doAssert iter == iter2 + doAssert iter2 != nil + doAssert not iter2.isNil + doAssert not iter.isNil + iter = iterator(): int = + yield 456 + doAssert iter != nil + doAssert not iter.isNil + doAssert iter != iter2 + +static: main() +main() diff --git a/tests/system/tconcat.nim b/tests/system/tconcat.nim new file mode 100644 index 000000000..fdce3ea00 --- /dev/null +++ b/tests/system/tconcat.nim @@ -0,0 +1,11 @@ +discard """ + output: "DabcD" +""" + +const + x = "abc" + +var v = "D" & x & "D" + +echo v + diff --git a/tests/system/tdeepcopy.nim b/tests/system/tdeepcopy.nim index 383d2e8d1..92ba48115 100644 --- a/tests/system/tdeepcopy.nim +++ b/tests/system/tdeepcopy.nim @@ -1,4 +1,5 @@ discard """ + matrix: "--mm:refc; --mm:orc --deepcopy:on" output: "ok" """ diff --git a/tests/system/tdollars.nim b/tests/system/tdollars.nim new file mode 100644 index 000000000..eabee81b3 --- /dev/null +++ b/tests/system/tdollars.nim @@ -0,0 +1,199 @@ +discard """ + matrix: "--mm:refc; --mm:orc; --backend:cpp; --backend:js --jsbigint64:off -d:nimStringHash2; --backend:js --jsbigint64:on" +""" + +#[ +if https://github.com/nim-lang/Nim/pull/14043 is merged (or at least its +tests/system/tostring.nim diff subset), merge +tests/system/tostring.nim into this file, named after dollars.nim + +The goal is to increase test coverage across backends while minimizing test code +duplication (which always results in weaker test coverage in practice). +]# + +import std/unittest +import std/private/jsutils +template test[T](a: T, expected: string) = + check $a == expected + var b = a + check $b == expected + static: + doAssert $a == expected + +template testType(T: typedesc) = + when T is bool: + test true, "true" + test false, "false" + elif T is char: + test char, "\0" + test char.high, static($T.high) + else: + test T.default, "0" + test 1.T, "1" + test T.low, static($T.low) + test T.high, static($T.high) + +block: # `$`(SomeInteger) + # direct tests + check $0'u8 == "0" + check $255'u8 == "255" + check $(-127'i8) == "-127" + + # known limitation: Error: number out of range: '128'i8', + # see https://github.com/timotheecour/Nim/issues/125 + # check $(-128'i8) == "-128" + + check $int8.low == "-128" + check $int8(-128) == "-128" + check $cast[int8](-128) == "-128" + + var a = 12345'u16 + check $a == "12345" + check $12345678'u64 == "12345678" + check $12345678'i64 == "12345678" + check $(-12345678'i64) == "-12345678" + + # systematic tests + testType uint8 + testType uint16 + testType uint32 + testType uint + + testType int8 + testType int16 + testType int32 + + testType int + testType bool + + whenJsNoBigInt64: discard + do: + testType uint64 + testType int64 + testType BiggestInt + +block: # #14350, #16674, #16686 for JS + var cstr: cstring + doAssert cstr == cstring(nil) + doAssert cstr == nil + doAssert cstr.isNil + doAssert cstr != cstring("") + doAssert cstr.len == 0 + + when defined(js): + cstr.add(cstring("abc")) + doAssert cstr == cstring("abc") + + var nil1, nil2: cstring = nil + + nil1.add(nil2) + doAssert nil1 == cstring(nil) + doAssert nil2 == cstring(nil) + + nil1.add(cstring("")) + doAssert nil1 == cstring("") + doAssert nil2 == cstring(nil) + + nil1.add(nil2) + doAssert nil1 == cstring("") + doAssert nil2 == cstring(nil) + + nil2.add(nil1) + doAssert nil1 == cstring("") + doAssert nil2 == cstring("") + +block: + when defined(js): # bug #18591 + let a1 = -1'i8 + let a2 = uint8(a1) + # if `uint8(a1)` changes meaning to `cast[uint8](a1)` in future, update this test; + # until then, this is the correct semantics. + let a3 = $a2 + doAssert a2 == 255'u8 + doAssert a3 == "255" + proc intToStr(a: uint8): cstring {.importjs: "(# + \"\")".} + doAssert $intToStr(a2) == "255" + else: + block: + let x = -1'i8 + let y = uint32(x) + doAssert $y == "4294967295" + block: + let x = -1'i16 + let y = uint32(x) + doAssert $y == "4294967295" + block: + let x = -1'i32 + let y = uint32(x) + doAssert $y == "4294967295" + block: + proc foo1(arg: int): string = + let x = uint32(arg) + $x + doAssert $foo1(-1) == "4294967295" + + block: + let x = 4294967295'u32 + doAssert $x == "4294967295" + block: + doAssert $(4294967295'u32) == "4294967295" + +proc main()= + block: + let a = -0.0 + doAssert $a == "-0.0" + doAssert $(-0.0) == "-0.0" + + block: + let a = 0.0 + doAssert $a == "0.0" + doAssert $(0.0) == "0.0" + + block: + let b = -0 + doAssert $b == "0" + doAssert $(-0) == "0" + + block: + let b = 0 + doAssert $b == "0" + doAssert $(0) == "0" + + doAssert $uint32.high == "4294967295" + + block: # addInt + var res = newStringOfCap(24) + template test2(a, b) = + res.setLen(0) + res.addInt a + doAssert res == b + + for i in 0 .. 9: + res.addInt int64(i) + doAssert res == "0123456789" + + res.setLen(0) + for i in -9 .. 0: + res.addInt int64(i) + doAssert res == "-9-8-7-6-5-4-3-2-10" + + whenJsNoBigInt64: discard + do: + test2 high(int64), "9223372036854775807" + test2 low(int64), "-9223372036854775808" + test2 high(int32), "2147483647" + test2 low(int32), "-2147483648" + test2 high(int16), "32767" + test2 low(int16), "-32768" + test2 high(int8), "127" + test2 low(int8), "-128" + + block: + const + a: array[3, char] = ['N', 'i', 'm'] + aStr = $(a) + + doAssert aStr == """['N', 'i', 'm']""" + +static: main() +main() diff --git a/tests/system/temptyecho.nim b/tests/system/temptyecho.nim new file mode 100644 index 000000000..a3c407897 --- /dev/null +++ b/tests/system/temptyecho.nim @@ -0,0 +1,6 @@ +discard """ +output: "\n" +""" + +echo() + diff --git a/tests/system/tensuremove.nim b/tests/system/tensuremove.nim new file mode 100644 index 000000000..668d5aed1 --- /dev/null +++ b/tests/system/tensuremove.nim @@ -0,0 +1,131 @@ +discard """ + targets: "c js" + matrix: "--cursorinference:on; --cursorinference:off" +""" + +block: + type + X = object + s: string + + proc `=copy`(x: var X, y: X) = + x.s = "copied " & y.s + + proc `=sink`(x: var X, y: X) = + `=destroy`(x) + wasMoved(x) + x.s = "moved " & y.s + + proc consume(x: sink X) = + discard x.s + + proc main = + let m = "abcdefg" + var x = X(s: ensureMove m) + consume(ensureMove x) + + static: main() + main() + +block: + type + String = object + id: string + + proc hello = + var s = String(id: "1") + var m = ensureMove s + doAssert m.id == "1" + + hello() + +block: + type + String = object + id: string + + proc hello = + var n = "1" + var s = String(id: ensureMove n) + var m = ensureMove s + doAssert m.id == "1" + + hello() + +block: + type + String = object + id: string + + proc hello = + var n = "1" + var s = [ensureMove n] + var m = ensureMove s + doAssert m[0] == "1" + + hello() + +block: + type + String = object + id: string + + proc hello = + var n = "1" + var s = @[ensureMove n] + var m = ensureMove s + doAssert m[0] == "1" + + hello() + +block: + type + String = object + id: string + + proc hello = + var s = String(id: "1") + var m = ensureMove s.id + doAssert m == "1" + + hello() + +block: + proc foo = + var x = 1 + let y = ensureMove x # move + when not defined(js): + doAssert (y, x) == (1, 0) # (1, 0) + foo() + +block: + proc foo = + var x = 1 + let y = ensureMove x # move + doAssert y == 1 + foo() + +block: + proc foo = + var x = @[1, 2, 3] + let y = ensureMove x[0] # move + doAssert y == 1 + when not defined(js): + doAssert x == @[0, 2, 3] + foo() + +block: + proc foo = + var x = [1, 2, 3] + let y = ensureMove x[0] # move + doAssert y == 1 + when not defined(js): + doAssert x == @[0, 2, 3] + foo() + +block: + proc foo = + var x = @["1", "2", "3"] + let y = ensureMove x[0] # move + doAssert y == "1" + foo() diff --git a/tests/system/tensuremove1.nim b/tests/system/tensuremove1.nim new file mode 100644 index 000000000..b7e19c4fb --- /dev/null +++ b/tests/system/tensuremove1.nim @@ -0,0 +1,16 @@ +discard """ + errormsg: "cannot move 's', which introduces an implicit copy" + matrix: "--cursorinference:on; --cursorinference:off" +""" + +type + String = object + id: string + +proc hello = + var s = String(id: "1") + var m = ensureMove s + discard m + discard s + +hello() \ No newline at end of file diff --git a/tests/system/tensuremove2.nim b/tests/system/tensuremove2.nim new file mode 100644 index 000000000..39bbeb22e --- /dev/null +++ b/tests/system/tensuremove2.nim @@ -0,0 +1,15 @@ +discard """ + errormsg: "Nested expressions cannot be moved: 'if true: s else: String()'" +""" + +type + String = object + id: string + +proc hello = + var s = String(id: "1") + var m = ensureMove(if true: s else: String()) + discard m + discard s + +hello() \ No newline at end of file diff --git a/tests/system/tensuremove3.nim b/tests/system/tensuremove3.nim new file mode 100644 index 000000000..eca032673 --- /dev/null +++ b/tests/system/tensuremove3.nim @@ -0,0 +1,28 @@ +discard """ + errormsg: "cannot move 'x', passing 'x' to a sink parameter introduces an implicit copy" + matrix: "--cursorinference:on; --cursorinference:off" +""" + +block: + type + X = object + s: string + + proc `=copy`(x: var X, y: X) = + x.s = "copied " & y.s + + proc `=sink`(x: var X, y: X) = + `=destroy`(x) + wasMoved(x) + x.s = "moved " & y.s + + proc consume(x: sink X) = + discard x.s + + proc main = + var s = "abcdefg" + var x = X(s: ensureMove s) + consume(ensureMove x) + discard x + + main() \ No newline at end of file diff --git a/tests/system/tenum_array_repr.nim b/tests/system/tenum_array_repr.nim index 3634692e3..39b1a5f9a 100644 --- a/tests/system/tenum_array_repr.nim +++ b/tests/system/tenum_array_repr.nim @@ -2,10 +2,8 @@ discard """ output: ''' 1 [a, b] - 2 [c, d] - 4 [e, f]''' """ diff --git a/tests/system/tfielditerator.nim b/tests/system/tfielditerator.nim new file mode 100644 index 000000000..7e063c6cf --- /dev/null +++ b/tests/system/tfielditerator.nim @@ -0,0 +1,126 @@ +discard """ + output: ''' +a char: true +a char: false +an int: 5 +an int: 6 +a string: abc +false +true +true +false +true +a: a +b: b +x: 5 +y: 6 +z: abc +a char: true +a char: false +an int: 5 +an int: 6 +a string: abc +a string: I'm root! +CMP false +CMP true +CMP true +CMP false +CMP true +CMP true +a: a +b: b +x: 5 +y: 6 +z: abc +thaRootMan: I'm root! +myDisc: enC +c: Z +enC +Z +''' +""" + +block titerator1: + type + TMyTuple = tuple[a, b: char, x, y: int, z: string] + + proc p(x: char) = echo "a char: ", x <= 'a' + proc p(x: int) = echo "an int: ", x + proc p(x: string) = echo "a string: ", x + + var x: TMyTuple = ('a', 'b', 5, 6, "abc") + var y: TMyTuple = ('A', 'b', 5, 9, "abc") + + for f in fields(x): + p f + + for a, b in fields(x, y): + echo a == b + + for key, val in fieldPairs(x): + echo key, ": ", val + + doAssert x != y + doAssert x == x + doAssert(not (x < x)) + doAssert x <= x + doAssert y < x + doAssert y <= x + + +block titerator2: + type + SomeRootObj = object of RootObj + thaRootMan: string + TMyObj = object of SomeRootObj + a, b: char + x, y: int + z: string + + TEnum = enum enA, enB, enC + TMyCaseObj = object + case myDisc: TEnum + of enA: a: int + of enB: b: string + of enC: c: char + + proc p(x: char) = echo "a char: ", x <= 'a' + proc p(x: int) = echo "an int: ", x + proc p(x: string) = echo "a string: ", x + + proc myobj(a, b: char, x, y: int, z: string): TMyObj = + result.a = a; result.b = b; result.x = x; result.y = y; result.z = z + result.thaRootMan = "I'm root!" + + var x = myobj('a', 'b', 5, 6, "abc") + var y = myobj('A', 'b', 5, 9, "abc") + + for f in fields(x): + p f + + for a, b in fields(x, y): + echo "CMP ", a == b + + for key, val in fieldPairs(x): + echo key, ": ", val + + var co = TMyCaseObj(myDisc: enC, c: 'Z') + for key, val in fieldPairs(co): + echo key, ": ", val + + for val in fields(co): + echo val + +block: + type + Enum = enum A, B + Object = object + case a: Enum + of A: + integer: int + of B: + time: string + + let x = A + let s = Object(a: x) + doAssert s.integer == 0 diff --git a/tests/system/tfields.nim b/tests/system/tfields.nim new file mode 100644 index 000000000..0bf3a4e1a --- /dev/null +++ b/tests/system/tfields.nim @@ -0,0 +1,108 @@ +discard """ + output: ''' +n +n +(one: 1, two: 2, three: 3) +1 +2 +3 +(one: 4, two: 5, three: 6) +4 +(one: 7, two: 8, three: 9) +7 +8 +9 +(foo: 38, other: "string here") +43 +100 +90 +''' +""" + + +block tindex: + type + TMyTuple = tuple[a, b: int] + + proc indexOf(t: typedesc, name: string): int = + ## takes a tuple and looks for the field by name. + ## returs index of that field. + var + d: t + i = 0 + for n, x in fieldPairs(d): + if n == name: return i + i.inc + raise newException(ValueError, "No field " & name & " in type " & + astToStr(t)) + + doAssert TMyTuple.indexOf("b") == 1 + + + +block ttemplate: + # bug #1902 + # This works. + for name, value in (n: "v").fieldPairs: + echo name + + template wrapper(): void = + for name, value in (n: "v").fieldPairs: + echo name + wrapper() + + + +block tbreak: + # bug #2134 + type + TestType = object + one: int + two: int + three: int + + var + ab = TestType(one:1, two:2, three:3) + ac = TestType(one:4, two:5, three:6) + ad = TestType(one:7, two:8, three:9) + tstSeq = [ab, ac, ad] + + for tstElement in mitems(tstSeq): + echo tstElement + for tstField in fields(tstElement): + #for tstField in [1,2,4,6]: + echo tstField + if tstField == 4: + break + + + +block timplicit_with_partial: + type + Base = ref object of RootObj + Foo {.partial.} = ref object of Base + + proc my(f: Foo) = + #var f.next = f + let f.foo = 38 + let f.other = "string here" + echo f[] + echo f.foo + 5 + + var g: Foo + new(g) + my(g) + + type + FooTask {.partial.} = ref object of RootObj + + proc foo(t: FooTask) {.liftLocals: t.} = + var x = 90 + if true: + var x = 10 + while x < 100: + inc x + echo x + echo x + + foo(FooTask()) \ No newline at end of file diff --git a/tests/system/tgcnone.nim b/tests/system/tgcnone.nim new file mode 100644 index 000000000..1ccb9e29c --- /dev/null +++ b/tests/system/tgcnone.nim @@ -0,0 +1,7 @@ +discard """ + matrix: "--mm:none -d:useMalloc" +""" +# bug #15617 +# bug #22262 +let x = 4 +doAssert x == 4 diff --git a/tests/system/tgcregions.nim b/tests/system/tgcregions.nim new file mode 100644 index 000000000..e14865be3 --- /dev/null +++ b/tests/system/tgcregions.nim @@ -0,0 +1,6 @@ +discard """ +cmd: "nim c --gc:regions $file" +""" + +# issue #12597 +# it just tests that --gc:regions compiles. Nothing else. :'( diff --git a/tests/system/timmutableinc.nim b/tests/system/timmutableinc.nim new file mode 100644 index 000000000..e857800b3 --- /dev/null +++ b/tests/system/timmutableinc.nim @@ -0,0 +1,8 @@ +discard """ + errormsg: "type mismatch: got <int>" + file: "timmutableinc.nim" + line: 8 +""" +var x = 0 + +inc(x+1) diff --git a/tests/system/tinvalidnot.nim b/tests/system/tinvalidnot.nim new file mode 100644 index 000000000..df0291a8a --- /dev/null +++ b/tests/system/tinvalidnot.nim @@ -0,0 +1,19 @@ +discard """ + errormsg: "type mismatch" + file: "tinvalidnot.nim" + line: 14 +""" +# BUG: following compiles, but should not: + +proc nodeOfDegree(x: int): bool = + result = false + +proc main = + for j in 0..2: + for i in 0..10: + if not nodeOfDegree(1) >= 0: #ERROR_MSG type mismatch + echo "Yes" + else: + echo "No" + +main() diff --git a/tests/system/tio.nim b/tests/system/tio.nim index c4d041560..52a21837a 100644 --- a/tests/system/tio.nim +++ b/tests/system/tio.nim @@ -22,12 +22,12 @@ proc echoLoop(str: string): string = while not output.atEnd: result.add(output.readLine) -suite "io": - suite "readAll": - test "stdin": +block: # io + block: # readAll + block: # stdin check: echoLoop(STRING_DATA) == STRING_DATA - test "file": + block: # file check: readFile(TEST_FILE).strip == STRING_DATA diff --git a/tests/system/tlocals.nim b/tests/system/tlocals.nim new file mode 100644 index 000000000..e59976102 --- /dev/null +++ b/tests/system/tlocals.nim @@ -0,0 +1,76 @@ +discard """ + matrix: "--mm:refc; --mm:orc" + output: '''(x: "string here", a: 1) +b is 5 +x is 12''' +""" + +proc simple[T](a: T) = + var + x = "string here" + echo locals() + +simple(1) + +type Foo2[T]=object + a2: T + +proc numFields*(T: typedesc[tuple|object]): int= + var t:T + for _ in t.fields: inc result + +proc test(baz: int, qux: var int): int = + var foo: Foo2[int] + let bar = "abc" + let c1 = locals() + doAssert numFields(c1.foo.type) == 1 + doAssert c1.bar == "abc" + doAssert c1.baz == 123 + doAssert c1.result == 0 + doAssert c1.qux == 456 + +var x1 = 456 +discard test(123, x1) + +# bug #11958 +proc foo() = + var a = 5 + proc bar() {.nimcall.} = + var b = 5 + for k, v in fieldpairs(locals()): + echo k, " is ", v + + bar() +foo() + + +proc foo2() = + var a = 5 + proc bar2() {.nimcall.} = + for k, v in fieldpairs(locals()): + echo k, " is ", v + + bar2() +foo2() + + +proc foo3[T](y: T) = + var a = 5 + proc bar2[T](x: T) {.nimcall.} = + for k, v in fieldpairs(locals()): + echo k, " is ", v + + bar2(y) + +foo3(12) + +block: # bug #12682 + template foo(): untyped = + var c1 = locals() + 1 + + proc testAll()= + doAssert foo() == 1 + let c2=locals() + + testAll() diff --git a/tests/system/tlowhigh.nim b/tests/system/tlowhigh.nim new file mode 100644 index 000000000..6ae871255 --- /dev/null +++ b/tests/system/tlowhigh.nim @@ -0,0 +1,32 @@ +discard """ + action: run + output: ''' +18446744073709551615 +9223372036854775807 +4294967295 +0 +0 +''' +""" + +var x: range[-1'f32..1'f32] +doAssert x.low == -1'f32 +doAssert x.high == 1'f32 +doAssert x.type.low == -1'f32 +doAssert x.type.high == 1'f32 +var y: range[-1'f64..1'f64] +doAssert y.low == -1'f64 +doAssert y.high == 1'f64 +doAssert y.type.low == -1'f64 +doAssert y.type.high == 1'f64 + +# bug #11972 +var num: uint8 +doAssert num.high.float == 255.0 + +echo high(uint64) +echo high(int64) +echo high(uint32) + +echo low(uint64) +echo low(uint32) diff --git a/tests/system/tmagics.nim b/tests/system/tmagics.nim new file mode 100644 index 000000000..6088c9600 --- /dev/null +++ b/tests/system/tmagics.nim @@ -0,0 +1,62 @@ +discard """ + matrix: "--mm:refc" + output: ''' +true +true +false +true +true +false +true +''' +joinable: false +""" + +block tlowhigh: + type myEnum = enum e1, e2, e3, e4, e5 + var a: array[myEnum, int] + + for i in low(a) .. high(a): + a[i] = 0 + + proc sum(a: openArray[int]): int = + result = 0 + for i in low(a)..high(a): + inc(result, a[i]) + + doAssert sum([1, 2, 3, 4]) == 10 + + +block t8693: + type Foo = int | float + + proc bar(t1, t2: typedesc): bool = + echo (t1 is t2) + (t2 is t1) + + proc bar[T](x: T, t2: typedesc): bool = + echo (T is t2) + (t2 is T) + + doAssert bar(int, Foo) == false + doAssert bar(4, Foo) == false + doAssert bar(any, int) + doAssert bar(int, any) == false + doAssert bar(Foo, Foo) + doAssert bar(any, Foo) + doAssert bar(Foo, any) == false + +block t9442: + var v1: ref char + var v2: string + var v3: seq[char] + GC_ref(v1) + GC_unref(v1) + GC_ref(v2) + GC_unref(v2) + GC_ref(v3) + GC_unref(v3) + +block: # bug #12229 + proc foo(T: typedesc) = discard + foo(ref) diff --git a/tests/system/tmemory.nim b/tests/system/tmemory.nim new file mode 100644 index 000000000..553037011 --- /dev/null +++ b/tests/system/tmemory.nim @@ -0,0 +1,16 @@ +import std/assertions + +block: # cmpMem + type + SomeHash = array[15, byte] + + var + a: SomeHash + b: SomeHash + + a[^1] = byte(1) + let c = a + + doAssert cmpMem(a.addr, b.addr, sizeof(SomeHash)) > 0 + doAssert cmpMem(b.addr, a.addr, sizeof(SomeHash)) < 0 + doAssert cmpMem(a.addr, c.addr, sizeof(SomeHash)) == 0 diff --git a/tests/system/tnew.nim b/tests/system/tnew.nim new file mode 100644 index 000000000..c28c1187f --- /dev/null +++ b/tests/system/tnew.nim @@ -0,0 +1,61 @@ +discard """ +matrix: "--mm:refc; --mm:orc" +outputsub: ''' +Simple tree node allocation worked! +Simple cycle allocation worked! +''' +joinable: false +""" + +# Test the implementation of the new operator +# and the code generation for gc walkers +# (and the garbage collector): + +type + PNode = ref TNode + TNode = object + data: int + str: string + le, ri: PNode + + TStressTest = ref array[0..45, array[1..45, TNode]] + +proc finalizer(n: PNode) = + write(stdout, n.data) + write(stdout, " is now freed\n") + +proc newNode(data: int, le, ri: PNode): PNode = + when defined(gcDestructors): # using finalizer breaks the test for orc + new(result) + else: + new(result, finalizer) + result.le = le + result.ri = ri + result.data = data + +# now loop and build a tree +proc main() = + var + i = 0 + p: TStressTest + while i < 1000: + var n: PNode + + n = newNode(i, nil, newNode(i + 10000, nil, nil)) + inc(i) + new(p) + + write(stdout, "Simple tree node allocation worked!\n") + i = 0 + while i < 1000: + var m = newNode(i + 20000, nil, nil) + var k = newNode(i + 30000, nil, nil) + m.le = m + m.ri = k + k.le = m + k.ri = k + inc(i) + + write(stdout, "Simple cycle allocation worked!\n") + +main() diff --git a/tests/system/tnewderef.nim b/tests/system/tnewderef.nim new file mode 100644 index 000000000..3394dbddf --- /dev/null +++ b/tests/system/tnewderef.nim @@ -0,0 +1,11 @@ +discard """ + output: 3 + +""" + +var x: ref int +new(x) +x[] = 3 + +echo x[] + diff --git a/tests/system/tnewstring_uninitialized.nim b/tests/system/tnewstring_uninitialized.nim new file mode 100644 index 000000000..9bc0e1622 --- /dev/null +++ b/tests/system/tnewstring_uninitialized.nim @@ -0,0 +1,11 @@ +discard """ + matrix: "--mm:refc;" +""" + +# bug #22555 +var x = newStringUninit(10) +doAssert x.len == 10 +for i in 0..<x.len: + x[i] = chr(ord('a') + i) + +doAssert x == "abcdefghij" diff --git a/tests/system/tnilconcats.nim b/tests/system/tnilconcats.nim index c1126405c..69fc3913c 100644 --- a/tests/system/tnilconcats.nim +++ b/tests/system/tnilconcats.nim @@ -26,7 +26,8 @@ when true: # casting an empty string as sequence with shallow() should not segfault var s2: string - shallow(s2) + when defined(gcRefc): + shallow(s2) s2 &= "foo" doAssert s2 == "foo" diff --git a/tests/system/tnim_stacktrace_override.nim b/tests/system/tnim_stacktrace_override.nim new file mode 100644 index 000000000..c75da9d9b --- /dev/null +++ b/tests/system/tnim_stacktrace_override.nim @@ -0,0 +1,18 @@ +discard """ + cmd: "nim c -d:nimStacktraceOverride $file" + output: '''begin +Traceback (most recent call last, using override) +Error: unhandled exception: stack trace produced [ValueError] +''' + exitcode: 1 +""" + +import asyncfutures + +proc main = + echo "begin" + if true: + raise newException(ValueError, "stack trace produced") + echo "unreachable" + +main() diff --git a/tests/system/tostring.nim b/tests/system/tostring.nim index ea4a44417..bb6e453fb 100644 --- a/tests/system/tostring.nim +++ b/tests/system/tostring.nim @@ -1,7 +1,3 @@ -discard """ - output: "DONE: tostring.nim" -""" - doAssert "@[23, 45]" == $(@[23, 45]) doAssert "[32, 45]" == $([32, 45]) doAssert """@["", "foo", "bar"]""" == $(@["", "foo", "bar"]) @@ -51,7 +47,7 @@ import strutils let arr = ['H','e','l','l','o',' ','W','o','r','l','d','!','\0'] doAssert $arr == "['H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!', '\\x00']" -doAssert $cstring(unsafeAddr arr) == "Hello World!" +doAssert $cast[cstring](addr arr) == "Hello World!" proc takes(c: cstring) = doAssert c == cstring"" @@ -72,7 +68,7 @@ doAssert yy == "" proc bar(arg: cstring) = doAssert arg[0] == '\0' -proc baz(arg: openarray[char]) = +proc baz(arg: openArray[char]) = doAssert arg.len == 0 proc stringCompare() = @@ -83,9 +79,9 @@ proc stringCompare() = doAssert b == "bee" b.add g doAssert b == "bee" - c.add 123.456 + c.addFloat 123.456 doAssert c == "123.456" - d.add 123456 + d.addInt 123456 doAssert d == "123456" doAssert e == "" @@ -108,7 +104,7 @@ bar(nilstring) static: stringCompare() -# bug 8847 +# issue #8847 var a2: cstring = "fo\"o2" block: @@ -116,5 +112,14 @@ block: s.addQuoted a2 doAssert s == "\"fo\\\"o2\"" - -echo "DONE: tostring.nim" +# issue #16650 +template fn() = + doAssert len(cstring"ab\0c") == 5 + doAssert len(cstring("ab\0c")) == 2 + when nimvm: + discard + else: + let c = cstring("ab\0c") + doAssert len(c) == 2 +fn() +static: fn() diff --git a/tests/system/trealloc.nim b/tests/system/trealloc.nim index 7180b8eda..1d3e00aff 100644 --- a/tests/system/trealloc.nim +++ b/tests/system/trealloc.nim @@ -1,6 +1,7 @@ discard """ output: '''success''' joinable: false + disabled: "openbsd" """ # bug #4818 @@ -11,12 +12,12 @@ const BUFFER_SIZE = 5000 var buffer = cast[ptr uint16](alloc(BUFFER_SIZE)) var total_size: int64 = 0 -for i in 0 .. 4000: - let size = BUFFER_SIZE * i - #echo "requesting ", size - total_size += size.int64 - buffer = cast[ptr uint16](realloc(buffer, size)) - #echo totalSize, " total: ", getTotalMem(), " occupied: ", getOccupiedMem(), " free: ", getFreeMem() +for i in 0 .. 1000: + let size = BUFFER_SIZE * i + #echo "requesting ", size + total_size += size.int64 + buffer = cast[ptr uint16](realloc(buffer, size)) + #echo totalSize, " total: ", getTotalMem(), " occupied: ", getOccupiedMem(), " free: ", getFreeMem() dealloc(buffer) echo "success" diff --git a/tests/system/trefs.nim b/tests/system/trefs.nim new file mode 100644 index 000000000..8c36aec52 --- /dev/null +++ b/tests/system/trefs.nim @@ -0,0 +1,15 @@ +discard """ + targets: "c js" +""" + +# bug #21317 +proc parseHook*(v: var ref int) = + var a: ref int + new(a) + a[] = 123 + v = a + +proc fromJson2*(): ref int = + parseHook(result) + +doAssert fromJson2()[] == 123 diff --git a/tests/system/tsigexitcode.nim b/tests/system/tsigexitcode.nim new file mode 100644 index 000000000..249256b40 --- /dev/null +++ b/tests/system/tsigexitcode.nim @@ -0,0 +1,23 @@ +discard """ + joinable: false + disabled: windows +""" + +import os, osproc, posix, strutils + +proc main() = + if paramCount() > 0: + let signal = cint parseInt paramStr(1) + discard posix.raise(signal) + else: + # synchronize this list with lib/system/except.nim:registerSignalHandler() + let sigs = [SIGINT, SIGSEGV, SIGABRT, SIGFPE, SIGILL, SIGBUS, SIGPIPE] + for s in sigs: + let (_, exitCode) = execCmdEx(quoteShellCommand [getAppFilename(), $s]) + if s == SIGPIPE: + # SIGPIPE should be ignored + doAssert exitCode == 0, $(exitCode, s) + else: + doAssert exitCode == 128+s, $(exitCode, s) + +main() diff --git a/tests/system/tslices.nim b/tests/system/tslices.nim new file mode 100644 index 000000000..d0c68f8cb --- /dev/null +++ b/tests/system/tslices.nim @@ -0,0 +1,65 @@ +discard """ +output: ''' +456456 +456456 +456456 +Zugr5nd +egerichtetd +verichtetd +''' +""" + +# Test the new slices. + +var mystr = "Abgrund" +# mystr[..1] = "Zu" # deprecated +mystr[0..1] = "Zu" + +mystr[4..4] = "5" + +type + TEnum = enum e1, e2, e3, e4, e5, e6 + +var myarr: array[TEnum, int] = [1, 2, 3, 4, 5, 6] +myarr[e1..e3] = myarr[e4..e6] +# myarr[..e3] = myarr[e4..e6] # deprecated +myarr[0..e3] = myarr[e4..e6] + +for x in items(myarr): stdout.write(x) +echo() + +var myarr2: array[0..5, int] = [1, 2, 3, 4, 5, 6] +myarr2[0..2] = myarr2[3..5] + +for x in items(myarr2): stdout.write(x) +echo() + + +var myseq = @[1, 2, 3, 4, 5, 6] +myseq[0..2] = myseq[^3 .. ^1] + +for x in items(myseq): stdout.write(x) +echo() + +echo mystr + +mystr[4..4] = "u" + +# test full replacement +# mystr[.. ^2] = "egerichtet" # deprecated +mystr[0 .. ^2] = "egerichtet" + +echo mystr + +mystr[0..2] = "ve" +echo mystr + +var s = "abcdef" +s[1 .. ^2] = "xyz" +assert s == "axyzf" + +# issue mentioned in PR #19219 +type Foo = distinct uint64 +# < here calls `pred` which used to cause a codegen error +# `pred` compiles because distinct ordinals are considered ordinal +const slice = 0 ..< 42.Foo diff --git a/tests/system/tslimsystem.nim b/tests/system/tslimsystem.nim new file mode 100644 index 000000000..4815306b5 --- /dev/null +++ b/tests/system/tslimsystem.nim @@ -0,0 +1,6 @@ +discard """ + output: "123" + matrix: "-d:nimPreviewSlimSystem --mm:refc; -d:nimPreviewSlimSystem --mm:arc" +""" + +echo 123 \ No newline at end of file diff --git a/tests/system/tstatic.nim b/tests/system/tstatic.nim new file mode 100644 index 000000000..6e2893e2b --- /dev/null +++ b/tests/system/tstatic.nim @@ -0,0 +1,58 @@ +discard """ + targets: "c cpp js" +""" + +import std/strutils + +# bug #6133 +template main() = + block: + block: + proc foo(q: string, a: int): int = + result = q.len + + proc foo(q: static[string]): int = + result = foo(q, 5) + + doAssert foo("123") == 3 + + block: + type E = enum A + + if false: + var e = A + discard $e + + proc foo(a: string): int = + len(a) # 16640 + + proc foo(a: static[bool]): int {.used.} = + discard + + doAssert foo("") == 0 + + block: + proc foo(a: string): int = + len(a) + + proc foo(a: static[bool]): int {.used.} = + discard + + doAssert foo("abc") == 3 + + block: + proc parseInt(f: static[bool]): int {.used.} = discard + + doAssert "123".parseInt == 123 + block: + type + MyType = object + field: float32 + AType[T: static MyType] = distinct range[0f32 .. T.field] + var a: AType[MyType(field: 5f32)] + proc n(S: static Slice[int]): range[S.a..S.b] = discard + assert typeof(n 1..2) is range[1..2] + + +static: main() +main() diff --git a/tests/system/tstatic_callable.nim b/tests/system/tstatic_callable.nim new file mode 100644 index 000000000..92d1fca8d --- /dev/null +++ b/tests/system/tstatic_callable.nim @@ -0,0 +1,12 @@ +# bug #16987 + +proc getNum(a: int): int = a + +# Below calls "doAssert getNum(123) == 123" at compile time. +static: + doAssert getNum(123) == 123 + +# Below calls evaluate the "getNum(123)" at compile time, but the +# results of those calls get used at run time. +doAssert (static getNum(123)) == 123 +doAssert (static(getNum(123))) == 123 diff --git a/tests/system/tstatic_callable_error.nim b/tests/system/tstatic_callable_error.nim new file mode 100644 index 000000000..c6f1e3d07 --- /dev/null +++ b/tests/system/tstatic_callable_error.nim @@ -0,0 +1,14 @@ +# bug #16987 + +discard """ +errormsg: "cannot evaluate at compile time: inp" +nimout: ''' +tstatic_callable_error.nim(14, 21) Error: cannot evaluate at compile time: inp''' +""" + + +# line 10 +proc getNum(a: int): int = a + +let inp = 123 +echo (static getNum(inp)) diff --git a/tests/system/tsystem_misc.nim b/tests/system/tsystem_misc.nim index 38be01a13..1debb7c48 100644 --- a/tests/system/tsystem_misc.nim +++ b/tests/system/tsystem_misc.nim @@ -59,11 +59,6 @@ doAssert high(float) > low(float) doAssert high(float32) > low(float32) doAssert high(float64) > low(float64) -# bug #6710 -var s = @[1] -s.delete(0) - - proc foo(a: openArray[int]) = for x in a: echo x @@ -81,13 +76,13 @@ foo(toOpenArray(seqq, 1, 3)) # empty openArray issue #7904 foo(toOpenArray(seqq, 0, -1)) foo(toOpenArray(seqq, 1, 0)) -doAssertRaises(IndexError): +doAssertRaises(IndexDefect): foo(toOpenArray(seqq, 0, -2)) foo(toOpenArray(arr, 9, 8)) foo(toOpenArray(arr, 0, -1)) foo(toOpenArray(arr, 1, 0)) -doAssertRaises(IndexError): +doAssertRaises(IndexDefect): foo(toOpenArray(arr, 10, 8)) # test openArray of openArray @@ -106,11 +101,11 @@ var arrNeg: array[-3 .. -1, int] = [1, 2, 3] foo(toOpenArray(arrNeg, -3, -1)) foo(toOpenArray(arrNeg, 0, -1)) foo(toOpenArray(arrNeg, -3, -4)) -doAssertRaises(IndexError): +doAssertRaises(IndexDefect): foo(toOpenArray(arrNeg, -4, -1)) -doAssertRaises(IndexError): +doAssertRaises(IndexDefect): foo(toOpenArray(arrNeg, -1, 0)) -doAssertRaises(IndexError): +doAssertRaises(IndexDefect): foo(toOpenArray(arrNeg, -1, -3)) doAssertRaises(Exception): raise newException(Exception, "foo") @@ -118,9 +113,9 @@ doAssertRaises(Exception): block: var didThrow = false try: - doAssertRaises(IndexError): # should fail since it's wrong exception - raise newException(FieldError, "foo") - except AssertionError: + doAssertRaises(IndexDefect): # should fail since it's wrong exception + raise newException(FieldDefect, "foo") + except AssertionDefect: # ok, throwing was correct behavior didThrow = true doAssert didThrow @@ -136,12 +131,12 @@ let str = "0123456789" foo(toOpenArrayByte(str, 0, str.high)) -template boundedOpenArray[T](x: seq[T], first, last: int): openarray[T] = +template boundedOpenArray[T](x: seq[T], first, last: int): openArray[T] = toOpenarray(x, max(0, first), min(x.high, last)) # bug #9281 -proc foo[T](x: openarray[T]) = +proc foo[T](x: openArray[T]) = echo x.len let a = @[1, 2, 3] @@ -184,3 +179,49 @@ proc testMinMax(a,b: float32) = testMinMax(0.0, NaN) testMinMax(NaN, 0.0) + + +block: + type Foo = enum + k1, k2 + var + a = {k1} + b = {k1,k2} + doAssert a < b + + +block: # Ordinal + doAssert int is Ordinal + doAssert uint is Ordinal + doAssert int64 is Ordinal + doAssert uint64 is Ordinal + doAssert char is Ordinal + type Foo = enum k1, k2 + doAssert Foo is Ordinal + doAssert Foo is SomeOrdinal + doAssert enum is SomeOrdinal + + # these fail: + # doAssert enum is Ordinal # fails + # doAssert Ordinal is SomeOrdinal + # doAssert SomeOrdinal is Ordinal + +block: + proc p() = discard + + doAssert not compiles(echo p.rawProc.repr) + doAssert not compiles(echo p.rawEnv.repr) + doAssert not compiles(echo p.finished) + +proc bug23223 = # bug #23223 + var stuff = "hello" + stuff.insert "" + doAssert stuff == "hello" + +bug23223() + +block: # bug #23894 + let v = high(uint) div 2 + let s = v + 1 # 9223372036854775808 + let m = succ v + doAssert s == m diff --git a/tests/system/tuse_version16.nim b/tests/system/tuse_version16.nim new file mode 100644 index 000000000..802b617ad --- /dev/null +++ b/tests/system/tuse_version16.nim @@ -0,0 +1,49 @@ +discard """ + matrix: "-d:NimMajor=1 -d:NimMinor=6 -d:NimPatch=100" +""" + +{.warning[UnusedImport]: off.} + +import std/[ + # Core: + bitops, typetraits, lenientops, macros, volatile, + + # Algorithms: + algorithm, sequtils, + + # Collections: + critbits, deques, heapqueue, intsets, lists, options, sets, + sharedlist, tables, + + # Strings: + editdistance, wordwrap, parseutils, ropes, + pegs, strformat, strmisc, strscans, strtabs, + strutils, unicode, unidecode, + + # Generic operator system services: + os, streams, + + # Math libraries: + complex, math, mersenne, random, rationals, stats, sums, + + # Internet protocols: + httpcore, mimetypes, uri, + + # Parsers: + htmlparser, json, lexbase, parsecfg, parsecsv, parsesql, parsexml, + + # XML processing: + xmltree, xmlparser, + + # Generators: + htmlgen, + + # Hashing: + base64, hashes, + + # Miscellaneous: + colors, sugar, varints, +] + + +doAssert NimVersion == "1.6.100" diff --git a/tests/system/tlenvarargs.nim b/tests/system/tvarargslen.nim index ca12c8171..24b54a1e0 100644 --- a/tests/system/tlenvarargs.nim +++ b/tests/system/tvarargslen.nim @@ -1,9 +1,9 @@ discard """ output: ''' -tlenvarargs.nim:35:9 (1, 2) -tlenvarargs.nim:36:9 12 -tlenvarargs.nim:37:9 1 -tlenvarargs.nim:38:8 +tvarargslen.nim:35:2 (1, 2) +tvarargslen.nim:36:2 12 +tvarargslen.nim:37:2 1 +tvarargslen.nim:38:8 done ''' """ @@ -14,19 +14,19 @@ template myecho*(a: varargs[untyped]) = ## on macros.nim) so can be used in more contexts const info = instantiationInfo(-1, false) const loc = info.filename & ":" & $info.line & ":" & $info.column & " " - when lenVarargs(a) > 0: + when varargsLen(a) > 0: echo(loc, a) else: echo(loc) template fun*(a: varargs[untyped]): untyped = - lenVarargs(a) + varargsLen(a) template fun2*(a: varargs[typed]): untyped = - a.lenVarargs + a.varargsLen template fun3*(a: varargs[int]): untyped = - a.lenVarargs + a.varargsLen template fun4*(a: varargs[untyped]): untyped = len(a) @@ -49,11 +49,12 @@ proc main()= doAssert fun3(10) == 1 doAssert fun3(10, 11) == 2 - ## shows why `lenVarargs` can't be named `len` + ## shows why `varargsLen` can't be named `len` doAssert fun4("abcdef") == len("abcdef") ## workaround for BUG:D20191218T171447 whereby if testament expected output ends ## in space, testament strips it from expected output but not actual output, ## which leads to a mismatch when running test via megatest echo "done" + main() |