diff options
Diffstat (limited to 'tests')
102 files changed, 1655 insertions, 380 deletions
diff --git a/tests/array/tarray.nim b/tests/array/tarray.nim index 2a371b788..f7c1dbf7f 100644 --- a/tests/array/tarray.nim +++ b/tests/array/tarray.nim @@ -18,7 +18,7 @@ paper @[2, 3, 4]321 9.0 4.0 3 -@[(Field0: 1, Field1: 2), (Field0: 3, Field1: 5)] +@[(1, 2), (3, 5)] 2 @["a", "new one", "c"] @[1, 2, 3] diff --git a/tests/async/tasyncfilewrite.nim b/tests/async/tasyncfilewrite.nim index 373b93301..3baf2bbc6 100644 --- a/tests/async/tasyncfilewrite.nim +++ b/tests/async/tasyncfilewrite.nim @@ -9,7 +9,6 @@ import os, asyncfile, asyncdispatch const F = "test_async.txt" removeFile(F) -defer: removeFile(F) let f = openAsync(F, fmWrite) var futs = newSeq[Future[void]]() for i in 1..3: @@ -17,4 +16,4 @@ for i in 1..3: waitFor(all(futs)) f.close() echo readFile(F) - +removeFile(F) diff --git a/tests/async/tasynctry.nim b/tests/async/tasynctry.nim index b13c57951..a7cb5223d 100644 --- a/tests/async/tasynctry.nim +++ b/tests/async/tasynctry.nim @@ -6,6 +6,7 @@ Multiple idents in except Multiple except branches Multiple except branches 2 ''' +targets: "c" """ import asyncdispatch, strutils diff --git a/tests/async/twinasyncrw.nim b/tests/async/twinasyncrw.nim index 64c5d6c26..6763eb5a2 100644 --- a/tests/async/twinasyncrw.nim +++ b/tests/async/twinasyncrw.nim @@ -46,7 +46,7 @@ when defined(windows): success = false it = it.ai_next - dealloc(aiList) + freeAddrInfo(aiList) if not success: retFuture.fail(newException(OSError, osErrorMsg(lastError))) return retFuture diff --git a/tests/bind/tnicerrorforsymchoice.nim b/tests/bind/tnicerrorforsymchoice.nim index f16b323de..c06926805 100644 --- a/tests/bind/tnicerrorforsymchoice.nim +++ b/tests/bind/tnicerrorforsymchoice.nim @@ -1,10 +1,15 @@ discard """ errormsg: "type mismatch: got <proc (s: TScgi: ScgiState or AsyncScgiState) | proc (client: AsyncSocket, headers: StringTableRef, input: string){.noSideEffect, gcsafe, locks: 0.}>" - line: 18 + line: 23 """ +# Fake ScgiState objects, from now-deprecated scgi module +type + ScgiState* = object of RootObj ## SCGI state object + AsyncScgiState* = object of RootObj ## SCGI state object + #bug #442 -import scgi, sockets, asyncio, strtabs +import sockets, asyncio, strtabs proc handleSCGIRequest[TScgi: ScgiState | AsyncScgiState](s: TScgi) = discard proc handleSCGIRequest(client: AsyncSocket, headers: StringTableRef, diff --git a/tests/ccgbugs/t5701.nim b/tests/ccgbugs/t5701.nim index e69acbf31..ee6e48498 100644 --- a/tests/ccgbugs/t5701.nim +++ b/tests/ccgbugs/t5701.nim @@ -1,7 +1,7 @@ discard """ - output: '''(Field0: 1, Field1: 1) -(Field0: 2, Field1: 2) -(Field0: 3, Field1: 3) + output: '''(1, 1) +(2, 2) +(3, 3) ''' """ diff --git a/tests/ccgbugs/tforward_decl_only.nim b/tests/ccgbugs/tforward_decl_only.nim index 2a867bc3b..74fbae303 100644 --- a/tests/ccgbugs/tforward_decl_only.nim +++ b/tests/ccgbugs/tforward_decl_only.nim @@ -1,5 +1,7 @@ discard """ ccodecheck: "\\i !@('struct tyObject_MyRefObject'[0-z]+' {')" +ccodecheck: "\\i !@('mymoduleInit')" +ccodecheck: "\\i @('mymoduleDatInit')" output: "hello" """ diff --git a/tests/collections/tcollections_to_string.nim b/tests/collections/tcollections_to_string.nim index 0c4f1e91c..686b9916b 100644 --- a/tests/collections/tcollections_to_string.nim +++ b/tests/collections/tcollections_to_string.nim @@ -9,9 +9,9 @@ import lists import critbits # Tests for tuples -doAssert $(1, 2, 3) == "(Field0: 1, Field1: 2, Field2: 3)" -doAssert $("1", "2", "3") == """(Field0: "1", Field1: "2", Field2: "3")""" -doAssert $('1', '2', '3') == """(Field0: '1', Field1: '2', Field2: '3')""" +doAssert $(1, 2, 3) == "(1, 2, 3)" +doAssert $("1", "2", "3") == """("1", "2", "3")""" +doAssert $('1', '2', '3') == """('1', '2', '3')""" # Tests for seqs doAssert $(@[1, 2, 3]) == "@[1, 2, 3]" diff --git a/tests/compiler/nim.cfg b/tests/compiler/nim.cfg new file mode 100644 index 000000000..6f49473aa --- /dev/null +++ b/tests/compiler/nim.cfg @@ -0,0 +1,7 @@ +# note: consider moving tests/compilerapi/ to tests/compiler/ since +# that's more predictable. + +# note: without this, tests may succeed locally but fail on CI (it can succeed +# locally even when compiling via `./bin/nim` because `$HOME/.nimble` is being +# used). +--path:"../../" # so we can `import compiler/foo` in this dir diff --git a/tests/compiler/tasciitables.nim b/tests/compiler/tasciitables.nim new file mode 100644 index 000000000..0a5ee0f05 --- /dev/null +++ b/tests/compiler/tasciitables.nim @@ -0,0 +1,109 @@ +import compiler/unittest_light +import compiler/asciitables + +import strformat + +proc alignTableCustom(s: string, delim = '\t', sep = ","): string = + for cell in parseTableCells(s, delim): + result.add fmt"({cell.row},{cell.col}): " + for i in cell.text.len..<cell.width: + result.add " " + result.add cell.text + if cell.col < cell.ncols-1: + result.add sep + if cell.col == cell.ncols-1 and cell.row < cell.nrows - 1: + result.add '\n' + +proc testAlignTable() = + block: # test with variable width columns + var ret = "" + ret.add "12\t143\tbcdef\n" + ret.add "2\t14394852020\tbcdef\n" + ret.add "45342\t1\tbf\n" + ret.add "45342\t1\tbsadfasdfasfdasdff\n" + ret.add "453232323232342\t1\tbsadfasdfasfdasdff\n" + ret.add "45342\t1\tbf\n" + ret.add "45342\t1\tb afasf a ff\n" + ret.add "4\t1\tbf\n" + + assertEquals alignTable(ret), + """ +12 143 bcdef +2 14394852020 bcdef +45342 1 bf +45342 1 bsadfasdfasfdasdff +453232323232342 1 bsadfasdfasfdasdff +45342 1 bf +45342 1 b afasf a ff +4 1 bf +""" + + assertEquals alignTable(ret, fill = '.', sep = ","), + """ +12.............,143........,bcdef............. +2..............,14394852020,bcdef............. +45342..........,1..........,bf................ +45342..........,1..........,bsadfasdfasfdasdff +453232323232342,1..........,bsadfasdfasfdasdff +45342..........,1..........,bf................ +45342..........,1..........,b afasf a ff...... +4..............,1..........,bf................ +""" + + assertEquals alignTableCustom(ret, sep = " "), + """ +(0,0): 12 (0,1): 143 (0,2): bcdef +(1,0): 2 (1,1): 14394852020 (1,2): bcdef +(2,0): 45342 (2,1): 1 (2,2): bf +(3,0): 45342 (3,1): 1 (3,2): bsadfasdfasfdasdff +(4,0): 453232323232342 (4,1): 1 (4,2): bsadfasdfasfdasdff +(5,0): 45342 (5,1): 1 (5,2): bf +(6,0): 45342 (6,1): 1 (6,2): b afasf a ff +(7,0): 4 (7,1): 1 (7,2): bf +""" + + block: # test with 1 column + var ret = "12\nasdfa\nadf" + assertEquals alignTable(ret), """ +12 +asdfa +adf """ + + block: # test with empty input + var ret = "" + assertEquals alignTable(ret), "" + + block: # test with 1 row + var ret = "abc\tdef" + assertEquals alignTable(ret), """ +abc def""" + + block: # test with 1 row ending in \t + var ret = "abc\tdef\t" + assertEquals alignTable(ret), """ +abc def """ + + block: # test with 1 row starting with \t + var ret = "\tabc\tdef\t" + assertEquals alignTable(ret), """ + abc def """ + + + block: # test with variable number of cols per row + var ret = """ +a1,a2,a3 + +b1 +c1,c2 +,d1 +""" + assertEquals alignTableCustom(ret, delim = ',', sep = ","), + """ +(0,0): a1,(0,1): a2,(0,2): a3 +(1,0): ,(1,1): ,(1,2): +(2,0): b1,(2,1): ,(2,2): +(3,0): c1,(3,1): c2,(3,2): +(4,0): ,(4,1): d1,(4,2): +""" + +testAlignTable() diff --git a/tests/compiler/tunittest_light.nim b/tests/compiler/tunittest_light.nim new file mode 100644 index 000000000..422474002 --- /dev/null +++ b/tests/compiler/tunittest_light.nim @@ -0,0 +1,55 @@ +import compiler/unittest_light + +proc testAssertEquals() = + assertEquals("foo", "foo") + doAssertRaises(AssertionError): + assertEquals("foo", "foo ") + +proc testMismatch() = + assertEquals(1+1, 2*1) + + let a = """ + some test with space at the end of lines + + can be hard to spot differences when diffing in a terminal + without this helper function + +""" + + let b = """ + some test with space at the end of lines + + can be hard to spot differences when diffing in a terminal + without this helper function + +""" + + let output = mismatch(a, b) + let expected = """ + +lhs:{ some test with space at the end of lines \n +\n + can be hard to spot differences when diffing in a terminal \n + without this helper function\n +\n +} +rhs:{ some test with space at the end of lines \n +\n + can be hard to spot differences when diffing in a terminal \n + without this helper function\n +\n +} +lhs.len: 144 rhs.len: 143 +first mismatch index: 110 +lhs[i]: {" "} +rhs[i]: {"\n"} +lhs[0..<i]:{ some test with space at the end of lines \n +\n + can be hard to spot differences when diffing in a terminal }""" + + if output != expected: + echo output + doAssert false + +testMismatch() +testAssertEquals() diff --git a/tests/cpp/t10148.nim b/tests/cpp/t10148.nim new file mode 100644 index 000000000..e8dd3098f --- /dev/null +++ b/tests/cpp/t10148.nim @@ -0,0 +1,29 @@ +discard """ + output: '''Expected successful exit''' + joinable: false +""" + +import os + +proc another_proc: string = + ## trigger many GC allocations + var x = @[""] + for i in 0..100: + x.add $i + result = "not_existent_path" + +proc findlib2: string = + let path = getEnv("MYLIB2_DOES_NOT_EXIST_PATH") + let another_path = another_proc() + GC_fullCollect() + + if path.len > 0 and dirExists(path): + path / "alib_does_not_matter.dll" + elif fileExists(another_path): + another_path + else: + quit("Expected successful exit", 0) + +proc imported_func*(a: cint): cstring {.importc, dynlib: findlib2().} + +echo imported_func(0) diff --git a/tests/cpp/t10241.nim b/tests/cpp/t10241.nim new file mode 100644 index 000000000..21d6a0f4e --- /dev/null +++ b/tests/cpp/t10241.nim @@ -0,0 +1,19 @@ +discard """ + targets: "cpp" + action: "compile" +""" + +type + String* {.importcpp: "std::string", header: "string".} = object + +proc initString*(): String + {.importcpp: "std::string()", header: "string".} + +proc append*(this: var String, str: String): var String + {.importcpp: "append", header: "string", discardable.} + +var + s1 = initString() + s2 = initString() + +s1.append s2 diff --git a/tests/deprecated/tannot.nim b/tests/deprecated/tannot.nim new file mode 100644 index 000000000..d14f6cc23 --- /dev/null +++ b/tests/deprecated/tannot.nim @@ -0,0 +1,9 @@ +discard """ + nimout: '''tannot.nim(9, 1) Warning: efgh; foo1 is deprecated [Deprecated] +tannot.nim(9, 8) Warning: abcd; foo is deprecated [Deprecated] +''' +""" + +let foo* {.deprecated: "abcd".} = 42 +var foo1* {.deprecated: "efgh".} = 42 +foo1 = foo diff --git a/tests/deprecated/tdeprecated.nim b/tests/deprecated/tdeprecated.nim index 955a7f6ad..920f350cc 100644 --- a/tests/deprecated/tdeprecated.nim +++ b/tests/deprecated/tdeprecated.nim @@ -1,9 +1,19 @@ discard """ - nimout: "a is deprecated [Deprecated]" + nimout: '''tdeprecated.nim(10, 3) Warning: a is deprecated [Deprecated] +tdeprecated.nim(17, 11) Warning: asdf; enum 'Foo' which contains field 'a' is deprecated [Deprecated] +''' """ +block: + var + a {.deprecated.}: array[0..11, int] -var - a {.deprecated.}: array[0..11, int] + a[8] = 1 -a[8] = 1 +block t10111: + type + Foo {.deprecated: "asdf" .} = enum + a + + var _ = a + diff --git a/tests/destructor/helper.nim b/tests/destructor/helper.nim new file mode 100644 index 000000000..466065747 --- /dev/null +++ b/tests/destructor/helper.nim @@ -0,0 +1,3 @@ +type + MyTestObject*[T] = object + p: ptr T diff --git a/tests/destructor/tdestructor.nim b/tests/destructor/tdestructor.nim index c9f1caf2d..09dce19ab 100644 --- a/tests/destructor/tdestructor.nim +++ b/tests/destructor/tdestructor.nim @@ -7,21 +7,28 @@ mygeneric1 constructed mygeneric1 destroyed ---- mygeneric2 constructed -mygeneric2 destroyed myobj destroyed +mygeneric2 destroyed ---- mygeneric3 constructed mygeneric1 destroyed ---- -mygeneric1 destroyed ----- +mydistinctObj constructed myobj destroyed +mygeneric2 destroyed +------------------ ---- ---- myobj destroyed +mygeneric1 destroyed +myobj destroyed +myobj destroyed +myobj destroyed +--- +myobj destroyed +myobj destroyed +myobj destroyed ''' - cmd: '''nim c --newruntime $file''' - disabled: "true" """ type @@ -29,6 +36,11 @@ type x, y: int p: pointer +proc `=destroy`(o: var TMyObj) = + if o.p != nil: dealloc o.p + echo "myobj destroyed" + +type TMyGeneric1[T] = object x: T @@ -36,37 +48,40 @@ type x: A y: B +proc `=destroy`(o: var TMyGeneric1[int]) = + echo "mygeneric1 destroyed" + +proc `=destroy`[A, B](o: var TMyGeneric2[A, B]) = + echo "mygeneric2 destroyed" + +type TMyGeneric3[A, B, C] = object x: A y: B z: C - TObjKind = enum A, B, C, D + TDistinctObjX = distinct TMyGeneric3[TMyObj, TMyGeneric2[int, int], int] + TDistinctObj = TDistinctObjX + + TObjKind = enum Z, A, B, C, D TCaseObj = object + z: TMyGeneric3[TMyObj, float, int] case kind: TObjKind + of Z: discard of A: x: TMyGeneric1[int] of B, C: y: TMyObj else: case innerKind: TObjKind + of Z: discard of A, B, C: p: TMyGeneric3[int, float, string] of D: q: TMyGeneric3[TMyObj, int, int] r: string -proc `=destroy`(o: var TMyObj) = - if o.p != nil: dealloc o.p - echo "myobj destroyed" - -proc `=destroy`(o: var TMyGeneric1[int]) = - echo "mygeneric1 destroyed" - -proc `=destroy`[A, B](o: var TMyGeneric2[A, B]) = - echo "mygeneric2 destroyed" - proc open: TMyObj = # allow for superfluous () result = (TMyObj(x: 1, y: 2, p: alloc(3))) @@ -95,6 +110,12 @@ proc mygeneric3 = echo "mygeneric3 constructed" +proc mydistinctObj = + var x = TMyGeneric3[TMyObj, TMyGeneric2[int, int], int]( + x: open(), y: TMyGeneric2[int, int](x: 5, y: 15), z: 20) + + echo "mydistinctObj constructed" + echo "----" myobj() @@ -107,9 +128,11 @@ mygeneric2[int](10) echo "----" mygeneric3() +echo "----" +mydistinctObj() + proc caseobj = block: - echo "----" var o1 = TCaseObj(kind: A, x: TMyGeneric1[int](x: 10)) block: @@ -121,10 +144,16 @@ proc caseobj = var o3 = TCaseObj(kind: D, innerKind: B, r: "test", p: TMyGeneric3[int, float, string](x: 10, y: 1.0, z: "test")) - block: - echo "----" - var o4 = TCaseObj(kind: D, innerKind: D, r: "test", - q: TMyGeneric3[TMyObj, int, int](x: open(), y: 1, z: 0)) +echo "------------------" caseobj() +proc caseobj_test_sink: TCaseObj = + # check that lifted sink can destroy case val correctly + result = TCaseObj(kind: D, innerKind: D, r: "test", + q: TMyGeneric3[TMyObj, int, int](x: open(), y: 1, z: 0)) + result = TCaseObj(kind: B, y: open()) + + +echo "---" +discard caseobj_test_sink() \ No newline at end of file diff --git a/tests/destructor/terror_module.nim b/tests/destructor/terror_module.nim new file mode 100644 index 000000000..f3d7c9b26 --- /dev/null +++ b/tests/destructor/terror_module.nim @@ -0,0 +1,20 @@ +discard """ +joinable: false +cmd: "nim check $file" +errormsg: "type bound operation `=deepcopy` can be defined only in the same module with its type (MyTestObject)" +nimout: ''' +terror_module.nim(14, 1) Error: type bound operation `=destroy` can be defined only in the same module with its type (MyTestObject) +terror_module.nim(16, 1) Error: type bound operation `=sink` can be defined only in the same module with its type (MyTestObject) +terror_module.nim(18, 1) Error: type bound operation `=` can be defined only in the same module with its type (MyTestObject) +terror_module.nim(20, 1) Error: type bound operation `=deepcopy` can be defined only in the same module with its type (MyTestObject) +''' +""" +import helper + +proc `=destroy`[T](x: var MyTestObject[T]) = discard + +proc `=sink`[T](x: var MyTestObject[T], y:MyTestObject[T]) = discard + +proc `=`[T](x: var MyTestObject[T], y: MyTestObject[T]) = discard + +proc `=deepcopy`[T](x: ptr MyTestObject[T]): ptr MyTestObject[T] = discard diff --git a/tests/discard/tneedsdiscard.nim b/tests/discard/tneedsdiscard.nim index 7d2997b3f..d9483947f 100644 --- a/tests/discard/tneedsdiscard.nim +++ b/tests/discard/tneedsdiscard.nim @@ -1,5 +1,5 @@ discard """ - errormsg: '''expression 'open(f, "arg.txt", fmRead, -1)' is of type 'bool' and has to be discarded; start of expression here: tneedsdiscard.nim(7, 2)''' + errormsg: '''expression 'open(f, "arg.txt", fmRead, -1)' is of type 'bool' and has to be discarded; start of expression here: tneedsdiscard.nim(7, 3)''' line: 10 """ diff --git a/tests/enum/tenumfieldpragma.nim b/tests/enum/tenumfieldpragma.nim new file mode 100644 index 000000000..604a8f019 --- /dev/null +++ b/tests/enum/tenumfieldpragma.nim @@ -0,0 +1,22 @@ +discard """ + nimout: '''tenumfieldpragma.nim(20, 10) Warning: d is deprecated [Deprecated] +tenumfieldpragma.nim(21, 10) Warning: e is deprecated [Deprecated] +tenumfieldpragma.nim(22, 10) Warning: f is deprecated [Deprecated] +''' +""" + +type + A = enum + a + b = "abc" + c = (10, "def") + d {.deprecated.} + e {.deprecated.} = "ghi" + f {.deprecated.} = (20, "jkl") + +var v1 = a +var v2 = b +var v3 = c +var v4 = d +var v5 = e +var v6 = f diff --git a/tests/deprecated/tnoannot.nim b/tests/enum/tenumfieldpragmanoannot.nim index ac168952e..47f920827 100644 --- a/tests/deprecated/tnoannot.nim +++ b/tests/enum/tenumfieldpragmanoannot.nim @@ -1,7 +1,10 @@ discard """ errormsg: "annotation to deprecated not supported here" - line: 7 + line: 8 """ -var foo* {.deprecated.} = 42 -var foo1* {.deprecated: "no".} = 42 +type + A = enum + a {.deprecated: "njshd".} + +var v1 = a diff --git a/tests/errmsgs/m8794.nim b/tests/errmsgs/m8794.nim new file mode 100644 index 000000000..12e61cf54 --- /dev/null +++ b/tests/errmsgs/m8794.nim @@ -0,0 +1,2 @@ +type Foo3* = object + a1: int diff --git a/tests/errmsgs/t8794.nim b/tests/errmsgs/t8794.nim new file mode 100644 index 000000000..7f16a42fe --- /dev/null +++ b/tests/errmsgs/t8794.nim @@ -0,0 +1,39 @@ +discard """ + cmd: "nim check $options $file" + errormsg: "" + nimout: ''' +t8794.nim(39, 27) Error: undeclared field: 'a3' for type m8794.Foo3[declared in m8794.nim(1, 6)] +''' +""" + + + + + + + + + + + + +## line 20 + +## issue #8794 + +import m8794 + +when false: # pending https://github.com/nim-lang/Nim/pull/10091 add this + type Foo = object + a1: int + + discard Foo().a2 + +type Foo3b = Foo3 +var x2: Foo3b + +proc getFun[T](): T = + var a: T + a + +discard getFun[type(x2)]().a3 diff --git a/tests/errmsgs/t9768.nim b/tests/errmsgs/t9768.nim new file mode 100644 index 000000000..18588c87c --- /dev/null +++ b/tests/errmsgs/t9768.nim @@ -0,0 +1,30 @@ +discard """ + errmsg: "unhandled exception:" + file: "system.nim" + nimout: ''' +stack trace: (most recent call last) +t9768.nim(28, 33) main +t9768.nim(23, 11) foo1 +''' +""" + + + + + + + + + + +## line 20 + +proc foo1(a: int): auto = + doAssert a < 4 + result = a * 2 + +proc main()= + static: + if foo1(1) > 0: discard foo1(foo1(2)) + +main() diff --git a/tests/errmsgs/tinteger_literals.nim b/tests/errmsgs/tinteger_literals.nim new file mode 100644 index 000000000..98c92a227 --- /dev/null +++ b/tests/errmsgs/tinteger_literals.nim @@ -0,0 +1,15 @@ +discard """ +cmd: "nim check $file" +errormsg: "number out of range: '300'u8'" +nimout: ''' +tinteger_literals.nim(12, 9) Error: number out of range: '18446744073709551616'u64' +tinteger_literals.nim(13, 9) Error: number out of range: '9223372036854775808'i64' +tinteger_literals.nim(14, 9) Error: number out of range: '9223372036854775808' +tinteger_literals.nim(15, 9) Error: number out of range: '300'u8' +''' +""" + +discard 18446744073709551616'u64 # high(uint64) + 1 +discard 9223372036854775808'i64 # high(int64) + 1 +discard 9223372036854775808 # high(int64) + 1 +discard 300'u8 \ No newline at end of file diff --git a/tests/errmsgs/tnested_generic_instantiation.nim b/tests/errmsgs/tnested_generic_instantiation.nim index 6aea7cbcc..77353605c 100644 --- a/tests/errmsgs/tnested_generic_instantiation.nim +++ b/tests/errmsgs/tnested_generic_instantiation.nim @@ -17,3 +17,9 @@ converter toWrapped[T](value: T): Wrapped[T] = let result = Plain() discard $result + +proc foo[T2](a: Wrapped[T2]) = + # Error: generic instantiation too nested + discard $a + +foo(result) diff --git a/tests/errmsgs/tnested_generic_instantiation2.nim b/tests/errmsgs/tnested_generic_instantiation2.nim new file mode 100644 index 000000000..d9bba15b0 --- /dev/null +++ b/tests/errmsgs/tnested_generic_instantiation2.nim @@ -0,0 +1,27 @@ +discard """ +errormsg: "generic instantiation too nested" +""" + +#[ +bug #4766 +see also: tnested_generic_instantiation.nim +]# + +proc toString*[T](x: T) = + for name, value in fieldPairs(x): + when compiles(toString(value)): + discard + toString(value) + +type + Plain = ref object + discard + + Wrapped[T] = object + value: T + +converter toWrapped[T](value: T): Wrapped[T] = + Wrapped[T](value: value) + +let result = Plain() +toString(result) diff --git a/tests/errmsgs/treportunused.nim b/tests/errmsgs/treportunused.nim index c74fea46f..b339e06bf 100644 --- a/tests/errmsgs/treportunused.nim +++ b/tests/errmsgs/treportunused.nim @@ -1,12 +1,12 @@ discard """ nimout: ''' -treportunused.nim(19, 10) Hint: 'treportunused.s1(a: string)[declared in treportunused.nim(19, 9)]' is declared but not used [XDeclaredButNotUsed] +treportunused.nim(19, 10) Hint: 's1' is declared but not used [XDeclaredButNotUsed] treportunused.nim(26, 5) Hint: 's8' is declared but not used [XDeclaredButNotUsed] -treportunused.nim(22, 6) Hint: 'treportunused.s4()[declared in treportunused.nim(22, 5)]' is declared but not used [XDeclaredButNotUsed] +treportunused.nim(22, 6) Hint: 's4' is declared but not used [XDeclaredButNotUsed] treportunused.nim(25, 7) Hint: 's7' is declared but not used [XDeclaredButNotUsed] treportunused.nim(24, 7) Hint: 's6' is declared but not used [XDeclaredButNotUsed] -treportunused.nim(23, 6) Hint: 'treportunused.s5(a: T)[declared in treportunused.nim(23, 5)]' is declared but not used [XDeclaredButNotUsed] -treportunused.nim(20, 10) Hint: 'treportunused.s2()[declared in treportunused.nim(20, 9)]' is declared but not used [XDeclaredButNotUsed] +treportunused.nim(23, 6) Hint: 's5' is declared but not used [XDeclaredButNotUsed] +treportunused.nim(20, 10) Hint: 's2' is declared but not used [XDeclaredButNotUsed] treportunused.nim(29, 6) Hint: 's11' is declared but not used [XDeclaredButNotUsed] treportunused.nim(27, 5) Hint: 's9' is declared but not used [XDeclaredButNotUsed] treportunused.nim(21, 10) Hint: 's3' is declared but not used [XDeclaredButNotUsed] diff --git a/tests/errmsgs/tunknown_named_parameter.nim b/tests/errmsgs/tunknown_named_parameter.nim index b6b855136..8a3bcaf03 100644 --- a/tests/errmsgs/tunknown_named_parameter.nim +++ b/tests/errmsgs/tunknown_named_parameter.nim @@ -2,10 +2,6 @@ discard """ cmd: "nim check $file" errormsg: "type mismatch: got <string, set[char], maxsplits: int literal(1)>" nimout: ''' -proc rsplit(s: string; sep: string; maxsplit: int = -1): seq[string] - first type mismatch at position: 2 - required type: string - but expression '{':'}' is of type: set[char] proc rsplit(s: string; sep: char; maxsplit: int = -1): seq[string] first type mismatch at position: 2 required type: char @@ -13,6 +9,10 @@ proc rsplit(s: string; sep: char; maxsplit: int = -1): seq[string] proc rsplit(s: string; seps: set[char] = Whitespace; maxsplit: int = -1): seq[string] first type mismatch at position: 3 unknown named parameter: maxsplits +proc rsplit(s: string; sep: string; maxsplit: int = -1): seq[string] + first type mismatch at position: 2 + required type: string + but expression '{':'}' is of type: set[char] expression: rsplit("abc:def", {':'}, maxsplits = 1) ''' diff --git a/tests/exception/t9657.nim b/tests/exception/t9657.nim index 5d5164f4f..c96a0a597 100644 --- a/tests/exception/t9657.nim +++ b/tests/exception/t9657.nim @@ -1,6 +1,8 @@ discard """ action: run exitcode: 1 + target: "c" """ +# todo: remove `target: "c"` workaround once #10343 is properly fixed close stdmsg writeLine stdmsg, "exception!" diff --git a/tests/exception/tdefer1.nim b/tests/exception/tdefer1.nim index b84ba7681..db46bad27 100644 --- a/tests/exception/tdefer1.nim +++ b/tests/exception/tdefer1.nim @@ -1,6 +1,5 @@ discard """ output: '''hi -hi 1 hi 2 @@ -10,13 +9,6 @@ A''' # bug #1742 -template test(): untyped = - let a = 0 - defer: echo "hi" - a - -let i = test() - import strutils let x = try: parseInt("133a") except: -1 @@ -31,7 +23,7 @@ template atFuncEnd = template testB(): untyped = let a = 0 - defer: echo "hi" # Delete this line to make it work + defer: echo "hi" a proc main = diff --git a/tests/float/tfloatnan.nim b/tests/float/tfloatnan.nim index 29937a862..8f384c3d9 100644 --- a/tests/float/tfloatnan.nim +++ b/tests/float/tfloatnan.nim @@ -14,3 +14,31 @@ echo "Nim: ", f32, " (float)" let f64: float64 = NaN echo "Nim: ", f64, " (double)" + +block: # issue #10305 + # with `-O3 -ffast-math`, generated C/C++ code is not nan compliant + # user can pass `--passC:-ffast-math` if he doesn't care. + proc fun() = + # this was previously failing at compile time with a nim compiler + # that was compiled with `nim cpp -d:release` + let a1 = 0.0 + let a = 0.0/a1 + let b1 = a == 0.0 + let b2 = a == a + doAssert not b1 + doAssert not b2 + + proc fun2(i: int) = + # this was previously failing simply with `nim cpp -d:release`; the + # difference with above example is that optimization (const folding) can't + # take place in this example to hide the non-compliant nan bug. + let a = 0.0/(i.float) + let b1 = a == 0.0 + let b2 = a == a + doAssert not b1 + doAssert not b2 + + static: fun() + fun() + fun2(0) + diff --git a/tests/gc/gcbench.nim b/tests/gc/gcbench.nim index 782daf793..fc5d6864f 100644 --- a/tests/gc/gcbench.nim +++ b/tests/gc/gcbench.nim @@ -65,55 +65,58 @@ proc newNode(L, r: PNode): PNode = const kStretchTreeDepth = 18 # about 16Mb kLongLivedTreeDepth = 16 # about 4Mb - kArraySize = 500000 # about 4Mb + kArraySize = 500000 # about 4Mb kMinTreeDepth = 4 kMaxTreeDepth = 16 +when not declared(withScratchRegion): + template withScratchRegion(body: untyped) = body + # Nodes used by a tree of a given size -proc TreeSize(i: int): int = return ((1 shl (i + 1)) - 1) +proc treeSize(i: int): int = return ((1 shl (i + 1)) - 1) # Number of iterations to use for a given tree depth -proc NumIters(i: int): int = - return 2 * TreeSize(kStretchTreeDepth) div TreeSize(i) +proc numIters(i: int): int = + return 2 * treeSize(kStretchTreeDepth) div treeSize(i) # Build tree top down, assigning to older objects. -proc Populate(iDepth: int, thisNode: PNode) = +proc populate(iDepth: int, thisNode: PNode) = if iDepth <= 0: return else: new(thisNode.left) new(thisNode.right) - Populate(iDepth-1, thisNode.left) - Populate(iDepth-1, thisNode.right) + populate(iDepth-1, thisNode.left) + populate(iDepth-1, thisNode.right) # Build tree bottom-up -proc MakeTree(iDepth: int): PNode = +proc makeTree(iDepth: int): PNode = if iDepth <= 0: new(result) else: - return newNode(MakeTree(iDepth-1), MakeTree(iDepth-1)) + return newNode(makeTree(iDepth-1), makeTree(iDepth-1)) -proc PrintDiagnostics() = +proc printDiagnostics() = echo("Total memory available: " & $getTotalMem() & " bytes") echo("Free memory: " & $getFreeMem() & " bytes") -proc TimeConstruction(depth: int) = +proc timeConstruction(depth: int) = var root, tempTree: PNode iNumIters: int - iNumIters = NumIters(depth) + iNumIters = numIters(depth) echo("Creating " & $iNumIters & " trees of depth " & $depth) var t = epochTime() for i in 0..iNumIters-1: new(tempTree) - Populate(depth, tempTree) + populate(depth, tempTree) tempTree = nil echo("\tTop down construction took " & $(epochTime() - t) & "msecs") t = epochTime() for i in 0..iNumIters-1: - tempTree = MakeTree(depth) + tempTree = makeTree(depth) tempTree = nil echo("\tBottom up construction took " & $(epochTime() - t) & "msecs") @@ -127,39 +130,42 @@ proc main() = echo("Garbage Collector Test") echo(" Stretching memory with a binary tree of depth " & $kStretchTreeDepth) - PrintDiagnostics() + printDiagnostics() var t = epochTime() # Stretch the memory space quickly - tempTree = MakeTree(kStretchTreeDepth) - tempTree = nil + withScratchRegion: + tempTree = makeTree(kStretchTreeDepth) + tempTree = nil # Create a long lived object echo(" Creating a long-lived binary tree of depth " & $kLongLivedTreeDepth) new(longLivedTree) - Populate(kLongLivedTreeDepth, longLivedTree) + populate(kLongLivedTreeDepth, longLivedTree) # Create long-lived array, filling half of it echo(" Creating a long-lived array of " & $kArraySize & " doubles") - newSeq(myarray, kArraySize) - for i in 0..kArraySize div 2 - 1: - myarray[i] = 1.0 / toFloat(i) + withScratchRegion: + newSeq(myarray, kArraySize) + for i in 0..kArraySize div 2 - 1: + myarray[i] = 1.0 / toFloat(i) - PrintDiagnostics() + printDiagnostics() - var d = kMinTreeDepth - while d <= kMaxTreeDepth: - TimeConstruction(d) - inc(d, 2) + var d = kMinTreeDepth + while d <= kMaxTreeDepth: + withScratchRegion: + timeConstruction(d) + inc(d, 2) - if longLivedTree == nil or myarray[1000] != 1.0/1000.0: - echo("Failed") - # fake reference to LongLivedTree - # and array to keep them from being optimized away + if longLivedTree == nil or myarray[1000] != 1.0/1000.0: + echo("Failed") + # fake reference to LongLivedTree + # and array to keep them from being optimized away var elapsed = epochTime() - t - PrintDiagnostics() + printDiagnostics() echo("Completed in " & $elapsed & "ms. Success!") when defined(GC_setMaxPause): diff --git a/tests/gc/gcleak.nim b/tests/gc/gcleak.nim index 24ac1036a..0b2e6e14d 100644 --- a/tests/gc/gcleak.nim +++ b/tests/gc/gcleak.nim @@ -12,7 +12,7 @@ type proc makeObj(): TTestObj = result.x = "Hello" -for i in 1 .. 1_000_000: +for i in 1 .. 100_000: when defined(gcMarkAndSweep) or defined(boehmgc): GC_fullcollect() var obj = makeObj() diff --git a/tests/gc/thavlak.nim b/tests/gc/thavlak.nim index 09c07785e..2d8df7c1a 100644 --- a/tests/gc/thavlak.nim +++ b/tests/gc/thavlak.nim @@ -12,9 +12,10 @@ Found 1 loops (including artificial root node) (5)''' # bug #3184 -import tables -import sequtils -import sets +import tables, sequtils, sets, strutils + +when not declared(withScratchRegion): + template withScratchRegion(body: untyped) = body type BasicBlock = object @@ -418,8 +419,9 @@ proc run(self: var LoopTesterApp) = echo "15000 dummy loops" for i in 1..15000: - var h = newHavlakLoopFinder(self.cfg, newLsg()) - var res = h.findLoops + withScratchRegion: + var h = newHavlakLoopFinder(self.cfg, newLsg()) + var res = h.findLoops echo "Constructing CFG..." var n = 2 @@ -446,12 +448,17 @@ proc run(self: var LoopTesterApp) = var sum = 0 for i in 1..5: - write stdout, "." - flushFile(stdout) - var hlf = newHavlakLoopFinder(self.cfg, newLsg()) - sum += hlf.findLoops - #echo getOccupiedMem() + withScratchRegion: + write stdout, "." + flushFile(stdout) + var hlf = newHavlakLoopFinder(self.cfg, newLsg()) + sum += hlf.findLoops + #echo getOccupiedMem() echo "\nFound ", loops, " loops (including artificial root node) (", sum, ")" + when false: + echo("Total memory available: " & formatSize(getTotalMem()) & " bytes") + echo("Free memory: " & formatSize(getFreeMem()) & " bytes") + var l = newLoopTesterApp() l.run diff --git a/tests/gc/tlists.nim b/tests/gc/tlists.nim index 26b32396c..959cc5f7c 100644 --- a/tests/gc/tlists.nim +++ b/tests/gc/tlists.nim @@ -10,15 +10,13 @@ import lists import strutils proc mkleak() = - # allocate 10 MB via linked lists + # allocate 1 MB via linked lists let numberOfLists = 100 for i in countUp(1, numberOfLists): var leakList = initDoublyLinkedList[string]() - let numberOfLeaks = 50000 + let numberOfLeaks = 5000 for j in countUp(1, numberOfLeaks): - let leakSize = 200 - let leaked = newString(leakSize) - leakList.append(leaked) + leakList.append(newString(200)) proc mkManyLeaks() = for i in 0..0: @@ -29,7 +27,7 @@ proc mkManyLeaks() = # lists and bring the memory usage down to a few MB's. GC_fullCollect() when false: echo getOccupiedMem() - if getOccupiedMem() > 8 * 200 * 50_000 * 2: + if getOccupiedMem() > 8 * 200 * 5000 * 2: echo GC_getStatistics() quit "leaking" echo "Success" diff --git a/tests/generics/treentranttypes.nim b/tests/generics/treentranttypes.nim index 2ef049ce2..31fa25293 100644 --- a/tests/generics/treentranttypes.nim +++ b/tests/generics/treentranttypes.nim @@ -1,6 +1,6 @@ discard """ output: ''' -(Field0: 10, Field1: (Field0: "test", Field1: 1.2)) +(10, ("test", 1.2)) 3x3 Matrix [[0.0, 2.0, 3.0], [2.0, 0.0, 5.0], [2.0, 0.0, 5.0]] 2x3 Matrix [[0.0, 2.0, 3.0], [2.0, 0.0, 5.0]] diff --git a/tests/iter/titervaropenarray.nim b/tests/iter/titervaropenarray.nim index 701f652df..4469fdcf5 100644 --- a/tests/iter/titervaropenarray.nim +++ b/tests/iter/titervaropenarray.nim @@ -1,5 +1,6 @@ discard """ output: "123" + targets: "C" """ # Try to break the transformation pass: iterator iterAndZero(a: var openArray[int]): int = diff --git a/tests/js/t9410.nim b/tests/js/t9410.nim index 9aca6d45b..78c329a24 100644 --- a/tests/js/t9410.nim +++ b/tests/js/t9410.nim @@ -1,13 +1,3 @@ -template doAssert(exp: untyped) = - when defined(echot9410): - let r = exp - echo $(instantiationInfo().line) & ":\n " & astToStr(exp) & "\n was " & repr(r) - when not defined(noassertt9410): - system.doAssert r - else: - when not defined(noassertt9410): - system.doAssert exp - template tests = block: var i = 0 @@ -428,6 +418,33 @@ template tests = let xptr2 = cast[type(xptr)](p2) doAssert xptr == xptr2 + + block: # var types + block t10202: + type Point = object + x: float + y: float + + var points: seq[Point] + + points.add(Point(x:1, y:2)) + + for i, p in points.mpairs: + p.x += 1 + + doAssert points[0].x == 2 + + block: + var ints = @[1, 2, 3] + for i, val in mpairs ints: + val *= 10 + doAssert ints == @[10, 20, 30] + + block: + var seqOfSeqs = @[@[1, 2], @[3, 4]] + for i, val in mpairs seqOfSeqs: + val[0] *= 10 + doAssert seqOfSeqs == @[@[10, 2], @[30, 4]] when false: block: # openarray diff --git a/tests/js/tclosures.nim b/tests/js/tclosures.nim index 659c60092..70037f4bf 100644 --- a/tests/js/tclosures.nim +++ b/tests/js/tclosures.nim @@ -49,3 +49,47 @@ for i in 1 .. 10: let results = runCallbacks() doAssert(expected == $results) + +block issue7048: + block: + proc foo(x: seq[int]): auto = + proc bar: int = x[1] + bar + + var stuff = @[1, 2] + let f = foo(stuff) + stuff[1] = 321 + doAssert f() == 2 + + block: + proc foo(x: tuple[things: string]; y: array[3, int]): auto = + proc very: auto = + proc deeply: auto = + proc nested: (char, int) = (x.things[0], y[1]) + nested + deeply + very() + + var + stuff = (things: "NIM") + stuff2 = [32, 64, 96] + let f = foo(stuff, stuff2) + stuff.things = "VIM" + stuff2[1] *= 10 + doAssert f()() == ('N', 64) + doAssert (stuff.things[0], stuff2[1]) == ('V', 640) + + block: + proc foo(x: ptr string): auto = + proc bar(): int = len(x[]) + bar + + var + s1 = "xyz" + s2 = "stuff" + p = addr s1 + + let f = foo(p) + p = addr s2 + doAssert len(p[]) == 5 + doAssert f() == 3 \ No newline at end of file diff --git a/tests/js/test1.nim b/tests/js/test1.nim index 7f1d346f0..73e7a37ed 100644 --- a/tests/js/test1.nim +++ b/tests/js/test1.nim @@ -20,3 +20,35 @@ proc onButtonClick(inputElement: string) {.exportc.} = onButtonClick(inputElement) +block: + var s: string + s.add("hi") + doAssert(s == "hi") + +block: + var s: string + s.insert("hi", 0) + doAssert(s == "hi") + +block: + var s: string + s.setLen(2) + s[0] = 'h' + s[1] = 'i' + doAssert(s == "hi") + +block: + var s: seq[int] + s.setLen(2) + doAssert(s == @[0, 0]) + +block: + var s: seq[int] + s.insert(2, 0) + doAssert(s == @[2]) + +block: + var s: seq[int] + s.add(2) + doAssert(s == @[2]) + diff --git a/tests/js/test2.nim b/tests/js/test2.nim index 0bfb99139..9ecdbb35c 100644 --- a/tests/js/test2.nim +++ b/tests/js/test2.nim @@ -9,6 +9,9 @@ js 3.14 # This file tests the JavaScript generator +doAssert getCurrentException() == nil +doAssert getCurrentExceptionMsg() == "" + # #335 proc foo() = var bar = "foo" diff --git a/tests/js/testobjs.nim b/tests/js/testobjs.nim index 78f0b4766..b61d06471 100644 --- a/tests/js/testobjs.nim +++ b/tests/js/testobjs.nim @@ -54,3 +54,20 @@ let test2 = test1 echo toJSON(test1) echo toJSON(test2) + +block issue10005: + type + Player = ref object of RootObj + id*: string + nickname*: string + color*: string + + proc newPlayer(nickname: string, color: string): Player = + let pl = Player(color: "#123", nickname: nickname) + return Player( + id: "foo", + nickname: nickname, + color: color, + ) + + doAssert newPlayer("foo", "#1232").nickname == "foo" diff --git a/tests/js/tjsffi.nim b/tests/js/tjsffi.nim index 2420c60f6..8bd40a3c4 100644 --- a/tests/js/tjsffi.nim +++ b/tests/js/tjsffi.nim @@ -22,6 +22,13 @@ true Event { name: 'click: test' } Event { name: 'reloaded: test' } Event { name: 'updates: test' } +true +true +true +true +true +true +true ''' """ @@ -317,3 +324,12 @@ block: jslib.subscribe("updates"): console.log jsarguments[0] +block: + + echo jsUndefined == jsNull + echo jsUndefined == nil + echo jsNull == nil + echo jsUndefined.isNil + echo jsNull.isNil + echo jsNull.isNull + echo jsUndefined.isUndefined diff --git a/tests/macros/tquotedo.nim b/tests/macros/tquotedo.nim index cd1f69116..0aae87bf0 100644 --- a/tests/macros/tquotedo.nim +++ b/tests/macros/tquotedo.nim @@ -3,6 +3,7 @@ output: ''' 123 Hallo Welt Hallo Welt +1 ''' """ @@ -23,3 +24,13 @@ macro foobar(arg: untyped): untyped = foobar: echo "Hallo Welt" + +# bug #3744 +import macros +macro t(): untyped = + return quote do: + proc tp(): int = + result = 1 +t() + +echo tp() diff --git a/tests/macros/tvarargsuntyped.nim b/tests/macros/tvarargsuntyped.nim index 657ed47d6..5a06adcca 100644 --- a/tests/macros/tvarargsuntyped.nim +++ b/tests/macros/tvarargsuntyped.nim @@ -3,7 +3,9 @@ discard """ (left: 2, r: 7, x: 8, height: 4, s: test, width: 3, y: 9, top: 1, g: 7, b: 8) (left: 2, r: 7, x: 8, height: 4, s: text, width: 3, y: 9, top: 1, g: 7, b: 8) (left: 2, r: 7, x: 8, height: 4, s: text, width: 3, y: 9, top: 4, g: 7, b: 8) -(left: 2, r: 7, x: 8, height: 4, s: test, width: 3, y: 9, top: 1, g: 7, b: 8)''' +(left: 2, r: 7, x: 8, height: 4, s: test, width: 3, y: 9, top: 1, g: 7, b: 8) +10 +hello 18.0''' """ import macros @@ -78,3 +80,29 @@ let width: cint = 3 let height: cint = 4 bar(rect(top, left, width, height), "test", point(8, 9), color(7,7,8)) + + +# bug #10075 + +import macros + +proc convert_hidden_stdconv(args: NimNode): NimNode = + var n = args + while n.len == 1 and n[0].kind == nnkHiddenStdConv: + n = n[0][1] + return n + +macro t2(s: int, v: varargs[untyped]): untyped = + let v = convert_hidden_stdconv(v) + echo v.treeRepr + let (v1, v2) = (v[0], v[1]) + quote do: + echo `v1`, " ", `v2` + +template t1(s: int, v: varargs[typed]) = + #static: + # dumpTree v + echo s + t2(s, v) + +t1(10, "hello", 18.0) diff --git a/tests/manyloc/keineschweine/enet_server/enet_server.nim b/tests/manyloc/keineschweine/enet_server/enet_server.nim index 3bb259386..336e57755 100644 --- a/tests/manyloc/keineschweine/enet_server/enet_server.nim +++ b/tests/manyloc/keineschweine/enet_server/enet_server.nim @@ -103,7 +103,7 @@ handlers[HZoneJoinReq] = proc(client: PClient; buffer: PBuffer) = when true: - import parseopt, matchers, os, json + import parseopt, os, json if enetInit() != 0: diff --git a/tests/manyloc/keineschweine/server/old_dirserver.nim b/tests/manyloc/keineschweine/server/old_dirserver.nim index cfb0b0377..390b738aa 100644 --- a/tests/manyloc/keineschweine/server/old_dirserver.nim +++ b/tests/manyloc/keineschweine/server/old_dirserver.nim @@ -157,7 +157,7 @@ proc poll*(timeout: int = 250) = c.outputBuf.flush() when true: - import parseopt, matchers, strutils + import parseopt, strutils var cfgFile = "dirserver_settings.json" for kind, key, val in getOpt(): case kind diff --git a/tests/manyloc/keineschweine/server/old_sg_server.nim b/tests/manyloc/keineschweine/server/old_sg_server.nim index d046df9dd..473880e2b 100644 --- a/tests/manyloc/keineschweine/server/old_sg_server.nim +++ b/tests/manyloc/keineschweine/server/old_sg_server.nim @@ -142,7 +142,7 @@ proc poll*(timeout: int = 250) = c.outputBuf.flush() when true: - import parseopt, matchers, strutils + import parseopt, strutils var zoneCfgFile = "./server_settings.json" for kind, key, val in getOpt(): case kind diff --git a/tests/manyloc/nake/nakefile.nim b/tests/manyloc/nake/nakefile.nim index 3e8609169..35ed3cbb0 100644 --- a/tests/manyloc/nake/nakefile.nim +++ b/tests/manyloc/nake/nakefile.nim @@ -76,13 +76,14 @@ task "testskel", "create skeleton test dir for testing": task "clean", "cleanup generated files": var dirs = @["nimcache", "server"/"nimcache"] - dirs.map(proc(x: var string) = + dirs.apply(proc(x: var string) = if existsDir(x): removeDir(x)) task "download", "download game assets": var skipAssets = false path = expandFilename("data") + client = newHttpClient() path.add DirSep path.add(extractFilename(GameAssets)) if existsFile(path): @@ -101,7 +102,7 @@ task "download", "download game assets": echo "Downloading from ", GameAssets if not skipAssets: echo "Downloading to ", path - downloadFile GameAssets, path + client.downloadFile(GameAssets, path) echo "Download finished" let targetDir = parentDir(parentDir(path)) @@ -126,7 +127,7 @@ task "download", "download game assets": else: return path = extractFilename(BinLibs) - downloadFile BinLibs, path + client.downloadFile(BinLibs, path) echo "Downloaded dem libs ", path when true: echo "Unpack it yourself, sorry." else: ## this crashes, dunno why diff --git a/tests/manyloc/standalone/barebone.nim b/tests/manyloc/standalone/barebone.nim index 9d75f8f2e..0b38616b2 100644 --- a/tests/manyloc/standalone/barebone.nim +++ b/tests/manyloc/standalone/barebone.nim @@ -1,4 +1,8 @@ - +discard """ +ccodecheck: "\\i !@('systemInit')" +ccodecheck: "\\i !@('systemDatInit')" +output: "hello" +""" # bug #2041: Macros need to be available for os:standalone! import macros diff --git a/tests/metatype/tmetatype_issues.nim b/tests/metatype/tmetatype_issues.nim index c5040f9ba..c184689a1 100644 --- a/tests/metatype/tmetatype_issues.nim +++ b/tests/metatype/tmetatype_issues.nim @@ -1,7 +1,7 @@ discard """ output:''' void -(Field0: "string", Field1: "string") +("string", "string") 1 mod 7 @[2, 2, 2, 2, 2] impl 2 called @@ -9,6 +9,7 @@ asd Foo Bar ''' +joinable: false """ import typetraits, macros diff --git a/tests/metatype/ttypetraits2.nim b/tests/metatype/ttypetraits2.nim new file mode 100644 index 000000000..a436da7ec --- /dev/null +++ b/tests/metatype/ttypetraits2.nim @@ -0,0 +1,18 @@ +# todo: merge with $nimc_D/tests/metatype/ttypetraits.nim (currently disabled) + +from typetraits import `$` # checks fix for https://github.com/c-blake/cligen/issues/84 + +import typetraits + +block: # isNamedTuple + type Foo1 = (a:1,).type + type Foo2 = (Field0:1,).type + type Foo3 = ().type + type Foo4 = object + + doAssert (a:1,).type.isNamedTuple + doAssert Foo1.isNamedTuple + doAssert Foo2.isNamedTuple + doAssert not Foo3.isNamedTuple + doAssert not Foo4.isNamedTuple + doAssert not (1,).type.isNamedTuple diff --git a/tests/method/tmapper.nim b/tests/method/tmapper.nim index a5d03f700..9162d0eec 100644 --- a/tests/method/tmapper.nim +++ b/tests/method/tmapper.nim @@ -1,5 +1,5 @@ discard """ - errormsg: "invalid declaration order; cannot attach 'step' to method defined here: tmapper.nim(22, 7)" + errormsg: "invalid declaration order; cannot attach 'step' to method defined here: tmapper.nim(22, 8)" line: 25 """ diff --git a/tests/misc/tparseopt.nim b/tests/misc/tparseopt.nim index cbed5d476..7d5071c3e 100644 --- a/tests/misc/tparseopt.nim +++ b/tests/misc/tparseopt.nim @@ -29,55 +29,120 @@ kind: cmdLongOption key:val -- left: kind: cmdLongOption key:val -- debug:3 kind: cmdShortOption key:val -- l:4 kind: cmdShortOption key:val -- r:2''' +joinable: false """ -from parseopt import nil -from parseopt2 import nil +when defined(testament_tparseopt): + import os + proc main() = + let args = commandLineParams() + echo args + for i, ai in args: + echo "arg ", i, " ai.len:", ai.len, " :{", ai, "}" + main() +else: + from parseopt import nil + from parseopt2 import nil -block: - echo "parseopt" - for kind, key, val in parseopt.getopt(): - echo "kind: ", kind, "\tkey:val -- ", key, ":", val + block: + echo "parseopt" + for kind, key, val in parseopt.getopt(): + echo "kind: ", kind, "\tkey:val -- ", key, ":", val - # pass custom cmdline arguments - echo "first round" - var argv = "--left --debug:3 -l=4 -r:2" - var p = parseopt.initOptParser(argv) - for kind, key, val in parseopt.getopt(p): - echo "kind: ", kind, "\tkey:val -- ", key, ":", val - break - # reset getopt iterator and check arguments are returned correctly. - echo "second round" - for kind, key, val in parseopt.getopt(p): - echo "kind: ", kind, "\tkey:val -- ", key, ":", val + # pass custom cmdline arguments + echo "first round" + var argv = "--left --debug:3 -l=4 -r:2" + var p = parseopt.initOptParser(argv) + for kind, key, val in parseopt.getopt(p): + echo "kind: ", kind, "\tkey:val -- ", key, ":", val + break + # reset getopt iterator and check arguments are returned correctly. + echo "second round" + for kind, key, val in parseopt.getopt(p): + echo "kind: ", kind, "\tkey:val -- ", key, ":", val - # bug #9619 - var x = parseopt.initOptParser(@["--foo:", "--path"], allowWhitespaceAfterColon = false) - for kind, key, val in parseopt.getopt(x): - echo kind, " ", key + # bug #9619 + var x = parseopt.initOptParser(@["--foo:", "--path"], + allowWhitespaceAfterColon = false) + for kind, key, val in parseopt.getopt(x): + echo kind, " ", key -block: - echo "parseoptNoVal" - # test NoVal mode with custom cmdline arguments - var argv = "--left --debug:3 -l -r:2 --debug 2 --debug=1 -r1 -r=0 -lr4" - var p = parseopt.initOptParser(argv, - shortNoVal = {'l'}, longNoVal = @["left"]) - for kind, key, val in parseopt.getopt(p): - echo "kind: ", kind, "\tkey:val -- ", key, ":", val + block: + echo "parseoptNoVal" + # test NoVal mode with custom cmdline arguments + var argv = "--left --debug:3 -l -r:2 --debug 2 --debug=1 -r1 -r=0 -lr4" + var p = parseopt.initOptParser(argv, + shortNoVal = {'l'}, longNoVal = @["left"]) + for kind, key, val in parseopt.getopt(p): + echo "kind: ", kind, "\tkey:val -- ", key, ":", val -block: - echo "parseopt2" - for kind, key, val in parseopt2.getopt(): - echo "kind: ", kind, "\tkey:val -- ", key, ":", val + block: + echo "parseopt2" + for kind, key, val in parseopt2.getopt(): + echo "kind: ", kind, "\tkey:val -- ", key, ":", val - # pass custom cmdline arguments - echo "first round" - var argv: seq[string] = @["--left", "--debug:3", "-l=4", "-r:2"] - var p = parseopt2.initOptParser(argv) - for kind, key, val in parseopt2.getopt(p): - echo "kind: ", kind, "\tkey:val -- ", key, ":", val - break - # reset getopt iterator and check arguments are returned correctly. - echo "second round" - for kind, key, val in parseopt2.getopt(p): - echo "kind: ", kind, "\tkey:val -- ", key, ":", val + # pass custom cmdline arguments + echo "first round" + var argv: seq[string] = @["--left", "--debug:3", "-l=4", "-r:2"] + var p = parseopt2.initOptParser(argv) + for kind, key, val in parseopt2.getopt(p): + echo "kind: ", kind, "\tkey:val -- ", key, ":", val + break + # reset getopt iterator and check arguments are returned correctly. + echo "second round" + for kind, key, val in parseopt2.getopt(p): + echo "kind: ", kind, "\tkey:val -- ", key, ":", val + + import osproc, os, strutils + from stdtest/specialpaths import buildDir + import "../.." / compiler/unittest_light + + block: # fix #9951 (and make it work for parseopt and parseopt2) + template runTest(parseoptCustom) = + var p = parseoptCustom.initOptParser(@["echo \"quoted\""]) + let expected = when defined(windows): + """"echo \"quoted\""""" + else: + """'echo "quoted"'""" + assertEquals parseoptCustom.cmdLineRest(p), expected + + doAssert "a5'b" == "a5\'b" + + let args = @["a1b", "a2 b", "", "a4\"b", "a5'b", r"a6\b", "a7\'b"] + var p2 = parseoptCustom.initOptParser(args) + let expected2 = when defined(windows): + """a1b "a2 b" "" a4\"b a5'b a6\b a7'b""" + else: + """a1b 'a2 b' '' 'a4"b' 'a5'"'"'b' 'a6\b' 'a7'"'"'b'""" + doAssert "a5'b" == "a5\'b" + assertEquals parseoptCustom.cmdLineRest(p2), expected2 + runTest(parseopt) + runTest(parseopt2) + + block: # fix #9842 + let exe = buildDir / "D20190112T145450".addFileExt(ExeExt) + defer: + when not defined(windows): + # workaround #10359 ; innocuous to skip since we're saving under `buildDir` + removeFile exe + let args = @["a1b", "a2 b", "", "a4\"b", "a5'b", r"a6\b", "a7\'b"] + let cmd = "$# c -r --verbosity:0 -o:$# -d:testament_tparseopt $# $#" % + [getCurrentCompilerExe(), exe, currentSourcePath(), + args.quoteShellCommand] + var ret = execCmdEx(cmd, options = {}) + if ret.exitCode != 0: + # before bug fix, running cmd would show: + # sh: -c: line 0: unexpected EOF while looking for matching `"'\n + echo "exitCode: ", ret.exitCode, " cmd:", cmd + doAssert false + stripLineEnd(ret.output) + assertEquals ret.output, + """ +@["a1b", "a2 b", "", "a4\"b", "a5\'b", "a6\\b", "a7\'b"] +arg 0 ai.len:3 :{a1b} +arg 1 ai.len:4 :{a2 b} +arg 2 ai.len:0 :{} +arg 3 ai.len:4 :{a4"b} +arg 4 ai.len:4 :{a5'b} +arg 5 ai.len:4 :{a6\b} +arg 6 ai.len:4 :{a7'b}""" diff --git a/tests/misc/tsizeof.nim b/tests/misc/tsizeof.nim index f60c7fa00..25c566171 100644 --- a/tests/misc/tsizeof.nim +++ b/tests/misc/tsizeof.nim @@ -36,27 +36,24 @@ macro testSizeAlignOf(args: varargs[untyped]): untyped = if nim_size != c_size or nim_align != c_align: var msg = strAlign(`arg`.type.name & ": ") if nim_size != c_size: - msg.add " size(got, expected): " & $nim_size & " != " & $c_size + msg.add " size(got, expected): " & $nim_size & " != " & $c_size if nim_align != c_align: msg.add " align(get, expected): " & $nim_align & " != " & $c_align echo msg failed = true -macro testOffsetOf(a,b1,b2: untyped): untyped = +macro testOffsetOf(a, b: untyped): untyped = let typeName = newLit(a.repr) - let member = newLit(b2.repr) + let member = newLit(b.repr) result = quote do: let - c_offset = c_offsetof(`a`,`b1`) - nim_offset = offsetof(`a`,`b2`) + c_offset = c_offsetof(`a`,`b`) + nim_offset = offsetof(`a`,`b`) if c_offset != nim_offset: echo `typeName`, ".", `member`, " offsetError, C: ", c_offset, " nim: ", nim_offset failed = true -template testOffsetOf(a,b: untyped): untyped = - testOffsetOf(a,b,b) - proc strAlign(arg: string): string = const minLen = 22 result = arg @@ -337,16 +334,16 @@ testinstance: testOffsetOf(AlignAtEnd, b) testOffsetOf(AlignAtEnd, c) - testOffsetOf(SimpleBranch, "_Ukind", a) - testOffsetOf(SimpleBranch, "_Ukind", b) - testOffsetOf(SimpleBranch, "_Ukind", c) + testOffsetOf(SimpleBranch, a) + testOffsetOf(SimpleBranch, b) + testOffsetOf(SimpleBranch, c) testOffsetOf(PaddingBeforeBranchA, cause) - testOffsetOf(PaddingBeforeBranchA, "_Ukind", a) + testOffsetOf(PaddingBeforeBranchA, a) testOffsetOf(PaddingBeforeBranchB, cause) - testOffsetOf(PaddingBeforeBranchB, "_Ukind", a) + testOffsetOf(PaddingBeforeBranchB, a) - testOffsetOf(PaddingAfterBranch, "_Ukind", a) + testOffsetOf(PaddingAfterBranch, a) testOffsetOf(PaddingAfterBranch, cause) testOffsetOf(Foobar, c) @@ -367,15 +364,15 @@ testinstance: testOffsetOf(EnumObjectB, d) testOffsetOf(RecursiveStuff, kind) - testOffsetOf(RecursiveStuff, "_Ukind.S1.a", a) - testOffsetOf(RecursiveStuff, "_Ukind.S2.b", b) - testOffsetOf(RecursiveStuff, "_Ukind.S3.kind2", kind2) - testOffsetOf(RecursiveStuff, "_Ukind.S3._Ukind2.S1.ca1", ca1) - testOffsetOf(RecursiveStuff, "_Ukind.S3._Ukind2.S1.ca2", ca2) - testOffsetOf(RecursiveStuff, "_Ukind.S3._Ukind2.S2.cb", cb) - testOffsetOf(RecursiveStuff, "_Ukind.S3._Ukind2.S3.cc", cc) - testOffsetOf(RecursiveStuff, "_Ukind.S3.d1", d1) - testOffsetOf(RecursiveStuff, "_Ukind.S3.d2", d2) + testOffsetOf(RecursiveStuff, a) + testOffsetOf(RecursiveStuff, b) + testOffsetOf(RecursiveStuff, kind2) + testOffsetOf(RecursiveStuff, ca1) + testOffsetOf(RecursiveStuff, ca2) + testOffsetOf(RecursiveStuff, cb) + testOffsetOf(RecursiveStuff, cc) + testOffsetOf(RecursiveStuff, d1) + testOffsetOf(RecursiveStuff, d2) main() @@ -394,6 +391,29 @@ type assert sizeof(Bar) == 12 +# bug #10082 +type + A = int8 # change to int16 and get sizeof(C)==6 + B = int16 + C = object {.packed.} + d {.bitsize: 1.}: A + e {.bitsize: 7.}: A + f {.bitsize: 16.}: B + +assert sizeof(C) == 3 + + +type + MixedBitsize = object {.packed.} + a: uint32 + b {.bitsize: 8.}: uint8 + c {.bitsize: 1.}: uint8 + d {.bitsize: 7.}: uint8 + e {.bitsize: 16.}: uint16 + f: uint32 + +doAssert sizeof(MixedBitsize) == 12 + if failed: quit("FAIL") else: diff --git a/tests/modules/mimport_in_config.nim b/tests/modules/mimport_in_config.nim new file mode 100644 index 000000000..555b6074d --- /dev/null +++ b/tests/modules/mimport_in_config.nim @@ -0,0 +1,2 @@ +type + DefinedInB* = int diff --git a/tests/modules/timport_in_config.nim b/tests/modules/timport_in_config.nim new file mode 100644 index 000000000..847b063bd --- /dev/null +++ b/tests/modules/timport_in_config.nim @@ -0,0 +1,9 @@ +discard """ +output: '''hallo''' +joinable: false +""" + +# bug #9978, #9994 +var x: DefinedInB + +echo "hi".replace("i", "allo") diff --git a/tests/modules/timport_in_config.nim.cfg b/tests/modules/timport_in_config.nim.cfg new file mode 100644 index 000000000..2633e1012 --- /dev/null +++ b/tests/modules/timport_in_config.nim.cfg @@ -0,0 +1,2 @@ +--import: "strutils" +--import: "mimport_in_config" diff --git a/tests/modules/tmismatchedvisibility.nim b/tests/modules/tmismatchedvisibility.nim index 4bf244807..fd582b571 100644 --- a/tests/modules/tmismatchedvisibility.nim +++ b/tests/modules/tmismatchedvisibility.nim @@ -1,5 +1,5 @@ discard """ - errormsg: "public implementation 'tmismatchedvisibility.foo(a: int)[declared in tmismatchedvisibility.nim(6, 5)]' has non-public forward declaration in " + errormsg: "public implementation 'tmismatchedvisibility.foo(a: int)[declared in tmismatchedvisibility.nim(6, 6)]' has non-public forward declaration in " line: 8 """ diff --git a/tests/nim.cfg b/tests/nim.cfg new file mode 100644 index 000000000..577baaacd --- /dev/null +++ b/tests/nim.cfg @@ -0,0 +1 @@ +--path:"../testament/lib" # so we can `import stdtest/foo` in this dir diff --git a/tests/niminaction/Chapter8/sdl/sdl_test.nim b/tests/niminaction/Chapter8/sdl/sdl_test.nim index a49e08911..1c4d258fb 100644 --- a/tests/niminaction/Chapter8/sdl/sdl_test.nim +++ b/tests/niminaction/Chapter8/sdl/sdl_test.nim @@ -17,12 +17,24 @@ discard pollEvent(nil) renderer.setDrawColor 29, 64, 153, 255 renderer.clear renderer.setDrawColor 255, 255, 255, 255 -var points = [ - (260'i32, 320'i32), - (260'i32, 110'i32), - (360'i32, 320'i32), - (360'i32, 110'i32) -] + +when defined(c): + # just to ensure code from NimInAction still works, but + # the `else` branch would work as well in C mode + var points = [ + (260'i32, 320'i32), + (260'i32, 110'i32), + (360'i32, 320'i32), + (360'i32, 110'i32) + ] +else: + var points = [ + (260.cint, 320.cint), + (260.cint, 110.cint), + (360.cint, 320.cint), + (360.cint, 110.cint) + ] + renderer.drawLines(addr points[0], points.len.cint) renderer.present diff --git a/tests/objects/t3734.nim b/tests/objects/t3734.nim new file mode 100644 index 000000000..cebef6081 --- /dev/null +++ b/tests/objects/t3734.nim @@ -0,0 +1,17 @@ +discard """ +output: "i0" +""" + +type + Application = object + config: void + i: int + f: void + +proc printFields(rec: Application) = + for k, v in fieldPairs(rec): + echo k, v + +var app: Application + +printFields(app) diff --git a/tests/objects/tobjcov.nim b/tests/objects/tobjcov.nim index 817c1fcda..6c587e04d 100644 --- a/tests/objects/tobjcov.nim +++ b/tests/objects/tobjcov.nim @@ -1,8 +1,12 @@ discard """ action: compile +target: "c" """ # Covariance is not type safe: +# Note: `nim cpp` makes it a compile error (after codegen), even with: +# `var f = cast[proc (x: var TA) {.nimcall.}](cast[pointer](bp))`, which +# currently removes all the `cast` in cgen'd code, hence the compile error. type TA = object of RootObj diff --git a/tests/objects/tobject.nim b/tests/objects/tobject.nim index 61ef7442e..fbf531c3d 100644 --- a/tests/objects/tobject.nim +++ b/tests/objects/tobject.nim @@ -17,3 +17,23 @@ suite "object basic methods": check($obj == "(foo: 1)") test "it should test equality based on fields": check(makeObj(1) == makeObj(1)) + +# bug #10203 + +type + TMyObj = TYourObj + TYourObj = object of RootObj + x, y: int + +proc init: TYourObj = + result.x = 0 + result.y = -1 + +proc f(x: var TYourObj) = + discard + +var m: TMyObj = init() +f(m) + +var a: TYourObj = m +var b: TMyObj = a diff --git a/tests/objvariant/tyaoption.nim b/tests/objvariant/tyaoption.nim index 7a29b8008..80bfa4bae 100644 --- a/tests/objvariant/tyaoption.nim +++ b/tests/objvariant/tyaoption.nim @@ -1,7 +1,8 @@ discard """ output: '''some(str), some(5), none some(5!) -some(10)''' +some(10) +34''' """ import strutils @@ -45,3 +46,25 @@ let a3 = intOrString(some(5)) #echo a1 echo a2 echo a3 + + +# bug #10033 + +type + Token = enum + Int, + Float + + Base = ref object of RootObj + case token: Token + of Int: + bInt: int + of Float: + bFloat: float + + Child = ref object of Base + +let c = new Child +c.token = Int +c.bInt = 34 +echo c.bInt diff --git a/tests/parallel/twrong_refcounts.nim b/tests/parallel/twrong_refcounts.nim index ac428762d..ed3c1b894 100644 --- a/tests/parallel/twrong_refcounts.nim +++ b/tests/parallel/twrong_refcounts.nim @@ -1,7 +1,10 @@ discard """ output: "Success" + target: "c" """ +# Note: target: "cpp" fails because we can't yet have `extern "C"` mangling in +# `exportc` procs. import math, random, threadPool # --- diff --git a/tests/pragmas/t5149.nim b/tests/pragmas/t5149.nim new file mode 100644 index 000000000..2d242a8d5 --- /dev/null +++ b/tests/pragmas/t5149.nim @@ -0,0 +1,12 @@ +discard """ + errormsg: "{.exportc.} not allowed for type aliases" + line: 9 +""" + +type + X* = object + a: int + Y* {.exportc.} = X + +proc impl*(x: X) = + echo "it works" diff --git a/tests/pragmas/tcustom_pragma.nim b/tests/pragmas/tcustom_pragma.nim index 0bc4d2f18..e04d3de26 100644 --- a/tests/pragmas/tcustom_pragma.nim +++ b/tests/pragmas/tcustom_pragma.nim @@ -175,24 +175,56 @@ var foo: Something foo.cardinal = north doAssert foo.b.hasCustomPragma(thingy) == true - -proc myproc(s: string): int = +proc myproc(s: string): int = {.thingy.}: s.len doAssert myproc("123") == 3 let xx = compiles: - proc myproc_bad(s: string): int = + proc myproc_bad(s: string): int = {.not_exist.}: s.len doAssert: xx == false - -macro checkSym(s: typed{nkSym}): untyped = +macro checkSym(s: typed{nkSym}): untyped = let body = s.getImpl.body doAssert body[1].kind == nnkPragmaBlock doAssert body[1][0].kind == nnkPragma doAssert body[1][0][0] == bindSym"thingy" -checkSym(myproc) \ No newline at end of file +checkSym(myproc) + +# var and let pragmas +block: + template myAttr() {.pragma.} + template myAttr2(x: int) {.pragma.} + template myAttr3(x: string) {.pragma.} + + let a {.myAttr,myAttr2(2),myAttr3:"test".}: int = 0 + let b {.myAttr,myAttr2(2),myAttr3:"test".} = 0 + var x {.myAttr,myAttr2(2),myAttr3:"test".}: int = 0 + var y {.myAttr,myAttr2(2),myAttr3:"test".}: int + var z {.myAttr,myAttr2(2),myAttr3:"test".} = 0 + + template check(s: untyped) = + doAssert s.hasCustomPragma(myAttr) + doAssert s.hasCustomPragma(myAttr2) + doAssert s.getCustomPragmaVal(myAttr2) == 2 + doAssert s.hasCustomPragma(myAttr3) + doAssert s.getCustomPragmaVal(myAttr3) == "test" + + check(a) + check(b) + check(x) + check(y) + check(z) + +# pragma with multiple fields +block: + template myAttr(first: string, second: int, third: float) {.pragma.} + let a {.myAttr("one", 2, 3.0).} = 0 + let ps = a.getCustomPragmaVal(myAttr) + doAssert ps.first == ps[0] and ps.first == "one" + doAssert ps.second == ps[1] and ps.second == 2 + doAssert ps.third == ps[2] and ps.third == 3.0 diff --git a/tests/pragmas/tused.nim b/tests/pragmas/tused.nim index 7616c1215..d0c533f9a 100644 --- a/tests/pragmas/tused.nim +++ b/tests/pragmas/tused.nim @@ -1,7 +1,7 @@ discard """ nimout: ''' compile start -tused.nim(17, 8) Hint: 'tused.echoSub(a: int, b: int)[declared in tused.nim(17, 7)]' is declared but not used [XDeclaredButNotUsed] +tused.nim(17, 8) Hint: 'echoSub' is declared but not used [XDeclaredButNotUsed] compile end''' output: "8\n8" joinable: false diff --git a/tests/proc/tillegalreturntype.nim b/tests/proc/tillegalreturntype.nim new file mode 100644 index 000000000..be9e2147e --- /dev/null +++ b/tests/proc/tillegalreturntype.nim @@ -0,0 +1,12 @@ +discard """ + cmd: "nim check $file" + errmsg: "" + nimout: '''tillegalreturntype.nim(8, 11) Error: return type 'typed' is only valid for macros and templates +tillegalreturntype.nim(11, 11) Error: return type 'untyped' is only valid for macros and templates''' +""" + +proc x(): typed = + discard + +proc y(): untyped = + discard diff --git a/tests/proc/typed.nim b/tests/proc/typed.nim new file mode 100644 index 000000000..2e8117634 --- /dev/null +++ b/tests/proc/typed.nim @@ -0,0 +1,7 @@ +discard """ + errormsg: "'typed' is only allowed in templates and macros" + line: 6 +""" + +proc fun(x:typed)=discard +fun(10) diff --git a/tests/proc/untyped.nim b/tests/proc/untyped.nim new file mode 100644 index 000000000..f8b3ead7b --- /dev/null +++ b/tests/proc/untyped.nim @@ -0,0 +1,7 @@ +discard """ + errormsg: "'untyped' is only allowed in templates and macros" + line: 6 +""" + +proc fun(x:untyped)=discard +fun(10) diff --git a/tests/statictypes/tstatictypes.nim b/tests/statictypes/tstatictypes.nim index 2a3b7332d..b7cde6124 100644 --- a/tests/statictypes/tstatictypes.nim +++ b/tests/statictypes/tstatictypes.nim @@ -116,3 +116,24 @@ block: Tensor[B: static[Backend]; T] = object BackProp[B: static[Backend],T] = proc (gradient: Tensor[B,T]): Tensor[B,T] + +# https://github.com/nim-lang/Nim/issues/10073 +block: + proc foo[N: static int](x: var int, + y: int, + z: static int, + arr: array[N, int]): auto = + var t1 = (a: x, b: y, c: z, d: N) + var t2 = (x, y, z, N) + doAssert t1 == t2 + result = t1 + + var y = 20 + var x = foo(y, 10, 15, [1, 2, 3]) + doAssert x == (20, 10, 15, 3) + +# #7609 +block: + type + Coord[N: static[int]] = tuple[col, row: range[0'i8 .. (N.int8-1)]] + Point[N: static[int]] = range[0'i16 .. N.int16 * N.int16 - 1] diff --git a/tests/stdlib/t10231.nim b/tests/stdlib/t10231.nim new file mode 100644 index 000000000..2bb64b475 --- /dev/null +++ b/tests/stdlib/t10231.nim @@ -0,0 +1,15 @@ +discard """ + target: cpp + action: run + exitcode: 0 +""" + +import os + +# consider moving this inside tosproc (taking care that it's for cpp mode) + +if paramCount() == 0: + # main process + doAssert execShellCmd(getAppFilename().quoteShell & " test") == 1 +else: + quit 1 diff --git a/tests/stdlib/tgetaddrinfo.nim b/tests/stdlib/tgetaddrinfo.nim new file mode 100644 index 000000000..39102e131 --- /dev/null +++ b/tests/stdlib/tgetaddrinfo.nim @@ -0,0 +1,36 @@ +discard """ + exitcode: 0 + output: "" +""" + +# bug: https://github.com/nim-lang/Nim/issues/10198 + +import nativesockets + +block DGRAM_UDP: + let aiList = getAddrInfo("127.0.0.1", 999.Port, AF_INET, SOCK_DGRAM, IPPROTO_UDP) + doAssert aiList != nil + doAssert aiList.ai_addr != nil + doAssert aiList.ai_addrlen == 16 + doAssert aiList.ai_next == nil + freeAddrInfo aiList + +when defined(posix): + + block RAW_ICMP: + # the port will be ignored + let aiList = getAddrInfo("127.0.0.1", 999.Port, AF_INET, SOCK_RAW, IPPROTO_ICMP) + doAssert aiList != nil + doAssert aiList.ai_addr != nil + doAssert aiList.ai_addrlen == 16 + doAssert aiList.ai_next == nil + freeAddrInfo aiList + + block RAW_ICMPV6: + # the port will be ignored + let aiList = getAddrInfo("::1", 999.Port, AF_INET6, SOCK_RAW, IPPROTO_ICMPV6) + doAssert aiList != nil + doAssert aiList.ai_addr != nil + doAssert aiList.ai_addrlen == 28 + doAssert aiList.ai_next == nil + freeAddrInfo aiList diff --git a/tests/stdlib/tjsonmacro.nim b/tests/stdlib/tjsonmacro.nim index 33332447b..2e95b4833 100644 --- a/tests/stdlib/tjsonmacro.nim +++ b/tests/stdlib/tjsonmacro.nim @@ -516,3 +516,7 @@ when true: var w = u.to(MyDistRef) doAssert v.name == "smith" doAssert MyRef(w).name == "smith" + + block test_tuple: + doAssert $(%* (a1: 10, a2: "foo")) == """{"a1":10,"a2":"foo"}""" + doAssert $(%* (10, "foo")) == """[10,"foo"]""" diff --git a/tests/stdlib/tmath.nim b/tests/stdlib/tmath.nim index 581308a7e..bdb5aa332 100644 --- a/tests/stdlib/tmath.nim +++ b/tests/stdlib/tmath.nim @@ -4,6 +4,10 @@ discard """ [Suite] random float +[Suite] cumsum + +[Suite] random sample + [Suite] ^ ''' @@ -11,34 +15,34 @@ discard """ import math, random, os import unittest -import sets +import sets, tables suite "random int": test "there might be some randomness": var set = initSet[int](128) - randomize() + for i in 1..1000: incl(set, random(high(int))) check len(set) == 1000 test "single number bounds work": - randomize() + var rand: int for i in 1..1000: rand = random(1000) check rand < 1000 check rand > -1 test "slice bounds work": - randomize() + var rand: int for i in 1..1000: rand = random(100..1000) check rand < 1000 check rand >= 100 - test "randomize() again gives new numbers": - randomize() + test " again gives new numbers": + var rand1 = random(1000000) os.sleep(200) - randomize() + var rand2 = random(1000000) check rand1 != rand2 @@ -46,32 +50,93 @@ suite "random int": suite "random float": test "there might be some randomness": var set = initSet[float](128) - randomize() + for i in 1..100: incl(set, random(1.0)) check len(set) == 100 test "single number bounds work": - randomize() + var rand: float for i in 1..1000: rand = random(1000.0) check rand < 1000.0 check rand > -1.0 test "slice bounds work": - randomize() + var rand: float for i in 1..1000: rand = random(100.0..1000.0) check rand < 1000.0 check rand >= 100.0 - test "randomize() again gives new numbers": - randomize() + test " again gives new numbers": + var rand1:float = random(1000000.0) os.sleep(200) - randomize() + var rand2:float = random(1000000.0) check rand1 != rand2 +suite "cumsum": + test "cumsum int seq return": + let counts = [ 1, 2, 3, 4 ] + check counts.cumsummed == [ 1, 3, 6, 10 ] + + test "cumsum float seq return": + let counts = [ 1.0, 2.0, 3.0, 4.0 ] + check counts.cumsummed == [ 1.0, 3.0, 6.0, 10.0 ] + + test "cumsum int in-place": + var counts = [ 1, 2, 3, 4 ] + counts.cumsum + check counts == [ 1, 3, 6, 10 ] + + test "cumsum float in-place": + var counts = [ 1.0, 2.0, 3.0, 4.0 ] + counts.cumsum + check counts == [ 1.0, 3.0, 6.0, 10.0 ] + +suite "random sample": + test "non-uniform array sample unnormalized int CDF": + let values = [ 10, 20, 30, 40, 50 ] # values + let counts = [ 4, 3, 2, 1, 0 ] # weights aka unnormalized probabilities + var histo = initCountTable[int]() + let cdf = counts.cumsummed # unnormalized CDF + for i in 0 ..< 5000: + histo.inc(sample(values, cdf)) + check histo.len == 4 # number of non-zero in `counts` + # Any one bin is a binomial random var for n samples, each with prob p of + # adding a count to k; E[k]=p*n, Var k=p*(1-p)*n, approximately Normal for + # big n. So, P(abs(k - p*n)/sqrt(p*(1-p)*n))>3.0) =~ 0.0027, while + # P(wholeTestFails) =~ 1 - P(binPasses)^4 =~ 1 - (1-0.0027)^4 =~ 0.01. + for i, c in counts: + if c == 0: + check values[i] notin histo + continue + let p = float(c) / float(cdf[^1]) + let n = 5000.0 + let expected = p * n + let stdDev = sqrt(n * p * (1.0 - p)) + check abs(float(histo[values[i]]) - expected) <= 3.0 * stdDev + + test "non-uniform array sample normalized float CDF": + let values = [ 10, 20, 30, 40, 50 ] # values + let counts = [ 0.4, 0.3, 0.2, 0.1, 0 ] # probabilities + var histo = initCountTable[int]() + let cdf = counts.cumsummed # normalized CDF + for i in 0 ..< 5000: + histo.inc(sample(values, cdf)) + check histo.len == 4 # number of non-zero in ``counts`` + for i, c in counts: + if c == 0: + check values[i] notin histo + continue + let p = float(c) / float(cdf[^1]) + let n = 5000.0 + let expected = p * n + let stdDev = sqrt(n * p * (1.0 - p)) + # NOTE: like unnormalized int CDF test, P(wholeTestFails) =~ 0.01. + check abs(float(histo[values[i]]) - expected) <= 3.0 * stdDev + suite "^": test "compiles for valid types": check: compiles(5 ^ 2) diff --git a/tests/stdlib/tmget.nim b/tests/stdlib/tmget.nim index 5792b6282..5e2e327f4 100644 --- a/tests/stdlib/tmget.nim +++ b/tests/stdlib/tmget.nim @@ -11,10 +11,10 @@ Can't access 6 Can't access 6 10 11 -Can't access 6 +0 10 11 -Can't access 6 +0 10 11 Can't access 6 @@ -85,7 +85,7 @@ block: except KeyError: echo "Can't access 6" echo x[5] - x[5] += 1 + x.inc 5, 1 var c = x[5] echo c @@ -97,7 +97,7 @@ block: except KeyError: echo "Can't access 6" echo x[5] - x[5] += 1 + x.inc 5, 1 var c = x[5] echo c diff --git a/tests/stdlib/tos.nim b/tests/stdlib/tos.nim index 467f64fff..e4e14d5a1 100644 --- a/tests/stdlib/tos.nim +++ b/tests/stdlib/tos.nim @@ -189,62 +189,44 @@ block walkDirRec: removeDir("walkdir_test") -block normalizedPath: - when defined(posix): - block relative: - doAssert normalizedPath(".") == "." - doAssert normalizedPath("..") == ".." - doAssert normalizedPath("../") == ".." - doAssert normalizedPath("../..") == "../.." - doAssert normalizedPath("../a/..") == ".." - doAssert normalizedPath("../a/../") == ".." - doAssert normalizedPath("./") == "." - - block absolute: - doAssert normalizedPath("/") == "/" - doAssert normalizedPath("/.") == "/" - doAssert normalizedPath("/..") == "/" - doAssert normalizedPath("/../") == "/" - doAssert normalizedPath("/../..") == "/" - doAssert normalizedPath("/../../") == "/" - doAssert normalizedPath("/../../../") == "/" - doAssert normalizedPath("/a/b/../../foo") == "/foo" - doAssert normalizedPath("/a/b/../../../foo") == "/foo" - doAssert normalizedPath("/./") == "/" - doAssert normalizedPath("//") == "/" - doAssert normalizedPath("///") == "/" - doAssert normalizedPath("/a//b") == "/a/b" - doAssert normalizedPath("/a///b") == "/a/b" - doAssert normalizedPath("/a/b/c/..") == "/a/b" - doAssert normalizedPath("/a/b/c/../") == "/a/b" +when not defined(windows): + block walkDirRelative: + createDir("walkdir_test") + createSymlink(".", "walkdir_test/c") + for k, p in walkDir("walkdir_test", true): + doAssert k == pcLinkToDir + removeDir("walkdir_test") - else: - block relative: - doAssert normalizedPath(".") == "." - doAssert normalizedPath("..") == ".." - doAssert normalizedPath("..\\") == ".." - doAssert normalizedPath("..\\..") == "..\\.." - doAssert normalizedPath("..\\a\\..") == ".." - doAssert normalizedPath("..\\a\\..\\") == ".." - doAssert normalizedPath(".\\") == "." - - block absolute: - doAssert normalizedPath("\\") == "\\" - doAssert normalizedPath("\\.") == "\\" - doAssert normalizedPath("\\..") == "\\" - doAssert normalizedPath("\\..\\") == "\\" - doAssert normalizedPath("\\..\\..") == "\\" - doAssert normalizedPath("\\..\\..\\") == "\\" - doAssert normalizedPath("\\..\\..\\..\\") == "\\" - doAssert normalizedPath("\\a\\b\\..\\..\\foo") == "\\foo" - doAssert normalizedPath("\\a\\b\\..\\..\\..\\foo") == "\\foo" - doAssert normalizedPath("\\.\\") == "\\" - doAssert normalizedPath("\\\\") == "\\" - doAssert normalizedPath("\\\\\\") == "\\" - doAssert normalizedPath("\\a\\\\b") == "\\a\\b" - doAssert normalizedPath("\\a\\\\\\b") == "\\a\\b" - doAssert normalizedPath("\\a\\b\\c\\..") == "\\a\\b" - doAssert normalizedPath("\\a\\b\\c\\..\\") == "\\a\\b" +block normalizedPath: + doAssert normalizedPath("") == "" + block relative: + doAssert normalizedPath(".") == "." + doAssert normalizedPath("foo/..") == "." + doAssert normalizedPath("foo//../bar/.") == "bar" + doAssert normalizedPath("..") == ".." + doAssert normalizedPath("../") == ".." + doAssert normalizedPath("../..") == unixToNativePath"../.." + doAssert normalizedPath("../a/..") == ".." + doAssert normalizedPath("../a/../") == ".." + doAssert normalizedPath("./") == "." + + block absolute: + doAssert normalizedPath("/") == unixToNativePath"/" + doAssert normalizedPath("/.") == unixToNativePath"/" + doAssert normalizedPath("/..") == unixToNativePath"/.." + doAssert normalizedPath("/../") == unixToNativePath"/.." + doAssert normalizedPath("/../..") == unixToNativePath"/../.." + doAssert normalizedPath("/../../") == unixToNativePath"/../.." + doAssert normalizedPath("/../../../") == unixToNativePath"/../../.." + doAssert normalizedPath("/a/b/../../foo") == unixToNativePath"/foo" + doAssert normalizedPath("/a/b/../../../foo") == unixToNativePath"/../foo" + doAssert normalizedPath("/./") == unixToNativePath"/" + doAssert normalizedPath("//") == unixToNativePath"/" + doAssert normalizedPath("///") == unixToNativePath"/" + doAssert normalizedPath("/a//b") == unixToNativePath"/a/b" + doAssert normalizedPath("/a///b") == unixToNativePath"/a/b" + doAssert normalizedPath("/a/b/c/..") == unixToNativePath"/a/b" + doAssert normalizedPath("/a/b/c/../") == unixToNativePath"/a/b" block isHidden: when defined(posix): @@ -265,3 +247,21 @@ block absolutePath: doAssert absolutePath("a", "/b/c") == "/b/c" / "a" doAssert absolutePath("/a", "b/") == "/a" +block splitFile: + doAssert splitFile("") == ("", "", "") + doAssert splitFile("abc/") == ("abc", "", "") + doAssert splitFile("/") == ("/", "", "") + doAssert splitFile("./abc") == (".", "abc", "") + doAssert splitFile(".txt") == ("", ".txt", "") + doAssert splitFile("abc/.txt") == ("abc", ".txt", "") + doAssert splitFile("abc") == ("", "abc", "") + doAssert splitFile("abc.txt") == ("", "abc", ".txt") + doAssert splitFile("/abc.txt") == ("/", "abc", ".txt") + doAssert splitFile("/foo/abc.txt") == ("/foo", "abc", ".txt") + doAssert splitFile("/foo/abc.txt.gz") == ("/foo", "abc.txt", ".gz") + doAssert splitFile(".") == ("", ".", "") + doAssert splitFile("abc/.") == ("abc", ".", "") + doAssert splitFile("..") == ("", "..", "") + doAssert splitFile("a/..") == ("a", "..", "") + +# execShellCmd is tested in tosproc diff --git a/tests/stdlib/tosproc.nim b/tests/stdlib/tosproc.nim index 9d57d4574..b8d3be9bb 100644 --- a/tests/stdlib/tosproc.nim +++ b/tests/stdlib/tosproc.nim @@ -1,23 +1,99 @@ -discard """ - output: "" -""" # test the osproc module -import os, osproc +import stdtest/specialpaths +import "../.." / compiler/unittest_light -block execProcessTest: - let dir = parentDir(currentSourcePath()) - let (outp, err) = execCmdEx("nim c " & quoteShell(dir / "osproctest.nim")) - doAssert err == 0 - let exePath = dir / addFileExt("osproctest", ExeExt) - let outStr1 = execProcess(exePath, workingDir=dir, args=["foo", "b A r"], options={}) - doAssert outStr1 == dir & "\nfoo\nb A r\n" +when defined(case_testfile): # compiled test file for child process + from posix import exitnow + proc c_exit2(code: c_int): void {.importc: "_exit", header: "<unistd.h>".} + import os + var a = 0 + proc fun(b = 0) = + a.inc + if a mod 10000000 == 0: # prevents optimizing it away + echo a + fun(b+1) - const testDir = "t e st" - createDir(testDir) - doAssert dirExists(testDir) - let outStr2 = execProcess(exePath, workingDir=testDir, args=["x yz"], options={}) - doAssert outStr2 == absolutePath(testDir) & "\nx yz\n" + proc main() = + let args = commandLineParams() + echo (msg: "child binary", pid: getCurrentProcessId()) + let arg = args[0] + echo (arg: arg) + case arg + of "exit_0": + if true: quit(0) + of "exitnow_139": + if true: exitnow(139) + of "c_exit2_139": + if true: c_exit2(139) + of "quit_139": + # `exitStatusLikeShell` doesn't distinguish between a process that + # exit(139) and a process that gets killed with `SIGSEGV` because + # 139 = 11 + 128 = SIGSEGV + 128. + # However, as #10249 shows, this leads to bad debugging experience + # when a child process dies with SIGSEGV, leaving no trace of why it + # failed. The shell (and lldb debugger) solves that by inserting a + # helpful msg: `segmentation fault` when it detects a signal killed + # the child. + # todo: expose an API that will show more diagnostic, returing + # (exitCode, signal) instead of just `shellExitCode`. + if true: quit(139) + of "exit_recursion": # stack overflow by infinite recursion + fun() + echo a + of "exit_array": # bad array access + echo args[1] + main() - removeDir(testDir) - removeFile(exePath) +else: + + import os, osproc, strutils, posix + + block execShellCmdTest: + ## first, compile child program + const nim = getCurrentCompilerExe() + const sourcePath = currentSourcePath() + let output = buildDir / "D20190111T024543".addFileExt(ExeExt) + let cmd = "$# c -o:$# -d:release -d:case_testfile $#" % [nim, output, + sourcePath] + # we're testing `execShellCmd` so don't rely on it to compile test file + # note: this should be exported in posix.nim + proc c_system(cmd: cstring): cint {.importc: "system", + header: "<stdlib.h>".} + assertEquals c_system(cmd), 0 + + ## use it + template runTest(arg: string, expected: int) = + echo (arg2: arg, expected2: expected) + assertEquals execShellCmd(output & " " & arg), expected + + runTest("exit_0", 0) + runTest("exitnow_139", 139) + runTest("c_exit2_139", 139) + runTest("quit_139", 139) + runTest("exit_array", 1) + when defined(posix): # on windows, -1073741571 + runTest("exit_recursion", SIGSEGV.int + 128) # bug #10273: was returning 0 + assertEquals exitStatusLikeShell(SIGSEGV), SIGSEGV + 128.cint + + block execProcessTest: + let dir = parentDir(currentSourcePath()) + let (outp, err) = execCmdEx("nim c " & quoteShell(dir / "osproctest.nim")) + doAssert err == 0 + let exePath = dir / addFileExt("osproctest", ExeExt) + let outStr1 = execProcess(exePath, workingDir = dir, args = ["foo", + "b A r"], options = {}) + doAssert outStr1 == dir & "\nfoo\nb A r\n" + + const testDir = "t e st" + createDir(testDir) + doAssert dirExists(testDir) + let outStr2 = execProcess(exePath, workingDir = testDir, args = ["x yz"], + options = {}) + doAssert outStr2 == absolutePath(testDir) & "\nx yz\n" + + removeDir(testDir) + try: + removeFile(exePath) + except OSError: + discard diff --git a/tests/stdlib/trepr.nim b/tests/stdlib/trepr.nim index 33cb581ef..c1941bd38 100644 --- a/tests/stdlib/trepr.nim +++ b/tests/stdlib/trepr.nim @@ -1,5 +1,6 @@ discard """ - output: "{a, b}{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}" + output: '''{a, b}{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'} +[1, 2, 3, 4, 5, 6]''' """ type @@ -25,3 +26,11 @@ when false: # "a", "b", "c", "d", "e" #] #echo(repr(testseq)) + +# bug #7878 +proc test(variable: var openarray[int]) = + echo repr(variable) + +var arr = [1, 2, 3, 4, 5, 6] + +test(arr) diff --git a/tests/stdlib/ttimes.nim b/tests/stdlib/ttimes.nim index ed87b15ac..3999c968f 100644 --- a/tests/stdlib/ttimes.nim +++ b/tests/stdlib/ttimes.nim @@ -245,6 +245,17 @@ suite "ttimes": parseTestExcp("12345", "uuuu") parseTestExcp("-1 BC", "UUUU g") + test "incorrect inputs: invalid sign": + parseTestExcp("+1", "YYYY") + parseTestExcp("+1", "dd") + parseTestExcp("+1", "MM") + parseTestExcp("+1", "hh") + parseTestExcp("+1", "mm") + parseTestExcp("+1", "ss") + + test "_ as a separator": + discard parse("2000_01_01", "YYYY'_'MM'_'dd") + test "dynamic timezone": let tz = staticTz(seconds = -9000) let dt = initDateTime(1, mJan, 2000, 12, 00, 00, tz) diff --git a/tests/stdlib/tunittest.nim b/tests/stdlib/tunittest.nim index c8656bbff..65baefef0 100644 --- a/tests/stdlib/tunittest.nim +++ b/tests/stdlib/tunittest.nim @@ -50,7 +50,6 @@ test "unittest multiple requires": import math, random from strutils import parseInt proc defectiveRobot() = - randomize() case random(1..4) of 1: raise newException(OSError, "CANNOT COMPUTE!") of 2: discard parseInt("Hello World!") diff --git a/tests/system/tsystem_misc.nim b/tests/system/tsystem_misc.nim index 3bbb5eff1..a20e6b3bf 100644 --- a/tests/system/tsystem_misc.nim +++ b/tests/system/tsystem_misc.nim @@ -30,6 +30,20 @@ discard """ ''' """ + +block: + const a2 = $(int) + const a3 = $int + doAssert a2 == "int" + doAssert a3 == "int" + + proc fun[T: typedesc](t: T) = + const a2 = $(t) + const a3 = $t + doAssert a2 == "int" + doAssert a3 == "int" + fun(int) + # check high/low implementations doAssert high(int) > low(int) doAssert high(int8) > low(int8) @@ -98,6 +112,18 @@ doAssertRaises(IndexError): foo(toOpenArray(arrNeg, -1, 0)) doAssertRaises(IndexError): foo(toOpenArray(arrNeg, -1, -3)) +doAssertRaises(Exception): + raise newException(Exception, "foo") + +block: + var didThrow = false + try: + doAssertRaises(IndexError): # should fail since it's wrong exception + raise newException(FieldError, "foo") + except AssertionError: + # ok, throwing was correct behavior + didThrow = true + doAssert didThrow type seqqType = ptr UncheckedArray[int] let qData = cast[seqqType](addr seqq[0]) @@ -122,3 +148,14 @@ let a = @[1, 2, 3] # a.boundedOpenArray(1, 2).foo() # Works echo a.boundedOpenArray(1, 2).len # Internal compiler error + +block: # `$`*[T: tuple|object](x: T) + doAssert $(foo1:0, bar1:"a") == """(foo1: 0, bar1: "a")""" + doAssert $(foo1:0, ) == """(foo1: 0)""" + doAssert $(0, "a") == """(0, "a")""" + doAssert $(0, ) == "(0,)" + type Foo = object + x:int + x2:float + doAssert $Foo(x:2) == "(x: 2, x2: 0.0)" + doAssert $() == "()" diff --git a/tests/test_nimscript.nims b/tests/test_nimscript.nims index b9a6097c2..3efbb0a4c 100644 --- a/tests/test_nimscript.nims +++ b/tests/test_nimscript.nims @@ -17,7 +17,6 @@ import parseutils import deques import sequtils import strutils -import subexes import tables import unicode import uri diff --git a/tests/testament/tshouldfail.nim b/tests/testament/tshouldfail.nim index d35dd99ac..ebf941fab 100644 --- a/tests/testament/tshouldfail.nim +++ b/tests/testament/tshouldfail.nim @@ -2,30 +2,30 @@ discard """ cmd: "testament/tester --directory:testament --colors:off --backendLogging:off --nim:../compiler/nim category shouldfail" action: compile nimout: ''' -FAIL: tccodecheck.nim C +FAIL: tests/shouldfail/tccodecheck.nim C Failure: reCodegenFailure Expected: baz -FAIL: tcolumn.nim C +FAIL: tests/shouldfail/tcolumn.nim C Failure: reLinesDiffer -FAIL: terrormsg.nim C +FAIL: tests/shouldfail/terrormsg.nim C Failure: reMsgsDiffer -FAIL: texitcode1.nim C +FAIL: tests/shouldfail/texitcode1.nim C Failure: reExitcodesDiffer -FAIL: tfile.nim C +FAIL: tests/shouldfail/tfile.nim C Failure: reFilesDiffer -FAIL: tline.nim C +FAIL: tests/shouldfail/tline.nim C Failure: reLinesDiffer -FAIL: tmaxcodesize.nim C +FAIL: tests/shouldfail/tmaxcodesize.nim C Failure: reCodegenFailure max allowed size: 1 -FAIL: tnimout.nim C +FAIL: tests/shouldfail/tnimout.nim C Failure: reMsgsDiffer -FAIL: toutput.nim C +FAIL: tests/shouldfail/toutput.nim C Failure: reOutputsDiffer -FAIL: toutputsub.nim C +FAIL: tests/shouldfail/toutputsub.nim C Failure: reOutputsDiffer -FAIL: tsortoutput.nim C +FAIL: tests/shouldfail/tsortoutput.nim C Failure: reOutputsDiffer ''' """ diff --git a/tests/threads/tactors.nim b/tests/threads/tactors.nim deleted file mode 100644 index ea052b9bd..000000000 --- a/tests/threads/tactors.nim +++ /dev/null @@ -1,13 +0,0 @@ -discard """ - outputsub: "150" -""" - -import actors - -var - pool: ActorPool[int, void] -createActorPool(pool) -for i in 0 ..< 300: - pool.spawn(i, proc (x: int) {.thread.} = echo x) -pool.join() - diff --git a/tests/threads/tactors2.nim b/tests/threads/tactors2.nim deleted file mode 100644 index e8afe203c..000000000 --- a/tests/threads/tactors2.nim +++ /dev/null @@ -1,25 +0,0 @@ -discard """ - output: "1" -""" - -import actors - -type - some_type {.pure, final.} = object - bla: int - -proc thread_proc(input: some_type): some_type {.thread.} = - result.bla = 1 - -proc main() = - var actorPool: ActorPool[some_type, some_type] - createActorPool(actorPool, 1) - - var some_data: some_type - - var inchannel = spawn(actorPool, some_data, thread_proc) - var recv_data = ^inchannel - close(inchannel[]) - echo recv_data.bla - -main() diff --git a/tests/threads/trecursive_actor.nim b/tests/threads/trecursive_actor.nim deleted file mode 100644 index d7072aa53..000000000 --- a/tests/threads/trecursive_actor.nim +++ /dev/null @@ -1,20 +0,0 @@ -discard """ - disabled: yes - outputsub: "0" -""" - -import actors - -var - a: TActorPool[int, void] -createActorPool(a) - -proc task(i: int) {.thread.} = - echo i - if i != 0: a.spawn (i-1, task) - -# count from 9 till 0 and check 0 is somewhere in the output -a.spawn(9, task) -a.join() - - diff --git a/tests/trmacros/trmacros_various2.nim b/tests/trmacros/trmacros_various2.nim index d500c49de..c1367cb1b 100644 --- a/tests/trmacros/trmacros_various2.nim +++ b/tests/trmacros/trmacros_various2.nim @@ -77,3 +77,13 @@ block tstar: # check that it's been optimized properly: doAssert calls == 1 + +# bug #7524 +template in_to_out(typIn, typOut: typedesc) = + proc to_out(x: typIn{lit}): typOut = result = ord(x) + +# Generating the proc via template doesn't work +in_to_out(char, int) + +# This works +proc to_out2(x: char{lit}): int = result = ord(x) diff --git a/tests/tuples/ttuples_various.nim b/tests/tuples/ttuples_various.nim index 010893ced..94a2f3ff0 100644 --- a/tests/tuples/ttuples_various.nim +++ b/tests/tuples/ttuples_various.nim @@ -66,6 +66,22 @@ block unpack_asgn: +block unpack_const: + const (a, ) = (1, ) + doAssert a == 1 + + const (b, c) = (2, 3) + doAssert b == 2 + doAssert c == 3 + + # bug #10098 + const (x, y, z) = (4, 5, 6) + doAssert x == 4 + doAssert y == 5 + doAssert z == 6 + + + block tuple_subscript: proc`[]` (t: tuple, key: string): string = for name, field in fieldPairs(t): diff --git a/tests/tuples/tuple_with_nil.nim b/tests/tuples/tuple_with_nil.nim index e09c53407..1b210b2bf 100644 --- a/tests/tuples/tuple_with_nil.nim +++ b/tests/tuples/tuple_with_nil.nim @@ -4,7 +4,6 @@ import parseutils import unicode import math import fenv -#import unsigned import pegs import streams diff --git a/tests/typerel/t4799.nim b/tests/typerel/t4799.nim index 075893476..814ad361d 100644 --- a/tests/typerel/t4799.nim +++ b/tests/typerel/t4799.nim @@ -1,4 +1,5 @@ discard """ + targets: "c cpp" output: "OK" """ diff --git a/tests/typerel/t4799_1.nim b/tests/typerel/t4799_1.nim index 549b6bf3c..e66aa1a9a 100644 --- a/tests/typerel/t4799_1.nim +++ b/tests/typerel/t4799_1.nim @@ -1,4 +1,5 @@ discard """ + targets: "c cpp" outputsub: '''ObjectAssignmentError''' exitcode: "1" """ diff --git a/tests/typerel/t4799_2.nim b/tests/typerel/t4799_2.nim index cfd399a6e..ff20c2426 100644 --- a/tests/typerel/t4799_2.nim +++ b/tests/typerel/t4799_2.nim @@ -1,4 +1,5 @@ discard """ + targets: "c cpp" outputsub: '''ObjectAssignmentError''' exitcode: "1" """ diff --git a/tests/typerel/t4799_3.nim b/tests/typerel/t4799_3.nim index 784eee8fc..4a8a158dd 100644 --- a/tests/typerel/t4799_3.nim +++ b/tests/typerel/t4799_3.nim @@ -1,4 +1,5 @@ discard """ + targets: "c cpp" outputsub: '''ObjectAssignmentError''' exitcode: "1" """ diff --git a/tests/vm/tcompiletimesideeffects.nim b/tests/vm/tcompiletimesideeffects.nim new file mode 100644 index 000000000..4cd57b3bd --- /dev/null +++ b/tests/vm/tcompiletimesideeffects.nim @@ -0,0 +1,42 @@ +discard """ + output: +''' +@[0, 1, 2] +@[3, 4, 5] +@[0, 1, 2] +3 +4 +''' +""" + +template runNTimes(n: int, f : untyped) : untyped = + var accum: seq[type(f)] + for i in 0..n-1: + accum.add(f) + accum + +var state {.compileTime.} : int = 0 +proc fill(): int {.compileTime.} = + result = state + inc state + +# invoke fill() at compile time as a compile time expression +const C1 = runNTimes(3, fill()) +echo C1 + +# invoke fill() at compile time as a set of compile time statements +const C2 = + block: + runNTimes(3, fill()) +echo C2 + +# invoke fill() at compile time after a compile time reset of state +const C3 = + block: + state = 0 + runNTimes(3, fill()) +echo C3 + +# evaluate fill() at compile time and use the results at runtime +echo fill() +echo fill() diff --git a/tests/vm/tgorge.nim b/tests/vm/tgorge.nim index 11c49a4cc..1f77d2c95 100644 --- a/tests/vm/tgorge.nim +++ b/tests/vm/tgorge.nim @@ -10,6 +10,8 @@ import os template getScriptDir(): string = parentDir(instantiationInfo(-1, true).filename) +# See also simpler test in Nim/tests/vm/tvmops.nim for a simpler +# cross platform way. block gorge: const execName = when defined(windows): "tgorge.bat" else: "./tgorge.sh" diff --git a/tests/vm/tissues.nim b/tests/vm/tissues.nim index 021b902ad..063559d2e 100644 --- a/tests/vm/tissues.nim +++ b/tests/vm/tissues.nim @@ -1,16 +1,14 @@ -discard """ - nimout: "(Field0: 2, Field1: 2, Field2: 2, Field3: 2)" -""" - import macros -block t9043: - proc foo[N: static[int]](dims: array[N, int])= +block t9043: # issue #9043 + proc foo[N: static[int]](dims: array[N, int]): string = const N1 = N const N2 = dims.len - static: echo (N, dims.len, N1, N2) + const ret = $(N, dims.len, N1, N2) + static: doAssert ret == $(N, dims.len, N1, N2) + ret - foo([1, 2]) + doAssert foo([1, 2]) == "(2, 2, 2, 2)" block t4952: proc doCheck(tree: NimNode) = diff --git a/tests/vm/treset.nim b/tests/vm/treset.nim new file mode 100644 index 000000000..56fe19b19 --- /dev/null +++ b/tests/vm/treset.nim @@ -0,0 +1,28 @@ +static: + type Obj = object + field: int + var o = Obj(field: 1) + reset(o) + doAssert o.field == 0 + +static: + var i = 2 + reset(i) + doAssert i == 0 + +static: + var i = new int + reset(i) + doAssert i.isNil + +static: + var s = @[1, 2, 3] + reset(s) + doAssert s == @[] + +static: + proc f() = + var i = 2 + reset(i) + doAssert i == 0 + f() \ No newline at end of file diff --git a/tests/vm/tvmops.nim b/tests/vm/tvmops.nim new file mode 100644 index 000000000..c9caaf32b --- /dev/null +++ b/tests/vm/tvmops.nim @@ -0,0 +1,47 @@ +#[ +test for vmops.nim +]# +import os +import math +import strutils + +template forceConst(a: untyped): untyped = + ## Force evaluation at CT, useful for example here: + ## `callFoo(forceConst(getBar1()), getBar2())` + ## instead of: + ## block: + ## const a = getBar1() + ## `callFoo(a, getBar2())` + const ret = a + ret + +static: + # TODO: add more tests + block: #getAppFilename, gorgeEx, gorge + const nim = getCurrentCompilerExe() + let ret = gorgeEx(nim & " --version") + doAssert ret.exitCode == 0 + doAssert ret.output.contains "Nim Compiler" + let ret2 = gorgeEx(nim & " --unexistant") + doAssert ret2.exitCode != 0 + let output3 = gorge(nim & " --version") + doAssert output3.contains "Nim Compiler" + + block: + const key = "D20181210T175037" + const val = "foo" + putEnv(key, val) + doAssert existsEnv(key) + doAssert getEnv(key) == val + + block: + # sanity check (we probably don't need to test for all ops) + const a1 = arcsin 0.3 + let a2 = arcsin 0.3 + doAssert a1 == a2 + +block: + # Check against bugs like #9176 + doAssert getCurrentCompilerExe() == forceConst(getCurrentCompilerExe()) + if false: #pending #9176 + doAssert gorgeEx("unexistant") == forceConst(gorgeEx("unexistant")) |