discard """ targets: "c js" """ # xxx move all tests under `main` import std/sequtils import strutils from algorithm import sorted {.experimental: "strictEffects".} {.push warningAsError[Effect]: on.} {.experimental: "strictFuncs".} # helper for testing double substitution side effects which are handled # by `evalOnceAs` var counter = 0 proc identity[T](a: T): auto = counter.inc a block: # concat test let s1 = @[1, 2, 3] s2 = @[4, 5] s3 = @[6, 7] total = concat(s1, s2, s3) doAssert total == @[1, 2, 3, 4, 5, 6, 7] block: # count test let s1 = @[1, 2, 3, 2] s2 = @['a', 'b', 'x', 'a'] a1 = [1, 2, 3, 2] a2 = ['a', 'b', 'x', 'a'] r0 = count(s1, 0) r1 = count(s1, 1) r2 = count(s1, 2) r3 = count(s2, 'y') r4 = count(s2, 'x') r5 = count(s2, 'a') ar0 = count(a1, 0) ar1 = count(a1, 1) ar2 = count(a1, 2) ar3 = count(a2, 'y') ar4 = count(a2, 'x') ar5 = count(a2, 'a') doAssert r0 == 0 doAssert r1 == 1 doAssert r2 == 2 doAssert r3 == 0 doAssert r4 == 1 doAssert r5 == 2 doAssert ar0 == 0 doAssert ar1 == 1 doAssert ar2 == 2 doAssert ar3 == 0 doAssert ar4 == 1 doAssert ar5 == 2 block: # cycle tests let a = @[1, 2, 3] b: seq[int] = @[] c = [1, 2, 3] doAssert a.cycle(3) == @[1, 2, 3, 1, 2, 3, 1, 2, 3] doAssert a.cycle(0) == @[] #doAssert a.cycle(-1) == @[] # will not compile! doAssert b.cycle(3) == @[] doAssert c.cycle(3) == @[1, 2, 3, 1, 2, 3, 1, 2, 3] doAssert c.cycle(0) == @[] block: # repeat tests doAssert repeat(10, 5) == @[10, 10, 10, 10, 10] doAssert repeat(@[1, 2, 3], 2) == @[@[1, 2, 3], @[1, 2, 3]] doAssert repeat([1, 2, 3], 2) == @[[1, 2, 3], [1, 2, 3]] block: # deduplicates test let dup1 = @[1, 1, 3, 4, 2, 2, 8, 1, 4] dup2 = @["a", "a", "c", "d", "d"] dup3 = [1, 1, 3, 4, 2, 2, 8, 1, 4] dup4 = ["a", "a", "c", "d", "d"] unique1 = deduplicate(dup1) unique2 = deduplicate(dup2) unique3 = deduplicate(dup3) unique4 = deduplicate(dup4) unique5 = deduplicate(dup1.sorted, true) unique6 = deduplicate(dup2, true) unique7 = deduplicate(dup3.sorted, true) unique8 = deduplicate(dup4, true) doAssert unique1 == @[1, 3, 4, 2, 8] doAssert unique2 == @["a", "c", "d"] doAssert unique3 == @[1, 3, 4, 2, 8] doAssert unique4 == @["a", "c", "d"] doAssert unique5 == @[1, 2, 3, 4, 8] doAssert unique6 == @["a", "c", "d"] doAssert unique7 == @[1, 2, 3, 4, 8] doAssert unique8 == @["a", "c", "d"] block: # zip test let short = @[1, 2, 3] long = @[6, 5, 4, 3, 2, 1] words = @["one", "two", "three"] ashort = [1, 2, 3] along = [6, 5, 4, 3, 2, 1] awords = ["one", "two", "three"] zip1 = zip(short, long) zip2 = zip(short, words) zip3 = zip(ashort, along) doAssert zip1 == @[(1, 6), (2, 5), (3, 4)] doAssert zip2 == @[(1, "one"), (2, "two"), (3, "three")] doAssert zip3 == @[(1, 6), (2, 5), (3, 4)] doAssert zip1[2][1] == 4 doAssert zip2[2][1] == "three" doAssert zip3[2][1] == 4 when (NimMajor, NimMinor) <= (1, 0): let # In Nim 1.0.x and older, zip returned a seq of tuple strictly # with fields named "a" and "b". zipAb = zip(ashort, awords) doAssert zipAb == @[(a: 1, b: "one"), (2, "two"), (3, "three")] doAssert zipAb[2].b == "three" else: let # As zip returns seq of anonymous tuples, they can be assigned # to any variable that's a sequence of named tuples too. zipXy: seq[tuple[x: int, y: string]] = zip(ashort, awords) zipMn: seq[tuple[m: int, n: string]] = zip(ashort, words) doAssert zipXy == @[(x: 1, y: "one"), (2, "two"), (3, "three")] doAssert zipMn == @[(m: 1, n: "one"), (2, "two"), (3, "three")] doAssert zipXy[2].y == "three" doAssert zipMn[2].n == "three" block: # distribute tests let numbers = @[1, 2, 3, 4, 5, 6, 7] doAssert numbers.distribute(3) == @[@[1, 2, 3], @[4, 5], @[6, 7]] doAssert numbers.distribute(6)[0] == @[1, 2] doAssert numbers.distribute(6)[5] == @[7] let a = @[1, 2, 3, 4, 5, 6, 7] doAssert a.distribute(1, true) == @[@[1, 2, 3, 4, 5, 6, 7]] doAssert a.distribute(1, false) == @[@[1, 2, 3, 4, 5, 6, 7]] doAssert a.distribute(2, true) == @[@[1, 2, 3, 4], @[5, 6, 7]] doAssert a.distribute(2, false) == @[@[1, 2, 3, 4], @[5, 6, 7]] doAssert a.distribute(3, true) == @[@[1, 2, 3], @[4, 5], @[6, 7]] doAssert a.distribute(3, false) == @[@[1, 2, 3], @[4, 5, 6], @[7]] doAssert a.distribute(4, true) == @[@[1, 2], @[3, 4], @[5, 6], @[7]] doAssert a.distribute(4, false) == @[@[1, 2], @[3, 4], @[5, 6], @[7]] doAssert a.distribute(5, true) == @[@[1, 2], @[3, 4], @[5], @[6], @[7]] doAssert a.distribute(5, false) == @[@[1, 2], @[3, 4], @[5, 6], @[7], @[]] doAssert a.distribute(6, true) == @[@[1, 2], @[3], @[4], @[5], @[6], @[7]] doAssert a.distribute(6, false) == @[ @[1, 2], @[3, 4], @[5, 6], @[7], @[], @[]] doAssert a.distribute(8, false) == a.distribute(8, true) doAssert a.distribute(90, false) == a.distribute(90, true) var b = @[0] for f in 1 .. 25: b.add(f) doAssert b.distribute(5, true)[4].len == 5 doAssert b.distribute(5, false)[4].len == 2 block: # map test let numbers = @[1, 4, 5, 8, 9, 7, 4] anumbers = [1, 4, 5, 8, 9, 7, 4] m1 = map(numbers, proc(x: int): int = 2*x) m2 = map(anumbers, proc(x: int): int = 2*x) doAssert m1 == @[2, 8, 10, 16, 18, 14, 8] doAssert m2 == @[2, 8, 10, 16, 18, 14, 8] block: # apply test var a = @["1", "2", "3", "4"] apply(a, proc(x: var string) = x &= "42") doAssert a == @["142", "242", "342", "442"] block: # filter proc test let colors = @["red", "yellow", "black"] acolors = ["red", "yellow", "black"] f1 = filter(colors, proc(x: string): bool = x.len < 6) f2 = filter(colors) do (x: string) -> bool: x.len > 5 f3 = filter(acolors, proc(x: string): bool = x.len < 6) f4 = filter(acolors) do (x: string) -> bool: x.len > 5 doAssert f1 == @["red", "black"] doAssert f2 == @["yellow"] doAssert f3 == @["red", "black"] doAssert f4 == @["yellow"] block: # filter iterator test let numbers = @[1, 4, 5, 8, 9, 7, 4] let anumbers = [1, 4, 5, 8, 9, 7, 4] doAssert toSeq(filter(numbers, proc (x: int): bool = x mod 2 == 0)) == @[4, 8, 4] doAssert toSeq(filter(anumbers, proc (x: int): bool = x mod 2 == 0)) == @[4, 8, 4] block: # keepIf test var floats = @[13.0, 12.5, 5.8, 2.0, 6.1, 9.9, 10.1] keepIf(floats, proc(x: float): bool = x > 10) doAssert floats == @[13.0, 12.5, 10.1] block: # insert tests var dest = @[1, 1, 1, 1, 1, 1, 1, 1] let src = @[2, 2, 2, 2, 2, 2] outcome = @[1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1] dest.insert(src, 3) doAssert dest == outcome, """\ Inserting [2,2,2,2,2,2] into [1,1,1,1,1,1,1,1] at 3 is [1,1,1,2,2,2,2,2,2,1,1,1,1,1]""" block: # filterIt test let temperatures = @[-272.15, -2.0, 24.5, 44.31, 99.9, -113.44] acceptable = filterIt(temperatures, it < 50 and it > -10) notAcceptable = filterIt(temperatures, it > 50 or it < -10) doAssert acceptable == @[-2.0, 24.5, 44.31] doAssert notAcceptable == @[-272.15, 99.9, -113.44] block: # keepItIf test var candidates = @["foo", "bar", "baz", "foobar"] keepItIf(candidates, it.len == 3 and it[0] == 'b') doAssert candidates == @["bar", "baz"] block: # all let numbers = @[1, 4, 5, 8, 9, 7, 4] anumbers = [1, 4, 5, 8, 9, 7, 4] len0seq: seq[int] = @[] doAssert all(numbers, proc (x: int): bool = return x < 10) == true doAssert all(numbers, proc (x: int): bool = return x < 9) == false doAssert all(len0seq, proc (x: int): bool = return false) == true doAssert all(anumbers, proc (x: int): bool = return x < 10) == true doAssert all(anumbers, proc (x: int): bool = return x < 9) == false block: # allIt let numbers = @[1, 4, 5, 8, 9, 7, 4] anumbers = [1, 4, 5, 8, 9, 7, 4] len0seq: seq[int] = @[] doAssert allIt(numbers, it < 10) == true doAssert allIt(numbers, it < 9) == false doAssert allIt(len0seq, false) == true doAssert allIt(anumbers, it < 10) == true doAssert allIt(anumbers, it < 9) == false block: # any let numbers = @[1, 4, 5, 8, 9, 7, 4] anumbers = [1, 4, 5, 8, 9, 7, 4] len0seq: seq[int] = @[] doAssert any(numbers, proc (x: int): bool = return x > 8) == true doAssert any(numbers, proc (x: int): bool = return x > 9) == false doAssert any(len0seq, proc (x: int): bool = return true) == false doAssert any(anumbers, proc (x: int): bool = return x > 8) == true doAssert any(anumbers, proc (x: int): bool = return x > 9) == false block: # anyIt let numbers = @[1, 4, 5, 8, 9, 7, 4] anumbers = [1, 4, 5, 8, 9, 7, 4] len0seq: seq[int] = @[] doAssert anyIt(numbers, it > 8) == true doAssert anyIt(numbers, it > 9) == false doAssert anyIt(len0seq, true) == false doAssert anyIt(anumbers, it > 8) == true doAssert anyIt(anumbers, it > 9) == false block: # toSeq test block: let numeric = @[1, 2, 3, 4, 5, 6, 7, 8, 9] oddNumbers = toSeq(filter(numeric) do (x: int) -> bool: if x mod 2 == 1: result = true) doAssert oddNumbers == @[1, 3, 5, 7, 9] block: doAssert [1, 2].toSeq == @[1, 2] doAssert @[1, 2].toSeq == @[1, 2] doAssert @[1, 2].toSeq == @[1, 2] doAssert toSeq(@[1, 2]) == @[1, 2] block: iterator myIter(seed: int): auto = for i in 0..