UNPKG

5.5 kBtext/coffeescriptView Raw
1suite 'Function Literals', ->
2
3 suite 'Function Definition', ->
4
5 test 'basic functions', ->
6
7 fn = -> 3
8 eq 'function', typeof fn
9 ok fn instanceof Function
10 eq 3, fn()
11
12 test 'empty functions', ->
13 fn = ->
14 eq 'function', typeof fn
15 eq undefined, fn()
16 fn = () ->
17 eq 'function', typeof fn
18 eq undefined, fn()
19 fn = (->
20 )
21 eq 'function', typeof fn
22 eq undefined, fn()
23
24 test 'multiple nested single-line functions', ->
25 func = (x) -> (x) -> (x) -> x
26 eq 3, func(1)(2)(3)
27
28 test 'multiple nested single-line functions mixed with implicit calls', ->
29 fn = (one) -> (two) -> three four, (five) -> six seven, eight, (nine) ->
30 eq 'function', typeof fn
31
32 test "self-referencing functions", ->
33 changeMe = ->
34 changeMe = 2
35 eq 'function', typeof changeMe
36 eq 2, changeMe()
37 eq 2, changeMe
38
39 test "#1859: inline function bodies shouldn't modify prior postfix ifs", ->
40 list = [1, 2, 3]
41 ok true if list.some (x) -> x is 2
42
43
44 suite 'Bound Function Definition', ->
45
46 #test 'basic bound functions', ->
47 # obj = {
48 # bound: ->
49 # (=> this)()
50 # unbound: ->
51 # (-> this)()
52 # nested: ->
53 # (=>
54 # (=>
55 # (=> this)()
56 # )()
57 # )()
58 # }
59 # eq obj, obj.bound()
60 # ok obj isnt obj.unbound()
61 # eq obj, obj.nested()
62
63 #test "fancy bound functions", ->
64 # obj = {
65 # one: ->
66 # do =>
67 # return this.two()
68 # two: ->
69 # do =>
70 # do =>
71 # do =>
72 # return this.three
73 # three: 3
74 # }
75 # eq obj.one(), 3
76
77 test "#1844: bound functions in nested comprehensions causing empty var statements", ->
78 a = ((=>) for a in [0] for b in [0])
79 eq 1, a.length
80
81
82 suite 'Parameter List Features', ->
83
84 #test "splats", ->
85 # arrayEq [0, 1, 2], (((splat...) -> splat) 0, 1, 2)
86 # arrayEq [2, 3], (((_, _1, splat...) -> splat) 0, 1, 2, 3)
87 # arrayEq [0, 1], (((splat..., _, _1) -> splat) 0, 1, 2, 3)
88 # arrayEq [2], (((_, _1, splat..., _2) -> splat) 0, 1, 2, 3)
89
90 #test "destructured splatted parameters", ->
91 # arr = [0,1,2]
92 # splatArray = ([a...]) -> a
93 # splatArrayRest = ([a...],b...) -> arrayEq(a,b); b
94 # arrayEq splatArray(arr), arr
95 # arrayEq splatArrayRest(arr,0,1,2), arr
96
97 test "@-parameters: automatically assign an argument's value to a property of the context", ->
98 nonce = {}
99
100 ((@prop) ->).call context = {}, nonce
101 eq nonce, context.prop
102
103 #((splat..., @prop) ->).apply context = {}, [0, 0, nonce]
104 #eq nonce, context.prop
105
106 #((@prop...) ->).call context = {}, 0, nonce, 0
107 #eq nonce, context.prop[1]
108
109 eq 0, ((@prop) -> @prop).call {}, 0
110 eq 'undefined', ((@prop) -> typeof prop).call {}, 0
111
112 #test "@-parameters and splats with constructors", ->
113 # a = {}
114 # b = {}
115 # class Klass
116 # constructor: (@first, splat..., @last) ->
117 #
118 # obj = new Klass a, 0, 0, b
119 # eq a, obj.first
120 # eq b, obj.last
121
122 #test "destructuring splats", ->
123 # (([{a: [b], c}]...) ->
124 # eq 1, b
125 # eq 2, c
126 # ) {a: [1], c: 2}
127
128 test "default values", ->
129 nonceA = {}
130 nonceB = {}
131 a = (_,_1,arg=nonceA) -> arg
132 eq nonceA, a()
133 eq nonceA, a(0)
134 eq nonceB, a(0,0,nonceB)
135 eq nonceA, a(0,0,undefined)
136 eq nonceA, a(0,0,null)
137 eq false , a(0,0,false)
138 eq nonceB, a(undefined,undefined,nonceB,undefined)
139 b = (_,arg=nonceA,_1,_2) -> arg
140 eq nonceA, b()
141 eq nonceA, b(0)
142 eq nonceB, b(0,nonceB)
143 eq nonceA, b(0,undefined)
144 eq nonceA, b(0,null)
145 eq false , b(0,false)
146 eq nonceB, b(undefined,nonceB,undefined)
147 c = (arg=nonceA,_,_1) -> arg
148 eq nonceA, c()
149 eq 0, c(0)
150 eq nonceB, c(nonceB)
151 eq nonceA, c(undefined)
152 eq nonceA, c(null)
153 eq false , c(false)
154 eq nonceB, c(nonceB,undefined,undefined)
155
156 test "default values with @-parameters", ->
157 nonceA = {}
158 nonceB = {}
159 obj = {f: (q = nonceA, @p = nonceB) -> q}
160 eq nonceA, obj.f()
161 eq nonceB, obj.p
162 eq nonceB, obj.f nonceB, nonceA
163 eq nonceA, obj.p
164
165 #test "default values with splatted arguments", ->
166 # withSplats = (a = 2, b..., c = 3, d = 5) -> a * (b.length + 1) * c * d
167 # eq 30, withSplats()
168 # eq 15, withSplats(1)
169 # eq 5, withSplats(1,1)
170 # eq 1, withSplats(1,1,1)
171 # eq 2, withSplats(1,1,1,1)
172
173 test "default values with function calls", ->
174 counter = 0
175 fn = -> ++counter
176 eq 1, ((x = fn()) -> x)()
177 eq fn, ((x = fn()) -> x) fn
178 eq 0, ((x = fn) -> x()) -> 0
179 eq 2, ((x = fn()) -> x)()
180
181 test "arguments vs parameters", ->
182 nonce = {}
183 f = (x) -> x()
184 eq nonce, f (x) -> nonce
185 g = -> f
186 eq nonce, g(f) -> nonce
187
188 test "#2258: allow whitespace-style parameter lists in function definitions", ->
189 func = (
190 a, b, c
191 ) -> c
192 eq func(1, 2, 3), 3
193 func = (
194 a
195 b
196 c
197 ) -> b
198 eq func(1, 2, 3), 2
199 func = (
200 a,
201 b,
202 c
203 ) -> b
204 eq func(1, 2, 3), 2
205
206 test '#66: functions whose final expression is `throw` should compile', ->
207 (->) -> throw {}
208 (->) ->
209 a = Math.random()
210 if a then throw {}