mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
133 lines
3.1 KiB
CoffeeScript
133 lines
3.1 KiB
CoffeeScript
# Soaks
|
|
# -----
|
|
|
|
# * Soaked Property Access
|
|
# * Soaked Method Invocation
|
|
# * Soaked Function Invocation
|
|
|
|
|
|
# Soaked Property Access
|
|
|
|
test "soaked property access", ->
|
|
nonce = {}
|
|
obj = a: b: nonce
|
|
eq nonce , obj?.a.b
|
|
eq nonce , obj?['a'].b
|
|
eq nonce , obj.a?.b
|
|
eq nonce , obj?.a?['b']
|
|
eq undefined, obj?.a?.non?.existent?.property
|
|
|
|
test "soaked property access caches method calls", ->
|
|
nonce ={}
|
|
obj = fn: -> a: nonce
|
|
eq nonce , obj.fn()?.a
|
|
eq undefined, obj.fn()?.b
|
|
|
|
test "soaked property access caching", ->
|
|
nonce = {}
|
|
counter = 0
|
|
fn = ->
|
|
counter++
|
|
'self'
|
|
obj =
|
|
self: -> @
|
|
prop: nonce
|
|
eq nonce, obj[fn()]()[fn()]()[fn()]()?.prop
|
|
eq 3, counter
|
|
|
|
test "method calls on soaked methods", ->
|
|
nonce = {}
|
|
obj = null
|
|
eq undefined, obj?.a().b()
|
|
obj = a: -> b: -> nonce
|
|
eq nonce , obj?.a().b()
|
|
|
|
test "postfix existential operator mixes well with soaked property accesses", ->
|
|
eq false, nonexistent?.property?
|
|
|
|
test "function invocation with soaked property access", ->
|
|
id = (_) -> _
|
|
eq undefined, id nonexistent?.method()
|
|
|
|
test "if-to-ternary should safely parenthesize soaked property accesses", ->
|
|
ok (if nonexistent?.property then false else true)
|
|
|
|
test "#726: don't check for a property on a conditionally-referenced nonexistent thing", ->
|
|
eq undefined, nonexistent?[Date()]
|
|
|
|
test "#756: conditional assignment edge cases", ->
|
|
# TODO: improve this test
|
|
a = null
|
|
ok isNaN a?.b.c + 1
|
|
eq undefined, a?.b.c += 1
|
|
eq undefined, ++a?.b.c
|
|
eq undefined, delete a?.b.c
|
|
|
|
test "operations on soaked properties", ->
|
|
# TODO: improve this test
|
|
a = b: {c: 0}
|
|
eq 1, a?.b.c + 1
|
|
eq 1, a?.b.c += 1
|
|
eq 2, ++a?.b.c
|
|
eq yes, delete a?.b.c
|
|
|
|
|
|
# Soaked Method Invocation
|
|
|
|
test "soaked method invocation", ->
|
|
nonce = {}
|
|
counter = 0
|
|
obj =
|
|
self: -> @
|
|
increment: -> counter++; @
|
|
eq obj , obj.self?()
|
|
eq undefined, obj.method?()
|
|
eq nonce , obj.self?().property = nonce
|
|
eq undefined, obj.method?().property = nonce
|
|
eq obj , obj.increment().increment().self?()
|
|
eq 2 , counter
|
|
|
|
test "#733: conditional assignments", ->
|
|
a = b: {c: null}
|
|
eq a.b?.c?(), undefined
|
|
a.b?.c or= (it) -> it
|
|
eq a.b?.c?(1), 1
|
|
eq a.b?.c?([2, 3]...), 2
|
|
|
|
|
|
# Soaked Function Invocation
|
|
|
|
test "soaked function invocation", ->
|
|
nonce = {}
|
|
id = (_) -> _
|
|
eq nonce , id?(nonce)
|
|
eq nonce , (id? nonce)
|
|
eq undefined, nonexistent?(nonce)
|
|
eq undefined, (nonexistent? nonce)
|
|
|
|
test "soaked function invocation with generated functions", ->
|
|
nonce = {}
|
|
id = (_) -> _
|
|
maybe = (fn, arg) -> if typeof fn is 'function' then () -> fn(arg)
|
|
eq maybe(id, nonce)?(), nonce
|
|
eq (maybe id, nonce)?(), nonce
|
|
eq (maybe false, nonce)?(), undefined
|
|
|
|
test "soaked constructor invocation", ->
|
|
eq 42 , +new Number? 42
|
|
eq undefined, new Other? 42
|
|
|
|
test "soaked constructor invocations with caching and property access", ->
|
|
semaphore = 0
|
|
nonce = {}
|
|
class C
|
|
constructor: ->
|
|
ok false if semaphore
|
|
semaphore++
|
|
prop: nonce
|
|
eq nonce, (new C())?.prop
|
|
eq 1, semaphore
|
|
|
|
test "soaked function invocation safe on non-functions", ->
|
|
eq undefined, (0)?(1)
|
|
eq undefined, (0)? 1, 2
|