diff options
Diffstat (limited to 'drnim/tests')
-rw-r--r-- | drnim/tests/config.nims | 10 | ||||
-rw-r--r-- | drnim/tests/tbasic_array_index.nim | 51 | ||||
-rw-r--r-- | drnim/tests/tensures.nim | 74 | ||||
-rw-r--r-- | drnim/tests/tphi.nim | 23 | ||||
-rw-r--r-- | drnim/tests/tsetlen_invalidates.nim | 26 |
5 files changed, 184 insertions, 0 deletions
diff --git a/drnim/tests/config.nims b/drnim/tests/config.nims new file mode 100644 index 000000000..346b0b4e6 --- /dev/null +++ b/drnim/tests/config.nims @@ -0,0 +1,10 @@ +switch("path", "$nim/testament/lib") # so we can `import stdtest/foo` in this dir + +## prevent common user config settings to interfere with testament expectations +## Indifidual tests can override this if needed to test for these options. +switch("colors", "off") +switch("filenames", "canonical") +switch("excessiveStackTrace", "off") + +# we only want to check the marked parts in the tests: +switch("staticBoundChecks", "off") diff --git a/drnim/tests/tbasic_array_index.nim b/drnim/tests/tbasic_array_index.nim new file mode 100644 index 000000000..8ae019e78 --- /dev/null +++ b/drnim/tests/tbasic_array_index.nim @@ -0,0 +1,51 @@ +discard """ + nimout: '''tbasic_array_index.nim(26, 17) Warning: cannot prove: 0 <= len(a) - 4; counter example: a.len -> 0 [IndexCheck] +tbasic_array_index.nim(32, 5) Warning: cannot prove: 4.0 <= 1.0 [IndexCheck] +tbasic_array_index.nim(38, 36) Warning: cannot prove: a <= 10'u32; counter example: a -> #x000000000000000b +''' + cmd: "drnim $file" + action: "compile" +""" + +{.push staticBoundChecks: defined(nimDrNim).} + +proc takeNat(n: Natural) = + discard + +proc p(a, b: openArray[int]) = + if a.len > 0: + echo a[0] + + for i in 0..a.len-8: + #{.invariant: i < a.len.} + echo a[i] + + for i in 0..min(a.len, b.len)-1: + echo a[i], " ", b[i] + + takeNat(a.len - 4) + +proc r(x: range[0.0..1.0]) = echo x + +proc sum() = + r 1.0 + r 4.0 + +proc ru(x: range[1u32..10u32]) = echo x + +proc xu(a: uint) = + if a >= 4u: + let chunk = range[1u32..10u32](a) + ru chunk + +proc parse(s: string) = + var i = 0 + + while i < s.len and s[i] != 'a': + inc i + +parse("abc") + +{.pop.} + +p([1, 2, 3], [4, 5]) diff --git a/drnim/tests/tensures.nim b/drnim/tests/tensures.nim new file mode 100644 index 000000000..f4e8f84e6 --- /dev/null +++ b/drnim/tests/tensures.nim @@ -0,0 +1,74 @@ +discard """ + nimout: '''tensures.nim(18, 10) Warning: BEGIN [User] +tensures.nim(27, 5) Warning: cannot prove: +0 < n [IndexCheck] +tensures.nim(47, 17) Warning: cannot prove: a < 4; counter example: y -> 2 +a`2 -> 4 +a`1 -> 3 +a -> 2 [IndexCheck] +tensures.nim(69, 17) Warning: cannot prove: a < 4; counter example: y -> 2 +a`1 -> 4 +a -> 2 [IndexCheck] +tensures.nim(73, 10) Warning: END [User]''' + cmd: "drnim $file" + action: "compile" +""" +import std/logic +{.push staticBoundChecks: defined(nimDrNim).} +{.warning: "BEGIN".} + +proc fac(n: int) {.requires: n > 0.} = + discard + +proc g(): int {.ensures: result > 0.} = + result = 10 + +fac 7 # fine +fac -45 # wrong + +fac g() # fine + +proc main = + var x = g() + fac x + +main() + +proc myinc(x: var int) {.ensures: x == old(x)+1.} = + inc x + {.assume: old(x)+1 == x.} + +proc mainB(y: int) = + var a = y + if a < 3: + myinc a + {.assert: a < 4.} + myinc a + {.assert: a < 4.} # now this is wrong! + +mainB(3) + +proc a(yy, z: int) {.requires: (yy - z) > 6.} = discard +# 'requires' must be weaker (or equal) +# 'ensures' must be stronger (or equal) + +# a 'is weaker than' b iff b -> a +# a 'is stronger than' b iff a -> b +# --> We can use Z3 to compute whether 'var x: T = q' is valid + +type + F = proc (yy, z3: int) {.requires: z3 < 5 and z3 > -5 and yy > 10.} + +var + x: F = a # valid? + +proc testAsgn(y: int) = + var a = y + if a < 3: + a = a + 2 + {.assert: a < 4.} + +testAsgn(3) + +{.warning: "END".} +{.pop.} diff --git a/drnim/tests/tphi.nim b/drnim/tests/tphi.nim new file mode 100644 index 000000000..7ff49f4dc --- /dev/null +++ b/drnim/tests/tphi.nim @@ -0,0 +1,23 @@ +discard """ + nimout: '''tphi.nim(9, 10) Warning: BEGIN [User] +tphi.nim(22, 10) Warning: END [User]''' + cmd: "drnim $file" + action: "compile" +""" +import std/logic +{.push staticBoundChecks: defined(nimDrNim).} +{.warning: "BEGIN".} + +proc testAsgn(y: int) = + var a = y + if a > 0: + if a > 3: + a = a + 2 + else: + a = a + 1 + {.assert: a > 1.} + +testAsgn(3) + +{.warning: "END".} +{.pop.} diff --git a/drnim/tests/tsetlen_invalidates.nim b/drnim/tests/tsetlen_invalidates.nim new file mode 100644 index 000000000..f3e595744 --- /dev/null +++ b/drnim/tests/tsetlen_invalidates.nim @@ -0,0 +1,26 @@ +discard """ + nimout: '''tsetlen_invalidates.nim(12, 10) Warning: BEGIN [User] +tsetlen_invalidates.nim(18, 12) Warning: cannot prove: 0 <= len(a) + -1; counter example: a`1.len -> 0 +a.len -> 1 [IndexCheck] +tsetlen_invalidates.nim(26, 10) Warning: END [User] +''' + cmd: "drnim $file" + action: "compile" +""" + +{.push staticBoundChecks: defined(nimDrNim).} +{.warning: "BEGIN".} + +proc p() = + var a = newSeq[int](3) + if a.len > 0: + a.setLen 0 + echo a[0] + + if a.len > 0: + echo a[0] + +{.pop.} + +p() +{.warning: "END".} |