diff --git a/test/arguments.coffee b/test/arguments.coffee index 30dfa865..41a80dde 100644 --- a/test/arguments.coffee +++ b/test/arguments.coffee @@ -6,8 +6,7 @@ id = (_) -> if arguments.length is 1 then _ else Array::slice.call(arguments) -# basic argument passing tests -(-> +test "basic argument passing tests", -> a = {} b = {} c = {} @@ -15,10 +14,8 @@ id = (_) -> eq 2, (id 1, 2)[1] eq a, (id a) eq c, (id a, b, c)[2] -)() -# passing arguments on separate lines -(-> +test "passing arguments on separate lines", -> a = {} b = {} c = {} @@ -36,28 +33,24 @@ id = (_) -> )) eq b, (id b) -)() -# reference `arguments` inside of functions -(-> +test "reference `arguments` inside of functions", -> sumOfArgs = -> sum = (a,b)-> a + b Array::reduce.call(arguments,sum,0) eq 10, sumOfArgs(0, 1, 2, 3, 4) -)() #### Parameter List Features -# splats -eq 2, (((splat...) -> splat) 0,1,2)[2] -eq 3, (((_, _, splat...) -> splat) 0,1,2,3)[1] -eq 1, (((splat..., _, _) -> splat) 0,1,2,3)[1] -eq 2, (((_, _, splat..., _) -> splat) 0,1,2,3)[0] +test "splats", -> + eq 2, (((splat...) -> splat) 0,1,2)[2] + eq 3, (((_, _, splat...) -> splat) 0,1,2,3)[1] + eq 1, (((splat..., _, _) -> splat) 0,1,2,3)[1] + eq 2, (((_, _, splat..., _) -> splat) 0,1,2,3)[0] -# @-parameters: automatically assign an argument's value to a property of the context -(-> +test "@-parameters: automatically assign an argument's value to a property of the context", -> nonce = {} ((@prop) ->).call context = {}, nonce @@ -73,10 +66,8 @@ eq 2, (((_, _, splat..., _) -> splat) 0,1,2,3)[0] # the argument should still be able to be referenced normally eq nonce, (((@prop) -> prop).call {}, nonce) -)() -# @-parameters and splats with constructors -(-> +test "@-parameters and splats with constructors", -> a = {} b = {} class Klass @@ -85,16 +76,14 @@ eq 2, (((_, _, splat..., _) -> splat) 0,1,2,3)[0] obj = new Klass a, 0, 0, b eq a, obj.first eq b, obj.last -)() -# destructuring in function definition -(([{a: [b], c}]...) -> - eq 1, b - eq 2, c -) {a: [1], c: 2} +test "destructuring in function definition", -> + (([{a: [b], c}]...) -> + eq 1, b + eq 2, c + ) {a: [1], c: 2} -# default values -(-> +test "default values", -> nonceA = {} nonceB = {} a = (_,_,arg=nonceA) -> arg @@ -121,23 +110,18 @@ eq 2, (((_, _, splat..., _) -> splat) 0,1,2,3)[0] eq nonceA, c(null) eq false , c(false) eq nonceB, c(nonceB,undefined,undefined) -)() -# default values with @-parameters -(-> +test "default values with @-parameters", -> a = {} b = {} obj = f: (q = a, @p = b) -> q eq a, obj.f() eq b, obj.p -)() -# default values with splatted arguments -(-> +test "default values with splatted arguments", -> withSplats = (a = 2, b..., c = 3, d = 5) -> a * (b.length + 1) * c * d eq 30, withSplats() eq 15, withSplats(1) eq 5, withSplats(1,1) eq 1, withSplats(1,1,1) eq 2, withSplats(1,1,1,1) -)() diff --git a/test/assignment.coffee b/test/assignment.coffee index ee2540ce..59b59c0b 100644 --- a/test/assignment.coffee +++ b/test/assignment.coffee @@ -3,32 +3,27 @@ ################ -# context property assignment (using @) -(-> +test "context property assignment (using @)", -> nonce = {} addMethod = -> @method = -> nonce this eq nonce, addMethod.call({}).method() -)() -# unassignable values -(-> +test "unassignable values", -> nonce = {} for nonref in ['', '""', '0', 'f()'].concat CoffeeScript.RESERVED eq nonce, (try CoffeeScript.compile "#{nonref} = v" catch e then nonce) -)() -# compound assignments should not declare -# TODO: make description more clear -# TODO: remove reference to Math -eq Math, (-> Math or= 0)() +test "compound assignments should not declare", -> + # TODO: make description more clear + # TODO: remove reference to Math + eq Math, (-> Math or= 0)() #### Statements as Expressions -# assign the result of a try/catch block -(-> +test "assign the result of a try/catch block", -> # multiline result = try nonexistent * missing @@ -39,10 +34,8 @@ eq Math, (-> Math or= 0)() # single line result = try nonexistent * missing catch error then true eq true, result -)() -# conditionals -(-> +test "conditionals", -> # assign inside the condition of a conditional statement nonce = {} if a = nonce then 1 @@ -53,10 +46,8 @@ eq Math, (-> Math or= 0)() # assign the result of a conditional statement c = if true then nonce eq nonce, c -)() -# assign inside the condition of a `while` loop -(-> +test "assign inside the condition of a `while` loop", -> nonce = {} count = 1 a = nonce while count-- @@ -65,13 +56,11 @@ eq Math, (-> Math or= 0)() while count-- b = nonce eq nonce, b -)() #### Compound Assignment -# compound assignment (math operators) -(-> +test "compound assignment (math operators)", -> num = 10 num -= 5 eq 5, num @@ -84,10 +73,8 @@ eq Math, (-> Math or= 0)() num %= 3 eq 2, num -)() -# more compound assignment -(-> +test "more compound assignment", -> a = {} val = undefined val ||= a @@ -105,7 +92,6 @@ eq Math, (-> Math or= 0)() val ?= c val ?= true eq c, val -)() #### Destructuring Assignment diff --git a/test/break.coffee b/test/break.coffee index acbc3868..a9618293 100644 --- a/test/break.coffee +++ b/test/break.coffee @@ -3,17 +3,14 @@ ########### -# break at the top level -(-> +test "break at the top level", -> for i in [1,2,3] result = i if i == 2 break eq 2, result -)() -# break *not* at the top level -(-> +test "break *not* at the top level", -> someFunc = () -> i = 0 while ++i < 3 @@ -21,4 +18,3 @@ break if i > 1 result eq 2, someFunc() -)() diff --git a/test/exception_handling.coffee b/test/exception_handling.coffee new file mode 100644 index 00000000..1d41f954 --- /dev/null +++ b/test/exception_handling.coffee @@ -0,0 +1,85 @@ +################ +## Exceptions ## +################ + +# shared nonce +nonce = {} + +#### Throw + +test "basic exception throwing", -> + throws (-> throw ->), -> + throws (-> throw new ->), -> + +#### Empty Try/Catch/Finally + +test "try can exist alone", -> + try + +test "try/catch with empty try, empty catch", -> + try + # nothing + catch err + # nothing + +test "single-line try/catch with empty try, empty catch", -> + try catch err + +test "try/finally with empty try, empty finally", -> + try + # nothing + finally + # nothing + +test "single-line try/finally with empty try, empty finally", -> + try finally + +test "try/catch/finally with empty try, empty catch, empty finally", -> + try + catch err + finally + +test "single-line try/catch/finally with empty try, empty catch, empty finally", -> + try catch err then finally + + +#### Try/Catch/Finally as an Expression + +test "return the result of try when no exception is thrown", -> + result = try + nonce + catch err + undefined + finally + undefined + eq nonce, result + +test "single-line result of try when no exception is thrown", -> + result = try nonce catch err then undefined + eq nonce, result + +test "return the result of catch when an exception is thrown", -> + result = try + throw -> + catch err + nonce + eq nonce, result + +test "single-line result of catch when an exception is thrown", -> + result = try throw -> catch err then nonce + eq nonce, result + +test "optional catch", -> + fn = -> + try throw -> + nonce + eq nonce, fn() + + +#### Try/Catch/Finally Interaction With Other Constructs + +test "try/catch with empty catch as last statement in a function body", -> + fn = -> + try nonce + catch err + eq nonce, fn() diff --git a/test/exceptions.coffee b/test/exceptions.coffee deleted file mode 100644 index 1998f208..00000000 --- a/test/exceptions.coffee +++ /dev/null @@ -1,85 +0,0 @@ -################ -## Exceptions ## -################ - -# shared nonce -nonce = {} - -#### Throw - -# basic exception throwing -throws (-> throw ->), -> -throws (-> throw new ->), -> - -#### Empty Try/Catch/Finally - -# try can exist alone -try - -# try/catch with empty try, empty catch -try - # nothing -catch err - # nothing - -# single-line try/catch with empty try, empty catch -try catch err - -# try/finally with empty try, empty finally -try - # nothing -finally - # nothing - -# single-line try/finally with empty try, empty finally -try finally - -# try/catch/finally with empty try, empty catch, empty finally -try -catch err -finally - -# single-line try/catch/finally with empty try, empty catch, empty finally -try catch err then finally - - -#### Try/Catch/Finally as an Expression - -# return the result of try when no exception is thrown -result = try - nonce -catch err - undefined -finally - undefined -eq nonce, result - -# single-line result of try when no exception is thrown -result = try nonce catch err then undefined -eq nonce, result - -# return the result of catch when an exception is thrown -result = try - throw -> -catch err - nonce -eq nonce, result - -# single-line result of catch when an exception is thrown -result = try throw -> catch err then nonce -eq nonce, result - -# optional catch -fn = -> - try throw -> - nonce -eq nonce, fn() - - -#### Try/Catch/Finally Interaction With Other Constructs - -# try/catch with empty catch as last statement in a function body -func = -> - try nonce - catch err -ok func() is nonce diff --git a/test/operators.coffee b/test/operators.coffee index 50411db9..eb7a0ee8 100644 --- a/test/operators.coffee +++ b/test/operators.coffee @@ -3,18 +3,15 @@ ############### -# binary (2-ary) math operators do not require spaces -(-> +test "binary (2-ary) math operators do not require spaces", -> a = 1 b = -1 eq +1, a*-b eq -1, a*+b eq +1, a/-b eq -1, a/+b -)() -# operators should respect new lines as spaced -(-> +test "operators should respect new lines as spaced", -> a = 123 + 456 eq 579, a @@ -22,13 +19,11 @@ b = "1#{2}3" + "456" eq '123456', b -)() -# multiple operators should space themselves -eq (+ +1), (- -1) +test "multiple operators should space themselves", -> + eq (+ +1), (- -1) -# bitwise operators -(-> +test "bitwise operators", -> eq 2, (10 & 3) eq 11, (10 | 3) eq 9, (10 ^ 3) @@ -41,22 +36,18 @@ eq (+ +1), (- -1) num = 10; eq 80, (num <<= 3) num = 10; eq 1, (num >>= 3) num = 10; eq 1, (num >>>= 3) -)() -# `instanceof` -(-> +test "`instanceof`", -> ok new String instanceof String ok new Boolean instanceof Boolean # `instanceof` supports negation by prefixing the operator with `not` ok new Number not instanceof String ok new Array not instanceof Boolean -)() #### Compound Assignment Operators -# boolean operators -(-> +test "boolean operators", -> nonce = {} a = 0 @@ -79,20 +70,16 @@ eq (+ +1), (- -1) e = f = false e and= f or true eq false, e -)() -# compound assignment as a sub expression -(-> +test "compound assignment as a sub expression", -> [a, b, c] = [1, 2, 3] eq 6, (a + b += c) eq 1, a eq 5, b eq 3, c -)() -# compound assignment should be careful about caching variables # *note: this test could still use refactoring* -(-> +test "compound assignment should be careful about caching variables", -> count = 0 list = [] @@ -119,10 +106,8 @@ eq (+ +1), (- -1) base().five ?= 5 eq 5, base.five eq 5, count -)() -# compound assignment with implicit objects -(-> +test "compound assignment with implicit objects", -> obj = undefined obj ?= one: 1 @@ -134,44 +119,37 @@ eq (+ +1), (- -1) eq undefined, obj.one eq 2, obj.two -)() #### `is`,`isnt`,`==`,`!=` -# `==` and `is` should be interchangeable. -(-> +test "`==` and `is` should be interchangeable", -> a = b = 1 ok a is 1 and b == 1 ok a == b ok a is b -)() -# `!=` and `isnt` should be interchangeable. -(-> +test "`!=` and `isnt` should be interchangeable", -> a = 0 b = 1 ok a isnt 1 and b != 0 ok a != b ok a isnt b -)() #### `in`, `of` # - `in` should check if an array contains a value using `indexOf` # - `of` should check if a property is defined on an object using `in` -(-> +test "in, of", -> arr = [1] ok 0 of arr ok 1 in arr # prefixing `not` to `in and `of` should negate them ok 1 not of arr ok 0 not in arr -)() -# `in` should be able to operate on an array literal -(-> +test "`in` should be able to operate on an array literal", -> ok 2 in [0, 1, 2, 3] ok 4 not in [0, 1, 2, 3] arr = [0, 1, 2, 3] @@ -185,10 +163,8 @@ eq (+ +1), (- -1) val = 0 ok val++ of arr ok val++ not of arr -)() -# `of` and `in` should be able to operate on instance variables -(-> +test "`of` and `in` should be able to operate on instance variables", -> obj = { list: [2,3] in_list: (value) -> value in @list @@ -200,60 +176,52 @@ eq (+ +1), (- -1) ok obj.not_in_list 1 ok obj.of_list 0 ok obj.not_of_list 2 -)() -#???: `in` with cache and `__indexOf` should work in argument lists -eq 1, [Object() in Array()].length +test "#???: `in` with cache and `__indexOf` should work in argument lists", -> + eq 1, [Object() in Array()].length -#737: `in` should have higher precedence than logical operators. -eq 1, 1 in [1] and 1 +test "#737: `in` should have higher precedence than logical operators", -> + eq 1, 1 in [1] and 1 -#768: `in` should preserve evaluation order. -(-> +test "#768: `in` should preserve evaluation order", -> share = 0 a = -> share++ if share is 0 b = -> share++ if share is 1 c = -> share++ if share is 2 ok a() not in [b(),c()] eq 3, share -)() #### Chainable Operators -ok 100 > 10 > 1 > 0 > -1 -ok -1 < 0 < 1 < 10 < 100 +test "chainable operators", -> + ok 100 > 10 > 1 > 0 > -1 + ok -1 < 0 < 1 < 10 < 100 -# `is` and `isnt` may be chained -ok true is not false is true is not false -ok 0 is 0 isnt 1 is 1 +test "`is` and `isnt` may be chained", -> + ok true is not false is true is not false + ok 0 is 0 isnt 1 is 1 -# different comparison operators (`>`,`<`,`is`,etc.) may be combined -ok 1 < 2 > 1 -ok 10 < 20 > 2+3 is 5 +test "different comparison operators (`>`,`<`,`is`,etc.) may be combined", -> + ok 1 < 2 > 1 + ok 10 < 20 > 2+3 is 5 -# some chainable operators can be negated by `unless` -ok (true unless 0==10!=100) +test "some chainable operators can be negated by `unless`", -> + ok (true unless 0==10!=100) -# operator precedence: `|` lower than `<` -eq 1, 1 | 2 < 3 < 4 +test "operator precedence: `|` lower than `<`", -> + eq 1, 1 | 2 < 3 < 4 -# preserve references -(-> +test "preserve references", -> a = b = c = 1 # `a == b <= c` should become `a === b && b <= c` # (this test does not seem to test for this) ok a == b <= c -)() -# chained operations should evaluate each value only once -(-> +test "chained operations should evaluate each value only once", -> a = 0 ok 1 > a++ < 1 -)() -#891: incorrect inversion of chained comparisons -(-> +test "#891: incorrect inversion of chained comparisons", -> ok (true unless 0 > 1 > 2) ok (true unless (NaN = 0/0) < 0/0 < NaN) -)()