diff options
Diffstat (limited to 'tests/range')
-rw-r--r-- | tests/range/compilehelpers.nim | 5 | ||||
-rw-r--r-- | tests/range/t19678.nim | 17 | ||||
-rw-r--r-- | tests/range/tcompiletime_range_checks.nim | 52 | ||||
-rw-r--r-- | tests/range/tenums.nim | 33 | ||||
-rw-r--r-- | tests/range/texplicitvarconv.nim | 13 | ||||
-rw-r--r-- | tests/range/toutofrangevarconv.nim | 14 | ||||
-rw-r--r-- | tests/range/trange.nim | 156 | ||||
-rw-r--r-- | tests/range/tsubrange.nim | 20 | ||||
-rw-r--r-- | tests/range/tsubrange2.nim | 15 | ||||
-rw-r--r-- | tests/range/tsubrange3.nim | 17 |
10 files changed, 342 insertions, 0 deletions
diff --git a/tests/range/compilehelpers.nim b/tests/range/compilehelpers.nim new file mode 100644 index 000000000..08f97a5bf --- /dev/null +++ b/tests/range/compilehelpers.nim @@ -0,0 +1,5 @@ +template accept(e) = + static: assert(compiles(e)) + +template reject(e) = + static: assert(not compiles(e)) diff --git a/tests/range/t19678.nim b/tests/range/t19678.nim new file mode 100644 index 000000000..88f7eff89 --- /dev/null +++ b/tests/range/t19678.nim @@ -0,0 +1,17 @@ +discard """ + cmd: "nim check --hints:off $file" + errormsg: "" + nimout: ''' +t19678.nim(13, 13) Error: range of string is invalid + + + +''' +""" + +case "5": + of "0" .. "9": + discard + else: + discard + diff --git a/tests/range/tcompiletime_range_checks.nim b/tests/range/tcompiletime_range_checks.nim new file mode 100644 index 000000000..2d3f292ec --- /dev/null +++ b/tests/range/tcompiletime_range_checks.nim @@ -0,0 +1,52 @@ +discard """ + cmd: "nim check --hint:Processing:off --hint:Conf:off $file" + errormsg: "18446744073709551615 can't be converted to int8" + nimout: ''' +tcompiletime_range_checks.nim(36, 21) Error: 2147483648 can't be converted to int32 +tcompiletime_range_checks.nim(38, 34) Error: 255 can't be converted to FullNegativeRange +tcompiletime_range_checks.nim(39, 34) Error: 18446744073709551615 can't be converted to HalfNegativeRange +tcompiletime_range_checks.nim(40, 34) Error: 300 can't be converted to FullPositiveRange +tcompiletime_range_checks.nim(41, 30) Error: 101 can't be converted to UnsignedRange +tcompiletime_range_checks.nim(42, 32) Error: -9223372036854775808 can't be converted to SemiOutOfBounds +tcompiletime_range_checks.nim(44, 22) Error: nan can't be converted to int32 +tcompiletime_range_checks.nim(46, 23) Error: 1e+100 can't be converted to uint64 +tcompiletime_range_checks.nim(49, 22) Error: 18446744073709551615 can't be converted to int64 +tcompiletime_range_checks.nim(50, 22) Error: 18446744073709551615 can't be converted to int32 +tcompiletime_range_checks.nim(51, 22) Error: 18446744073709551615 can't be converted to int16 +tcompiletime_range_checks.nim(52, 21) Error: 18446744073709551615 can't be converted to int8 + ''' +""" + +type + UnsignedRange* = range[0'u64 .. 100'u64] + SemiOutOfBounds* = range[0x7ffffffffffffe00'u64 .. 0x8000000000000100'u64] + FullOutOfBounds* = range[0x8000000000000000'u64 .. 0x8000000000000200'u64] + + FullNegativeRange* = range[-200 .. -100] + HalfNegativeRange* = range[-50 .. 50] + FullPositiveRange* = range[100 .. 200] + +let acceptA* = int32(0x7fffffff'i64) +let acceptB* = (uint64(0'i64)) +let acceptD* = (HalfNegativeRange(25'u64)) +let acceptE* = (UnsignedRange(50'u64)) +let acceptF* = (SemiOutOfBounds(0x7ffffffffffffe00'i64)) +let acceptH* = (SemiOutOfBounds(0x8000000000000000'u64)) + +let rejectA* = int32(0x80000000'i64) +let rejectB* = (uint64(-1'i64)) +let rejectC* = (FullNegativeRange(0xff'u32)) +let rejectD* = (HalfNegativeRange(0xffffffffffffffff'u64)) # internal `intVal` is `-1` which would be in range. +let rejectE* = (FullPositiveRange(300'u64)) +let rejectF* = (UnsignedRange(101'u64)) +let rejectG* = (SemiOutOfBounds(0x8000000000000000'i64)) # + +let rejectH* = (int32(NaN)) +let rejectI* = (int64(1e100)) +let rejectJ* = (uint64(1e100)) + +# removed cross checks from tarithm.nim +let rejectK* = (int64(0xFFFFFFFFFFFFFFFF'u64)) +let rejectL* = (int32(0xFFFFFFFFFFFFFFFF'u64)) +let rejectM* = (int16(0xFFFFFFFFFFFFFFFF'u64)) +let rejectN* = (int8(0xFFFFFFFFFFFFFFFF'u64)) diff --git a/tests/range/tenums.nim b/tests/range/tenums.nim new file mode 100644 index 000000000..3cdf06fe2 --- /dev/null +++ b/tests/range/tenums.nim @@ -0,0 +1,33 @@ +discard """ + cmd: "nim check --hints:off $file" + errormsg: "type mismatch: got <BC>" + nimout: ''' +tenums.nim(32, 20) Error: type mismatch: got <Letters> +but expected one of: +proc takesChristmasColor(color: ChristmasColors) + first type mismatch at position: 1 + required type for color: ChristmasColors + but expression 'A' is of type: Letters + +expression: takesChristmasColor(A) +tenums.nim(33, 20) Error: type mismatch: got <BC> +but expected one of: +proc takesChristmasColor(color: ChristmasColors) + first type mismatch at position: 1 + required type for color: ChristmasColors + but expression 'BC(C)' is of type: BC + +expression: takesChristmasColor(BC(C)) +''' +""" + +type + Colors = enum Red, Green, Blue + ChristmasColors = range[Red .. Green] + Letters = enum A, B, C + BC = range[B .. C] + +proc takesChristmasColor(color: ChristmasColors) = discard +takesChristmasColor(Green) +takesChristmasColor(A) +takesChristmasColor(BC(C)) diff --git a/tests/range/texplicitvarconv.nim b/tests/range/texplicitvarconv.nim new file mode 100644 index 000000000..8da8a8878 --- /dev/null +++ b/tests/range/texplicitvarconv.nim @@ -0,0 +1,13 @@ +# related to issue #24032 + +proc `++`(n: var int) = + n += 1 + +type + r = range[ 0..15 ] + +var a: r = 14 + +++int(a) # this should be mutable + +doAssert a == 15 diff --git a/tests/range/toutofrangevarconv.nim b/tests/range/toutofrangevarconv.nim new file mode 100644 index 000000000..1ee4d340e --- /dev/null +++ b/tests/range/toutofrangevarconv.nim @@ -0,0 +1,14 @@ +discard """ + outputsub: "value out of range: 5 notin 0 .. 3 [RangeDefect]" + exitcode: "1" +""" + +# make sure out of bounds range conversion is detected for `var` conversions + +type R = range[0..3] + +proc foo(x: var R) = + doAssert x in 0..3 + +var x = 5 +foo(R(x)) diff --git a/tests/range/trange.nim b/tests/range/trange.nim new file mode 100644 index 000000000..abfa7d474 --- /dev/null +++ b/tests/range/trange.nim @@ -0,0 +1,156 @@ +discard """ + output: ''' +TSubRange: 5 from 1 to 10 +#FF3722 +''' +""" + + +block tbug499771: + type + TSubRange = range[1 .. 10] + TEnum = enum A, B, C + var sr: TSubRange = 5 + echo("TSubRange: " & $sr & " from " & $low(TSubRange) & " to " & + $high(TSubRange)) + + const cset = {A} + {B} + doAssert A in cset + doAssert B in cset + doAssert C notin cset + + + +include compilehelpers +block tmatrix3: + type + Matrix[M, N, T] = object + aij: array[M, array[N, T]] + + Matrix2[T] = Matrix[range[0..1], range[0..1], T] + + Matrix3[T] = Matrix[range[0..2], range[0..2], T] + + proc mn(x: Matrix): Matrix.T = x.aij[0][0] + + proc m2(x: Matrix2): Matrix2.T = x.aij[0][0] + + proc m3(x: Matrix3): auto = x.aij[0][0] + + var + matn: Matrix[range[0..3], range[0..2], int] + mat2: Matrix2[int] + mat3: Matrix3[float] + + doAssert m3(mat3) == 0.0 + doAssert mn(mat3) == 0.0 + doAssert m2(mat2) == 0 + doAssert mn(mat2) == 0 + doAssert mn(matn) == 0 + + reject m3(mat2) + reject m3(matn) + reject m2(mat3) + reject m2(matn) + + + +block tn8vsint16: + type + n32 = range[0..high(int)] + n8 = range[0'i8..high(int8)] + + proc `+`(a: n32, b: n32{nkIntLit}): n32 = discard + + proc `-`(a: n8, b: n8): n8 = n8(system.`-`(a, b)) + + var x, y: n8 + var z: int16 + + # ensure this doesn't call our '-' but system.`-` for int16: + doAssert z - n8(9) == -9 + + + +import strutils +block tcolors: + type TColor = distinct uint32 + + proc rgb(r, g, b: range[0..255]): TColor = + result = TColor(r or g shl 8 or b shl 16) + proc `$`(c: TColor): string = + result = "#" & toHex(uint32(c), 6) + echo rgb(34, 55, 255) + + block: + type + TColor = distinct uint32 + TColorComponent = distinct uint8 + + proc red(a: TColor): TColorComponent = + result = TColorComponent(uint32(a) and 0xff'u32) + proc green(a: TColor): TColorComponent = + result = TColorComponent(uint32(a) shr 8'u32 and 0xff'u32) + proc blue(a: TColor): TColorComponent = + result = TColorComponent(uint32(a) shr 16'u32 and 0xff'u32) + proc rgb(r, g, b: range[0..255]): TColor = + result = TColor(r or g shl 8 or b shl 8) + + proc `+!` (a, b: TColorComponent): TColorComponent = + ## saturated arithmetic: + result = TColorComponent(min(int(uint8(a)) + int(uint8(b)), 255)) + + proc `+` (a, b: TColor): TColor = + ## saturated arithmetic for colors makes sense, I think: + return rgb(int(red(a) +! red(b)), int(green(a) +! green(b)), int(blue(a) +! blue(b))) + + discard rgb(34, 55, 255) + +block: + type + R8 = range[0'u8 .. 10'u8] + R16 = range[0'u16 .. 10'u16] + R32 = range[0'u32 .. 10'u32] + + var + x1 = R8(4) + x2 = R16(4) + x3 = R32(4) + + doAssert $x1 & $x2 & $x3 == "444" + +block: + var x1: range[0'f..1'f] = 1 + const x2: range[0'f..1'f] = 1 + var x3: range[0'u8..1'u8] = 1 + const x4: range[0'u8..1'u8] = 1 + + var x5: range[0'f32..1'f32] = 1'f64 + const x6: range[0'f32..1'f32] = 1'f64 + + reject: + var x09: range[0'i8..1'i8] = 1.int + reject: + var x10: range[0'i64..1'i64] = 1'u64 + + const x11: range[0'f..1'f] = 2'f + reject: + const x12: range[0'f..1'f] = 2 + +# ensure unsigned array indexing is remains lenient: +var a: array[4'u, string] + +for i in 0..<a.len: + a[i] = "foo" + +# Check range to ordinal conversions +block: + var + a: int16 + b: range[0'i32..45'i32] = 3 + c: uint16 + d: range[0'u32..46'u32] = 3 + a = b + c = d + doAssert a == b + doAssert c == d diff --git a/tests/range/tsubrange.nim b/tests/range/tsubrange.nim new file mode 100644 index 000000000..f778c55eb --- /dev/null +++ b/tests/range/tsubrange.nim @@ -0,0 +1,20 @@ +discard """ + errormsg: "cannot convert 60 to TRange" + line: 20 +""" + +type + TRange = range[0..40] + +proc p(r: TRange) = + discard + +var + r: TRange + y = 50 +r = y + +p y + +const + myConst: TRange = 60 diff --git a/tests/range/tsubrange2.nim b/tests/range/tsubrange2.nim new file mode 100644 index 000000000..fbd1ca760 --- /dev/null +++ b/tests/range/tsubrange2.nim @@ -0,0 +1,15 @@ +discard """ + outputsub: "value out of range: 50 notin 0 .. 40 [RangeDefect]" + exitcode: "1" +""" + +type + TRange = range[0..40] + +proc p(r: TRange) = + discard + +var + r: TRange + y = 50 +p y diff --git a/tests/range/tsubrange3.nim b/tests/range/tsubrange3.nim new file mode 100644 index 000000000..55eb4618b --- /dev/null +++ b/tests/range/tsubrange3.nim @@ -0,0 +1,17 @@ +discard """ + outputsub: "value out of range: 50 notin 0 .. 40 [RangeDefect]" + exitcode: "1" +""" + +type + TRange = range[0..40] + +proc p(r: TRange) = + discard + +var + r: TRange + y = 50 +r = y + +#p y |