mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
72ab6feb2f
* fix #4889 * test * move test from 'control_flow' to 'ranges' * More range tests
244 lines
5.7 KiB
CoffeeScript
244 lines
5.7 KiB
CoffeeScript
# Range Literals
|
|
# --------------
|
|
|
|
# TODO: add indexing and method invocation tests: [1..4][0] is 1, [0...3].toString()
|
|
|
|
# shared array
|
|
shared = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
|
|
|
test "basic inclusive ranges", ->
|
|
arrayEq [1, 2, 3] , [1..3]
|
|
arrayEq [0, 1, 2] , [0..2]
|
|
arrayEq [0, 1] , [0..1]
|
|
arrayEq [0] , [0..0]
|
|
arrayEq [-1] , [-1..-1]
|
|
arrayEq [-1, 0] , [-1..0]
|
|
arrayEq [-1, 0, 1], [-1..1]
|
|
|
|
test "basic exclusive ranges", ->
|
|
arrayEq [1, 2, 3] , [1...4]
|
|
arrayEq [0, 1, 2] , [0...3]
|
|
arrayEq [0, 1] , [0...2]
|
|
arrayEq [0] , [0...1]
|
|
arrayEq [-1] , [-1...0]
|
|
arrayEq [-1, 0] , [-1...1]
|
|
arrayEq [-1, 0, 1], [-1...2]
|
|
|
|
arrayEq [], [1...1]
|
|
arrayEq [], [0...0]
|
|
arrayEq [], [-1...-1]
|
|
|
|
# Should not trigger implicit call, e.g. rest ... => rest(...)
|
|
arrayEq [1, 2, 3] , [1 ... 4]
|
|
arrayEq [0, 1, 2] , [0 ... 3]
|
|
arrayEq [0, 1] , [0 ... 2]
|
|
arrayEq [0] , [0 ... 1]
|
|
arrayEq [-1] , [-1 ... 0]
|
|
arrayEq [-1, 0] , [-1 ... 1]
|
|
arrayEq [-1, 0, 1], [-1 ... 2]
|
|
|
|
arrayEq [], [1 ... 1]
|
|
arrayEq [], [0 ... 0]
|
|
arrayEq [], [-1 ... -1]
|
|
|
|
test "downward ranges", ->
|
|
arrayEq shared, [9..0].reverse()
|
|
arrayEq [5, 4, 3, 2] , [5..2]
|
|
arrayEq [2, 1, 0, -1], [2..-1]
|
|
|
|
arrayEq [3, 2, 1] , [3..1]
|
|
arrayEq [2, 1, 0] , [2..0]
|
|
arrayEq [1, 0] , [1..0]
|
|
arrayEq [0] , [0..0]
|
|
arrayEq [-1] , [-1..-1]
|
|
arrayEq [0, -1] , [0..-1]
|
|
arrayEq [1, 0, -1] , [1..-1]
|
|
arrayEq [0, -1, -2], [0..-2]
|
|
|
|
arrayEq [4, 3, 2], [4...1]
|
|
arrayEq [3, 2, 1], [3...0]
|
|
arrayEq [2, 1] , [2...0]
|
|
arrayEq [1] , [1...0]
|
|
arrayEq [] , [0...0]
|
|
arrayEq [] , [-1...-1]
|
|
arrayEq [0] , [0...-1]
|
|
arrayEq [0, -1] , [0...-2]
|
|
arrayEq [1, 0] , [1...-1]
|
|
arrayEq [2, 1, 0], [2...-1]
|
|
|
|
test "ranges with variables as enpoints", ->
|
|
[a, b] = [1, 3]
|
|
arrayEq [1, 2, 3], [a..b]
|
|
arrayEq [1, 2] , [a...b]
|
|
b = -2
|
|
arrayEq [1, 0, -1, -2], [a..b]
|
|
arrayEq [1, 0, -1] , [a...b]
|
|
|
|
test "ranges with expressions as endpoints", ->
|
|
[a, b] = [1, 3]
|
|
arrayEq [2, 3, 4, 5, 6], [(a+1)..2*b]
|
|
arrayEq [2, 3, 4, 5] , [(a+1)...2*b]
|
|
|
|
# Should not trigger implicit call, e.g. rest ... => rest(...)
|
|
arrayEq [2, 3, 4, 5] , [(a+1) ... 2*b]
|
|
|
|
test "large ranges are generated with looping constructs", ->
|
|
down = [99..0]
|
|
eq 100, (len = down.length)
|
|
eq 0, down[len - 1]
|
|
|
|
up = [0...100]
|
|
eq 100, (len = up.length)
|
|
eq 99, up[len - 1]
|
|
|
|
test "for-from loops over ranges", ->
|
|
array1 = []
|
|
for x from [20..30]
|
|
array1.push(x)
|
|
break if x is 25
|
|
arrayEq array1, [20, 21, 22, 23, 24, 25]
|
|
|
|
test "for-from comprehensions over ranges", ->
|
|
array1 = (x + 10 for x from [20..25])
|
|
ok array1.join(' ') is '30 31 32 33 34 35'
|
|
|
|
array2 = (x for x from [20..30] when x %% 2 == 0)
|
|
ok array2.join(' ') is '20 22 24 26 28 30'
|
|
|
|
test "#1012 slices with arguments object", ->
|
|
expected = [0..9]
|
|
argsAtStart = (-> [arguments[0]..9]) 0
|
|
arrayEq expected, argsAtStart
|
|
argsAtEnd = (-> [0..arguments[0]]) 9
|
|
arrayEq expected, argsAtEnd
|
|
argsAtBoth = (-> [arguments[0]..arguments[1]]) 0, 9
|
|
arrayEq expected, argsAtBoth
|
|
|
|
test "#1409: creating large ranges outside of a function body", ->
|
|
CoffeeScript.eval '[0..100]'
|
|
|
|
test "#2047: Infinite loop possible when `for` loop with `range` uses variables", ->
|
|
up = 1
|
|
down = -1
|
|
a = 1
|
|
b = 5
|
|
|
|
testRange = (arg) ->
|
|
[from, to, step, expectedResult] = arg
|
|
r = (x for x in [from..to] by step)
|
|
arrayEq r, expectedResult
|
|
|
|
testData = [
|
|
[1, 5, 1, [1..5]]
|
|
[1, 5, -1, []]
|
|
[1, 5, up, [1..5]]
|
|
[1, 5, down, []]
|
|
|
|
[a, 5, 1, [1..5]]
|
|
[a, 5, -1, []]
|
|
[a, 5, up, [1..5]]
|
|
[a, 5, down, []]
|
|
|
|
[1, b, 1, [1..5]]
|
|
[1, b, -1, []]
|
|
[1, b, up, [1..5]]
|
|
[1, b, down, []]
|
|
|
|
[a, b, 1, [1..5]]
|
|
[a, b, -1, []]
|
|
[a, b, up, [1..5]]
|
|
[a, b, down, []]
|
|
|
|
[5, 1, 1, []]
|
|
[5, 1, -1, [5..1]]
|
|
[5, 1, up, []]
|
|
[5, 1, down, [5..1]]
|
|
|
|
[5, a, 1, []]
|
|
[5, a, -1, [5..1]]
|
|
[5, a, up, []]
|
|
[5, a, down, [5..1]]
|
|
|
|
[b, 1, 1, []]
|
|
[b, 1, -1, [5..1]]
|
|
[b, 1, up, []]
|
|
[b, 1, down, [5..1]]
|
|
|
|
[b, a, 1, []]
|
|
[b, a, -1, [5..1]]
|
|
[b, a, up, []]
|
|
[b, a, down, [5..1]]
|
|
]
|
|
|
|
testRange d for d in testData
|
|
|
|
test "#2047: from, to and step as variables", ->
|
|
up = 1
|
|
down = -1
|
|
a = 1
|
|
b = 5
|
|
|
|
r = (x for x in [a..b] by up)
|
|
arrayEq r, [1..5]
|
|
|
|
r = (x for x in [a..b] by down)
|
|
arrayEq r, []
|
|
|
|
r = (x for x in [b..a] by up)
|
|
arrayEq r, []
|
|
|
|
r = (x for x in [b..a] by down)
|
|
arrayEq r, [5..1]
|
|
|
|
a = 1
|
|
b = -1
|
|
step = 0
|
|
r = (x for x in [b..a] by step)
|
|
arrayEq r, []
|
|
|
|
test "#4884: Range not declaring var for the 'i'", ->
|
|
'use strict'
|
|
[0..21].forEach (idx) ->
|
|
idx + 1
|
|
|
|
eq global.i, undefined
|
|
|
|
test "#4889: `for` loop unexpected behavior", ->
|
|
n = 1
|
|
result = []
|
|
for i in [0..n]
|
|
result.push i
|
|
for j in [(i+1)..n]
|
|
result.push j
|
|
|
|
arrayEq result, [0,1,1,2,1]
|
|
|
|
test "#4889: `for` loop unexpected behavior with `by 1` on second loop", ->
|
|
n = 1
|
|
result = []
|
|
for i in [0..n]
|
|
result.push i
|
|
for j in [(i+1)..n] by 1
|
|
result.push j
|
|
|
|
arrayEq result, [0,1,1]
|
|
|
|
test "countdown example from docs", ->
|
|
countdown = (num for num in [10..1])
|
|
arrayEq countdown, [10,9,8,7,6,5,4,3,2,1]
|
|
|
|
test "counting up when the range goes down returns an empty array", ->
|
|
countdown = (num for num in [10..1] by 1)
|
|
arrayEq countdown, []
|
|
|
|
test "counting down when the range goes up returns an empty array", ->
|
|
countup = (num for num in [1..10] by -1)
|
|
arrayEq countup, []
|
|
|
|
test "counting down by too much returns just the first value", ->
|
|
countdown = (num for num in [10..1] by -100)
|
|
arrayEq countdown, [10]
|
|
|
|
test "counting up by too much returns just the first value", ->
|
|
countup = (num for num in [1..10] by 100)
|
|
arrayEq countup, [1]
|