summary refs log tree commit diff stats
path: root/tests/array/tarray.nim
diff options
context:
space:
mode:
authorMiran <narimiran@users.noreply.github.com>2018-10-12 17:02:46 +0200
committerAndreas Rumpf <rumpf_a@web.de>2018-10-12 17:02:46 +0200
commit7f18d7cbc1fc8ad87c389b8d4d873e1d1169f794 (patch)
tree8c4839495fd6fc10376dc44cc8f9c7e3c625d18f /tests/array/tarray.nim
parentd2b04a8bc7a78845d25e8b789184ae54e98073ec (diff)
downloadNim-7f18d7cbc1fc8ad87c389b8d4d873e1d1169f794.tar.gz
Merge tests into a larger file (part 1 of ∞) (#9318)
* merge actiontable tests

* merge arithm tests

* merge array tests

* merge assign tests

* merge bind tests

* merge casestmt tests

* merge closure tests

* merge cnt seq tests

* merge collections tests

* merge concept issues tests

* merge concept tests

* fix failing tests

* smaller outputs

Use `doAssert` where possible.

* fix wrong output

* split `tcomputedgoto`

* revert merging concepts

* fix failing test
Diffstat (limited to 'tests/array/tarray.nim')
-rw-r--r--tests/array/tarray.nim576
1 files changed, 529 insertions, 47 deletions
diff --git a/tests/array/tarray.nim b/tests/array/tarray.nim
index 5e947e745..948e63a89 100644
--- a/tests/array/tarray.nim
+++ b/tests/array/tarray.nim
@@ -1,52 +1,534 @@
 discard """
   file: "tarray.nim"
-  output: "100124"
+  output:
+'''
+[4, 5, 6]
+
+[16, 25, 36]
+
+[16, 25, 36]
+
+apple
+banana
+Fruit
+2
+4
+3
+none
+skin
+paper
+@[2, 3, 4]321
+9.0 4.0
+3
+@[(Field0: 1, Field1: 2), (Field0: 3, Field1: 5)]
+2
+@["a", "new one", "c"]
+@[1, 2, 3]
+3
+dflfdjkl__abcdefgasfsgdfgsgdfggsdfasdfsafewfkljdsfajs
+dflfdjkl__abcdefgasfsgdfgsgdfggsdfasdfsafewfkljdsfajsdf
+kgdchlfniambejop
+fjpmholcibdgeakn
+'''
 """
-# simple check for one dimensional arrays
+
+block tarray:
+  type
+    TMyArray = array[0..2, int]
+    TMyRecord = tuple[x, y: int]
+    TObj = object
+      arr: TMyarray
+
+
+  proc sum(a: openarray[int]): int =
+    result = 0
+    var i = 0
+    while i < len(a):
+      inc(result, a[i])
+      inc(i)
+
+  proc getPos(r: TMyRecord): int =
+    result = r.x + r.y
+
+  doAssert sum([1, 2, 3, 4]) == 10
+  doAssert sum([]) == 0
+  doAssert getPos( (x: 5, y: 7) ) == 12
+
+  # bug #1669
+  let filesToCreate = ["tempdir/fl1.a", "tempdir/fl2.b",
+              "tempdir/tempdir2/fl3.e", "tempdir/tempdir2/tempdir3/fl4.f"]
+
+  var found: array[0..filesToCreate.high, bool]
+
+  doAssert found.len == 4
+
+  # make sure empty arrays are assignable (bug #6853)
+  const arr1: array[0, int] = []
+  const arr2 = []
+  let arr3: array[0, string] = []
+
+  doAssert(arr1.len == 0)
+  doAssert(arr2.len == 0)
+  doAssert(arr3.len == 0)
+
+  # Negative array length is not allowed (#6852)
+  doAssert(not compiles(block:
+    var arr: array[-1, int]))
+
+
+  proc mul(a, b: TMyarray): TMyArray =
+    result = a
+    for i in 0..len(a)-1:
+      result[i] = a[i] * b[i]
+
+  var
+    x, y: TMyArray
+    o: TObj
+
+  proc varArr1(x: var TMyArray): var TMyArray = x
+  proc varArr2(x: var TObj): var TMyArray = x.arr
+
+  x = [4, 5, 6]
+  echo repr(varArr1(x))
+
+  y = x
+  echo repr(mul(x, y))
+
+  o.arr = mul(x, y)
+  echo repr(varArr2(o))
+
+
+  const
+    myData = [[1,2,3], [4, 5, 6]]
+
+  doAssert myData[0][2] == 3
+
+
+
+block tarraycons:
+  type
+    TEnum = enum
+      eA, eB, eC, eD, eE, eF
+
+  const
+    myMapping: array[TEnum, array[0..1, int]] = [
+      eA: [1, 2],
+      eB: [3, 4],
+      [5, 6],
+      eD: [0: 8, 1: 9],
+      eE: [0: 8, 9],
+      eF: [2, 1: 9]
+    ]
+
+  doAssert myMapping[eC][1] == 6
+
+
+
+block tarraycons_ptr_generic:
+  type
+    Fruit = object of RootObj
+      name: string
+    Apple = object of Fruit
+    Banana = object of Fruit
+
+  var
+    ir = Fruit(name: "Fruit")
+    ia = Apple(name: "apple")
+    ib = Banana(name: "banana")
+
+  let x = [ia.addr, ib.addr, ir.addr]
+  for c in x: echo c.name
+
+  type
+    Vehicle[T] = object of RootObj
+      tire: T
+    Car[T] = object of Vehicle[T]
+    Bike[T] = object of Vehicle[T]
+
+  var v = Vehicle[int](tire: 3)
+  var c = Car[int](tire: 4)
+  var b = Bike[int](tire: 2)
+
+  let y = [b.addr, c.addr, v.addr]
+  for c in y: echo c.tire
+
+  type
+    Book[T] = ref object of RootObj
+      cover: T
+    Hard[T] = ref object of Book[T]
+    Soft[T] = ref object of Book[T]
+
+  var bn = Book[string](cover: "none")
+  var hs = Hard[string](cover: "skin")
+  var bp = Soft[string](cover: "paper")
+
+  let z = [bn, hs, bp]
+  for c in z: echo c.cover
+
+
+
+block tarraylen:
+  var a: array[0, int]
+  doAssert a.len == 0
+  doAssert array[0..0, int].len == 1
+  doAssert array[0..0, int]([1]).len == 1
+  doAssert array[1..1, int].len == 1
+  doAssert array[1..1, int]([1]).len == 1
+  doAssert array[2, int].len == 2
+  doAssert array[2, int]([1, 2]).len == 2
+  doAssert array[1..3, int].len == 3
+  doAssert array[1..3, int]([1, 2, 3]).len == 3
+  doAssert array[0..2, int].len == 3
+  doAssert array[0..2, int]([1, 2, 3]).len == 3
+  doAssert array[-2 .. -2, int].len == 1
+  doAssert([1, 2, 3].len == 3)
+  doAssert([42].len == 1)
+
+
+
+
+type ustring = distinct string
+converter toUString(s: string): ustring = ustring(s)
+
+block tarrayindx:
+  proc putEnv(key, val: string) =
+    # XXX: we have to leak memory here, as we cannot
+    # free it before the program ends (says Borland's
+    # documentation)
+    var
+      env: ptr array[0..500000, char]
+    env = cast[ptr array[0..500000, char]](alloc(len(key) + len(val) + 2))
+    for i in 0..len(key)-1: env[i] = key[i]
+    env[len(key)] = '='
+    for i in 0..len(val)-1:
+      env[len(key)+1+i] = val[i]
+
+  # bug #7153
+  const
+    UnsignedConst = 1024'u
+  type
+    SomeObject = object
+      s1: array[UnsignedConst, uint32]
+
+  var
+    obj: SomeObject
+
+  doAssert obj.s1[0] == 0
+  doAssert obj.s1[0u] == 0
+
+  # bug #8049
+  proc `[]`(s: ustring, i: int): ustring = s
+  doAssert "abcdefgh"[1..2] == "bc"
+  doAssert "abcdefgh"[1..^2] == "bcdefg"
+
+
+
+block troof:
+  proc foo[T](x, y: T): T = x
+
+  var a = @[1, 2, 3, 4]
+  var b: array[3, array[2, float]] = [[1.0,2], [3.0,4], [8.0,9]]
+  echo a[1.. ^1], a[^2], a[^3], a[^4]
+  echo b[^1][^1], " ", (b[^2]).foo(b[^1])[^1]
+
+  b[^1] = [8.8, 8.9]
+
+  var c: seq[(int, int)] = @[(1,2), (3,4)]
+
+  proc takeA(x: ptr int) = echo x[]
+
+  takeA(addr c[^1][0])
+  c[^1][1] = 5
+  echo c
+
+  proc useOpenarray(x: openArray[int]) =
+    echo x[^2]
+
+  proc mutOpenarray(x: var openArray[string]) =
+    x[^2] = "new one"
+
+  useOpenarray([1, 2, 3])
+
+  var z = @["a", "b", "c"]
+  mutOpenarray(z)
+  echo z
+
+  # bug #6675
+  var y: array[1..5, int] = [1,2,3,4,5]
+  y[3..5] = [1, 2, 3]
+  echo y[3..5]
+
+
+  var d: array['a'..'c', string] = ["a", "b", "c"]
+  doAssert d[^1] == "c"
+
+
+
+
+import strutils, sequtils, typetraits, os
 
 type
-  TMyArray = array[0..2, int]
-  TMyRecord = tuple[x, y: int]
-
-proc sum(a: TMyarray): int =
-  result = 0
-  var i = 0
-  while i < len(a):
-    inc(result, a[i])
-    inc(i)
-
-proc sum(a: openarray[int]): int =
-  result = 0
-  var i = 0
-  while i < len(a):
-    inc(result, a[i])
-    inc(i)
-
-proc getPos(r: TMyRecord): int =
-  result = r.x + r.y
-
-write(stdout, sum([1, 2, 3, 4]))
-write(stdout, sum([]))
-write(stdout, getPos( (x: 5, y: 7) ))
-#OUT 10012
-
-# bug #1669
-let filesToCreate = ["tempdir/fl1.a", "tempdir/fl2.b",
-            "tempdir/tempdir2/fl3.e", "tempdir/tempdir2/tempdir3/fl4.f"]
-
-var found: array[0..filesToCreate.high, bool]
-
-echo found.len
-
-# make sure empty arrays are assignable (bug #6853)
-const arr1: array[0, int] = []
-const arr2 = []
-let arr3: array[0, string] = []
-
-doAssert(arr1.len == 0)
-doAssert(arr2.len == 0)
-doAssert(arr3.len == 0)
-
-# Negative array length is not allowed (#6852)
-doAssert(not compiles(block:
-  var arr: array[-1, int]))
\ No newline at end of file
+  MetadataArray* = object
+    data*: array[8, int]
+    len*: int
+
+# Commenting the converter removes the error "lib/system.nim(3536, 3) Error: for a 'var' type a variable needs to be passed"
+converter toMetadataArray*(se: varargs[int]): MetadataArray {.inline.} =
+  result.len = se.len
+  for i in 0..<se.len:
+    result.data[i] = se[i]
+
+
+block troofregression:
+  when NimVersion >= "0.17.3":
+    type Index = int or BackwardsIndex
+    template `^^`(s, i: untyped): untyped =
+      when i is BackwardsIndex:
+        s.len - int(i)
+      else: i
+  else:
+    type Index = int
+    template `^^`(s, i: untyped): untyped =
+      i
+
+  ## With Nim devel from the start of the week (~Oct30) I managed to trigger "lib/system.nim(3536, 4) Error: expression has no address"
+  ## but I can't anymore after updating Nim (Nov5)
+  ## Now commenting this plain compiles and removes the error "lib/system.nim(3536, 3) Error: for a 'var' type a variable needs to be passed"
+  proc `[]`(a: var MetadataArray, idx: Index): var int {.inline.} =
+    a.data[a ^^ idx]
+
+
+  ##############################
+  ### Completely unrelated lib that triggers the issue
+
+  type
+    MySeq[T] = ref object
+      data: seq[T]
+
+  proc test[T](sx: MySeq[T]) =
+    # Removing the backward index removes the error "lib/system.nim(3536, 3) Error: for a 'var' type a variable needs to be passed"
+    echo sx.data[^1] # error here
+
+  let s = MySeq[int](data: @[1, 2, 3])
+  s.test()
+
+
+  # bug #6989
+
+  type Dist = distinct int
+
+  proc mypred[T: Ordinal](x: T): T = T(int(x)-1)
+  proc cons(x: int): Dist = Dist(x)
+
+  var d: Dist
+
+  template `^+`(s, i: untyped): untyped =
+    (when i is BackwardsIndex: s.len - int(i) else: int(i))
+
+  proc `...`[T, U](a: T, b: U): HSlice[T, U] =
+    result.a = a
+    result.b = b
+
+  proc `...`[T](b: T): HSlice[int, T] =
+    result.b = b
+
+  template `...<`(a, b: untyped): untyped =
+    ## a shortcut for 'a..pred(b)'.
+    a ... pred(b)
+
+  template check(a, b) =
+    if $a != b:
+      echo "Failure ", a, " != ", b
+
+  check type(4 ...< 1), "HSlice[system.int, system.int]"
+  check type(4 ...< ^1), "HSlice[system.int, system.BackwardsIndex]"
+  check type(4 ... pred(^1)), "HSlice[system.int, system.BackwardsIndex]"
+  check type(4 ... mypred(8)), "HSlice[system.int, system.int]"
+  check type(4 ... mypred(^1)), "HSlice[system.int, system.BackwardsIndex]"
+
+  var rot = 8
+
+  proc bug(s: string): string =
+    result = s
+    result = result[result.len - rot .. ^1] & "__" & result[0 ..< ^rot]
+
+  const testStr = "abcdefgasfsgdfgsgdfggsdfasdfsafewfkljdsfajsdflfdjkl"
+
+  echo bug(testStr)
+  echo testStr[testStr.len - 8 .. testStr.len - 1] & "__" & testStr[0 .. testStr.len - pred(rot)]
+
+  var
+    instructions = readFile(getAppDir() / "troofregression2.txt").split(',')
+    programs = "abcdefghijklmnop"
+
+  proc dance(dancers: string): string =
+    result = dancers
+    for instr in instructions:
+      let rem = instr[1 .. instr.high]
+      case instr[0]
+      of 's':
+        let rot = rem.parseInt
+        result = result[result.len - rot .. ^1] & result[0 ..< ^rot]
+      of 'x':
+        let
+          x = rem.split('/')
+          a = x[0].parseInt
+          b = x[1].parseInt
+        swap(result[a], result[b])
+      of 'p':
+        let
+          a = result.find(rem[0])
+          b = result.find(rem[^1])
+        result[a] = rem[^1]
+        result[b] = rem[0]
+      else: discard
+
+  proc longDance(dancers: string, iterations = 1_000_000_000): string =
+    var
+      dancers = dancers
+      seen = @[dancers]
+    for i in 1 .. iterations:
+      dancers = dancers.dance()
+      if dancers in seen:
+        return seen[iterations mod i]
+      seen.add(dancers)
+
+  echo dance(programs)
+  echo longDance(programs)
+
+
+
+block tunchecked:
+  {.boundchecks: on.}
+  type Unchecked {.unchecked.} = array[0, char]
+
+  var x = cast[ptr Unchecked](alloc(100))
+  x[5] = 'x'
+
+
+
+import macros
+block t7818:
+  # bug #7818
+  # this is not a macro bug, but array construction bug
+  # I use macro to avoid object slicing
+  # see #7712 and #7637
+
+  type
+    Vehicle[T] = object of RootObj
+      tire: T
+    Car[T] = object of Vehicle[T]
+    Bike[T] = object of Vehicle[T]
+
+  macro peek(n: typed): untyped =
+    let val = getTypeImpl(n).treeRepr
+    newLit(val)
+
+  block test_t7818:
+    var v = Vehicle[int](tire: 3)
+    var c = Car[int](tire: 4)
+    var b = Bike[int](tire: 2)
+
+    let y = peek([c, b, v])
+    let z = peek([v, c, b])
+    doAssert(y == z)
+
+  block test_t7906_1:
+    proc init(x: typedesc, y: int): ref x =
+      result = new(ref x)
+      result.tire = y
+
+    var v = init(Vehicle[int], 3)
+    var c = init(Car[int], 4)
+    var b = init(Bike[int], 2)
+
+    let y = peek([c, b, v])
+    let z = peek([v, c, b])
+    doAssert(y == z)
+
+  block test_t7906_2:
+    var v = Vehicle[int](tire: 3)
+    var c = Car[int](tire: 4)
+    var b = Bike[int](tire: 2)
+
+    let y = peek([c.addr, b.addr, v.addr])
+    let z = peek([v.addr, c.addr, b.addr])
+    doAssert(y == z)
+
+  block test_t7906_3:
+    type
+      Animal[T] = object of RootObj
+        hair: T
+      Mammal[T] = object of Animal[T]
+      Monkey[T] = object of Mammal[T]
+
+    var v = Animal[int](hair: 3)
+    var c = Mammal[int](hair: 4)
+    var b = Monkey[int](hair: 2)
+
+    let z = peek([c.addr, b.addr, v.addr])
+    let y = peek([v.addr, c.addr, b.addr])
+    doAssert(y == z)
+
+  type
+    Fruit[T] = ref object of RootObj
+      color: T
+    Apple[T] = ref object of Fruit[T]
+    Banana[T] = ref object of Fruit[T]
+
+  proc testArray[T](x: array[3, Fruit[T]]): string =
+    result = ""
+    for c in x:
+      result.add $c.color
+
+  proc testOpenArray[T](x: openArray[Fruit[T]]): string =
+    result = ""
+    for c in x:
+      result.add $c.color
+
+  block test_t7906_4:
+    var v = Fruit[int](color: 3)
+    var c = Apple[int](color: 4)
+    var b = Banana[int](color: 2)
+
+    let y = peek([c, b, v])
+    let z = peek([v, c, b])
+    doAssert(y == z)
+
+  block test_t7906_5:
+    var a = Fruit[int](color: 1)
+    var b = Apple[int](color: 2)
+    var c = Banana[int](color: 3)
+
+    doAssert(testArray([a, b, c]) == "123")
+    doAssert(testArray([b, c, a]) == "231")
+
+    doAssert(testOpenArray([a, b, c]) == "123")
+    doAssert(testOpenArray([b, c, a]) == "231")
+
+    doAssert(testOpenArray(@[a, b, c]) == "123")
+    doAssert(testOpenArray(@[b, c, a]) == "231")
+
+  proc testArray[T](x: array[3, ptr Vehicle[T]]): string =
+    result = ""
+    for c in x:
+      result.add $c.tire
+
+  proc testOpenArray[T](x: openArray[ptr Vehicle[T]]): string =
+    result = ""
+    for c in x:
+      result.add $c.tire
+
+  block test_t7906_6:
+    var u = Vehicle[int](tire: 1)
+    var v = Bike[int](tire: 2)
+    var w = Car[int](tire: 3)
+
+    doAssert(testArray([u.addr, v.addr, w.addr]) == "123")
+    doAssert(testArray([w.addr, u.addr, v.addr]) == "312")
+
+    doAssert(testOpenArray([u.addr, v.addr, w.addr]) == "123")
+    doAssert(testOpenArray([w.addr, u.addr, v.addr]) == "312")
+
+    doAssert(testOpenArray(@[u.addr, v.addr, w.addr]) == "123")
+    doAssert(testOpenArray(@[w.addr, u.addr, v.addr]) == "312")