summary refs log tree commit diff stats
path: root/tests/range
diff options
context:
space:
mode:
Diffstat (limited to 'tests/range')
-rw-r--r--tests/range/compilehelpers.nim5
-rw-r--r--tests/range/t19678.nim17
-rw-r--r--tests/range/tcompiletime_range_checks.nim52
-rw-r--r--tests/range/tenums.nim33
-rw-r--r--tests/range/texplicitvarconv.nim13
-rw-r--r--tests/range/toutofrangevarconv.nim14
-rw-r--r--tests/range/trange.nim156
-rw-r--r--tests/range/tsubrange.nim20
-rw-r--r--tests/range/tsubrange2.nim15
-rw-r--r--tests/range/tsubrange3.nim17
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