diff options
Diffstat (limited to 'tests/misc')
134 files changed, 3435 insertions, 1284 deletions
diff --git a/tests/misc/m15316.nim b/tests/misc/m15316.nim new file mode 100644 index 000000000..188d06946 --- /dev/null +++ b/tests/misc/m15316.nim @@ -0,0 +1 @@ +proc foo = (if) diff --git a/tests/misc/m15955.nim b/tests/misc/m15955.nim new file mode 100644 index 000000000..22da345db --- /dev/null +++ b/tests/misc/m15955.nim @@ -0,0 +1,4 @@ +proc add*(a, b: int): int {.cdecl, exportc.} = + a + b +proc sub*(a, b: int): int {.cdecl, exportc.} = + a - b \ No newline at end of file diff --git a/tests/misc/m15955_main.nim b/tests/misc/m15955_main.nim new file mode 100644 index 000000000..a71af8121 --- /dev/null +++ b/tests/misc/m15955_main.nim @@ -0,0 +1,11 @@ +import stdtest/specialpaths +import std/os + +const buildLib = buildDir / "libD20220923T19380" + +{.passL: buildLib.} +proc add*(a, b: int):int {.cdecl, importc.} +proc sub*(a, b: int):int {.cdecl, importc.} + +echo add(10, 5) +echo sub(10, 5) diff --git a/tests/misc/m20149.nim b/tests/misc/m20149.nim new file mode 100644 index 000000000..942262a6e --- /dev/null +++ b/tests/misc/m20149.nim @@ -0,0 +1,2 @@ +let x = 12 +echo x diff --git a/tests/misc/m20456.nims b/tests/misc/m20456.nims new file mode 100644 index 000000000..8a9313129 --- /dev/null +++ b/tests/misc/m20456.nims @@ -0,0 +1 @@ +echo 123 \ No newline at end of file diff --git a/tests/misc/mbackend.nim b/tests/misc/mbackend.nim new file mode 100644 index 000000000..b6578a212 --- /dev/null +++ b/tests/misc/mbackend.nim @@ -0,0 +1,30 @@ +#[ +We can't merge this test inside a `when defined(cpp)` because some bug that was +fixed would not trigger in that case. +]# + +import std/compilesettings + +static: + ## bugfix 1: this used to CT error with: Error: unhandled exception: mimportcpp.nim(6, 18) `defined(cpp)` + doAssert defined(cpp) + doAssert querySetting(backend) == "cpp" + + ## checks that `--backend:c` has no side effect (ie, can be overridden by subsequent commands) + doAssert not defined(c) + doAssert not defined(js) + doAssert not defined(js) + +type + std_exception {.importcpp: "std::exception", header: "<exception>".} = object +proc what(s: std_exception): cstring {.importcpp: "((char *)#.what())".} + +var isThrown = false +try: + ## bugfix 2: this used to CT error with: Error: only a 'ref object' can be raised + raise std_exception() +except std_exception as ex: + doAssert ex.what().len > 0 + isThrown = true + +doAssert isThrown diff --git a/tests/misc/mbetterrun.nim b/tests/misc/mbetterrun.nim new file mode 100644 index 000000000..d4f427af0 --- /dev/null +++ b/tests/misc/mbetterrun.nim @@ -0,0 +1,3 @@ +const mbetterrunVal {.strdefine.} = "" +static: echo "compiling: " & mbetterrunVal +echo "running: " & mbetterrunVal diff --git a/tests/misc/mfield_defect.nim b/tests/misc/mfield_defect.nim new file mode 100644 index 000000000..53bfba40e --- /dev/null +++ b/tests/misc/mfield_defect.nim @@ -0,0 +1,30 @@ +#[ +ran from trunner +]# + + + + + + +# line 10 +type Kind = enum k0, k1, k2, k3, k4 + +type Foo = object + case kind: Kind + of k0: f0: int + of k1: f1: int + of k2: f2: int + of k3: f3: int + of k4: f4: int + +proc main()= + var foo = Foo(kind: k3, f3: 3) + let s1 = foo.f3 + doAssert s1 == 3 + let s2 = foo.f2 + +when defined case1: + static: main() +when defined case2: + main() diff --git a/tests/misc/mimportc.nim b/tests/misc/mimportc.nim new file mode 100644 index 000000000..602c6372d --- /dev/null +++ b/tests/misc/mimportc.nim @@ -0,0 +1,26 @@ +#[ +this test will grow with more importc+importcpp tests; see driver in trunner.nim +]# + +{.emit:""" +struct A { + static int fun0(int a){ + return a; + } + static int& fun1(int& a){ + return a; + } +}; +""".} + +proc fun0*(a: cint): int {.importcpp:"A::$1(@)".} +proc fun1*(a: var cint): var int {.importcpp:"A::$1(@)".} = + ## some comment; this test is for #14314 + runnableExamples: discard + +proc main()= + var a = 10.cint + doAssert fun0(a) == a + doAssert fun1(a).addr == a.addr + echo "witness" +main() diff --git a/tests/misc/mjsondoc.nim b/tests/misc/mjsondoc.nim new file mode 100644 index 000000000..016c8522d --- /dev/null +++ b/tests/misc/mjsondoc.nim @@ -0,0 +1,14 @@ +proc doSomething*(x, y: int): int = + ## do something + x + y + +const + a* = 1 ## echo 1234 + b* = "test" + +type + MyEnum* = enum + foo, bar + +proc foo2*[T: int, M: string, U](x: T, y: U, z: M) = + echo 1 diff --git a/tests/misc/modulea.nim b/tests/misc/modulea.nim new file mode 100644 index 000000000..a9e6b364e --- /dev/null +++ b/tests/misc/modulea.nim @@ -0,0 +1,2 @@ +type modulea* = object + a: int diff --git a/tests/misc/msizeof5.nim b/tests/misc/msizeof5.nim new file mode 100644 index 000000000..63573a705 --- /dev/null +++ b/tests/misc/msizeof5.nim @@ -0,0 +1,131 @@ +## tests for -d:checkAbi used by addAbiCheck via NIM_STATIC_ASSERT + +{.emit:"""/*TYPESECTION*/ +struct Foo1{ + int a; +}; +struct Foo2{ + int a; +}; +enum Foo3{k1, k2}; +typedef enum Foo3 Foo3b; +typedef enum Foo4{k3, k4} Foo4; + +typedef int Foo5[3]; + +typedef struct Foo6{ + int a1; + bool a2; + double a3; + struct Foo6* a4; +} Foo6; +""".} + +template ensureCgen(T: typedesc) = + ## ensures cgen + var a {.volatile.}: T + +block: + type Foo1Alias{.importc: "struct Foo1", size: sizeof(cint).} = object + a: cint + ensureCgen Foo1Alias + +block: + type Foo3Alias{.importc: "enum Foo3", size: sizeof(cint).} = enum + k1, k2 + ensureCgen Foo3Alias + +block: + type Foo3bAlias{.importc: "Foo3b", size: sizeof(cint).} = enum + k1, k2 + ensureCgen Foo3bAlias + +block: + type Foo3b{.importc, size: sizeof(cint).} = enum + k1, k2 + ensureCgen Foo3b + static: + doAssert Foo3b.sizeof == cint.sizeof + +block: + type Foo4{.importc, size: sizeof(cint).} = enum + k3, k4 + # adding entries should not yield duplicate ABI checks, as enforced by + # `typeABICache`. + # Currently the test doesn't check for this but you can inspect the cgen'd file + ensureCgen Foo4 + ensureCgen Foo4 + ensureCgen Foo4 + +block: + type Foo5{.importc.} = array[3, cint] + ensureCgen Foo5 + +block: + type Foo5{.importc.} = array[3, cint] + ensureCgen Foo5 + +block: # CT sizeof + type Foo6GT = object # grountruth + a1: cint + a2: bool + a3: cfloat + a4: ptr Foo6GT + + type Foo6{.importc, completeStruct.} = object + a1: cint + a2: bool + a3: cfloat + a4: ptr Foo6 + + static: doAssert compiles(static(Foo6.sizeof)) + static: doAssert Foo6.sizeof == Foo6GT.sizeof + static: doAssert (Foo6, int, array[2, Foo6]).sizeof == + (Foo6GT, int, array[2, Foo6GT]).sizeof + +block: + type GoodImportcType {.importc: "signed char", nodecl.} = char + # "good" in sense the sizeof will match + ensureCgen GoodImportcType + +block: + type Foo6{.importc.} = object + a1: cint + doAssert compiles(Foo6.sizeof) + static: doAssert not compiles(static(Foo6.sizeof)) + +when defined caseBad: + # Each case below should give a static cgen assert fail message + + block: + type BadImportcType {.importc: "unsigned char", nodecl.} = uint64 + # "sizeof" check will fail + ensureCgen BadImportcType + + block: + type Foo2AliasBad{.importc: "struct Foo2", size: 1.} = object + a: cint + ensureCgen Foo2AliasBad + + block: + type Foo5{.importc.} = array[4, cint] + ensureCgen Foo5 + + block: + type Foo5{.importc.} = array[3, bool] + ensureCgen Foo5 + + block: + type Foo6{.importc:"struct Foo6", completeStruct.} = object + a1: cint + # a2: bool # missing this should trigger assert fail + a3: cfloat + a4: ptr Foo6 + ensureCgen Foo6 + + when false: + block: + # pre-existing BUG: this should give a CT error in semcheck because `size` + # disagrees with `array[3, cint]` + type Foo5{.importc, size: 1.} = array[3, cint] + ensureCgen Foo5 diff --git a/tests/misc/msizeof5.nim.cfg b/tests/misc/msizeof5.nim.cfg new file mode 100644 index 000000000..dc0712a8c --- /dev/null +++ b/tests/misc/msizeof5.nim.cfg @@ -0,0 +1,5 @@ +# Do not limit number of error messages from backend compiler. +gcc.options.always %= "${gcc.options.always} -fmax-errors=100" +clang.options.always %= "${clang.options.always} -ferror-limit=100" +gcc.cpp.options.always %= "${gcc.cpp.options.always} -fmax-errors=100" +clang.cpp.options.always %= "${clang.cpp.options.always} -ferror-limit=100" diff --git a/tests/misc/mtlsemulation.h b/tests/misc/mtlsemulation.h new file mode 100644 index 000000000..992977acd --- /dev/null +++ b/tests/misc/mtlsemulation.h @@ -0,0 +1,37 @@ +#include <stdio.h> + +struct Foo1 { + /* + uncommenting would give: + error: initializer for thread-local variable must be a constant expression + N_LIB_PRIVATE NIM_THREADVAR Foo1 g1__9brEZhPEldbVrNpdRGmWESA; + */ + // Foo1() noexcept { } + + /* + uncommenting would give: + error: type of thread-local variable has non-trivial destruction + */ + // ~Foo1() { } + int x; +}; + +struct Foo2 { + Foo2() noexcept { } + ~Foo2() { } + int x; +}; + +static int ctorCalls = 0; +static int dtorCalls = 0; + +struct Foo3 { + Foo3() noexcept { + ctorCalls = ctorCalls + 1; + x = 10; + } + ~Foo3() { + dtorCalls = dtorCalls + 1; + } + int x; +}; diff --git a/tests/misc/mvarious.nim b/tests/misc/mvarious.nim index d1587faec..8efe7c92f 100644 --- a/tests/misc/mvarious.nim +++ b/tests/misc/mvarious.nim @@ -1,6 +1,6 @@ # Test a submodule #type -# TStringArr = array [0.. *] of string +# TStringArr = array[0.. *] of string proc exportme* = discard diff --git a/tests/misc/parsecomb.nim b/tests/misc/parsecomb.nim index 05fe97ad1..4f149cbf6 100644 --- a/tests/misc/parsecomb.nim +++ b/tests/misc/parsecomb.nim @@ -1,3 +1,7 @@ +discard """ + matrix: "--mm:arc; --mm:refc" +""" + type Input[T] = object toks: seq[T] index: int @@ -29,10 +33,10 @@ method runInput[T, O](self: Parser[T, O], inp: Input[T]): Result[T, O] = # XXX: above needed for now, as without the `tmp` bit below, it compiles to invalid C. tmp(self)(inp) -method run*[T, O](self: Parser[T, O], toks: seq[T]): Result[T, O] = +proc run*[T, O](self: Parser[T, O], toks: seq[T]): Result[T, O] = self.runInput(Input[T](toks: toks, index: 0)) -method chain*[T, O1, O2](self: Parser[T, O1], nextp: proc (v: O1): Parser[T, O2]): Parser[T, O2] = +proc chain*[T, O1, O2](self: Parser[T, O1], nextp: proc (v: O1): Parser[T, O2]): Parser[T, O2] = result = proc (inp: Input[T]): Result[T, O2] = let r = self.runInput(inp) case r.kind: @@ -41,7 +45,7 @@ method chain*[T, O1, O2](self: Parser[T, O1], nextp: proc (v: O1): Parser[T, O2] of rkFailure: Result[T, O2](kind: rkFailure) -method skip[T](self: Input[T], n: int): Input[T] = +method skip[T](self: Input[T], n: int): Input[T] {.base.} = Input[T](toks: self.toks, index: self.index + n) proc pskip*[T](n: int): Parser[T, tuple[]] = @@ -69,11 +73,11 @@ proc `+`*[T, O](first: Parser[T, O], second: Parser[T, O]): Parser[T, O] = # end of primitives (definitions involving Parser(..)) -method map*[T, O1, O2](self: Parser[T, O1], p: proc (v: O1): O2): Parser[T, O2] = +proc map*[T, O1, O2](self: Parser[T, O1], p: proc (v: O1): O2): Parser[T, O2] = self.chain(proc (v: O1): Parser[T, O2] = unit[T, O2](p(v))) -method then*[T, O1, O2](self: Parser[T, O1], next: Parser[T, O2]): Parser[T, O2] = +proc then*[T, O1, O2](self: Parser[T, O1], next: Parser[T, O2]): Parser[T, O2] = self.chain(proc (v: O1): Parser[T, O2] = next) diff --git a/tests/misc/t11634.nim b/tests/misc/t11634.nim new file mode 100644 index 000000000..390af40f4 --- /dev/null +++ b/tests/misc/t11634.nim @@ -0,0 +1,17 @@ +discard """ + action: reject +""" + +type Foo = ref object + val: int + +proc divmod(a, b: Foo): (Foo, Foo) = + ( + Foo(val: a.val div b.val), + Foo(val: a.val mod b.val) + ) + +block: + let a {.compileTime.} = Foo(val: 2) + let b {.compileTime.} = Foo(val: 3) + let (c11634 {.compileTime.}, d11634 {.compileTime.}) = divmod(a, b) diff --git a/tests/misc/t12480.nim b/tests/misc/t12480.nim new file mode 100644 index 000000000..992533ef6 --- /dev/null +++ b/tests/misc/t12480.nim @@ -0,0 +1,5 @@ +discard """ + errormsg: "'return' not allowed here" +""" + +return \ No newline at end of file diff --git a/tests/misc/t12869.nim b/tests/misc/t12869.nim new file mode 100644 index 000000000..054e28a03 --- /dev/null +++ b/tests/misc/t12869.nim @@ -0,0 +1,14 @@ +discard """ + errormsg: "type mismatch: got <openArray[int], proc (x: GenericParam, y: GenericParam): auto, SortOrder>" + line: 12 +""" + +import sugar +from algorithm import sorted, SortOrder + +let a = 5 + +proc sorted*[T](a: openArray[T], key: proc(v: T): int, order = SortOrder.Ascending): seq[T] = + sorted(a, (x, y) => key(x) < key(y), order) + +echo sorted(@[9, 1, 8, 2, 6, 4, 5, 0], (x) => (a - x).abs) diff --git a/tests/misc/t14667.nim b/tests/misc/t14667.nim new file mode 100644 index 000000000..3034e2841 --- /dev/null +++ b/tests/misc/t14667.nim @@ -0,0 +1,12 @@ +discard """ + matrix: "--cc:vcc" + disabled: "linux" + disabled: "bsd" + disabled: "osx" + disabled: "unix" + disabled: "posix" +""" + +type A = tuple +discard () +discard default(A) diff --git a/tests/misc/t15351.nim b/tests/misc/t15351.nim new file mode 100644 index 000000000..c31e604a2 --- /dev/null +++ b/tests/misc/t15351.nim @@ -0,0 +1,5 @@ +discard """ + action: "compile" +""" +var + ## TODO: broken diff --git a/tests/misc/t15955.nim b/tests/misc/t15955.nim new file mode 100644 index 000000000..7441e5398 --- /dev/null +++ b/tests/misc/t15955.nim @@ -0,0 +1,22 @@ +discard """ +joinable: false +""" + +import stdtest/specialpaths +import std/[osproc, strformat, os] + +const + nim = getCurrentCompilerExe() + buildLib = buildDir / "libD20220923T19380" + currentDir = splitFile(currentSourcePath).dir + file = currentDir / "m15955.nim" + main = currentDir / "m15955_main.nim" + + +proc runCmd(cmd: string) = + let (msg, code) = execCmdEx(cmd) + doAssert code == 0, msg + + +runCmd fmt"{nim} c -o:{buildLib} --nomain --nimMainPrefix:libA -f --app:staticlib {file}" +runCmd fmt"{nim} c -r {main}" diff --git a/tests/misc/t16244.nim b/tests/misc/t16244.nim new file mode 100644 index 000000000..5e8128736 --- /dev/null +++ b/tests/misc/t16244.nim @@ -0,0 +1,9 @@ +discard """ + errormsg: "type mismatch: got <int, float64>" + line: 9 +""" + +proc g(): auto = 1 +proc h(): auto = 1.0 + +var a = g() + h() diff --git a/tests/misc/t16264.nim b/tests/misc/t16264.nim new file mode 100644 index 000000000..afe319e6c --- /dev/null +++ b/tests/misc/t16264.nim @@ -0,0 +1,2 @@ +import times +doAssert low(Time) == fromUnix(0) \ No newline at end of file diff --git a/tests/misc/t16541.nim b/tests/misc/t16541.nim new file mode 100644 index 000000000..452327e8f --- /dev/null +++ b/tests/misc/t16541.nim @@ -0,0 +1,12 @@ +discard """ + action: "reject" + +""" + +import strutils, sugar, nre + +proc my_replace*(s: string, r: Regex, by: string | (proc (match: string): string)): string = + nre.replace(s, r, by) + +discard my_replace("abcde", re"[bcd]", match => match.to_upper) == "aBCDe" +discard my_replace("abcde", re"[bcd]", (match: string) => match.to_upper) == "aBCDe" diff --git a/tests/misc/t17286.nim b/tests/misc/t17286.nim new file mode 100644 index 000000000..3a54e624e --- /dev/null +++ b/tests/misc/t17286.nim @@ -0,0 +1,16 @@ +discard """ + cmd: "nim check -b:js $file" + action: "compile" +""" + +# bug #17286 + +import std/compilesettings + +static: + doAssert querySetting(backend) == "js" + doAssert defined(js) + doAssert not defined(c) + +import random +randomize() \ No newline at end of file diff --git a/tests/misc/t18077.nim b/tests/misc/t18077.nim new file mode 100644 index 000000000..6cd05d575 --- /dev/null +++ b/tests/misc/t18077.nim @@ -0,0 +1,21 @@ +discard """ + cmd: '''nim doc -d:nimTestsT18077b:4 --doccmd:"-d:nimTestsT18077 -d:nimTestsT18077b:3 --hints:off" $file''' + action: compile +""" + +# bug #18077 + +const nimTestsT18077b {.intdefine.} = 1 + +static: + when defined(nimdoc): + doAssert nimTestsT18077b == 4 + doAssert not defined(nimTestsT18077) + else: + doAssert defined(nimTestsT18077) + doAssert nimTestsT18077b == 3 + +runnableExamples: + const nimTestsT18077b {.intdefine.} = 2 + doAssert nimTestsT18077b == 3 + doAssert defined(nimTestsT18077) diff --git a/tests/misc/t18079.nim b/tests/misc/t18079.nim new file mode 100644 index 000000000..ae64bbff9 --- /dev/null +++ b/tests/misc/t18079.nim @@ -0,0 +1,15 @@ +discard """ + matrix: "--mm:orc" +""" + +type + Foo = object + y: int + + Bar = object + x: Foo + +proc baz(state: var Bar):int = + state.x.y = 2 + state.x.y +doAssert baz((ref Bar)(x: (new Foo)[])[]) == 2 diff --git a/tests/misc/t19046.nim b/tests/misc/t19046.nim new file mode 100644 index 000000000..b3bfec7ae --- /dev/null +++ b/tests/misc/t19046.nim @@ -0,0 +1,19 @@ +discard """ + targets: "c cpp" + matrix: "--threads:on" + disabled: "win" + disabled: "osx" + action: compile +""" + +# bug #19046 + +import std/os + +var t: Thread[void] + +proc test = discard +proc main = + createThread(t, test) + pinToCpu(t, 1) +main() \ No newline at end of file diff --git a/tests/misc/t20253.nim b/tests/misc/t20253.nim new file mode 100644 index 000000000..d47c36c55 --- /dev/null +++ b/tests/misc/t20253.nim @@ -0,0 +1,10 @@ +discard """ + errormsg: "'result' requires explicit initialization" + line: 10 +""" + +type Meow {.requiresInit.} = object + init: bool + +proc initMeow(): Meow = + discard diff --git a/tests/misc/t20289.nim b/tests/misc/t20289.nim new file mode 100644 index 000000000..5a0a269f0 --- /dev/null +++ b/tests/misc/t20289.nim @@ -0,0 +1,15 @@ +discard """ + action: reject +""" + +type E[T] = object + v: T + +template j[T](R: type E[T], x: untyped): R = R(v: x) +template d[T](O: type E, v: T): E[T] = E[T].j(v) + +proc w[T](): E[T] = + template r(k: int): auto = default(T) + E.d r + +discard w[int]() diff --git a/tests/misc/t20456_2.nim b/tests/misc/t20456_2.nim new file mode 100644 index 000000000..37e52c452 --- /dev/null +++ b/tests/misc/t20456_2.nim @@ -0,0 +1,14 @@ +discard """ + joinable: false +""" + +import std/[osproc, os, strformat] +from stdtest/specialpaths import testsDir + +when defined(nimPreviewSlimSystem): + import std/assertions + +const + nim = getCurrentCompilerExe() + file = testsDir / "misc" / "m20456.nims" +doAssert execCmd(fmt"{nim} check {file}") == 0 diff --git a/tests/misc/t20883.nim b/tests/misc/t20883.nim new file mode 100644 index 000000000..92e7929f4 --- /dev/null +++ b/tests/misc/t20883.nim @@ -0,0 +1,13 @@ +discard """ + action: reject +nimout: ''' +t20883.nim(13, 4) template/generic instantiation of `foo` from here +t20883.nim(9, 11) Error: cannot instantiate: 'U' +''' +""" + +proc foo*[U](x: U = U(1e-6)) = + echo x + +foo[float]() +foo() diff --git a/tests/misc/t21109.nim b/tests/misc/t21109.nim new file mode 100644 index 000000000..0f7980896 --- /dev/null +++ b/tests/misc/t21109.nim @@ -0,0 +1,13 @@ +discard """ + action: reject + errormsg: "type expected" + file: "iterators.nim" +""" + + +template b(j: untyped) = j +template m() = discard + +b: + for t, f in @[]: + m() diff --git a/tests/misc/t21443.nim b/tests/misc/t21443.nim new file mode 100644 index 000000000..70413c5b3 --- /dev/null +++ b/tests/misc/t21443.nim @@ -0,0 +1,6 @@ +import std/envvars + +# bug #19292 +putEnv("NimPutEnvTest", "test") +# bug #21122 +doAssert getEnv("NimPutEnvTest") == "test" diff --git a/tests/misc/t23240.nim b/tests/misc/t23240.nim new file mode 100644 index 000000000..d5edcefe8 --- /dev/null +++ b/tests/misc/t23240.nim @@ -0,0 +1,6 @@ +discard """ + cmd: "nim c foo/bar.nim" + action: "reject" + errormsg: "cannot open 'foo/'" + file: "" +""" diff --git a/tests/misc/t3482.nim b/tests/misc/t3482.nim new file mode 100644 index 000000000..33b3b8f40 --- /dev/null +++ b/tests/misc/t3482.nim @@ -0,0 +1,15 @@ +discard """ + action: reject + nimout: "t3482.nim(13, 8) Error: undeclared identifier: 'output'" +""" +# bug #3482 (correct behavior since 1.4.0, cgen error in 1.2.0) +template foo*(body: typed) = + if true: + body + +proc test = + foo: + var output = "" + echo output.len + +test() diff --git a/tests/misc/t3907.nim b/tests/misc/t3907.nim new file mode 100644 index 000000000..45fc75e81 --- /dev/null +++ b/tests/misc/t3907.nim @@ -0,0 +1,10 @@ +import std/assertions + +let a = 0 +let b = if false: -1 else: a +doAssert b == 0 + +let c: range[0..high(int)] = 0 +let d = if false: -1 else: c + +doAssert d == 0 diff --git a/tests/misc/t5540.nim b/tests/misc/t5540.nim new file mode 100644 index 000000000..6a19e70e1 --- /dev/null +++ b/tests/misc/t5540.nim @@ -0,0 +1,45 @@ +# bug #5540; works in 1.2.0 +# fails in 1.0 (Error: cannot generate VM code for) +# fails in 0.18.0 (Error: type mismatch: got <type T>) + +block: + type + Fruit = object + Yellow = object + a: int + template getColor(x: typedesc[Fruit]): typedesc = Yellow + type + Banana[T] = object + b: T + a: getColor(Fruit) + Apple[T] = object + a: T + b: getColor(T) + block: + var x: Banana[int] + doAssert x.b == 0 + doAssert x.a is Yellow + block: + var x: Apple[Fruit] + doAssert x.b is Yellow + +block: + type + Fruit = object + Yellow = object + a: int + + template getColor(x: typedesc[Fruit]): typedesc = Yellow + + type + Banana[T] = object + b: T + a: getColor(Fruit) + + Apple[T] = object + a: T + b: getColor(T) + + var x: Banana[int] + x.b = 13 + x.a.a = 17 diff --git a/tests/misc/t6549.nim b/tests/misc/t6549.nim new file mode 100644 index 000000000..1d7393318 --- /dev/null +++ b/tests/misc/t6549.nim @@ -0,0 +1,4 @@ + +const l = $(range[low(uint64) .. high(uint64)]) +const r = "range 0..18446744073709551615(uint64)" +doAssert l == r diff --git a/tests/misc/t8404.nim b/tests/misc/t8404.nim new file mode 100644 index 000000000..87991071c --- /dev/null +++ b/tests/misc/t8404.nim @@ -0,0 +1,33 @@ +discard """ + targets: "c cpp js" +""" +template main() = + block: # bug #8404 + # can conv + template float2int(T) = + var a = -1.0 + let b = T(a) + doAssert b < 0 + let c = b + 1 + doAssert c is T + doAssert c == 0 + + float2int(int8) + float2int(int16) + float2int(int32) + float2int(int64) + + block: + # can handle middle conv + # `/` can trigger int to float + template float2int(T) = + let n = T(1 / 256) + doAssert n == 0 + + float2int(int8) + float2int(int16) + float2int(int32) + # float2int(int64) +main() +static: + main() diff --git a/tests/misc/t8545.nim b/tests/misc/t8545.nim new file mode 100644 index 000000000..48b886cb8 --- /dev/null +++ b/tests/misc/t8545.nim @@ -0,0 +1,24 @@ +discard """ + # just tests that this doesn't crash the compiler + errormsg: "cannot instantiate: 'a:type'" +""" + +# bug #8545 + +template bar(a: static[bool]): untyped = int + +proc main() = + proc foo1(a: static[bool]): auto = 1 + doAssert foo1(true) == 1 + + proc foo2(a: static[bool]): bar(a) = 1 + doAssert foo2(true) == 1 + + proc foo3(a: static[bool]): bar(cast[static[bool]](a)) = 1 + doAssert foo3(true) == 1 + + proc foo4(a: static[bool]): bar(static(a)) = 1 + doAssert foo4(true) == 1 + +static: main() +main() diff --git a/tests/misc/t9039.nim b/tests/misc/t9039.nim new file mode 100644 index 000000000..3271cd34e --- /dev/null +++ b/tests/misc/t9039.nim @@ -0,0 +1,24 @@ +discard """ + action: reject + nimout: ''' +t9039.nim(22, 22) Error: type mismatch: got <array[0..2, int], int, array[0..1, int]> +but expression 'nesting + 1' is of type: int +''' +""" + +# bug #9039; this used to hang in 0.19.0 + + + + + +# line 15 +func default(T: typedesc[array]): T = discard +doAssert default(array[3, int]) == [0, 0, 0] +func shapeBad*[T: not char](s: openArray[T], rank: static[int], nesting = 0, parent_shape = default(array[rank, int])): array[rank, int] = + result = parent_shape + result[nesting] = s.len + when (T is seq|array): + result = shapeBad(s[0], nesting + 1, result) +let a1 = [1, 2, 3].shapeBad(rank = 1) +let a2 = [[1, 2, 3], [4, 5, 6]].shapeBad(rank = 2) diff --git a/tests/misc/t9091.nim b/tests/misc/t9091.nim new file mode 100644 index 000000000..6e7a98ca5 --- /dev/null +++ b/tests/misc/t9091.nim @@ -0,0 +1,33 @@ +# bug #9091 + +import streams + +block: + type Mine = ref object + a: int + + proc write(io: Stream, t: Mine) = + io.write("sure") + + let str = newStringStream() + let mi = new Mine + + str.write(mi) + str.setPosition 0 + doAssert str.readAll == "sure" + +block: + type + AObj = object + x: int + + proc foo(a: int): string = "" + + proc test(args: varargs[string, foo]) = + doAssert false + + proc test(a: AObj) = + discard + + let x = AObj() + test(x) diff --git a/tests/misc/t9710.nim b/tests/misc/t9710.nim new file mode 100644 index 000000000..c65cb7bf4 --- /dev/null +++ b/tests/misc/t9710.nim @@ -0,0 +1,6 @@ +discard """ + matrix: "--debugger:native" +""" +# bug #9710 +for i in 1 || 200: + discard i diff --git a/tests/misc/t99bott.nim b/tests/misc/t99bott.nim index 62ccfbe16..f60023818 100644 --- a/tests/misc/t99bott.nim +++ b/tests/misc/t99bott.nim @@ -1,9 +1,9 @@ discard """ + errormsg: "cannot evaluate at compile time: bn" file: "t99bott.nim" line: 26 - errormsg: "cannot evaluate at compile time: bn" - disabled: false """ + ## 99 Bottles of Beer ## http://www.99-bottles-of-beer.net/ ## Nim version @@ -30,7 +30,3 @@ for bn in countdown(99, 1): echo "No more bottles of beer on the wall, no more bottles of beer." echo "Go to the store and buy some more, 99 bottles of beer on the wall." - - - - diff --git a/tests/misc/tack.nim b/tests/misc/tack.nim index a0afab9e8..458395ef6 100644 --- a/tests/misc/tack.nim +++ b/tests/misc/tack.nim @@ -1,5 +1,4 @@ discard """ - file: "tack.nim" output: "125" """ # the Ackermann function @@ -17,5 +16,4 @@ proc ack(x, y: int): int = # echo(ack(0, 0)) write(stdout, ack(3, 4)) #OUT 125 - - +write stdout, "\n" diff --git a/tests/misc/taddr.nim b/tests/misc/taddr.nim new file mode 100644 index 000000000..64f95c7e3 --- /dev/null +++ b/tests/misc/taddr.nim @@ -0,0 +1,295 @@ +discard """ + targets: "c cpp js" + matrix: "; -d:release" +""" + +type T = object + x: int + s: string + +var obj: T +var fieldAddr = addr(obj.x) +var objAddr = addr(obj) + +# Integer tests +var field = fieldAddr[] +doAssert field == 0 + +var objDeref = objAddr[] +doAssert objDeref.x == 0 + +# Change value +obj.x = 42 + +doAssert field == 0 +doAssert objDeref.x == 0 + +field = fieldAddr[] +objDeref = objAddr[] + +doAssert field == 42 +doAssert objDeref.x == 42 + +# String tests +obj.s = "lorem ipsum dolor sit amet" +when defined(gcArc) or defined(gcOrc): + prepareMutation(obj.s) + + +var indexAddr = addr(obj.s[2]) + +doAssert indexAddr[] == 'r' + +indexAddr[] = 'd' + +doAssert indexAddr[] == 'd' + +doAssert obj.s == "lodem ipsum dolor sit amet" + +# Bug #2148 +var x: array[2, int] +var y = addr x[1] + +y[] = 12 +doAssert(x[1] == 12) + +type + Foo = object + bar: int + +var foo: array[2, Foo] +var z = addr foo[1] + +z[].bar = 12345 +doAssert(foo[1].bar == 12345) + +var t : tuple[a, b: int] +var pt = addr t[1] +pt[] = 123 +doAssert(t.b == 123) + +#block: # Test "untyped" pointer. +proc testPtr(p: pointer, a: int) = + doAssert(a == 5) + (cast[ptr int](p))[] = 124 +var i = 123 +testPtr(addr i, 5) +doAssert(i == 124) + +var someGlobal = 5 +proc getSomeGlobalPtr(): ptr int = addr someGlobal +let someGlobalPtr = getSomeGlobalPtr() +doAssert(someGlobalPtr[] == 5) +someGlobalPtr[] = 10 +doAssert(someGlobal == 10) + +block: + # bug #14576 + # lots of these used to give: Error: internal error: genAddr: 2 + proc byLent[T](a: T): lent T = a + proc byPtr[T](a: T): ptr T = a.addr + + block: + let a = (10,11) + let (x,y) = byLent(a) + doAssert (x,y) == a + + block: # (with -d:release) bug #14578 + let a = 10 + doAssert byLent(a) == 10 + let a2 = byLent(a) + doAssert a2 == 10 + + block: + let a = [11,12] + doAssert byLent(a) == [11,12] # bug #15958 + let a2 = (11,) + doAssert byLent(a2) == (11,) + + block: + proc byLent2[T](a: seq[T]): lent T = a[1] + var a = @[20,21,22] + doAssert byLent2(a) == 21 + + block: # sanity checks + proc bar[T](a: var T): var T = a + var a = (10, 11) + let (k,v) = bar(a) + doAssert (k, v) == a + doAssert k == 10 + bar(a)[0]+=100 + doAssert a == (110, 11) + var a2 = 12 + doAssert bar(a2) == a2 + bar(a2).inc + doAssert a2 == 13 + + block: # pending bug #15959 + when false: + proc byLent2[T](a: T): lent type(a[0]) = a[0] + +proc test14420() = # bug #14420 + # s/proc/template/ would hit bug #16005 + block: + type Foo = object + x: float + + proc fn(a: var Foo): var float = + ## WAS: discard <- turn this into a comment (or a `discard`) and error disappears + # result = a.x # this works + a.x # WAS: Error: limited VM support for 'addr' + + proc fn2(a: var Foo): var float = + result = a.x # this works + a.x # WAS: Error: limited VM support for 'addr' + + var a = Foo() + discard fn(a) + discard fn2(a) + + block: + proc byLent2[T](a: T): lent T = + runnableExamples: discard + a + proc byLent3[T](a: T): lent T = + runnableExamples: discard + result = a + var a = 10 + let x3 = byLent3(a) # works + let x2 = byLent2(a) # WAS: Error: internal error: genAddr: nkStmtListExpr + + block: + type MyOption[T] = object + case has: bool + of true: + value: T + of false: + discard + func some[T](val: T): MyOption[T] = + result = MyOption[T](has: true, value: val) + func get[T](opt: MyOption[T]): lent T = + doAssert opt.has + # result = opt.value # this was ok + opt.value # this had the bug + let x = some(10) + doAssert x.get() == 10 + +template test14339() = # bug #14339 + block: + type + Node = ref object + val: int + proc bar(c: Node): var int = + var n = c # was: Error: limited VM support for 'addr' + c.val + var a = Node() + discard a.bar() + block: + type + Node = ref object + val: int + proc bar(c: Node): var int = + var n = c + doAssert n.val == n[].val + n.val + var a = Node(val: 3) + a.bar() = 5 + when nimvm: + doAssert a.val == 5 + else: + when not defined(js): # pending bug #16003 + doAssert a.val == 5 + +template testStatic15464() = # bug #15464 + proc access(s: var seq[char], i: int): var char = s[i] + proc access(s: var string, i: int): var char = s[i] + static: + var s = @['a', 'b', 'c'] + access(s, 2) = 'C' + doAssert access(s, 2) == 'C' + static: + var s = "abc" + access(s, 2) = 'C' + doAssert access(s, 2) == 'C' + +proc test15464() = # bug #15464 (v2) + proc access(s: var seq[char], i: int): var char = s[i] + proc access(s: var string, i: int): var char = s[i] + block: + var s = @['a', 'b', 'c'] + access(s, 2) = 'C' + doAssert access(s, 2) == 'C' + block: + var s = "abc" + access(s, 2) = 'C' + doAssert access(s, 2) == 'C' + +block: # bug #15939 + block: + const foo = "foo" + proc proc1(s: var string) = + if s[^1] notin {'a'..'z'}: + s = "" + proc proc2(f: string): string = + result = f + proc1(result) + const bar = proc2(foo) + doAssert bar == "foo" + +template prepareMutationForOrc(x: string) = + when defined(gcArc) or defined(gcOrc): + when nimvm: + discard + else: + prepareMutation(x) + +proc test15939() = # bug #15939 (v2) + template fn(a) = + when typeof(a) is string: + prepareMutationForOrc(a) + let pa = a[0].addr + doAssert pa != nil + doAssert pa[] == 'a' + pa[] = 'x' + doAssert pa[] == 'x' + doAssert a == "xbc" + when not defined js: # otherwise overflows + let pa2 = cast[ptr char](cast[int](pa) + 1) + doAssert pa2[] == 'b' + pa2[] = 'B' + doAssert a == "xBc" + + # mystring[ind].addr + var a = "abc" + fn(a) + + # mycstring[ind].addr + template cstringTest = + var a2 = "abc" + prepareMutationForOrc(a2) + var b2 = a2.cstring + fn(b2) + when nimvm: cstringTest() + else: # can't take address of cstring element in js + when not defined(js): cstringTest() + +block: # bug #23499 + template volatileStore[T](dest: ptr T, val: T) = + dest[] = val + + proc foo = + var ctr = 0 + volatileStore(addr ctr, 0) + + foo() + +template main = + # xxx wrap all other tests here like that so they're also tested in VM + test14420() + test14339() + test15464() + test15939() + +testStatic15464() +static: main() +main() diff --git a/tests/misc/tapp_lib_staticlib.nim b/tests/misc/tapp_lib_staticlib.nim new file mode 100644 index 000000000..92c9acbc3 --- /dev/null +++ b/tests/misc/tapp_lib_staticlib.nim @@ -0,0 +1,27 @@ +discard """ +joinable: false +""" + +# bug #16949 + +when defined case1: + proc foo(): int {.exportc.} = 10 +elif defined case2: + proc foo(): int {.exportc, dynlib.} = 10 +elif defined caseMain: + proc foo(): int {.importc.} + doAssert foo() == 10 +else: + import stdtest/specialpaths + import std/[os, strformat, strutils, compilesettings] + proc runCmd(cmd: string) = + doAssert execShellCmd(cmd) == 0, $cmd + const + file = currentSourcePath + nim = getCurrentCompilerExe() + mode = querySetting(backend) + proc test(lib, options: string) = + runCmd fmt"{nim} {mode} -o:{lib} --nomain {options} -f {file}" + # runCmd fmt"{nim} r -b:{mode} --passl:{lib} -d:caseMain -f {file}" # pending https://github.com/nim-lang/Nim/pull/16945 + test(buildDir / "libD20210205T172314.a", "--app:staticlib -d:nimLinkerWeakSymbols -d:case1") + test(buildDir / DynlibFormat % "D20210205T172720", "--app:lib -d:case2") diff --git a/tests/misc/tatomic.nim b/tests/misc/tatomic.nim deleted file mode 100644 index f3c56ffe3..000000000 --- a/tests/misc/tatomic.nim +++ /dev/null @@ -1,12 +0,0 @@ -discard """ - file: "tatomic.nim" - line: 7 - errormsg: "identifier expected, but found 'keyword atomic'" -""" -var - atomic: int - -echo atomic - - - diff --git a/tests/misc/tbug511622.nim b/tests/misc/tbug511622.nim index a5360423d..1af6380ed 100644 --- a/tests/misc/tbug511622.nim +++ b/tests/misc/tbug511622.nim @@ -1,8 +1,7 @@ discard """ - file: "tbug511622.nim" output: "3" """ -import StrUtils, Math +import math proc FibonacciA(n: int): int64 = var fn = float64(n) @@ -11,6 +10,3 @@ proc FibonacciA(n: int): int64 = return int64((pow(p, fn) + pow(q, fn)) / sqrt(5.0)) echo FibonacciA(4) #OUT 3 - - - diff --git a/tests/misc/tcast.nim b/tests/misc/tcast.nim new file mode 100644 index 000000000..73196e76c --- /dev/null +++ b/tests/misc/tcast.nim @@ -0,0 +1,108 @@ +discard """ + output: ''' +Hello World +Hello World +Hello World''' + joinable: false +""" +type MyProc = proc() {.cdecl.} +type MyProc2 = proc() {.nimcall.} +type MyProc3 = proc() #{.closure.} is implicit + +proc testProc() {.exportc:"foo".} = echo "Hello World" + +template reject(x) = doAssert(not compiles(x)) + +proc callPointer(p: pointer) = + # can cast to proc(){.cdecl.} + let ffunc0 = cast[MyProc](p) + # can cast to proc(){.nimcall.} + let ffunc1 = cast[MyProc2](p) + # cannot cast to proc(){.closure.} + reject: cast[MyProc3](p) + + ffunc0() + ffunc1() + + # bug #5901 + proc foo() {.importc.} + (cast[proc(a: int) {.cdecl.}](foo))(5) + +callPointer(cast[pointer](testProc)) + +reject: discard cast[enum](0) +proc a = echo "hi" + +reject: discard cast[ptr](a) + +# bug #15623 +block: + if false: + let x = cast[ptr int](nil) + echo x[] + +block: + if false: + var x: ref int = nil + echo cast[ptr int](x)[] + +block: + doAssert cast[int](cast[ptr int](nil)) == 0 + +block: + var x: ref int = nil + doAssert cast[int](cast[ptr int](x)) == 0 + +block: # cast of nil + block: + static: + let a = cast[pointer](nil) + doAssert a.repr == "nil" + + block: + static: + doAssert cast[ptr int](nil).repr == "nil" + + block: + const str = cast[ptr int](nil) + static: + doAssert str.repr == "nil" + + block: + static: + doAssert cast[ptr int](nil).repr == "nil" + + block: + static: + doAssert cast[RootRef](nil).repr == "nil" + + when false: # xxx bug #15730, not fixed yet + block: + static: + doAssert cast[cstring](nil).repr == "nil" + +template main() = + # xxx move all under here to get tested in VM + block: # cast of enum + type Koo = enum k1, k2 + type Goo = enum g1, g2 + type Boo = enum b1 = -1, b2, b3, b4 + type Coo = enum c1 = -1i8, c2, c3, c4 + when nimvm: + # xxx: Error: VM does not support 'cast' from tyEnum to tyEnum + discard + else: + doAssert cast[Koo](k2) == k2 + doAssert cast[Goo](k2) == g2 + doAssert cast[Goo](k2.ord) == g2 + + doAssert b3.ord == 1 + doAssert cast[Koo](b3) == k2 + doAssert cast[Boo](k2) == b3 + + doAssert c3.ord == 1 + doAssert cast[Koo](c3) == k2 + doAssert cast[Coo](k2) == c3 + +static: main() +main() diff --git a/tests/misc/tcmdline.nim b/tests/misc/tcmdline.nim index cb8cb402c..71e1301ca 100644 --- a/tests/misc/tcmdline.nim +++ b/tests/misc/tcmdline.nim @@ -1,3 +1,7 @@ +discard """ +outputsub: "Number of parameters: 0" +joinable: false +""" # Test the command line import diff --git a/tests/misc/tcolonisproc.nim b/tests/misc/tcolonisproc.nim deleted file mode 100644 index 665e9e604..000000000 --- a/tests/misc/tcolonisproc.nim +++ /dev/null @@ -1,13 +0,0 @@ - -proc p(a, b: int, c: proc ()) = - c() - -when false: - # language spec changed: - p(1, 3): - echo 1 - echo 3 - -p(1, 1, proc() = - echo 1 - echo 2) diff --git a/tests/misc/tconv.nim b/tests/misc/tconv.nim new file mode 100644 index 000000000..90fae868b --- /dev/null +++ b/tests/misc/tconv.nim @@ -0,0 +1,143 @@ +discard """ + matrix: "--warningAsError:EnumConv --warningAsError:CStringConv" +""" + +from std/enumutils import items # missing from the example code +from std/sequtils import toSeq + +template reject(x) = + static: doAssert(not compiles(x)) +template accept(x) = + static: doAssert(compiles(x)) + +reject: + const x = int8(300) + +reject: + const x = int64(NaN) + +type + R = range[0..10] + +reject: + const x = R(11) + +reject: + const x = R(11.0) + +reject: + const x = R(NaN) + +reject: + const x = R(Inf) + +type + FloatRange = range[0'f..10'f] + +reject: + const x = FloatRange(-1'f) + +reject: + const x = FloatRange(-1) + +reject: + const x = FloatRange(NaN) + +block: + const x = float32(NaN) + +type E = enum a, b, c + +reject: + const e = E(4) + +block: # issue 3766 + + type R = range[0..2] + + reject: + type + T[n: static[R]] = object + V = T[3.R] + + reject: + proc r(x: static[R]) = + echo x + r 3.R + + +block: # https://github.com/nim-lang/RFCs/issues/294 + type Koo = enum k1, k2 + type Goo = enum g1, g2 + + accept: Koo(k2) + accept: k2.Koo + accept: k2.int.Goo + + reject: Goo(k2) + reject: k2.Goo + reject: k2.string + + {.push warningAsError[EnumConv]:off.} + discard Goo(k2) + accept: Goo(k2) + accept: k2.Goo + reject: k2.string + {.pop.} + + reject: Goo(k2) + reject: k2.Goo + + type KooRange = range[k2..k2] + accept: KooRange(k2) + accept: k2.KooRange + let k2ranged: KooRange = k2 + accept: Koo(k2ranged) + accept: k2ranged.Koo + +reject: + # bug #18550 + proc f(c: char): cstring = + var x = newString(109*1024*1024) + x[0] = c + x + +{.push warning[AnyEnumConv]:on, warningAsError[AnyEnumConv]:on.} + +reject: + type + Foo = enum + one + three + + var va = 2 + var vb = va.Foo + +{.pop.} + +{.push warningAsError[HoleEnumConv]:on.} + +reject: + # bug #12815 + type + Hole = enum + one = 1 + three = 3 + + var va = 2 + var vb = va.Hole + +block: # bug #22844 + type + A = enum + a0 = 2 + a1 = 4 + a2 + B[T] = enum + b0 = 2 + b1 = 4 + + doAssert A.toSeq == [a0, a1, a2] + doAssert B[float].toSeq == [B[float].b0, B[float].b1] + +{.pop.} diff --git a/tests/misc/tcsharpusingstatement.nim b/tests/misc/tcsharpusingstatement.nim new file mode 100644 index 000000000..1ce553895 --- /dev/null +++ b/tests/misc/tcsharpusingstatement.nim @@ -0,0 +1,76 @@ +discard """ + output: "Using test.Closing test." +""" + +import + macros + +# This macro mimics the using statement from C# +# +# It's kept only as a test for the macro system +# Nim's destructors offer a mechanism for automatic +# disposal of resources. +# +macro autoClose(args: varargs[untyped]): untyped = + let e = callsite() + if e.len != 3: + error "Using statement: unexpected number of arguments. Got " & + $e.len & ", expected: 1 or more variable assignments and a block" + + var args = e + var body = e[2] + + var + variables : seq[NimNode] + closingCalls : seq[NimNode] + + newSeq(variables, 0) + newSeq(closingCalls, 0) + + for i in countup(1, args.len-2): + if args[i].kind == nnkExprEqExpr: + var varName = args[i][0] + var varValue = args[i][1] + + var varAssignment = newNimNode(nnkIdentDefs) + varAssignment.add(varName) + varAssignment.add(newNimNode(nnkEmpty)) # empty means no type + varAssignment.add(varValue) + variables.add(varAssignment) + + closingCalls.add(newCall(newIdentNode("close"), varName)) + else: + error "Using statement: Unexpected expression. Got " & + $args[i].kind & " instead of assignment." + + var varSection = newNimNode(nnkVarSection) + varSection.add(variables) + + var finallyBlock = newNimNode(nnkStmtList) + finallyBlock.add(closingCalls) + + result = quote do: + block: + `varSection` + try: + `body` + finally: + `finallyBlock` + +type + TResource* = object + field*: string + +proc openResource(param: string): TResource = + result.field = param + +proc close(r: var TResource) = + write(stdout, "Closing " & r.field & ".") + +proc use(r: var TResource) = + write(stdout, "Using " & r.field & ".") + +autoClose(r = openResource("test")): + use r + +write stdout, "\n" diff --git a/tests/misc/tdangerisrelease.nim b/tests/misc/tdangerisrelease.nim new file mode 100644 index 000000000..e1854dca5 --- /dev/null +++ b/tests/misc/tdangerisrelease.nim @@ -0,0 +1,14 @@ +discard """ + cmd: "nim c $options -r $file" + matrix: "-d:danger; -d:release" + output: ''' +a +b +c +''' +""" + +echo "a" +when defined(release): + echo "b" +echo "c" diff --git a/tests/misc/tdefine.nim b/tests/misc/tdefine.nim new file mode 100644 index 000000000..f3fa4711f --- /dev/null +++ b/tests/misc/tdefine.nim @@ -0,0 +1,77 @@ +discard """ +joinable: false +cmd: "nim c $options -d:booldef -d:booldef2=false -d:intdef=2 -d:strdef=foobar -d:namespaced.define=false -d:double.namespaced.define -r $file" +matrix: "; -d:useGenericDefine" +""" + +when defined(useGenericDefine): + {.pragma: booldefine2, define.} + {.pragma: intdefine2, define.} + {.pragma: strdefine2, define.} +else: + + {.pragma: booldefine2, booldefine.} + {.pragma: intdefine2, intdefine.} + {.pragma: strdefine2, strdefine.} + +const booldef {.booldefine2.} = false +const booldef2 {.booldefine2.} = true +const intdef {.intdefine2.} = 0 +const strdef {.strdefine2.} = "" + +doAssert defined(booldef) +doAssert defined(booldef2) +doAssert defined(intdef) +doAssert defined(strdef) +doAssert booldef +doAssert not booldef2 +doAssert intdef == 2 +doAssert strdef == "foobar" + +when defined(useGenericDefine): + block: + const uintdef {.define: "intdef".}: uint = 17 + doAssert intdef == int(uintdef) + const cstrdef {.define: "strdef".}: cstring = "not strdef" + doAssert $cstrdef == strdef + type FooBar = enum foo, bar, foobar + const enumdef {.define: "strdef".} = foo + doAssert $enumdef == strdef + doAssert enumdef == foobar + +# Intentionally not defined from command line +const booldef3 {.booldefine2.} = true +const intdef2 {.intdefine2.} = 1 +const strdef2 {.strdefine2.} = "abc" +type T = object + when booldef3: + field1: int + when intdef2 == 1: + field2: int + when strdef2 == "abc": + field3: int + +doAssert not defined(booldef3) +doAssert not defined(intdef2) +doAssert not defined(strdef2) +discard T(field1: 1, field2: 2, field3: 3) + +doAssert defined(namespaced.define) +const `namespaced.define` {.booldefine2.} = true +doAssert not `namespaced.define` +when defined(useGenericDefine): + const aliasToNamespacedDefine {.define: "namespaced.define".} = not `namespaced.define` +else: + const aliasToNamespacedDefine {.booldefine: "namespaced.define".} = not `namespaced.define` +doAssert aliasToNamespacedDefine == `namespaced.define` + +doAssert defined(double.namespaced.define) +const `double.namespaced.define` {.booldefine2.} = false +doAssert `double.namespaced.define` +when defined(useGenericDefine): + const aliasToDoubleNamespacedDefine {.define: "double.namespaced.define".} = not `double.namespaced.define` +else: + const aliasToDoubleNamespacedDefine {.booldefine: "double.namespaced.define".} = not `double.namespaced.define` +doAssert aliasToDoubleNamespacedDefine == `double.namespaced.define` + +doAssert not defined(namespaced.butnotdefined) diff --git a/tests/misc/tdllvar.nim b/tests/misc/tdllvar.nim index 1c1238e8d..68029ddf4 100644 --- a/tests/misc/tdllvar.nim +++ b/tests/misc/tdllvar.nim @@ -1,3 +1,7 @@ +discard """ +disabled: true +""" + import os proc getDllName: string = @@ -12,5 +16,3 @@ proc myImport2(s: int) {.cdecl, importc, dynlib: getDllName().} myImport("test2") myImport2(12) - - diff --git a/tests/misc/temit.nim b/tests/misc/temit.nim deleted file mode 100644 index c83235659..000000000 --- a/tests/misc/temit.nim +++ /dev/null @@ -1,20 +0,0 @@ -discard """ - file: "temit.nim" - output: "509" -""" -# Test the new ``emit`` pragma: - -{.emit: """ -static int cvariable = 420; - -""".} - -proc embedsC() = - var nimVar = 89 - {.emit: """printf("%d\n", cvariable + (int)`nimVar`);""".} - -embedsC() - - - - diff --git a/tests/misc/temptyecho.nim b/tests/misc/temptyecho.nim deleted file mode 100644 index 5f1aa6515..000000000 --- a/tests/misc/temptyecho.nim +++ /dev/null @@ -1,2 +0,0 @@ -echo() - diff --git a/tests/misc/tendian.nim b/tests/misc/tendian.nim deleted file mode 100644 index 91044f4d5..000000000 --- a/tests/misc/tendian.nim +++ /dev/null @@ -1,3 +0,0 @@ -# test the new endian magic - -writeLine(stdout, repr(system.cpuEndian)) diff --git a/tests/misc/tevents.nim b/tests/misc/tevents.nim deleted file mode 100644 index 5f2169f29..000000000 --- a/tests/misc/tevents.nim +++ /dev/null @@ -1,48 +0,0 @@ -discard """ -file: "tevents.nim" -output: '''HandlePrintEvent: Output -> Handled print event -HandlePrintEvent2: Output -> printing for ME -HandlePrintEvent2: Output -> printing for ME''' -""" - -import events - -type - TPrintEventArgs = object of TEventArgs - user*: string - -proc handleprintevent*(e: TEventArgs) = - write(stdout, "HandlePrintEvent: Output -> Handled print event\n") - -proc handleprintevent2*(e: TEventArgs) = - var args: TPrintEventArgs = TPrintEventArgs(e) - write(stdout, "HandlePrintEvent2: Output -> printing for " & args.user) - -var ee = initEventEmitter() - -var eventargs: TPrintEventArgs -eventargs.user = "ME\n" - -##method one test - -ee.on("print", handleprintevent) -ee.on("print", handleprintevent2) - -ee.emit("print", eventargs) - -##method two test - -type - TSomeObject = object of TObject - PrintEvent: TEventHandler - -var obj: TSomeObject -obj.PrintEvent = initEventHandler("print") -obj.PrintEvent.addHandler(handleprintevent2) - -ee.emit(obj.PrintEvent, eventargs) - -obj.PrintEvent.removeHandler(handleprintevent2) - -ee.emit(obj.PrintEvent, eventargs) - diff --git a/tests/misc/tfsmonitor.nim b/tests/misc/tfsmonitor.nim deleted file mode 100644 index 27e1a2e32..000000000 --- a/tests/misc/tfsmonitor.nim +++ /dev/null @@ -1,12 +0,0 @@ -# -# fsmonitor test -# - -import unittest -import fsmonitor - -suite "fsmonitor": - test "should not raise OSError, bug# 3611": - let m = newMonitor() - m.add("foo", {MonitorCloseWrite, MonitorCloseNoWrite}) - diff --git a/tests/misc/tgenconstraints.nim b/tests/misc/tgenconstraints.nim deleted file mode 100644 index 6e8fdc738..000000000 --- a/tests/misc/tgenconstraints.nim +++ /dev/null @@ -1,32 +0,0 @@ -discard """ - file: "tgenconstraints.nim" - line: 25 - disabled: true - errormsg: "cannot instantiate T2" -""" - -type - T1[T: int|string] = object - x: T - - T2[T: Ordinal] = object - x: T - -var x1: T1[int] -var x2: T1[string] -var x3: T2[int] - -proc foo[T](x: T): T2[T] {.discardable.} = - var o: T1[T] - -foo(10) - -# XXX: allow type intersections in situation like this -proc bar(x: int|TNumber): T1[type(x)] {.discardable.} = - when type(x) is TNumber: - var o: T2[type(x)] - -bar "test" -bar 100 -bar 1.1 - diff --git a/tests/misc/tgetstartmilsecs.nim b/tests/misc/tgetstartmilsecs.nim deleted file mode 100644 index bf508dd54..000000000 --- a/tests/misc/tgetstartmilsecs.nim +++ /dev/null @@ -1,7 +0,0 @@ -# -import times, os - -var start = epochTime() -os.sleep(1000) - -echo epochTime() - start #OUT 1000 diff --git a/tests/misc/thallo.nim b/tests/misc/thallo.nim index 17e955f03..8dac56023 100644 --- a/tests/misc/thallo.nim +++ b/tests/misc/thallo.nim @@ -1,4 +1,8 @@ -# Hallo +discard """ +action: compile +""" + +# noted this seems to be an old test file designed for manual testing. import os, strutils, macros @@ -7,7 +11,7 @@ type TMyEnum = enum meA, meB, meC, meD -when isMainModule: +when true: {.hint: "this is the main file".} proc fac[T](x: T): T = @@ -15,7 +19,7 @@ proc fac[T](x: T): T = if x <= 1: return 1 else: return x.`*`(fac(x-1)) -macro macrotest(n: expr): stmt {.immediate.} = +macro macrotest(n: varargs[untyped]): untyped = let n = callsite() expectKind(n, nnkCall) expectMinLen(n, 2) @@ -24,7 +28,7 @@ macro macrotest(n: expr): stmt {.immediate.} = result.add(newCall("write", n[1], n[i])) result.add(newCall("writeLine", n[1], newStrLitNode(""))) -macro debug(n: expr): stmt {.immediate.} = +macro debug(n: untyped): untyped = let n = callsite() result = newNimNode(nnkStmtList, n) for i in 1..n.len-1: @@ -44,7 +48,6 @@ echo(["a", "b", "c", "d"].len) for x in items(["What's", "your", "name", "?", ]): echo(x) var `name` = readLine(stdin) -{.breakpoint.} echo("Hi " & thallo.name & "!\n") debug(name) @@ -80,6 +83,5 @@ for i in 2..6: for j in countdown(i+4, 2): echo(fac(i * j)) -when isMainModule: +when true: {.hint: "this is the main file".} - diff --git a/tests/misc/theaproots.nim b/tests/misc/theaproots.nim index 77d0207b0..2dd345254 100644 --- a/tests/misc/theaproots.nim +++ b/tests/misc/theaproots.nim @@ -1,3 +1,7 @@ +discard """ +action: compile +""" + type Bar = object x: int @@ -24,7 +28,7 @@ proc acc(x: var Foo): var ref Bar = proc test(maybeFoo: var Foo, maybeSeq: var seq[ref Bar], - bars: var openarray[ref Bar], + bars: var openArray[ref Bar], maybeTup: var Tup) = var bb: ref Bar maybeFoo.rmaybe = bb diff --git a/tests/misc/thintoff.nim b/tests/misc/thintoff.nim deleted file mode 100644 index 95318ce9b..000000000 --- a/tests/misc/thintoff.nim +++ /dev/null @@ -1,12 +0,0 @@ -discard """ - file: "thintoff.nim" - output: "0" -""" - -{.hint[XDeclaredButNotUsed]: off.} -var - x: int - -echo x #OUT 0 - - diff --git a/tests/misc/tinc.nim b/tests/misc/tinc.nim deleted file mode 100644 index b74f85591..000000000 --- a/tests/misc/tinc.nim +++ /dev/null @@ -1,12 +0,0 @@ -discard """ - file: "tinc.nim" - line: 8 - errormsg: "type mismatch: got (int)" -""" -var x = 0 - -inc(x+1) - - - - diff --git a/tests/misc/tinit.nim b/tests/misc/tinit.nim index 02607909b..207cb17e8 100644 --- a/tests/misc/tinit.nim +++ b/tests/misc/tinit.nim @@ -1,5 +1,4 @@ discard """ - file: "tinit.nim" output: "Hello from module! Hello from main module!" """ # Test the new init section in modules @@ -8,5 +7,3 @@ import minit write(stdout, "Hello from main module!\n") #OUT Hello from module! Hello from main module! - - diff --git a/tests/misc/tinout.nim b/tests/misc/tinout.nim index 0b2a54d9f..bae0fb185 100644 --- a/tests/misc/tinout.nim +++ b/tests/misc/tinout.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "type mismatch: got <int literal(3)>" file: "tinout.nim" line: 12 - errormsg: "type mismatch: got (int literal(3))" """ # Test in out checking for parameters @@ -12,5 +12,3 @@ proc b() = abc(3) #ERROR b() - - diff --git a/tests/misc/tints.nim b/tests/misc/tints.nim deleted file mode 100644 index 5bfb8a17c..000000000 --- a/tests/misc/tints.nim +++ /dev/null @@ -1,81 +0,0 @@ -discard """ - output: ''' -0 0 -0 0 -Success''' -""" -# Test the different integer operations - -var testNumber = 0 - -template test(opr, a, b, c: expr): stmt {.immediate.} = - # test the expression at compile and runtime - block: - const constExpr = opr(a, b) - when constExpr != c: - {.error: "Test failed " & $constExpr & " " & $c.} - inc(testNumber) - #Echo("Test: " & $testNumber) - var aa = a - var bb = b - var varExpr = opr(aa, bb) - assert(varExpr == c) - -test(`+`, 12'i8, -13'i16, -1'i16) -test(`shl`, 0b11, 0b100, 0b110000) -when not defined(js): - test(`shl`, 0b11'i32, 0b100'i64, 0b110000'i64) -test(`shl`, 0b11'i32, 0b100'i32, 0b110000'i32) - -test(`or`, 0xf0f0'i16, 0x0d0d'i16, 0xfdfd'i16) -test(`and`, 0xf0f0'i16, 0xfdfd'i16, 0xf0f0'i16) - -when not defined(js): - test(`shr`, 0xffffffffffffffff'i64, 0x4'i64, 0x0fffffffffffffff'i64) -test(`shr`, 0xffff'i16, 0x4'i16, 0x0fff'i16) -test(`shr`, 0xff'i8, 0x4'i8, 0x0f'i8) - -when not defined(js): - test(`shr`, 0xffffffff'i64, 0x4'i64, 0x0fffffff'i64) -test(`shr`, 0xffffffff'i32, 0x4'i32, 0x0fffffff'i32) - -when not defined(js): - test(`shl`, 0xffffffffffffffff'i64, 0x4'i64, 0xfffffffffffffff0'i64) -test(`shl`, 0xffff'i16, 0x4'i16, 0xfff0'i16) -test(`shl`, 0xff'i8, 0x4'i8, 0xf0'i8) - -when not defined(js): - test(`shl`, 0xffffffff'i64, 0x4'i64, 0xffffffff0'i64) -test(`shl`, 0xffffffff'i32, 0x4'i32, 0xfffffff0'i32) - -# bug #916 -proc unc(a: float): float = - return a - -echo int(unc(0.5)), " ", int(unc(-0.5)) -echo int(0.5), " ", int(-0.5) - -block: # Casts to uint - template testCast(fromValue: typed, toType: typed, expectedResult: typed) = - let src = fromValue - let dst = cast[toType](src) - if dst != expectedResult: - echo "Casting ", astToStr(fromValue), " to ", astToStr(toType), " = ", dst.int, " instead of ", astToStr(expectedResult) - doAssert(dst == expectedResult) - - testCast(-1'i16, uint16, 0xffff'u16) - testCast(0xffff'u16, int16, -1'i16) - - testCast(0xff'u16, uint8, 0xff'u8) - testCast(0xffff'u16, uint8, 0xff'u8) - - testCast(-1'i16, uint32, 0xffffffff'u32) - testCast(0xffffffff'u32, int32, -1) - - testCast(0xfffffffe'u32, int32, -2'i32) - testCast(0xffffff'u32, int16, -1'i32) - - testCast(-5'i32, uint8, 251'u8) - - -echo("Success") #OUT Success diff --git a/tests/misc/tinvalidarrayaccess.nim b/tests/misc/tinvalidarrayaccess.nim deleted file mode 100644 index 03105b41b..000000000 --- a/tests/misc/tinvalidarrayaccess.nim +++ /dev/null @@ -1,14 +0,0 @@ -discard """ - errormsg: "index out of bounds" - line: 11 -""" - - -type TTestArr = array[0..1, int16] -var f: TTestArr -f[0] = 30 -f[1] = 40 -f[2] = 50 -f[3] = 60 - -echo(repr(f)) diff --git a/tests/misc/tinvalidnewseq.nim b/tests/misc/tinvalidnewseq.nim index 89083d8b2..7a95db020 100644 --- a/tests/misc/tinvalidnewseq.nim +++ b/tests/misc/tinvalidnewseq.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "type mismatch: got <array[0..6, string], int literal(7)>" file: "tinvalidnewseq.nim" line: 15 - errormsg: "type mismatch: got (array[0..6, string], int literal(7))" """ import re, strutils @@ -13,7 +13,7 @@ proc parseURL(url: string): TURL = var pattern: string = r"([a-zA-Z]+://)?(\w+?\.)?(\w+)(\.\w+)(:[0-9]+)?(/.+)?" var m: array[0..6, string] #Array with the matches newSeq(m, 7) #ERROR - discard regexprs.match(url, re(pattern), m) + discard re.match(url, re(pattern), m) result = (protocol: m[1], subdomain: m[2], domain: m[3] & m[4], port: m[5], path: m[6].split('/')) @@ -22,6 +22,3 @@ var r: TUrl r = parseUrl(r"http://google.com/search?var=bleahdhsad") echo(r.domain) - - - diff --git a/tests/misc/tissue710.nim b/tests/misc/tissue710.nim index 3b6d3e5f3..ec125b840 100644 --- a/tests/misc/tissue710.nim +++ b/tests/misc/tissue710.nim @@ -1,7 +1,7 @@ discard """ + errorMsg: "attempting to call routine: '||'" file: "tissue710.nim" line: 8 - errorMsg: "attempting to call undeclared routine: '||'" """ var sum = 0 for x in 3..1000: diff --git a/tests/misc/tjoinable.nim b/tests/misc/tjoinable.nim new file mode 100644 index 000000000..f23fca0d4 --- /dev/null +++ b/tests/misc/tjoinable.nim @@ -0,0 +1,3 @@ +# checks that megatest allows duplicate names, see also `tests/testament/tjoinable.nim` +doAssert defined(testing) +doAssert defined(nimMegatest) diff --git a/tests/misc/tlastmod.nim b/tests/misc/tlastmod.nim index 538b5e656..1cc1d4bd9 100644 --- a/tests/misc/tlastmod.nim +++ b/tests/misc/tlastmod.nim @@ -1,18 +1,25 @@ +discard """ +outputsub: "is newer than" +""" # test the new LastModificationTime() proc +let + file1 = "tests/testdata/data.csv" + file2 = "tests/testdata/doc1.xml" + import os, times, strutils proc main() = var - a, b: TTime - a = getLastModificationTime(paramStr(1)) - b = getLastModificationTime(paramStr(2)) + a, b: Time + a = getLastModificationTime(file1) + b = getLastModificationTime(file2) writeLine(stdout, $a) writeLine(stdout, $b) if a < b: - write(stdout, "$2 is newer than $1\n" % [paramStr(1), paramStr(2)]) + write(stdout, "$2 is newer than $1\n" % [file1, file2]) else: - write(stdout, "$1 is newer than $2\n" % [paramStr(1), paramStr(2)]) + write(stdout, "$1 is newer than $2\n" % [file1, file2]) main() diff --git a/tests/misc/tlocals.nim b/tests/misc/tlocals.nim deleted file mode 100644 index 3e240d3c8..000000000 --- a/tests/misc/tlocals.nim +++ /dev/null @@ -1,11 +0,0 @@ -discard """ - output: "(x: string here, a: 1)" -""" - -proc simple[T](a: T) = - var - x = "string here" - echo locals() - -simple(1) - diff --git a/tests/misc/tloops.nim b/tests/misc/tloops.nim index b160500af..61e0baf10 100644 --- a/tests/misc/tloops.nim +++ b/tests/misc/tloops.nim @@ -1,3 +1,10 @@ +discard """ +output: ''' +Hello!(x: 1, y: 2, z: 3) +(x: 1.0, y: 2.0) +''' +""" + # Test nested loops and some other things proc andTest() = @@ -84,4 +91,3 @@ proc main[T]() = echo myType2 main[int]() - diff --git a/tests/misc/tmandelbrot.nim b/tests/misc/tmandelbrot.nim deleted file mode 100644 index e9b7a3e5a..000000000 --- a/tests/misc/tmandelbrot.nim +++ /dev/null @@ -1,57 +0,0 @@ -discard """ - cmd: "nim $target --hints:on -d:release $options $file" -""" - -# -*- nim -*- - -import math -import os -import strutils - -type TComplex = tuple[re, im: float] - -proc `+` (a, b: TComplex): TComplex = - return (a.re + b.re, a.im + b.im) - -proc `*` (a, b: TComplex): TComplex = - result.re = a.re * b.re - a.im * b.im - result.im = a.re * b.im + a.im * b.re - -proc abs2 (a: TComplex): float = - return a.re * a.re + a.im * a.im - -var size = parseInt (paramStr (1)) -var bit = 128 -var byteAcc = 0 - -stdout.writeLine ("P4") -stdout.write ($size) -stdout.write (" ") -stdout.writeLine ($size) - -var fsize = float (size) -for y in 0 .. size-1: - var fy = 2.0 * float (y) / fsize - 1.0 - for x in 0 .. size-1: - var z = (0.0, 0.0) - var c = (float (2*x) / fsize - 1.5, fy) - - block iter: - for i in 0 .. 49: - z = z*z + c - if abs2 (z) >= 4.0: - break iter - byteAcc = byteAcc + bit - - if bit > 1: - bit = bit div 2 - else: - stdout.write (chr (byteAcc)) - bit = 128 - byteAcc = 0 - - if bit != 128: - stdout.write (chr (byteAcc)) - bit = 128 - byteAcc = 0 - diff --git a/tests/misc/tmemoization.nim b/tests/misc/tmemoization.nim index 180acd89b..c65692608 100644 --- a/tests/misc/tmemoization.nim +++ b/tests/misc/tmemoization.nim @@ -1,5 +1,5 @@ discard """ - msg: "test 1\ntest 2\ntest 3" + nimout: "test 1\ntest 2\ntest 3" output: "TEST 1\nTEST 2\nTEST 3" """ @@ -8,7 +8,7 @@ import strutils proc foo(s: static[string]): string = static: echo s - const R = s.toUpper + const R = s.toUpperAscii return R echo foo("test 1") diff --git a/tests/misc/tmodulea.nim b/tests/misc/tmodulea.nim new file mode 100644 index 000000000..5aeb1824b --- /dev/null +++ b/tests/misc/tmodulea.nim @@ -0,0 +1,3 @@ +from modulea import modulea + +#bug #6731 diff --git a/tests/misc/tnew.nim b/tests/misc/tnew.nim deleted file mode 100644 index 88e8bd02c..000000000 --- a/tests/misc/tnew.nim +++ /dev/null @@ -1,49 +0,0 @@ -# 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 = - 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/misc/tnewderef.nim b/tests/misc/tnewderef.nim deleted file mode 100644 index 3394dbddf..000000000 --- a/tests/misc/tnewderef.nim +++ /dev/null @@ -1,11 +0,0 @@ -discard """ - output: 3 - -""" - -var x: ref int -new(x) -x[] = 3 - -echo x[] - diff --git a/tests/misc/tnewsets.nim b/tests/misc/tnewsets.nim deleted file mode 100644 index f239d4aa2..000000000 --- a/tests/misc/tnewsets.nim +++ /dev/null @@ -1,6 +0,0 @@ -# new test for sets: - -const elem = ' ' - -var s: set[char] = {elem} -assert(elem in s and 'a' not_in s and 'c' not_in s ) diff --git a/tests/misc/tnewuns.nim b/tests/misc/tnewuns.nim deleted file mode 100644 index d6bae4fb1..000000000 --- a/tests/misc/tnewuns.nim +++ /dev/null @@ -1,12 +0,0 @@ -# test the new unsigned operations: - -import - strutils - -var - x, y: int - -x = 1 -y = high(int) - -writeLine(stdout, $ ( x +% y ) ) diff --git a/tests/misc/tnoforward.nim b/tests/misc/tnoforward.nim index 342e757b8..b6a71897a 100644 --- a/tests/misc/tnoforward.nim +++ b/tests/misc/tnoforward.nim @@ -1,8 +1,9 @@ discard """ - disabled: true + output: "10" """ -{. noforward: on .} +# {. noforward: on .} +{.experimental: "codeReordering".} proc foo(x: int) = bar x diff --git a/tests/misc/tnoinst.nim b/tests/misc/tnoinst.nim deleted file mode 100644 index 25ebe8dfc..000000000 --- a/tests/misc/tnoinst.nim +++ /dev/null @@ -1,17 +0,0 @@ -discard """ - line: 12 - errormsg: "instantiate 'notConcrete' explicitly" - disabled: "true" -""" - -proc wrap[T]() = - proc notConcrete[T](x, y: int): int = - var dummy: T - result = x - y - - var x: proc (x, y: T): int - x = notConcrete - - -wrap[int]() - diff --git a/tests/misc/tnolen.nim b/tests/misc/tnolen.nim index dcf6811eb..e0e8025d4 100644 --- a/tests/misc/tnolen.nim +++ b/tests/misc/tnolen.nim @@ -1,9 +1,8 @@ discard """ + errormsg: "type mismatch: got <int literal(3)>" line: 8 - errormsg: "type mismatch: got (int literal(3))" """ # please finally disallow Len(3) echo len(3) - diff --git a/tests/misc/tnoop.nim b/tests/misc/tnoop.nim deleted file mode 100644 index 1e3fbe6cf..000000000 --- a/tests/misc/tnoop.nim +++ /dev/null @@ -1,11 +0,0 @@ -discard """ - file: "tnoop.nim" - line: 11 - errormsg: "attempting to call undeclared routine: 'a'" -""" - - -var - a: int - -a() diff --git a/tests/misc/tnot.nim b/tests/misc/tnot.nim deleted file mode 100644 index 8c75c6bc0..000000000 --- a/tests/misc/tnot.nim +++ /dev/null @@ -1,19 +0,0 @@ -discard """ - tfile: "tnot.nim" - tline: 14 - errormsg: "type mismatch" -""" -# 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/misc/tparseopt.nim b/tests/misc/tparseopt.nim new file mode 100644 index 000000000..47be05bac --- /dev/null +++ b/tests/misc/tparseopt.nim @@ -0,0 +1,156 @@ +discard """ + output: ''' +parseopt +first round +kind: cmdLongOption key:val -- left: +second round +kind: cmdLongOption key:val -- left: +kind: cmdLongOption key:val -- debug:3 +kind: cmdShortOption key:val -- l:4 +kind: cmdShortOption key:val -- r:2 +cmdLongOption foo +cmdLongOption path +parseoptNoVal +kind: cmdLongOption key:val -- left: +kind: cmdLongOption key:val -- debug:3 +kind: cmdShortOption key:val -- l: +kind: cmdShortOption key:val -- r:2 +kind: cmdLongOption key:val -- debug:2 +kind: cmdLongOption key:val -- debug:1 +kind: cmdShortOption key:val -- r:1 +kind: cmdShortOption key:val -- r:0 +kind: cmdShortOption key:val -- l: +kind: cmdShortOption key:val -- r:4 +kind: cmdLongOption key:val -- debug: +cmdShortOption key: v value: '' +cmdArgument key: ABC value: '' +cmdShortOption key: v value: 'ABC' +cmdShortOption key: v value: '' +cmdArgument key: ABC value: '' +cmdShortOption key: v value: '' +cmdArgument key: ABC value: '' +cmdShortOption key: j value: '4' +cmdArgument key: ok value: '' +''' +joinable: false +""" + +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 + + 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 + + # 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 --debug:" + var p = parseopt.initOptParser(argv, + shortNoVal = {'l'}, longNoVal = @["left"]) + for kind, key, val in parseopt.getopt(p): + echo "kind: ", kind, "\tkey:val -- ", key, ":", val + + import osproc, os, strutils + from stdtest/specialpaths import buildDir + import stdtest/unittest_light + + block: # fix #9951 + 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) + + 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}""" + + + + block: + let args = @["-v", "ABC"] + var p = parseopt.initOptParser(args, shortnoVal = {'n'}, longnoVal = @["novalue"]) + for kind, key, val in parseopt.getopt(p): + echo kind," key: ", key, " value: '", val, "'" + + var r = parseopt.initOptParser(@["-v ABC"], shortnoVal = {'n'}, longnoVal = @["novalue"]) + for kind, key, val in parseopt.getopt(r): + echo kind," key: ", key, " value: '", val, "'" + + var s = parseopt.initOptParser("-v ABC", shortnoVal = {'v'}, longnoVal = @["novalue"]) + for kind, key, val in parseopt.getopt(s): + echo kind," key: ", key, " value: '", val, "'" + + var m = parseopt.initOptParser("-v ABC", shortnoVal = {'n'}, longnoVal = @["novalue"]) + for kind, key, val in parseopt.getopt(m): + echo kind," key: ", key, " value: '", val, "'" + + var n = parseopt.initOptParser("-j4 ok", shortnoVal = {'n'}, longnoVal = @["novalue"]) + for kind, key, val in parseopt.getopt(n): + echo kind," key: ", key, " value: '", val, "'" diff --git a/tests/misc/tpos.nim b/tests/misc/tpos.nim index bedb62e62..f7607d643 100644 --- a/tests/misc/tpos.nim +++ b/tests/misc/tpos.nim @@ -1,5 +1,4 @@ discard """ - file: "tpos.nim" output: "6" """ # test this particular function @@ -30,6 +29,5 @@ proc mypos(sub, s: string, start: int = 0): int = var sub = "hello" var s = "world hello" write(stdout, mypos(sub, s)) +write stdout, "\n" #OUT 6 - - diff --git a/tests/misc/tprep.nim b/tests/misc/tprep.nim index 8f40300d6..45f25b790 100644 --- a/tests/misc/tprep.nim +++ b/tests/misc/tprep.nim @@ -1,3 +1,11 @@ +discard """ +nimout: ''' +tprep.nim(25, 9) Hint: Case 2 [User] +tprep.nim(27, 11) Hint: Case 2.3 [User] +''' +outputsub: "" +""" + # Test the features that used to belong to the preprocessor import diff --git a/tests/misc/tquicksort.nim b/tests/misc/tquicksort.nim index 0867a3769..017c73fbc 100644 --- a/tests/misc/tquicksort.nim +++ b/tests/misc/tquicksort.nim @@ -17,10 +17,7 @@ proc echoSeq(a: seq[int]) = for i in low(a)..high(a): echo(a[i]) -var - list: seq[int] - -list = QuickSort(@[89,23,15,23,56,123,356,12,7,1,6,2,9,4,3]) -echoSeq(list) - +let list = QuickSort(@[89,23,15,23,56,123,356,12,7,1,6,2,9,4,3]) +let expected = @[1, 2, 3, 4, 6, 7, 9, 12, 15, 23, 56, 89, 123, 356] +doAssert list == expected diff --git a/tests/misc/tradix.nim b/tests/misc/tradix.nim index 36a4f39f6..f4fb56849 100644 --- a/tests/misc/tradix.nim +++ b/tests/misc/tradix.nim @@ -1,9 +1,37 @@ +discard """ +output: ''' +start tradix.nim +false +false +false +false +false +false +false +false +false +false +128 +1 +2 +3 +4 +255 +17 +45 +19000 +4294967288 +''' +""" + # implements and tests an efficient radix tree ## another method to store an efficient array of pointers: ## We use a radix tree with node compression. ## There are two node kinds: +echo "start tradix.nim" + const BitsPerUnit = 8*sizeof(int) type @@ -12,17 +40,17 @@ type TRadixNode {.pure, inheritable.} = object kind: TRadixNodeKind TRadixNodeLinear = object of TRadixNode - len: int8 - keys: array [0..31, int8] - vals: array [0..31, PRadixNode] + len: uint8 + keys: array[0..31, uint8] + vals: array[0..31, PRadixNode] TRadixNodeFull = object of TRadixNode - b: array [0..255, PRadixNode] + b: array[0..255, PRadixNode] TRadixNodeLeafBits = object of TRadixNode - b: array [0..7, int] + b: array[0..7, int] TRadixNodeLeafLinear = object of TRadixNode - len: int8 - keys: array [0..31, int8] + len: uint8 + keys: array[0..31, uint8] var root: PRadixNode @@ -31,8 +59,8 @@ proc searchInner(r: PRadixNode, a: int): PRadixNode = case r.kind of rnLinear: var x = cast[ptr TRadixNodeLinear](r) - for i in 0..ze(x.len)-1: - if ze(x.keys[i]) == a: return x.vals[i] + for i in 0..int(x.len)-1: + if int(x.keys[i]) == a: return x.vals[i] of rnFull: var x = cast[ptr TRadixNodeFull](r) return x.b[a] @@ -59,8 +87,8 @@ proc searchLeaf(r: PRadixNode, a: int): bool = return testBit(x.b[a /% BitsPerUnit], a) of rnLeafLinear: var x = cast[ptr TRadixNodeLeafLinear](r) - for i in 0..ze(x.len)-1: - if ze(x.keys[i]) == a: return true + for i in 0..int(x.len)-1: + if int(x.keys[i]) == a: return true else: assert(false) proc exclLeaf(r: PRadixNode, a: int) = @@ -70,9 +98,9 @@ proc exclLeaf(r: PRadixNode, a: int) = resetBit(x.b[a /% BitsPerUnit], a) of rnLeafLinear: var x = cast[ptr TRadixNodeLeafLinear](r) - var L = ze(x.len) + var L = int(x.len) for i in 0..L-1: - if ze(x.keys[i]) == a: + if int(x.keys[i]) == a: x.keys[i] = x.keys[L-1] dec(x.len) return @@ -101,10 +129,10 @@ proc excl*(r: PRadixNode, a: ByteAddress): bool = proc addLeaf(r: var PRadixNode, a: int): bool = if r == nil: # a linear node: - var x = cast[ptr TRadixNodeLinear](alloc(sizeof(TRadixNodeLinear))) + var x = cast[ptr TRadixNodeLinear](alloc0(sizeof(TRadixNodeLinear))) x.kind = rnLeafLinear - x.len = 1'i8 - x.keys[0] = toU8(a) + x.len = 1'u8 + x.keys[0] = uint8(a) r = x return false # not already in set case r.kind @@ -113,18 +141,18 @@ proc addLeaf(r: var PRadixNode, a: int): bool = return testOrSetBit(x.b[a /% BitsPerUnit], a) of rnLeafLinear: var x = cast[ptr TRadixNodeLeafLinear](r) - var L = ze(x.len) + var L = int(x.len) for i in 0..L-1: - if ze(x.keys[i]) == a: return true + if int(x.keys[i]) == a: return true if L <= high(x.keys): - x.keys[L] = toU8(a) + x.keys[L] = uint8(a) inc(x.len) else: # transform into a full node: var y = cast[ptr TRadixNodeLeafBits](alloc0(sizeof(TRadixNodeLeafBits))) y.kind = rnLeafBits - for i in 0..ze(x.len)-1: - var u = ze(x.keys[i]) + for i in 0..int(x.len)-1: + var u = int(x.keys[i]) setBit(y.b[u /% BitsPerUnit], u) setBit(y.b[a /% BitsPerUnit], a) dealloc(r) @@ -137,28 +165,28 @@ proc addInner(r: var PRadixNode, a: int, d: int): bool = var k = a shr d and 0xff if r == nil: # a linear node: - var x = cast[ptr TRadixNodeLinear](alloc(sizeof(TRadixNodeLinear))) + var x = cast[ptr TRadixNodeLinear](alloc0(sizeof(TRadixNodeLinear))) x.kind = rnLinear - x.len = 1'i8 - x.keys[0] = toU8(k) + x.len = 1'u8 + x.keys[0] = uint8(k) r = x return addInner(x.vals[0], a, d-8) case r.kind of rnLinear: var x = cast[ptr TRadixNodeLinear](r) - var L = ze(x.len) + var L = int(x.len) for i in 0..L-1: - if ze(x.keys[i]) == k: # already exists + if int(x.keys[i]) == k: # already exists return addInner(x.vals[i], a, d-8) if L <= high(x.keys): - x.keys[L] = toU8(k) + x.keys[L] = uint8(k) inc(x.len) return addInner(x.vals[L], a, d-8) else: # transform into a full node: var y = cast[ptr TRadixNodeFull](alloc0(sizeof(TRadixNodeFull))) y.kind = rnFull - for i in 0..L-1: y.b[ze(x.keys[i])] = x.vals[i] + for i in 0..L-1: y.b[int(x.keys[i])] = x.vals[i] dealloc(r) r = y return addInner(y.b[k], a, d-8) @@ -183,8 +211,8 @@ iterator innerElements(r: PRadixNode): tuple[prefix: int, n: PRadixNode] = yield (i, r.b[i]) of rnLinear: var r = cast[ptr TRadixNodeLinear](r) - for i in 0..ze(r.len)-1: - yield (ze(r.keys[i]), r.vals[i]) + for i in 0..int(r.len)-1: + yield (int(r.keys[i]), r.vals[i]) else: assert(false) iterator leafElements(r: PRadixNode): int = @@ -200,8 +228,8 @@ iterator leafElements(r: PRadixNode): int = yield i*BitsPerUnit+j of rnLeafLinear: var r = cast[ptr TRadixNodeLeafLinear](r) - for i in 0..ze(r.len)-1: - yield ze(r.keys[i]) + for i in 0..int(r.len)-1: + yield int(r.keys[i]) else: assert(false) iterator elements*(r: PRadixNode): ByteAddress {.inline.} = @@ -218,102 +246,9 @@ proc main() = r: PRadixNode = nil for x in items(numbers): echo testOrIncl(r, x) - for x in elements(r): echo(x) + for x in elements(r): + # ByteAddress being defined as a signed integer cases trouble + # exactly here + echo(cast[uint](x)) main() - - -when false: - proc traverse(r: PRadixNode, prefix: int, d: int) = - if r == nil: return - case r.kind - of rnLeafBits: - assert(d == 0) - var x = cast[ptr TRadixNodeLeafBits](r) - # iterate over any bit: - for i in 0..high(x.b): - if x.b[i] != 0: # test all bits for zero - for j in 0..BitsPerUnit-1: - if testBit(x.b[i], j): - visit(prefix or i*BitsPerUnit+j) - of rnLeafLinear: - assert(d == 0) - var x = cast[ptr TRadixNodeLeafLinear](r) - for i in 0..ze(x.len)-1: - visit(prefix or ze(x.keys[i])) - of rnFull: - var x = cast[ptr TRadixNodeFull](r) - for i in 0..high(r.b): - if r.b[i] != nil: - traverse(r.b[i], prefix or (i shl d), d-8) - of rnLinear: - var x = cast[ptr TRadixNodeLinear](r) - for i in 0..ze(x.len)-1: - traverse(x.vals[i], prefix or (ze(x.keys[i]) shl d), d-8) - - type - TRadixIter {.final.} = object - r: PRadixNode - p: int - x: int - - proc init(i: var TRadixIter, r: PRadixNode) = - i.r = r - i.x = 0 - i.p = 0 - - proc nextr(i: var TRadixIter): PRadixNode = - if i.r == nil: return nil - case i.r.kind - of rnFull: - var r = cast[ptr TRadixNodeFull](i.r) - while i.x <= high(r.b): - if r.b[i.x] != nil: - i.p = i.x - return r.b[i.x] - inc(i.x) - of rnLinear: - var r = cast[ptr TRadixNodeLinear](i.r) - if i.x < ze(r.len): - i.p = ze(r.keys[i.x]) - result = r.vals[i.x] - inc(i.x) - else: assert(false) - - proc nexti(i: var TRadixIter): int = - result = -1 - case i.r.kind - of rnLeafBits: - var r = cast[ptr TRadixNodeLeafBits](i.r) - # iterate over any bit: - for i in 0..high(r.b): - if x.b[i] != 0: # test all bits for zero - for j in 0..BitsPerUnit-1: - if testBit(x.b[i], j): - visit(prefix or i*BitsPerUnit+j) - of rnLeafLinear: - var r = cast[ptr TRadixNodeLeafLinear](i.r) - if i.x < ze(r.len): - result = ze(r.keys[i.x]) - inc(i.x) - - iterator elements(r: PRadixNode): ByteAddress {.inline.} = - var - a, b, c, d: TRadixIter - init(a, r) - while true: - var x = nextr(a) - if x != nil: - init(b, x) - while true: - var y = nextr(b) - if y != nil: - init(c, y) - while true: - var z = nextr(c) - if z != nil: - init(d, z) - while true: - var q = nexti(d) - if q != -1: - yield a.p shl 24 or b.p shl 16 or c.p shl 8 or q diff --git a/tests/misc/trangechecks.nim b/tests/misc/trangechecks.nim deleted file mode 100644 index 2c6f0f66d..000000000 --- a/tests/misc/trangechecks.nim +++ /dev/null @@ -1,43 +0,0 @@ -discard """ - output: '''10 -10 -1 -1 -true''' -""" - -# bug #1344 - -var expected: int -var x: range[1..10] = 10 - -try: - x += 1 - echo x -except OverflowError, RangeError: - expected += 1 - echo x - -try: - inc x - echo x -except OverflowError, RangeError: - expected += 1 - echo x - -x = 1 -try: - x -= 1 - echo x -except OverflowError, RangeError: - expected += 1 - echo x - -try: - dec x - echo x -except OverflowError, RangeError: - expected += 1 - echo x - -echo expected == 4 diff --git a/tests/misc/trawstr.nim b/tests/misc/trawstr.nim deleted file mode 100644 index 55e508acc..000000000 --- a/tests/misc/trawstr.nim +++ /dev/null @@ -1,12 +0,0 @@ -discard """ - file: "trawstr.nim" - line: 10 - errormsg: "closing \" expected" -""" -# Test the new raw strings: - -const - xxx = r"This is a raw string!" - yyy = "This not\" #ERROR - - diff --git a/tests/misc/treadln.nim b/tests/misc/treadln.nim deleted file mode 100644 index 1edbea992..000000000 --- a/tests/misc/treadln.nim +++ /dev/null @@ -1,12 +0,0 @@ -# test the improved readline handling that does not care whether its -# Macintosh, Unix or Windows text format. - -var - inp: File - line: string - -if open(inp, "readme.txt"): - while not endOfFile(inp): - line = readLine(inp) - echo("#" & line & "#") - close(inp) diff --git a/tests/misc/treadx.nim b/tests/misc/treadx.nim deleted file mode 100644 index 49b6ad691..000000000 --- a/tests/misc/treadx.nim +++ /dev/null @@ -1,14 +0,0 @@ - -when not defined(windows): - import posix - - var inp = "" - var buf: array[0..10, char] - while true: - var r = read(0, addr(buf), sizeof(buf)-1) - add inp, $buf - if r != sizeof(buf)-1: break - - echo inp - #dafkladskölklödsaf ölksdakölfölksfklwe4iojr389wr 89uweokf sdlkf jweklr jweflksdj fioewjfsdlfsd - diff --git a/tests/misc/trfc405.nim b/tests/misc/trfc405.nim new file mode 100644 index 000000000..0828879ee --- /dev/null +++ b/tests/misc/trfc405.nim @@ -0,0 +1,112 @@ + +{.experimental: "flexibleOptionalParams".} + +# https://github.com/nim-lang/RFCs/issues/405 + +template main = + template fn1(a = 1, b = 2, body): auto = (a, b, astToStr(body)) + let a1 = fn1(10, 20): + foo + doAssert a1 == (10, 20, "\nfoo") + + template fn2(a = 1, b = 2, body): auto = (a, b, astToStr(body)) + let a2 = fn2(a = 10): foo + doAssert a2 == (10, 2, "\nfoo") + let a2b = fn2(b = 20): foo + doAssert a2b == (1, 20, "\nfoo") + + template fn3(x: int, a = 1, b = 2, body): auto = (a, b, astToStr(body)) + let a3 = fn3(3, 10, 20): foo + doAssert a3 == (10, 20, "\nfoo") + let a3b = fn3(3, a = 10): foo + doAssert a3b == (10, 2, "\nfoo") + + template fn4(x: int, y: int, body): auto = (x, y, astToStr(body)) + let a4 = fn4(1, 2): foo + doAssert a4 == (1, 2, "\nfoo") + + template fn5(x = 1, y = 2, body: untyped = 3): auto = (x, y, astToStr(body)) + doAssert compiles(fn5(1, 2, foo)) + doAssert not compiles(fn5(1, foo)) + + block: + # with an overload + var witness = 0 + template fn6() = discard + template fn6(procname: string, body: untyped): untyped = witness.inc + fn6("abc"): discard + assert witness == 1 + + block: + # with overloads + var witness = 0 + template fn6() = discard + template fn6(a: int) = discard + template fn6(procname: string, body: untyped): untyped = witness.inc + fn6("abc"): discard + assert witness == 1 + + template fn6(b = 1.5, body: untyped): untyped = witness.inc + fn6(1.3): discard + assert witness == 2 + + block: + var witness = 0 + template fn6(a: int) = discard + template fn6(a: string) = discard + template fn6(ignore: string, b = 1.5, body: untyped): untyped = witness.inc + fn6(""): + foobar1 + foobar2 + doAssert witness == 1 + fn6(""): discard + doAssert witness == 2 + + block: # multi block args + template fn8(a = 1, b = 2, body1: untyped, body2: untyped): auto = (a, b, astToStr(body1), astToStr(body2)) + let a1 = fn8(): + foobar1 + foobar2 + do: + foobar3 + foobar4 + doAssert a1 == (1, 2, "\nfoobar1\nfoobar2", "\nfoobar3\nfoobar4") + + let a2 = fn8(b = 20): + foobar1 + foobar2 + do: + foobar3 + foobar4 + doAssert a2 == (1, 20, "\nfoobar1\nfoobar2", "\nfoobar3\nfoobar4") + + block: # issue #19015 + template hi(a: untyped, b: varargs[untyped]): untyped = + a + + var worked = false + hi: + worked = true + doAssert worked + worked = false + hi(doAssert(not worked)): + doesntCompile + hi(doAssert(not worked), doesntCompile, againDoesntCompile): + definitelyDoesntCompile + + template hi2(a: bool, b: untyped, c: varargs[untyped]): untyped = + b + doAssert a + + hi2 worked: + worked = true + doAssert worked + hi2 worked, doAssert(worked): + doesntCompile + hi2 worked, doAssert(worked), doesntCompile, againDoesntCompile: + definitelyDoesntCompile + hi2 worked, doAssert(worked), againDoesntCompile: + definitelyDoesntCompile + +static: main() +main() diff --git a/tests/misc/tromans.nim b/tests/misc/tromans.nim deleted file mode 100644 index 132c73ddd..000000000 --- a/tests/misc/tromans.nim +++ /dev/null @@ -1,71 +0,0 @@ -discard """ - file: "tromans.nim" - output: "success" -""" -import - strutils - -## Convert an integer to a Roman numeral -# See http://en.wikipedia.org/wiki/Roman_numerals for reference - -proc raiseInvalidValue(msg: string) {.noreturn.} = - # Yes, we really need a shorthand for this code... - var e: ref EInvalidValue - new(e) - e.msg = msg - raise e - -# I should use a class, perhaps. -# --> No. Why introduce additional state into such a simple and nice -# interface? State is evil. :D - -proc RomanToDecimal(romanVal: string): int = - result = 0 - var prevVal = 0 - for i in countdown(romanVal.len - 1, 0): - var val = 0 - case romanVal[i] - of 'I', 'i': val = 1 - of 'V', 'v': val = 5 - of 'X', 'x': val = 10 - of 'L', 'l': val = 50 - of 'C', 'c': val = 100 - of 'D', 'd': val = 500 - of 'M', 'm': val = 1000 - else: raiseInvalidValue("Incorrect character in roman numeral! (" & - $romanVal[i] & ")") - if val >= prevVal: - inc(result, val) - else: - dec(result, val) - prevVal = val - -proc DecimalToRoman(decValParam: int): string = - # Apparently numbers cannot be above 4000 - # Well, they can be (using overbar or parenthesis notation) - # but I see little interest (beside coding challenge) in coding them as - # we rarely use huge Roman numeral. - const romanComposites = [ - ("M", 1000), ("CM", 900), - ("D", 500), ("CD", 400), ("C", 100), - ("XC", 90), ("L", 50), ("XL", 40), ("X", 10), ("IX", 9), - ("V", 5), ("IV", 4), ("I", 1)] - if decValParam < 1 or decValParam > 3999: - raiseInvalidValue("number not representable") - result = "" - var decVal = decValParam - for key, val in items(romanComposites): - while decVal >= val: - dec(decVal, val) - result.add(key) - -for i in 1..100: - if RomanToDecimal(DecimalToRoman(i)) != i: quit "BUG" - -for i in items([1238, 1777, 3830, 2401, 379, 33, 940, 3973]): - if RomanToDecimal(DecimalToRoman(i)) != i: quit "BUG" - -echo "success" #OUT success - - - diff --git a/tests/misc/trunner.nim b/tests/misc/trunner.nim new file mode 100644 index 000000000..6e5487d1b --- /dev/null +++ b/tests/misc/trunner.nim @@ -0,0 +1,444 @@ +discard """ + targets: "c cpp" + joinable: false +""" + +## tests that don't quite fit the mold and are easier to handle via `execCmdEx` +## A few others could be added to here to simplify code. +## Note: this test is a bit slow but tests a lot of things; please don't disable. +## Note: if needed, we could use `matrix: "-d:case1; -d:case2"` to split this +## into several independent tests while retaining the common test helpers. + +import std/[strformat,os,osproc,unittest,compilesettings] +from std/sequtils import toSeq,mapIt +from std/algorithm import sorted +import stdtest/[specialpaths, unittest_light] +from std/private/globs import nativeToUnixPath +from strutils import startsWith, strip, removePrefix +from std/sugar import dup +import "$lib/../compiler/nimpaths" + +proc isDots(a: string): bool = + ## test for `hintProcessing` dots + a.startsWith(".") and a.strip(chars = {'.'}) == "" + +const + nim = getCurrentCompilerExe() + mode = querySetting(backend) + nimcache = buildDir / "nimcacheTrunner" + # instead of `querySetting(nimcacheDir)`, avoids stomping on other parallel tests + +proc runNimCmd(file, options = "", rtarg = ""): auto = + let fileabs = testsDir / file.unixToNativePath + # doAssert fileabs.fileExists, fileabs # disabled because this allows passing `nim r --eval:code fakefile` + let cmd = fmt"{nim} {mode} --hint:all:off {options} {fileabs} {rtarg}" + result = execCmdEx(cmd) + when false: # for debugging + echo cmd + echo result[0] & "\n" & $result[1] + +proc runNimCmdChk(file, options = "", rtarg = "", status = 0): string = + let (ret, status2) = runNimCmd(file, options, rtarg = rtarg) + doAssert status2 == status, $(file, options, status, status2) & "\n" & ret + ret + +proc genShellCmd(filename: string): string = + let filename = filename.quoteShell + when defined(windows): "cmd /c " & filename # or "cmd /c " ? + else: "sh " & filename + +when defined(nimTrunnerFfi): + block: # mevalffi + when defined(openbsd): + #[ + openbsd defines `#define stderr (&__sF[2])` which makes it cumbersome + for dlopen'ing inside `importcSymbol`. Instead of adding special rules + inside `importcSymbol` to handle this, we disable just the part that's + not working and will provide a more general, clean fix in future PR. + ]# + var opt = "-d:nimEvalffiStderrWorkaround" + let prefix = "" + else: + var opt = "" + let prefix = """ +hello world stderr +hi stderr +""" + let output = runNimCmdChk("vm/mevalffi.nim", fmt"{opt} --warnings:off --experimental:compiletimeFFI") + doAssert output == fmt""" +{prefix}foo +foo:100 +foo:101 +foo:102:103 +foo:102:103:104 +foo:0.03:asdf:103:105 +ret=[s1:foobar s2:foobar age:25 pi:3.14] +""", output + +elif not defined(nimTestsTrunnerDebugging): + # don't run twice the same test with `nimTrunnerFfi` + # use `-d:nimTestsTrunnerDebugging` for debugging convenience when you want to just run 1 test + import std/strutils + import std/json + template check2(msg) = doAssert msg in output, output + + block: # tests with various options `nim doc --project --index --docroot` + # regression tests for issues and PRS: #14376 #13223 #6583 ##13647 + let file = testsDir / "nimdoc/sub/mmain.nim" + let mainFname = "mmain.html" + let htmldocsDirCustom = nimcache / "htmldocsCustom" + let docroot = testsDir / "nimdoc" + let options = [ + 0: "--project", + 1: "--project --docroot", + 2: "", + 3: fmt"--outDir:{htmldocsDirCustom}", + 4: fmt"--docroot:{docroot}", + 5: "--project --useNimcache", + 6: "--index:off", + ] + + for i in 0..<options.len: + let htmldocsDir = case i + of 3: htmldocsDirCustom + of 5: nimcache / htmldocsDirname + else: file.parentDir / htmldocsDirname + + var cmd = fmt"{nim} doc --index:on --filenames:abs --hint:successX:on --nimcache:{nimcache} {options[i]} {file}" + removeDir(htmldocsDir) + let (outp, exitCode) = execCmdEx(cmd) + check exitCode == 0 + let ret = toSeq(walkDirRec(htmldocsDir, relative=true)).mapIt(it.nativeToUnixPath).sorted.join("\n") + let context = $(i, ret, cmd) + case i + of 0,5: + let htmlFile = htmldocsDir/mainFname + check htmlFile in outp # sanity check for `hintSuccessX` + assertEquals ret, fmt""" +{dotdotMangle}/imp.html +{dotdotMangle}/imp.idx +{docHackJsFname} +imp.html +imp.idx +imp2.html +imp2.idx +{mainFname} +mmain.idx +{nimdocOutCss} +{theindexFname}""", context + of 1: assertEquals ret, fmt""" +{docHackJsFname} +{nimdocOutCss} +tests/nimdoc/imp.html +tests/nimdoc/imp.idx +tests/nimdoc/sub/imp.html +tests/nimdoc/sub/imp.idx +tests/nimdoc/sub/imp2.html +tests/nimdoc/sub/imp2.idx +tests/nimdoc/sub/{mainFname} +tests/nimdoc/sub/mmain.idx +{theindexFname}""" + of 2, 3: assertEquals ret, fmt""" +{docHackJsFname} +{mainFname} +mmain.idx +{nimdocOutCss}""", context + of 4: assertEquals ret, fmt""" +{docHackJsFname} +{nimdocOutCss} +sub/{mainFname} +sub/mmain.idx""", context + of 6: assertEquals ret, fmt""" +{mainFname} +{nimdocOutCss}""", context + else: doAssert false + + block: # mstatic_assert + let (output, exitCode) = runNimCmd("ccgbugs/mstatic_assert.nim", "-d:caseBad") + check2 "sizeof(bool) == 2" + check exitCode != 0 + + block: # ABI checks + let file = "misc/msizeof5.nim" + block: + discard runNimCmdChk(file, "-d:checkAbi") + block: + let (output, exitCode) = runNimCmd(file, "-d:checkAbi -d:caseBad") + # on platforms that support _StaticAssert natively, errors will show full context, e.g.: + # error: static_assert failed due to requirement 'sizeof(unsigned char) == 8' + # "backend & Nim disagree on size for: BadImportcType{int64} [declared in mabi_check.nim(1, 6)]" + check2 "sizeof(unsigned char) == 8" + check2 "sizeof(struct Foo2) == 1" + check2 "sizeof(Foo5) == 16" + check2 "sizeof(Foo5) == 3" + check2 "sizeof(struct Foo6) == " + check exitCode != 0 + + import streams + block: # stdin input + let nimcmd = fmt"""{nim} r --hints:off - -firstparam "-second param" """ + let expected = """@["-firstparam", "-second param"]""" + block: + let p = startProcess(nimcmd, options = {poEvalCommand}) + p.inputStream.write("import os; echo commandLineParams()") + p.inputStream.close + var output = p.outputStream.readAll + let error = p.errorStream.readAll + doAssert p.waitForExit == 0 + doAssert error.len == 0, $error + output.stripLineEnd + check output == expected + p.errorStream.close + p.outputStream.close + + block: + when defined posix: + # xxx on windows, `poEvalCommand` should imply `/cmd`, (which should + # make this work), but currently doesn't + let cmd = fmt"""echo "import os; echo commandLineParams()" | {nimcmd}""" + var (output, exitCode) = execCmdEx(cmd) + output.stripLineEnd + check output == expected + doAssert exitCode == 0 + + block: # nim doc --backend:$backend --doccmd:$cmd + # test for https://github.com/nim-lang/Nim/issues/13129 + # test for https://github.com/nim-lang/Nim/issues/13891 + let file = testsDir / "nimdoc/m13129.nim" + for backend in fmt"{mode} js".split: + # pending #14343 this fails on windows: --doccmd:"-d:m13129Foo2 --hints:off" + let cmd = fmt"""{nim} doc -b:{backend} --nimcache:{nimcache} -d:m13129Foo1 "--doccmd:-d:m13129Foo2 --hints:off" --usenimcache --hints:off {file}""" + check execCmdEx(cmd) == (&"ok1:{backend}\nok2: backend: {backend}\n", 0) + # checks that --usenimcache works with `nim doc` + check fileExists(nimcache / "htmldocs/m13129.html") + + block: # mak sure --backend works with `nim r` + let cmd = fmt"{nim} r --backend:{mode} --hints:off --nimcache:{nimcache} {file}" + check execCmdEx(cmd) == ("ok3\n", 0) + + block: # nim jsondoc # bug #20132 + let file = testsDir / "misc/mjsondoc.nim" + let output = "nimcache_tjsondoc.json" + defer: removeFile(output) + let (msg, exitCode) = execCmdEx(fmt"{nim} jsondoc -o:{output} {file}") + doAssert exitCode == 0, msg + + let data = parseJson(readFile(output))["entries"] + doAssert data.len == 5 + let doSomething = data[0] + doAssert doSomething["name"].getStr == "doSomething" + doAssert doSomething["type"].getStr == "skProc" + doAssert doSomething["line"].getInt == 1 + doAssert doSomething["col"].getInt == 0 + doAssert doSomething["code"].getStr == "proc doSomething(x, y: int): int {.raises: [], tags: [], forbids: [].}" + let foo2 = data[4] + doAssert $foo2["signature"] == """{"arguments":[{"name":"x","type":"T"},{"name":"y","type":"U"},{"name":"z","type":"M"}],"genericParams":[{"name":"T","types":"int"},{"name":"M","types":"string"},{"name":"U"}]}""" + + block: # nim jsondoc # bug #11953 + let file = testsDir / "misc/mjsondoc.nim" + let destDir = testsDir / "misc/htmldocs" + removeDir(destDir) + defer: removeDir(destDir) + let (msg, exitCode) = execCmdEx(fmt"{nim} jsondoc {file}") + doAssert exitCode == 0, msg + + let data = parseJson(readFile(destDir / "mjsondoc.json"))["entries"] + doAssert data.len == 5 + let doSomething = data[0] + doAssert doSomething["name"].getStr == "doSomething" + doAssert doSomething["type"].getStr == "skProc" + doAssert doSomething["line"].getInt == 1 + doAssert doSomething["col"].getInt == 0 + doAssert doSomething["code"].getStr == "proc doSomething(x, y: int): int {.raises: [], tags: [], forbids: [].}" + + block: # further issues with `--backend` + let file = testsDir / "misc/mbackend.nim" + var cmd = fmt"{nim} doc -b:cpp --hints:off --nimcache:{nimcache} {file}" + check execCmdEx(cmd) == ("", 0) + cmd = fmt"{nim} check -b:c -b:cpp --hints:off --nimcache:{nimcache} {file}" + check execCmdEx(cmd) == ("", 0) + # issue https://github.com/timotheecour/Nim/issues/175 + cmd = fmt"{nim} c -b:js -b:cpp --hints:off --nimcache:{nimcache} {file}" + check execCmdEx(cmd) == ("", 0) + + block: # some importc tests + # issue #14314 + let file = testsDir / "misc/mimportc.nim" + let cmd = fmt"{nim} r -b:cpp --hints:off --nimcache:{nimcache} --warningAsError:ProveInit {file}" + check execCmdEx(cmd) == ("witness\n", 0) + + block: # bug #20149 + let file = testsDir / "misc/m20149.nim" + let cmd = fmt"{nim} r --hints:off --nimcache:{nimcache} --hintAsError:XDeclaredButNotUsed {file}" + check execCmdEx(cmd) == ("12\n", 0) + + block: # bug #15316 + when not defined(windows): + # This never worked reliably on Windows. Needs further investigation but it is hard to reproduce. + # Looks like a mild stack corruption when bailing out of nested exception handling. + let file = testsDir / "misc/m15316.nim" + let cmd = fmt"{nim} check --hints:off --nimcache:{nimcache} {file}" + check execCmdEx(cmd) == ("m15316.nim(1, 15) Error: expression expected, but found \')\'\nm15316.nim(2, 1) Error: expected: \':\', but got: \'[EOF]\'\nm15316.nim(2, 1) Error: expression expected, but found \'[EOF]\'\nm15316.nim(2, 1) " & + "Error: expected: \')\', but got: \'[EOF]\'\nError: illformed AST: \n", 1) + + + block: # config.nims, nim.cfg, hintConf, bug #16557 + let cmd = fmt"{nim} r --hint:all:off --hint:conf tests/newconfig/bar/mfoo.nim" + let (outp, exitCode) = execCmdEx(cmd, options = {poStdErrToStdOut}) + doAssert exitCode == 0 + let dir = getCurrentDir() + let files = """ +tests/config.nims +tests/newconfig/bar/nim.cfg +tests/newconfig/bar/config.nims +tests/newconfig/bar/mfoo.nim.cfg +tests/newconfig/bar/mfoo.nims""".splitLines + var expected = "" + for a in files: + let b = dir / a + expected.add &"Hint: used config file '{b}' [Conf]\n" + doAssert outp.endsWith expected, outp & "\n" & expected + + block: # bug #8219 + let file = "tests/newconfig/mconfigcheck.nims" + let cmd = fmt"{nim} check --hints:off {file}" + check execCmdEx(cmd) == ("", 0) + + block: # mfoo2.customext + let filename = testsDir / "newconfig/foo2/mfoo2.customext" + let cmd = fmt"{nim} e --hint:conf {filename}" + let (outp, exitCode) = execCmdEx(cmd, options = {poStdErrToStdOut}) + doAssert exitCode == 0 + var expected = &"Hint: used config file '{filename}' [Conf]\n" + doAssert outp.endsWith "123" & "\n" & expected + + + block: # nim --eval + let opt = "--hints:off" + check fmt"""{nim} {opt} --eval:"echo defined(nimscript)"""".execCmdEx == ("true\n", 0) + check fmt"""{nim} r {opt} --eval:"echo defined(c)"""".execCmdEx == ("true\n", 0) + check fmt"""{nim} r -b:js {opt} --eval:"echo defined(js)"""".execCmdEx == ("true\n", 0) + + block: # `hintProcessing` dots should not interfere with `static: echo` + friends + let cmd = fmt"""{nim} r --hint:all:off --hint:processing -f --eval:"static: echo 1+1"""" + let (outp, exitCode) = execCmdEx(cmd, options = {poStdErrToStdOut}) + template check3(cond) = doAssert cond, $(outp,) + doAssert exitCode == 0 + let lines = outp.splitLines + check3 lines.len == 3 + when not defined(windows): # xxx: on windows, dots not properly handled, gives: `....2\n\n` + check3 lines[0].isDots + check3 lines[1] == "2" + check3 lines[2] == "" + else: + check3 "2" in outp + + block: # nim secret + let opt = "--hint:all:off --hint:processing" + template check3(cond) = doAssert cond, $(outp,) + for extra in ["", "--stdout"]: + let cmd = fmt"""{nim} secret {opt} {extra}""" + # xxx minor bug: `nim --hint:QuitCalled:off secret` ignores the hint cmdline flag + template run(input2): untyped = + execCmdEx(cmd, options = {poStdErrToStdOut}, input = input2) + block: + let (outp, exitCode) = run """echo 1+2; import strutils; echo strip(" ab "); quit()""" + let lines = outp.splitLines + when not defined(windows): + check3 lines.len == 5 + check3 lines[0].isDots + # check3 lines[1].isDots # todo nim secret might use parsing pipeline + check3 lines[2].dup(removePrefix(">>> ")) == "3" # prompt depends on `nimUseLinenoise` + check3 lines[3] == "ab" + check3 lines[4] == "" + else: + check3 "3" in outp + check3 "ab" in outp + doAssert exitCode == 0 + block: + let (outp, exitCode) = run "echo 1+2; quit(2)" + check3 "3" in outp + doAssert exitCode == 2 + + block: # nimBetterRun + let file = "misc/mbetterrun.nim" + const nimcache2 = buildDir / "D20210423T185116" + removeDir nimcache2 + # related to `-d:nimBetterRun` + let opt = fmt"-r --usenimcache --nimcache:{nimcache2}" + var ret = "" + for a in @["v1", "v2", "v1", "v3"]: + ret.add runNimCmdChk(file, fmt"{opt} -d:mbetterrunVal:{a}") + ret.add runNimCmdChk(file, fmt"{opt} -d:mbetterrunVal:v2", rtarg = "arg1 arg2") + # rt arguments should not cause a recompilation + doAssert ret == """ +compiling: v1 +running: v1 +compiling: v2 +running: v2 +running: v1 +compiling: v3 +running: v3 +running: v2 +""", ret + + block: # nim dump + let cmd = fmt"{nim} dump --dump.format:json -d:D20210428T161003 --hints:off ." + let (ret, status) = execCmdEx(cmd) + doAssert status == 0 + let j = ret.parseJson + # sanity checks + doAssert "D20210428T161003" in j["defined_symbols"].to(seq[string]) + doAssert j["version"].to(string) == NimVersion + doAssert j["nimExe"].to(string) == getCurrentCompilerExe() + + block: # genscript + const nimcache2 = buildDir / "D20210524T212851" + removeDir(nimcache2) + let input = "tgenscript_fakefile" # no need for a real file, --eval is good enough + let output = runNimCmdChk(input, fmt"""--genscript --nimcache:{nimcache2.quoteShell} --eval:"echo(12345)" """) + doAssert output.len == 0, output + let ext = when defined(windows): ".bat" else: ".sh" + let filename = fmt"compile_{input}{ext}" # synchronize with `generateScript` + doAssert fileExists(nimcache2/filename), nimcache2/filename + let (outp, status) = execCmdEx(genShellCmd(filename), options = {poStdErrToStdOut}, workingDir = nimcache2) + doAssert status == 0, outp + let (outp2, status2) = execCmdEx(nimcache2 / input, options = {poStdErrToStdOut}) + doAssert outp2 == "12345\n", outp2 + doAssert status2 == 0 + + block: # UnusedImport + proc fn(opt: string, expected: string) = + let output = runNimCmdChk("msgs/mused3.nim", fmt"--warning:all:off --warning:UnusedImport --hint:DuplicateModuleImport {opt}") + doAssert output == expected, opt & "\noutput:\n" & output & "expected:\n" & expected + fn("-d:case1"): """ +mused3.nim(13, 8) Warning: imported and not used: 'mused3b' [UnusedImport] +""" + fn("-d:case2"): "" + fn("-d:case3"): "" + fn("-d:case4"): "" + fn("-d:case5"): "" + fn("-d:case6"): "" + fn("-d:case7"): "" + fn("-d:case8"): "" + fn("-d:case9"): "" + fn("-d:case10"): "" + when false: + fn("-d:case11"): """ + Warning: imported and not used: 'm2' [UnusedImport] + """ + fn("-d:case12"): """ +mused3.nim(75, 10) Hint: duplicate import of 'mused3a'; previous import here: mused3.nim(74, 10) [DuplicateModuleImport] +""" + + block: # FieldDefect + proc fn(opt: string, expected: string) = + let output = runNimCmdChk("misc/mfield_defect.nim", fmt"-r --warning:all:off --declaredlocs {opt}", status = 1) + doAssert expected in output, opt & "\noutput:\n" & output & "expected:\n" & expected + fn("-d:case1"): """mfield_defect.nim(25, 15) Error: field 'f2' is not accessible for type 'Foo' [discriminant declared in mfield_defect.nim(14, 8)] using 'kind = k3'""" + fn("-d:case2 --gc:refc"): """mfield_defect.nim(25, 15) field 'f2' is not accessible for type 'Foo' [discriminant declared in mfield_defect.nim(14, 8)] using 'kind = k3'""" + fn("-d:case1 -b:js"): """mfield_defect.nim(25, 15) Error: field 'f2' is not accessible for type 'Foo' [discriminant declared in mfield_defect.nim(14, 8)] using 'kind = k3'""" + fn("-d:case2 -b:js"): """field 'f2' is not accessible for type 'Foo' [discriminant declared in mfield_defect.nim(14, 8)] using 'kind = k3'""" + fn("-d:case2 --gc:arc"): """mfield_defect.nim(25, 15) field 'f2' is not accessible for type 'Foo' [discriminant declared in mfield_defect.nim(14, 8)] using 'kind = k3'""" +else: + discard # only during debugging, tests added here will run with `-d:nimTestsTrunnerDebugging` enabled diff --git a/tests/misc/trunner_special.nim b/tests/misc/trunner_special.nim new file mode 100644 index 000000000..e08b419b0 --- /dev/null +++ b/tests/misc/trunner_special.nim @@ -0,0 +1,37 @@ +discard """ + targets: "c cpp" + joinable: false + disabled: osx +""" + +#[ +Runs tests that require special treatment, e.g. because they rely on 3rd party code +or require external networking. + +xxx test all tests/untestable/* here, possibly with adjustments to make running times reasonable +]# + +import std/[strformat,os,unittest,compilesettings] +import stdtest/specialpaths + + +from stdtest/testutils import disableSSLTesting + + +const + nim = getCurrentCompilerExe() + mode = querySetting(backend) + +proc runCmd(cmd: string) = + let ret = execShellCmd(cmd) + check ret == 0 # allows more than 1 failure + +proc main = + let options = fmt"-b:{mode} --hints:off" + block: # SSL nimDisableCertificateValidation integration tests + runCmd fmt"{nim} r {options} -d:nimDisableCertificateValidation -d:ssl {testsDir}/untestable/thttpclient_ssl_disabled.nim" + block: # SSL certificate check integration tests + runCmd fmt"{nim} r {options} -d:ssl --threads:on --mm:refc {testsDir}/untestable/thttpclient_ssl_remotenetwork.nim" + +when not disableSSLTesting(): + main() diff --git a/tests/misc/tsamename.nim b/tests/misc/tsamename.nim new file mode 100644 index 000000000..b2d17a506 --- /dev/null +++ b/tests/misc/tsamename.nim @@ -0,0 +1,15 @@ +# bug #9891 + +import "."/tsamename2 + +# this works +callFun(fooBar2) + +when true: + # Error: attempting to call routine: 'processPattern' + callFun(fooBar) + +when true: + # BUG: Error: internal error: expr(skModule); unknown symbol + proc processPattern() = discard + callFun(fooBar) diff --git a/tests/misc/tsamename2.nim b/tests/misc/tsamename2.nim new file mode 100644 index 000000000..d2272f557 --- /dev/null +++ b/tests/misc/tsamename2.nim @@ -0,0 +1,4 @@ +proc fooBar*()=discard +proc fooBar2*()=discard +proc callFun*[Fun](processPattern: Fun) = + processPattern() diff --git a/tests/misc/tsemfold.nim b/tests/misc/tsemfold.nim new file mode 100644 index 000000000..2ce8d9560 --- /dev/null +++ b/tests/misc/tsemfold.nim @@ -0,0 +1,27 @@ +discard """ + action: run +""" + +doAssertRaises(OverflowDefect): discard low(int8) - 1'i8 +doAssertRaises(OverflowDefect): discard high(int8) + 1'i8 +doAssertRaises(OverflowDefect): discard abs(low(int8)) +doAssertRaises(DivByZeroDefect): discard 1 mod 0 +doAssertRaises(DivByZeroDefect): discard 1 div 0 +doAssertRaises(OverflowDefect): discard low(int8) div -1'i8 + +doAssertRaises(OverflowDefect): discard -low(int64) +doAssertRaises(OverflowDefect): discard low(int64) - 1'i64 +doAssertRaises(OverflowDefect): discard high(int64) + 1'i64 + +type E = enum eA, eB +doAssertRaises(OverflowDefect): discard eA.pred +doAssertRaises(OverflowDefect): discard eB.succ + +doAssertRaises(OverflowDefect): discard low(int8) * -1 +doAssertRaises(OverflowDefect): discard low(int64) * -1 +doAssertRaises(OverflowDefect): discard high(int8) * 2 +doAssertRaises(OverflowDefect): discard high(int64) * 2 + +doAssert abs(-1) == 1 +doAssert 2 div 2 == 1 +doAssert 2 * 3 == 6 diff --git a/tests/misc/tshadow_magic_type.nim b/tests/misc/tshadow_magic_type.nim index 03c83079e..8b2d26133 100644 --- a/tests/misc/tshadow_magic_type.nim +++ b/tests/misc/tshadow_magic_type.nim @@ -1,3 +1,10 @@ +discard """ +output: ''' +mylist +''' +""" + + type TListItemType* = enum RedisNil, RedisString @@ -14,11 +21,9 @@ proc seq*() = discard proc lrange*(key: string): TRedisList = - var foo: TListItem - foo.kind = RedisNil + var foo = TListItem(kind: RedisString, str: key) result = @[foo] -when isMainModule: - var p = lrange("mylist") - for i in items(p): - echo(i.str) +var p = lrange("mylist") +for i in items(p): + echo(i.str) diff --git a/tests/misc/tsimplesort.nim b/tests/misc/tsimplesort.nim index 9c6ad1207..395db55e6 100644 --- a/tests/misc/tsimplesort.nim +++ b/tests/misc/tsimplesort.nim @@ -10,7 +10,7 @@ type TSlotEnum = enum seEmpty, seFilled, seDeleted TKeyValuePair[A, B] = tuple[slot: TSlotEnum, key: A, val: B] TKeyValuePairSeq[A, B] = seq[TKeyValuePair[A, B]] - TTable* {.final, myShallow.}[A, B] = object + TTable*[A, B] {.final, myShallow.} = object data: TKeyValuePairSeq[A, B] counter: int @@ -40,11 +40,11 @@ proc mustRehash(length, counter: int): bool {.inline.} = assert(length > counter) result = (length * 2 < counter * 3) or (length - counter < 4) -proc nextTry(h, maxHash: THash): THash {.inline.} = +proc nextTry(h, maxHash: Hash): Hash {.inline.} = result = ((5 * h) + 1) and maxHash template rawGetImpl() = - var h: THash = hash(key) and high(t.data) # start with real hash value + var h: Hash = hash(key) and high(t.data) # start with real hash value while t.data[h].slot != seEmpty: if t.data[h].key == key and t.data[h].slot == seFilled: return h @@ -52,7 +52,7 @@ template rawGetImpl() = result = -1 template rawInsertImpl() = - var h: THash = hash(key) and high(data) + var h: Hash = hash(key) and high(data) while data[h].slot == seFilled: h = nextTry(h, high(data)) data[h].key = key @@ -112,13 +112,13 @@ proc initTable*[A, B](initialSize=64): TTable[A, B] = result.counter = 0 newSeq(result.data, initialSize) -proc toTable*[A, B](pairs: openarray[tuple[key: A, +proc toTable*[A, B](pairs: openArray[tuple[key: A, val: B]]): TTable[A, B] = ## creates a new hash table that contains the given `pairs`. result = initTable[A, B](nextPowerOfTwo(pairs.len+10)) for key, val in items(pairs): result[key] = val -template dollarImpl(): stmt = +template dollarImpl(): typed = if t.len == 0: result = "{:}" else: @@ -137,8 +137,7 @@ proc `$`*[A, B](t: TTable[A, B]): string = # ------------------------------ count tables ------------------------------- type - TCountTable* {.final, myShallow.}[ - A] = object ## table that counts the number of each key + TCountTable*[A] {.final, myShallow.} = object ## table that counts the number of each key data: seq[tuple[key: A, val: int]] counter: int @@ -162,7 +161,7 @@ iterator values*[A](t: TCountTable[A]): int = if t.data[h].val != 0: yield t.data[h].val proc RawGet[A](t: TCountTable[A], key: A): int = - var h: THash = hash(key) and high(t.data) # start with real hash value + var h: Hash = hash(key) and high(t.data) # start with real hash value while t.data[h].val != 0: if t.data[h].key == key: return h h = nextTry(h, high(t.data)) @@ -181,7 +180,7 @@ proc hasKey*[A](t: TCountTable[A], key: A): bool = proc rawInsert[A](t: TCountTable[A], data: var seq[tuple[key: A, val: int]], key: A, val: int) = - var h: THash = hash(key) and high(data) + var h: Hash = hash(key) and high(data) while data[h].val != 0: h = nextTry(h, high(data)) data[h].key = key data[h].val = val @@ -305,5 +304,3 @@ proc countTableTest1 = countTableTest1() echo true - - diff --git a/tests/misc/tsimtych.nim b/tests/misc/tsimtych.nim deleted file mode 100644 index 27a922f6a..000000000 --- a/tests/misc/tsimtych.nim +++ /dev/null @@ -1,12 +0,0 @@ -discard """ - file: "tsimtych.nim" - line: 10 - errormsg: "type mismatch: got (bool) but expected \'string\'" -""" -# Test 2 -# Simple type checking - -var a: string -a = false #ERROR - - diff --git a/tests/misc/tsizeof.nim b/tests/misc/tsizeof.nim index 4afd48472..ce5334664 100644 --- a/tests/misc/tsizeof.nim +++ b/tests/misc/tsizeof.nim @@ -1,10 +1,742 @@ -# Test the sizeof proc +discard """ + targets: "c cpp" + output: ''' +body executed +body executed +OK +macros api OK +''' +""" +# This is for Azure. The keyword ``alignof`` only exists in ``c++11`` +# and newer. On Azure gcc does not default to c++11 yet. +when defined(cpp) and not defined(windows): + {.passC: "-std=c++11".} + +# Object offsets are different for inheritance objects when compiling +# to c++. + +type + TMyEnum = enum + tmOne, tmTwo, tmThree, tmFour + + TMyArray1 = array[3, uint8] + TMyArray2 = array[1..3, int32] + TMyArray3 = array[TMyEnum, float64] + +var failed = false + +const + mysize1 = sizeof(TMyArray1) + mysize2 = sizeof(TMyArray2) + mysize3 = sizeof(TMyArray3) + +doAssert mysize1 == 3 +doAssert mysize2 == 12 +doAssert mysize3 == 32 + +import macros, typetraits + +macro testSizeAlignOf(args: varargs[untyped]): untyped = + result = newStmtList() + for arg in args: + result.add quote do: + let + c_size = c_sizeof(`arg`) + nim_size = sizeof(`arg`) + c_align = c_alignof(type(`arg`)) + nim_align = alignof(`arg`) + + 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 + if nim_align != c_align: + msg.add " align(get, expected): " & $nim_align & " != " & $c_align + echo msg + failed = true + + +macro testOffsetOf(a, b: untyped): untyped = + let typeName = newLit(a.repr) + let member = newLit(b.repr) + result = quote do: + let + 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 + +proc strAlign(arg: string): string = + const minLen = 22 + result = arg + for i in 0 ..< minLen - arg.len: + result &= ' ' + +macro c_offsetof(fieldAccess: typed): int32 = + ## Bullet proof implementation that works on actual offsetof operator + ## in the c backend. Assuming of course this implementation is + ## correct. + let s = if fieldAccess.kind == nnkCheckedFieldExpr: fieldAccess[0] + else: fieldAccess + let a = s[0].getTypeInst + let b = s[1] + result = quote do: + var res: int32 + {.emit: [res, " = offsetof(", `a`, ", ", `b`, ");"] .} + res + +template c_offsetof(t: typedesc, a: untyped): int32 = + var x: ptr t + c_offsetof(x[].a) + +macro c_sizeof(a: typed): int32 = + ## Bullet proof implementation that works using the sizeof operator + ## in the c backend. Assuming of course this implementation is + ## correct. + result = quote do: + var res: int32 + {.emit: [res, " = sizeof(", `a`, ");"] .} + res + +macro c_alignof(arg: untyped): untyped = + ## Bullet proof implementation that works on actual alignment + ## behavior measured at runtime. + let typeSym = genSym(nskType, "AlignTestType"&arg.repr) + result = quote do: + type + `typeSym` = object + causeAlign: byte + member: `arg` + c_offsetof(`typeSym`, member) + +macro testAlign(arg:untyped):untyped = + let prefix = newLit(arg.lineinfo & " alignof " & arg.repr & " ") + result = quote do: + let cAlign = c_alignof(`arg`) + let nimAlign = alignof(`arg`) + if cAlign != nimAlign: + echo `prefix`, cAlign, " != ", nimAlign + failed = true + +macro testSize(arg:untyped):untyped = + let prefix = newLit(arg.lineinfo & " sizeof " & arg.repr & " ") + result = quote do: + let cSize = c_sizeof(`arg`) + let nimSize = sizeof(`arg`) + if cSize != nimSize: + echo `prefix`, cSize, " != ", nimSize + failed = true + +type + MyEnum {.pure.} = enum + ValueA + ValueB + ValueC + + OtherEnum {.pure, size: 8.} = enum + ValueA + ValueB + + Enum1 {.pure, size: 1.} = enum + ValueA + ValueB + + Enum2 {.pure, size: 2.} = enum + ValueA + ValueB + + Enum4 {.pure, size: 4.} = enum + ValueA + ValueB + + Enum8 {.pure, size: 8.} = enum + ValueA + ValueB + + # Must have more than 32 elements so that set[MyEnum33] will become compile to an int64. + MyEnum33 {.pure.} = enum + Value1, Value2, Value3, Value4, Value5, Value6, + Value7, Value8, Value9, Value10, Value11, Value12, + Value13, Value14, Value15, Value16, Value17, Value18, + Value19, Value20, Value21, Value22, Value23, Value24, + Value25, Value26, Value27, Value28, Value29, Value30, + Value31, Value32, Value33 + +proc transformObjectconfigPacked(arg: NimNode): NimNode = + let debug = arg.kind == nnkPragmaExpr + + if arg.eqIdent("objectconfig"): + result = ident"packed" + else: + result = copyNimNode(arg) + for child in arg: + result.add transformObjectconfigPacked(child) + +proc removeObjectconfig(arg: NimNode): NimNode = + if arg.kind == nnkPragmaExpr and arg[1][0].eqIdent "objectconfig": + result = arg[0] + else: + result = copyNimNode(arg) + for child in arg: + result.add removeObjectconfig(child) + +macro testinstance(body: untyped): untyped = + let bodyPure = removeObjectconfig(body) + let bodyPacked = transformObjectconfigPacked(body) + + result = quote do: + proc pureblock(): void = + const usePacked {.inject.} = false + `bodyPure` + + pureblock() + + proc packedblock(): void = + const usePacked {.inject.} = true + `bodyPacked` + + packedblock() + +proc testPrimitiveTypes(): void = + testAlign(pointer) + testAlign(int) + testAlign(uint) + testAlign(int8) + testAlign(int16) + testAlign(int32) + testAlign(int64) + testAlign(uint8) + testAlign(uint16) + testAlign(uint32) + testAlign(uint64) + testAlign(float) + testAlign(float32) + testAlign(float64) + + testAlign(MyEnum) + testAlign(OtherEnum) + testAlign(Enum1) + testAlign(Enum2) + testAlign(Enum4) + testAlign(Enum8) + +testPrimitiveTypes() + +testinstance: + type + + EnumObjectA {.objectconfig.} = object + a : Enum1 + b : Enum2 + c : Enum4 + d : Enum8 + + EnumObjectB {.objectconfig.} = object + a : Enum8 + b : Enum4 + c : Enum2 + d : Enum1 + + TrivialType {.objectconfig.} = object + x,y,z: int8 + + SimpleAlignment {.objectconfig.} = object + # behaves differently on 32bit Windows and 32bit Linux + a,b: int8 + c: int64 + + AlignAtEnd {.objectconfig.} = object + a: int64 + b,c: int8 + + SimpleBranch {.objectconfig.} = object + case kind: MyEnum + of MyEnum.ValueA: + a: int16 + of MyEnum.ValueB: + b: int32 + of MyEnum.ValueC: + c: int64 + + PaddingBeforeBranchA {.objectconfig.} = object + cause: int8 + case kind: MyEnum + of MyEnum.ValueA: + a: int16 + of MyEnum.ValueB: + b: int32 + of MyEnum.ValueC: + c: int64 + + PaddingBeforeBranchB {.objectconfig.} = object + cause: int8 + case kind: MyEnum + of MyEnum.ValueA: + a: int8 + of MyEnum.ValueB: + b: int16 + of MyEnum.ValueC: + c: int32 + + PaddingAfterBranch {.objectconfig.} = object + case kind: MyEnum + of MyEnum.ValueA: + a: int8 + of MyEnum.ValueB: + b: int16 + of MyEnum.ValueC: + c: int32 + cause: int64 + + RecursiveStuff {.objectconfig.} = object + case kind: MyEnum # packedOffset: 0 + of MyEnum.ValueA: # packedOffset: + a: int16 # packedOffset: 1 + of MyEnum.ValueB: # packedOffset: + b: int32 # packedOffset: 1 + of MyEnum.ValueC: # packedOffset: + case kind2: MyEnum # packedOffset: 1 + of MyEnum.ValueA: # packedOffset: + ca1: int8 + ca2: int32 + of MyEnum.ValueB: # packedOffset: + cb: int32 # packedOffset: 2 + of MyEnum.ValueC: # packedOffset: + cc: int64 # packedOffset: 2 + d1: int8 + d2: int64 + + Foobar {.objectconfig.} = object + case kind: OtherEnum + of OtherEnum.ValueA: + a: uint8 + of OtherEnum.ValueB: + b: int8 + c: int8 + + PaddingOfSetEnum33 {.objectconfig.} = object + cause: int8 + theSet: set[MyEnum33] + + Bazing {.objectconfig.} = object of RootObj + a: int64 + # TODO test on 32 bit system + # only there the object header is smaller than the first member + + InheritanceA {.objectconfig.} = object of RootObj + a: char + + InheritanceB {.objectconfig.} = object of InheritanceA + b: char + + InheritanceC {.objectconfig.} = object of InheritanceB + c: char + + # from issue 4763 + GenericObject[T] {.objectconfig.} = object + a: int32 + b: T + + # this type mixes `packed` with `align`. + MyCustomAlignPackedObject {.objectconfig.} = object + a: char + b {.align: 32.}: int32 # align overrides `packed` for this field. + c: char + d: int32 # unaligned + + Kind = enum + K1, K2 + + AnotherEnum = enum + X1, X2, X3 + + MyObject = object + s: string + case k: Kind + of K1: nil + of K2: + x: float + y: int32 + z: AnotherEnum + + Stack[N: static int, T: object] = object + pad: array[128 - sizeof(array[N, ptr T]) - sizeof(int) - sizeof(pointer), byte] + stack: array[N, ptr T] + len*: int + rawMem: ptr array[N, T] + + Stack2[T: object] = object + pad: array[128 - sizeof(array[sizeof(T), ptr T]), byte] + + + const trivialSize = sizeof(TrivialType) # needs to be able to evaluate at compile time + + proc main(): void = + var t : TrivialType + var a : SimpleAlignment + var b : AlignAtEnd + var c : SimpleBranch + var d : PaddingBeforeBranchA + var e : PaddingBeforeBranchB + var f : PaddingAfterBranch + var g : RecursiveStuff + var ro : RootObj + var go : GenericObject[int64] + var po : PaddingOfSetEnum33 + var capo: MyCustomAlignPackedObject + var issue15516: MyObject + var issue12636_1: Stack[5, MyObject] + var issue12636_2: Stack2[MyObject] + + var + e1: Enum1 + e2: Enum2 + e4: Enum4 + e8: Enum8 + var + eoa: EnumObjectA + eob: EnumObjectB + + testAlign(SimpleAlignment) + + # sanity check to ensure both branches are actually executed + when usePacked: + doAssert sizeof(SimpleAlignment) == 10 + else: + doAssert sizeof(SimpleAlignment) > 10 + + testSizeAlignOf(t,a,b,c,d,e,f,g,ro,go,po, e1, e2, e4, e8, eoa, eob, capo, issue15516, issue12636_1, issue12636_2) + + type + WithBitsize {.objectconfig.} = object + bitfieldA {.bitsize: 16.}: uint32 + bitfieldB {.bitsize: 16.}: uint32 + + var wbs: WithBitsize + testSize(wbs) + + testOffsetOf(TrivialType, x) + testOffsetOf(TrivialType, y) + testOffsetOf(TrivialType, z) + + testOffsetOf(SimpleAlignment, a) + testOffsetOf(SimpleAlignment, b) + testOffsetOf(SimpleAlignment, c) + + testOffsetOf(AlignAtEnd, a) + testOffsetOf(AlignAtEnd, b) + testOffsetOf(AlignAtEnd, c) + + testOffsetOf(SimpleBranch, a) + testOffsetOf(SimpleBranch, b) + testOffsetOf(SimpleBranch, c) + + testOffsetOf(PaddingBeforeBranchA, cause) + testOffsetOf(PaddingBeforeBranchA, a) + testOffsetOf(PaddingBeforeBranchB, cause) + testOffsetOf(PaddingBeforeBranchB, a) + + testOffsetOf(PaddingAfterBranch, a) + testOffsetOf(PaddingAfterBranch, cause) + + testOffsetOf(Foobar, c) + + testOffsetOf(PaddingOfSetEnum33, cause) + testOffsetOf(PaddingOfSetEnum33, theSet) + + testOffsetOf(Bazing, a) + testOffsetOf(InheritanceA, a) + testOffsetOf(InheritanceB, b) + testOffsetOf(InheritanceC, c) + + testOffsetOf(EnumObjectA, a) + testOffsetOf(EnumObjectA, b) + testOffsetOf(EnumObjectA, c) + testOffsetOf(EnumObjectA, d) + testOffsetOf(EnumObjectB, a) + testOffsetOf(EnumObjectB, b) + testOffsetOf(EnumObjectB, c) + testOffsetOf(EnumObjectB, d) + + testOffsetOf(RecursiveStuff, kind) + 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) + + testOffsetOf(MyCustomAlignPackedObject, a) + testOffsetOf(MyCustomAlignPackedObject, b) + testOffsetOf(MyCustomAlignPackedObject, c) + testOffsetOf(MyCustomAlignPackedObject, d) + + echo "body executed" # sanity check to ensure this logic isn't skipped entirely + + + main() + +{.emit: """/*TYPESECTION*/ +typedef struct{ + float a; float b; +} Foo; +""".} + +type + Foo {.importc.} = object + + Bar = object + b: byte + foo: Foo + +assert sizeof(Bar) == 12 + +# bug #10082 +type + A = int8 # change to int16 and get sizeof(C)==6 + B = int16 + C {.packed.} = object + d {.bitsize: 1.}: A + e {.bitsize: 7.}: A + f {.bitsize: 16.}: B + +assert sizeof(C) == 3 + + +type + MixedBitsize {.packed.} = object + a: uint32 + b {.bitsize: 8.}: uint8 + c {.bitsize: 1.}: uint8 + d {.bitsize: 7.}: uint8 + e {.bitsize: 16.}: uint16 + f: uint32 + +doAssert sizeof(MixedBitsize) == 12 + + +type + MyUnionType {.union.} = object + a: int32 + b: float32 + + MyCustomAlignUnion {.union.} = object + c: char + a {.align: 32.}: int + + MyCustomAlignObject = object + c: char + a {.align: 32.}: int + +doAssert sizeof(MyUnionType) == 4 +doAssert sizeof(MyCustomAlignUnion) == 32 +doAssert alignof(MyCustomAlignUnion) == 32 +doAssert sizeof(MyCustomAlignObject) == 64 +doAssert alignof(MyCustomAlignObject) == 32 + + + + + + +########################################## +# bug #9794 +########################################## + +type + imported_double {.importc: "double".} = object + + Pod = object + v* : imported_double + seed*: int32 + + Pod2 = tuple[v: imported_double, seed: int32] + +proc foobar() = + testAlign(Pod) + testSize(Pod) + testAlign(Pod2) + testSize(Pod2) + doAssert sizeof(Pod) == sizeof(Pod2) + doAssert alignof(Pod) == alignof(Pod2) +foobar() + +if failed: + quit("FAIL") +else: + echo "OK" + +########################################## +# sizeof macros API +########################################## + +import macros + +type + Vec2f = object + x,y: float32 + + Vec4f = object + x,y,z,w: float32 + + # this type is constructed to have no platform depended alignment. + ParticleDataA = object + pos, vel: Vec2f + birthday: float32 + padding: float32 + moreStuff: Vec4f + +const expected = [ + # name size align offset + ("pos", 8, 4, 0), + ("vel", 8, 4, 8), + ("birthday", 4, 4, 16), + ("padding", 4, 4, 20), + ("moreStuff", 16, 4, 24) +] + +macro typeProcessing(arg: typed): untyped = + let recList = arg.getTypeImpl[2] + recList.expectKind nnkRecList + for i, identDefs in recList: + identDefs.expectKind nnkIdentDefs + identDefs.expectLen 3 + let sym = identDefs[0] + sym.expectKind nnkSym + doAssert expected[i][0] == sym.strVal + doAssert expected[i][1] == getSize(sym) + doAssert expected[i][2] == getAlign(sym) + doAssert expected[i][3] == getOffset(sym) + + result = newCall(bindSym"echo", newLit("macros api OK")) + +proc main() = + var mylocal: ParticleDataA + typeProcessing(mylocal) + +main() + +# issue #11320 use UncheckedArray + +type + Payload = object + something: int8 + vals: UncheckedArray[int32] + +proc payloadCheck() = + doAssert offsetOf(Payload, vals) == 4 + doAssert sizeof(Payload) == 4 + +payloadCheck() + +# offsetof tuple types + +type + MyTupleType = tuple + a: float64 + b: float64 + c: float64 + + MyOtherTupleType = tuple + a: float64 + b: imported_double + c: float64 + + MyCaseObject = object + val1: imported_double + case kind: bool + of true: + val2,val3: float32 + else: + val4,val5: int32 + +doAssert offsetof(MyTupleType, a) == 0 +doAssert offsetof(MyTupleType, b) == 8 +doAssert offsetof(MyTupleType, c) == 16 + +doAssert offsetof(MyOtherTupleType, a) == 0 +doAssert offsetof(MyOtherTupleType, b) == 8 + +# The following expression can only work if the offsetof expression is +# properly forwarded for the C code generator. +doAssert offsetof(MyOtherTupleType, c) == 16 +doAssert offsetof(Bar, foo) == 4 +doAssert offsetof(MyCaseObject, val1) == 0 +doAssert offsetof(MyCaseObject, kind) == 8 +doAssert offsetof(MyCaseObject, val2) == 12 +doAssert offsetof(MyCaseObject, val3) == 16 +doAssert offsetof(MyCaseObject, val4) == 12 +doAssert offsetof(MyCaseObject, val5) == 16 + +template reject(e) = + static: assert(not compiles(e)) + +reject: + const off1 = offsetof(MyOtherTupleType, c) + +reject: + const off2 = offsetof(MyOtherTupleType, b) + +reject: + const off3 = offsetof(MyCaseObject, kind) + + +type + MyPackedCaseObject {.packed.} = object + val1: imported_double + case kind: bool + of true: + val2,val3: float32 + else: + val4,val5: int32 + +# packed case object + +doAssert offsetof(MyPackedCaseObject, val1) == 0 +doAssert offsetof(MyPackedCaseObject, val2) == 9 +doAssert offsetof(MyPackedCaseObject, val3) == 13 +doAssert offsetof(MyPackedCaseObject, val4) == 9 +doAssert offsetof(MyPackedCaseObject, val5) == 13 + +reject: + const off5 = offsetof(MyPackedCaseObject, val2) + +reject: + const off6 = offsetof(MyPackedCaseObject, val3) + +reject: + const off7 = offsetof(MyPackedCaseObject, val4) + +reject: + const off8 = offsetof(MyPackedCaseObject, val5) + + +type + O0 = object + T0 = tuple[] + +doAssert sizeof(O0) == 1 +doAssert sizeof(T0) == 1 + + +type + # this thing may not have padding bytes at the end + PackedUnion* {.union, packed.} = object + a*: array[11, byte] + b*: int64 + +doAssert sizeof(PackedUnion) == 11 +doAssert alignof(PackedUnion) == 1 + +# bug #22553 type - TMyRecord {.final.} = object - x, y: int - b: bool - r: float - s: string + ChunkObj = object + data: UncheckedArray[byte] -write(stdout, sizeof(TMyRecord)) +doAssert sizeof(ChunkObj) == 1 +doAssert offsetOf(ChunkObj, data) == 1 diff --git a/tests/misc/tsizeof2.nim b/tests/misc/tsizeof2.nim new file mode 100644 index 000000000..da28de508 --- /dev/null +++ b/tests/misc/tsizeof2.nim @@ -0,0 +1,17 @@ +discard """ +errormsg: "'sizeof' requires '.importc' types to be '.completeStruct'" +line: 9 +""" + +type + MyStruct {.importc: "MyStruct".} = object + +const i = sizeof(MyStruct) + +echo i + +# bug #9868 +proc foo(a: SomeInteger): array[sizeof(a), byte] = + discard + +discard foo(1) diff --git a/tests/misc/tsizeof3.nim b/tests/misc/tsizeof3.nim new file mode 100644 index 000000000..f0ba8c4d0 --- /dev/null +++ b/tests/misc/tsizeof3.nim @@ -0,0 +1,58 @@ +discard """ +output: ''' +@[48, 57] +''' +""" +# bug #7238 + +type ByteArrayBE*[N: static[int]] = array[N, byte] + ## A byte array that stores bytes in big-endian order + +proc toByteArrayBE*[T: SomeInteger](num: T): ByteArrayBE[sizeof(T)]= + ## Convert an integer (in native host endianness) to a big-endian byte array + ## Notice the result type + const N = T.sizeof + for i in 0 ..< N: + result[i] = byte((num shr ((N-1-i) * 8)) and high(int8)) + +let a = 12345.toByteArrayBE +echo a[^2 .. ^1] # to make it work on both 32-bit and 64-bit + +#--------------------------------------------------------------------- + +type + Payload = object + something: int + vals: UncheckedArray[int] + +static: + doAssert(compiles(offsetOf(Payload, vals))) + + +type + GoodboySave* {.bycopy.} = object + saveCount: uint8 + savePoint: uint16 + shards: uint32 + friendCount: uint8 + friendCards: set[0..255] + locationsKnown: set[0..127] + locationsUnlocked: set[0..127] + pickupsObtained: set[0..127] + pickupsUsed: set[0..127] + pickupCount: uint8 + +block: # bug #20914 + block: + proc csizeof[T](a: T): int {.importc:"sizeof", nodecl.} + + var s: GoodboySave + doAssert sizeof(s) == 108 + doAssert csizeof(s) == static(sizeof(s)) + + block: + proc calignof[T](a: T): int {.importc:"alignof", header: "<stdalign.h>".} + + var s: set[0..256] + doAssert alignof(s) == 1 + doAssert calignof(s) == static(alignof(s)) diff --git a/tests/misc/tsizeof4.nim b/tests/misc/tsizeof4.nim new file mode 100644 index 000000000..94c08ba39 --- /dev/null +++ b/tests/misc/tsizeof4.nim @@ -0,0 +1,20 @@ +discard """ +disabled: "arm64" +""" + +# bug #11792 +type + m256d {.importc: "__m256d", header: "immintrin.h".} = object + + MyKind = enum + k1, k2, k3 + + MyTypeObj = object + kind: MyKind + x: int + amount: UncheckedArray[m256d] + + +# The sizeof(MyTypeObj) is not equal to (sizeof(int) + sizeof(MyKind)) due to +# alignment requirement of m256d, make sure Nim understands that +doAssert(sizeof(MyTypeObj) > sizeof(int) + sizeof(MyKind)) diff --git a/tests/misc/tslices.nim b/tests/misc/tslices.nim deleted file mode 100644 index 388a46509..000000000 --- a/tests/misc/tslices.nim +++ /dev/null @@ -1,59 +0,0 @@ -discard """ - file: "tslices.nim" - output: '''456456 -456456 -456456 -Zugr5nd -egerichtetd -verichtetd -''' -""" - -# Test the new slices. - -import strutils - -var mystr = "Abgrund" -mystr[..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] - -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" - -echo mystr - -mystr[0..2] = "ve" -echo mystr - -var s = "abcdef" -s[1 .. ^2] = "xyz" -assert s == "axyzf" - diff --git a/tests/misc/tsortdev.nim b/tests/misc/tsortdev.nim index f360d9646..6a290577b 100644 --- a/tests/misc/tsortdev.nim +++ b/tests/misc/tsortdev.nim @@ -1,5 +1,5 @@ discard """ - output: "done" + output: "done tsortdev" """ import algorithm, strutils @@ -39,7 +39,7 @@ proc cmpPlatforms(a, b: string): int = proc sorted[T](a: openArray[T]): bool = result = true - for i in 0 .. < a.high: + for i in 0 ..< a.high: if cmpPlatforms(a[i], a[i+1]) > 0: echo "Out of order: ", a[i], " ", a[i+1] result = false @@ -55,5 +55,4 @@ proc main() = for i in 0..1_000: main() -echo "done" - +echo "done tsortdev" diff --git a/tests/misc/tstrace.nim b/tests/misc/tstrace.nim index 23590d958..00af0af69 100644 --- a/tests/misc/tstrace.nim +++ b/tests/misc/tstrace.nim @@ -1,3 +1,23 @@ +discard """ +exitcode: 1 +output: ''' +Traceback (most recent call last) +tstrace.nim(36) tstrace +tstrace.nim(28) recTest +tstrace.nim(28) recTest +tstrace.nim(28) recTest +tstrace.nim(28) recTest +tstrace.nim(28) recTest +tstrace.nim(28) recTest +tstrace.nim(28) recTest +tstrace.nim(28) recTest +tstrace.nim(28) recTest +tstrace.nim(28) recTest +tstrace.nim(31) recTest +SIGSEGV: Illegal storage access. (Attempt to read from nil?) +''' +""" + # Test the new stacktraces (great for debugging!) {.push stack_trace: on.} diff --git a/tests/misc/tstrange.nim b/tests/misc/tstrange.nim index fee0f44e4..f8c063240 100644 --- a/tests/misc/tstrange.nim +++ b/tests/misc/tstrange.nim @@ -1,8 +1,9 @@ discard """ - file: "tstrange.nim" - output: '''hallo40 +output: ''' +hallo40 1 -2''' +2 +''' """ # test for extremely strange bug @@ -23,6 +24,5 @@ write(stdout, ack(5, 4)) # bug #1442 let h=3 -for x in 0.. <h.int: +for x in 0 ..< h.int: echo x - diff --git a/tests/misc/tstrdesc.nim b/tests/misc/tstrdesc.nim index d23160315..1479fcda8 100644 --- a/tests/misc/tstrdesc.nim +++ b/tests/misc/tstrdesc.nim @@ -1,12 +1,12 @@ var - x: array [0..2, int] + x: array[0..2, int] x = [0, 1, 2] type TStringDesc {.final.} = object len, space: int # len and space without counting the terminating zero - data: array [0..0, char] # for the '\0' character + data: array[0..0, char] # for the '\0' character var emptyString {.exportc: "emptyString".}: TStringDesc diff --git a/tests/misc/tstrdist.nim b/tests/misc/tstrdist.nim index 3e1939e73..53ace2fae 100644 --- a/tests/misc/tstrdist.nim +++ b/tests/misc/tstrdist.nim @@ -23,4 +23,4 @@ proc editDistance(a, b: string): int = c[(i-1)*n + (j-1)] = min(x,min(y,z)) return c[n*m] -write(stdout, editDistance("abc", "abd")) +doAssert editDistance("abc", "abd") == 3 diff --git a/tests/misc/ttlsemulation.nim b/tests/misc/ttlsemulation.nim new file mode 100644 index 000000000..767a9bd4e --- /dev/null +++ b/tests/misc/ttlsemulation.nim @@ -0,0 +1,76 @@ +discard """ + disabled: i386 + matrix: "-d:nimTtlsemulationCase1 --threads --tlsEmulation:on; -d:nimTtlsemulationCase2 --threads --tlsEmulation:off; -d:nimTtlsemulationCase3 --threads" + targets: "c cpp" +""" + +#[ +tests for: `.cppNonPod`, `--tlsEmulation` +]# + +import std/sugar + +block: + # makes sure the logic in config/nim.cfg or testament doesn't interfere with `--tlsEmulation` so we test the right thing. + when defined(nimTtlsemulationCase1): + doAssert compileOption("tlsEmulation") + elif defined(nimTtlsemulationCase2): + doAssert not compileOption("tlsEmulation") + elif defined(nimTtlsemulationCase3): + when defined(osx): + doAssert not compileOption("tlsEmulation") + else: + doAssert false + +block: + proc main1(): int = + var g0 {.threadvar.}: int + g0.inc + g0 + let s = collect: + for i in 0..<3: main1() + doAssert s == @[1,2,3] + +when defined(cpp): # bug #16752 + when defined(windows) and defined(nimTtlsemulationCase2): + discard # xxx this failed with exitCode 1 + else: + type Foo1 {.importcpp: "Foo1", header: "mtlsemulation.h".} = object + x: cint + type Foo2 {.cppNonPod, importcpp: "Foo2", header: "mtlsemulation.h".} = object + x: cint + + var ctorCalls {.importcpp.}: cint + var dtorCalls {.importcpp.}: cint + type Foo3 {.cppNonPod, importcpp: "Foo3", header: "mtlsemulation.h".} = object + x: cint + + proc sub(i: int) = + var g1 {.threadvar.}: Foo1 + var g2 {.threadvar.}: Foo2 + var g3 {.threadvar.}: Foo3 + discard g1 + discard g2 + + # echo (g3.x, ctorCalls, dtorCalls) + when compileOption("tlsEmulation"): + # xxx bug + discard + else: + doAssert g3.x.int == 10 + i + doAssert ctorCalls == 2 + doAssert dtorCalls == 1 + g3.x.inc + + proc main() = + doAssert ctorCalls == 0 + doAssert dtorCalls == 0 + block: + var f3: Foo3 + doAssert f3.x == 10 + doAssert ctorCalls == 1 + doAssert dtorCalls == 1 + + for i in 0..<3: + sub(i) + main() diff --git a/tests/misc/tunsigned64mod.nim b/tests/misc/tunsigned64mod.nim deleted file mode 100644 index 9c9e01c45..000000000 --- a/tests/misc/tunsigned64mod.nim +++ /dev/null @@ -1,24 +0,0 @@ - -# bug #1638 - -let v1 = 7 -let v2 = 7'u64 - -let t1 = v1 mod 2 # works -let t2 = 7'u64 mod 2'u64 # works -let t3 = v2 mod 2'u64 # Error: invalid type: 'range 0..1(uint64) -let t4 = (v2 mod 2'u64).uint64 # works - -# bug #2550 - -var x: uint # doesn't work -echo x mod 2 == 0 - -var y: uint64 # doesn't work -echo y mod 2 == 0 - -var z: uint32 # works -echo z mod 2 == 0 - -var a: int # works -echo a mod 2 == 0 diff --git a/tests/misc/tunsignedcmp.nim b/tests/misc/tunsignedcmp.nim deleted file mode 100644 index 9ffc0d119..000000000 --- a/tests/misc/tunsignedcmp.nim +++ /dev/null @@ -1,13 +0,0 @@ -discard """ - output: '''true -true -true''' -""" - -# bug 1420 -var x = 40'u32 -var y = 30'u32 -echo x > y # works - -echo((40'i32) > (30'i32)) -echo((40'u32) > (30'u32)) # Error: ordinal type expected diff --git a/tests/misc/tunsignedcomp.nim b/tests/misc/tunsignedcomp.nim deleted file mode 100644 index 19c8876b1..000000000 --- a/tests/misc/tunsignedcomp.nim +++ /dev/null @@ -1,136 +0,0 @@ -discard """ - output: '''''' - disabled: "true" -""" - -# All operations involving uint64 are commented out -# as they're not yet supported. -# All other operations are handled by implicit conversions from uints to ints -# uint64 could be supported but would need special implementation of the operators - -# unsigned < signed - -assert 10'u8 < 20'i8 -assert 10'u8 < 20'i16 -assert 10'u8 < 20'i32 -assert 10'u8 < 20'i64 - -assert 10'u16 < 20'i8 -assert 10'u16 < 20'i16 -assert 10'u16 < 20'i32 -assert 10'u16 < 20'i64 - -assert 10'u32 < 20'i8 -assert 10'u32 < 20'i16 -assert 10'u32 < 20'i32 -assert 10'u32 < 20'i64 - -# assert 10'u64 < 20'i8 -# assert 10'u64 < 20'i16 -# assert 10'u64 < 20'i32 -# assert 10'u64 < 20'i64 - -# signed < unsigned -assert 10'i8 < 20'u8 -assert 10'i8 < 20'u16 -assert 10'i8 < 20'u32 -# assert 10'i8 < 20'u64 - -assert 10'i16 < 20'u8 -assert 10'i16 < 20'u16 -assert 10'i16 < 20'u32 -# assert 10'i16 < 20'u64 - -assert 10'i32 < 20'u8 -assert 10'i32 < 20'u16 -assert 10'i32 < 20'u32 -# assert 10'i32 < 20'u64 - -assert 10'i64 < 20'u8 -assert 10'i64 < 20'u16 -assert 10'i64 < 20'u32 -# assert 10'i64 < 20'u64 - -# unsigned <= signed -assert 10'u8 <= 20'i8 -assert 10'u8 <= 20'i16 -assert 10'u8 <= 20'i32 -assert 10'u8 <= 20'i64 - -assert 10'u16 <= 20'i8 -assert 10'u16 <= 20'i16 -assert 10'u16 <= 20'i32 -assert 10'u16 <= 20'i64 - -assert 10'u32 <= 20'i8 -assert 10'u32 <= 20'i16 -assert 10'u32 <= 20'i32 -assert 10'u32 <= 20'i64 - -# assert 10'u64 <= 20'i8 -# assert 10'u64 <= 20'i16 -# assert 10'u64 <= 20'i32 -# assert 10'u64 <= 20'i64 - -# signed <= unsigned -assert 10'i8 <= 20'u8 -assert 10'i8 <= 20'u16 -assert 10'i8 <= 20'u32 -# assert 10'i8 <= 20'u64 - -assert 10'i16 <= 20'u8 -assert 10'i16 <= 20'u16 -assert 10'i16 <= 20'u32 -# assert 10'i16 <= 20'u64 - -assert 10'i32 <= 20'u8 -assert 10'i32 <= 20'u16 -assert 10'i32 <= 20'u32 -# assert 10'i32 <= 20'u64 - -assert 10'i64 <= 20'u8 -assert 10'i64 <= 20'u16 -assert 10'i64 <= 20'u32 -# assert 10'i64 <= 20'u64 - -# signed == unsigned -assert 10'i8 == 10'u8 -assert 10'i8 == 10'u16 -assert 10'i8 == 10'u32 -# assert 10'i8 == 10'u64 - -assert 10'i16 == 10'u8 -assert 10'i16 == 10'u16 -assert 10'i16 == 10'u32 -# assert 10'i16 == 10'u64 - -assert 10'i32 == 10'u8 -assert 10'i32 == 10'u16 -assert 10'i32 == 10'u32 -# assert 10'i32 == 10'u64 - -assert 10'i64 == 10'u8 -assert 10'i64 == 10'u16 -assert 10'i64 == 10'u32 -# assert 10'i64 == 10'u64 - -# unsigned == signed -assert 10'u8 == 10'i8 -assert 10'u8 == 10'i16 -assert 10'u8 == 10'i32 -# assert 10'u8 == 10'i64 - -assert 10'u16 == 10'i8 -assert 10'u16 == 10'i16 -assert 10'u16 == 10'i32 -# assert 10'u16 == 10'i64 - -assert 10'u32 == 10'i8 -assert 10'u32 == 10'i16 -assert 10'u32 == 10'i32 -# assert 10'u32 == 10'i64 - -# assert 10'u64 == 10'i8 -# assert 10'u64 == 10'i16 -# assert 10'u64 == 10'i32 -# assert 10'u64 == 10'i64 diff --git a/tests/misc/tunsignedconv.nim b/tests/misc/tunsignedconv.nim deleted file mode 100644 index 956e014da..000000000 --- a/tests/misc/tunsignedconv.nim +++ /dev/null @@ -1,41 +0,0 @@ - -# Tests unsigned literals and implicit conversion between uints and ints -# Passes if it compiles - -var h8:uint8 = 128 -var h16:uint16 = 32768 -var h32:uint32 = 2147483648'u32 -var h64:uint64 = 9223372036854775808'u64 -var foobar:uint64 = 9223372036854775813'u64 # Issue 728 - -var v8:uint8 = 10 -var v16:uint16 = 10 -var v32:uint32 = 10 -var v64:uint64 = 10 - -# u8 + literal produces u8: -var a8: uint8 = v8 + 10 -var a16: uint16 = v16 + 10 - -when false: - var d8 = v8 + 10'i8 - var d16 = v8 + 10'i16 - var d32 = v8 + 10'i32 - -when false: - # these dont work yet because unsigned.nim is stupid. XXX We need to fix this. - var f8 = v16 + 10'u8 - var f16 = v16 + 10'u16 - var f32 = v16 + 10'u32 - - var g8 = v32 + 10'u8 - var g16 = v32 + 10'u16 - var g32 = v32 + 10'u32 - -var ar: array[0..20, int] -var n8 = ar[v8] -var n16 = ar[v16] -var n32 = ar[v32] -var n64 = ar[v64] - - diff --git a/tests/misc/tunsignedinc.nim b/tests/misc/tunsignedinc.nim deleted file mode 100644 index 60c0559b0..000000000 --- a/tests/misc/tunsignedinc.nim +++ /dev/null @@ -1,28 +0,0 @@ - -block: # bug #2427 - var x = 0'u8 - dec x # OverflowError - x -= 1 # OverflowError - x = x - 1 # No error - - doAssert(x == 253'u8) - -block: - var x = 130'u8 - x += 130'u8 - doAssert(x == 4'u8) - -block: - var x = 40000'u16 - x = x + 40000'u16 - doAssert(x == 14464'u16) - -block: - var x = 4000000000'u32 - x = x + 4000000000'u32 - doAssert(x == 3705032704'u32) - -block: - var x = 123'u16 - x -= 125 - doAssert(x == 65534'u16) diff --git a/tests/misc/tunsignedmisc.nim b/tests/misc/tunsignedmisc.nim deleted file mode 100644 index 4b8157ddd..000000000 --- a/tests/misc/tunsignedmisc.nim +++ /dev/null @@ -1,66 +0,0 @@ -discard """ - errormsg: "number 0x123'u8 out of valid range" -""" - -# Bug #1179 - -# Unsigneds - -# 8 bit -let ref1 = 128'u8 shr 7 -let hex1 = 0x80'u8 shr 7 -let oct1 = 0c200'u8 shr 7 -let dig1 = 0b10000000'u8 shr 7 - -doAssert(ref1 == 1) -doAssert(ref1 == hex1) -doAssert(ref1 == oct1) -doAssert(ref1 == dig1) - -# 16 bit -let ref2 = 32768'u16 shr 15 -let hex2 = 0x8000'u16 shr 15 -let oct2 = 0c100000'u16 shr 15 -let dig2 = 0b1000000000000000'u16 shr 15 - -doAssert(ref2 == 1) -doAssert(ref2 == hex2) -doAssert(ref2 == oct2) -doAssert(ref2 == dig2) - -# 32 bit -let ref3 = 2147483648'u32 shr 31 -let hex3 = 0x80000000'u32 shr 31 -let oct3 = 0c20000000000'u32 shr 31 -let dig3 = 0b10000000000000000000000000000000'u32 shr 31 - -doAssert(ref3 == 1) -doAssert(ref3 == hex3) -doAssert(ref3 == oct3) -doAssert(ref3 == dig3) - -# Below doesn't work for lexer stage errors... -# doAssert(compiles(0xFF'u8) == true) -# doAssert(compiles(0xFFF'u16) == true) -# doAssert(compiles(0x7FFF'i16) == true) - -# doAssert(compiles(0x123'u8) == false) -# doAssert(compiles(0x123'i8) == false) -# doAssert(compiles(0x123123'u16) == false) -# doAssert(compiles(0x123123'i16) == false) - -# Should compile # -let boundOkHex1 = 0xFF'u8 -let boundOkHex2 = 0xFFFF'u16 -let boundOkHex3 = 0x7FFF'i16 - -let boundOkHex4 = 0x80'i8 -let boundOkHex5 = 0xFF'i8 -let boundOkHex6 = 0xFFFF'i16 -let boundOkHex7 = 0x7FFF'i16 - -# Should _not_ compile # -let boundBreakingHex1 = 0x123'u8 -let boundBreakingHex2 = 0x123'i8 -let boundBreakingHex3 = 0x123123'u16 -let boundBreakingHex4 = 0x123123'i16 diff --git a/tests/misc/tupcomingfeatures.nim b/tests/misc/tupcomingfeatures.nim deleted file mode 100644 index cf07b06df..000000000 --- a/tests/misc/tupcomingfeatures.nim +++ /dev/null @@ -1,39 +0,0 @@ -discard """ - output: '''0 -2 0 -0 -2''' -""" - -{.this: self.} - -type - Foo {.partial.} = object - a, b: int - -type - tupcomingfeatures.Foo = object - x: int - -proc yay(self: Foo) = - echo a, " ", b, " ", x - -proc footest[T](self: var Foo, a: T) = - b = 1+a - yay() - -proc nongeneric(self: Foo) = - echo a, " ", b - -var ff: Foo -footest(ff, -3) -ff.nongeneric - -{.experimental.} -using - c: Foo - x, y: int - -proc usesSig(c) = - echo "yummy" - -proc foobar(c, y) = - echo "yay" diff --git a/tests/misc/tvarious.nim b/tests/misc/tvarious.nim index 8124b3fc7..191107a87 100644 --- a/tests/misc/tvarious.nim +++ b/tests/misc/tvarious.nim @@ -1,3 +1,7 @@ +discard """ +action: compile +""" + # Test various aspects # bug #572 diff --git a/tests/misc/tvarious1.nim b/tests/misc/tvarious1.nim index 1d5ad876a..9c912ee8e 100644 --- a/tests/misc/tvarious1.nim +++ b/tests/misc/tvarious1.nim @@ -1,6 +1,6 @@ discard """ - file: "tlenopenarray.nim" - output: '''1 +output: ''' +1 0 Whopie 12 @@ -18,15 +18,15 @@ echo v[2] # bug #569 -import queues +import deques type TWidget = object - names: Queue[string] + names: Deque[string] -var w = TWidget(names: initQueue[string]()) +var w = TWidget(names: initDeque[string]()) -add(w.names, "Whopie") +addLast(w.names, "Whopie") for n in w.names: echo(n) @@ -46,3 +46,13 @@ echo value var ys = @[4.1, 5.6, 7.2, 1.7, 9.3, 4.4, 3.2] #var x = int(ys.high / 2) #echo ys[x] # Works echo ys[int(ys.high / 2)] # Doesn't work + + +# bug #19680 +var here = "" +when stderr is static: + doAssert false +else: + here = "works" + +doAssert here == "works" diff --git a/tests/misc/tvarnums.nim b/tests/misc/tvarnums.nim index 04a1ef53b..498099c49 100644 --- a/tests/misc/tvarnums.nim +++ b/tests/misc/tvarnums.nim @@ -1,5 +1,4 @@ discard """ - file: "tvarnums.nim" output: "Success!" """ # Test variable length binary integers @@ -8,7 +7,7 @@ import strutils type - TBuffer = array [0..10, int8] + TBuffer = array[0..10, uint8] proc toVarNum(x: int32, b: var TBuffer) = # encoding: first bit indicates end of number (0 if at end) @@ -22,11 +21,11 @@ proc toVarNum(x: int32, b: var TBuffer) = # anyway a = abs(x) # first 6 bits: - b[0] = toU8(ord(a >% 63'i32) shl 7 or (ord(x < 0'i32) shl 6) or (int(a) and 63)) - a = a shr 6'i32 # skip first 6 bits + b[0] = uint8(ord(a >% 63'i32) shl 7 or (ord(x < 0'i32) shl 6) or (int(a) and 63)) + a = (a shr 6'i32) and 0x03ffffff # skip first 6 bits var i = 1 while a != 0'i32: - b[i] = toU8(ord(a >% 127'i32) shl 7 or (int(a) and 127)) + b[i] = uint8(ord(a >% 127'i32) shl 7 or (int(a) and 127)) inc(i) a = a shr 7'i32 @@ -42,40 +41,40 @@ proc toVarNum64(x: int64, b: var TBuffer) = # anyway a = abs(x) # first 6 bits: - b[0] = toU8(ord(a >% 63'i64) shl 7 or (ord(x < 0'i64) shl 6) or int(a and 63)) - a = a shr 6 # skip first 6 bits + b[0] = uint8(ord(a >% 63'i64) shl 7 or (ord(x < 0'i64) shl 6) or int(a and 63)) + a = (a shr 6) and 0x03ffffffffffffff # skip first 6 bits var i = 1 while a != 0'i64: - b[i] = toU8(ord(a >% 127'i64) shl 7 or int(a and 127)) + b[i] = uint8(ord(a >% 127'i64) shl 7 or int(a and 127)) inc(i) a = a shr 7 proc toNum64(b: TBuffer): int64 = # treat first byte different: - result = ze64(b[0]) and 63 + result = int64(b[0]) and 63 var i = 0 Shift = 6'i64 - while (ze(b[i]) and 128) != 0: + while (int(b[i]) and 128) != 0: inc(i) - result = result or ((ze64(b[i]) and 127) shl Shift) + result = result or ((int64(b[i]) and 127) shl Shift) inc(Shift, 7) - if (ze(b[0]) and 64) != 0: # sign bit set? + if (int(b[0]) and 64) != 0: # sign bit set? result = not result +% 1 # this is the same as ``- result`` # but gives no overflow error for low(int) proc toNum(b: TBuffer): int32 = # treat first byte different: - result = ze(b[0]) and 63 + result = int32(b[0]) and 63 var i = 0 Shift = 6'i32 - while (ze(b[i]) and 128) != 0: + while (int(b[i]) and 128) != 0: inc(i) - result = result or ((int32(ze(b[i])) and 127'i32) shl Shift) + result = result or ((int32(b[i]) and 127'i32) shl Shift) Shift = Shift + 7'i32 - if (ze(b[0]) and (1 shl 6)) != 0: # sign bit set? + if (int(b[0]) and (1 shl 6)) != 0: # sign bit set? result = (not result) +% 1'i32 # this is the same as ``- result`` # but gives no overflow error for low(int) @@ -138,5 +137,3 @@ tm(low(int32)) tm(high(int32)) writeLine(stdout, "Success!") #OUT Success! - - diff --git a/tests/misc/tvcc.nim b/tests/misc/tvcc.nim new file mode 100644 index 000000000..10533729c --- /dev/null +++ b/tests/misc/tvcc.nim @@ -0,0 +1,9 @@ +discard """ + matrix: "--cc:vcc" + disabled: "linux" + disabled: "bsd" + disabled: "osx" + disabled: "unix" + disabled: "posix" +""" +doAssert true diff --git a/tests/misc/åäö.nim b/tests/misc/åäö.nim new file mode 100644 index 000000000..b3caa9861 --- /dev/null +++ b/tests/misc/åäö.nim @@ -0,0 +1,11 @@ +discard """ + action: run +""" + +# Tests that module names can contain multi byte characters + +let a = 1 +doAssert åäö.a == 1 + +proc inlined() {.inline.} = discard +inlined() \ No newline at end of file |