jashkenas--coffeescript/test/test_existence.coffee

143 lines
2.5 KiB
CoffeeScript

ok(if mySpecialVariable? then false else true)
mySpecialVariable = false
ok(if mySpecialVariable? then true else false)
# Existential assignment.
a = 5
a = null
a ?= 10
b ?= 10
ok a is 10 and b is 10
# The existential operator.
z = null
x = z ? "EX"
ok z is null and x is "EX"
i = 9
func = -> i += 1
result = func() ? 101
ok result is 10
ok (non ? existent ? variables ? 1) is 1
# Only evaluate once.
counter = 0
getNextNode = ->
throw "up" if counter
counter++
ok(if getNextNode()? then true else false)
# Existence chains, soaking up undefined properties:
obj =
prop: "hello"
eq obj?.prop, "hello"
eq obj?['prop'], "hello"
eq obj.prop?.length, 5
eq obj?.prop?['length'], 5
eq obj?.prop?.non?.existent?.property, undefined
# Soaks and caches method calls as well.
arr = ["--", "----"]
eq arr.pop()?.length, 4
eq arr.pop()?.length, 2
eq arr.pop()?.length, undefined
eq arr.pop()?.length?.non?.existent()?.property, undefined
# Soaks method calls safely.
value = null
eq value?.toString().toLowerCase(), undefined
value = 10
eq value?.toString().toLowerCase(), '10'
eq process.exit.nothing?.property() or 101, 101
counter = 0
func = ->
counter += 1
'prop'
obj =
prop: -> this
value: 25
ok obj[func()]()[func()]()[func()]()?.value is 25
ok counter is 3
ident = (obj) -> obj
eq ident(non?.existent().method()), undefined, 'soaks inner values'
# Soaks constructor invocations.
a = 0
class Foo
constructor: -> a += 1
bar: "bat"
ok (new Foo())?.bar is 'bat'
ok a is 1
ok not value?.property?, 'safely checks existence on soaks'
eq nothing?.value, undefined, 'safely calls values off of non-existent variables'
# Assign to the result of an exsitential operation with a minus.
x = null ? - 1
ok x is - 1
# Things that compile to ternaries should force parentheses, like operators do.
duration = if options?.animated then 150 else 0
ok duration is 0
# Function soaks.
plus1 = (x) -> x + 1
count = 0
obj = {
counter: -> count += 1; this
returnThis: -> this
}
ok plus1?(41) is 42
ok (plus1? 41) is 42
ok plus2?(41) is undefined
ok (plus2? 41) is undefined
ok obj.returnThis?() is obj
ok obj.counter().counter().returnThis?() is obj
ok count is 2
maybe_close = (f, arg) -> if typeof f is 'function' then () -> f(arg) else -1
ok maybe_close(plus1, 41)?() is 42
ok (maybe_close plus1, 41)?() is 42
ok (maybe_close 'string', 41)?() is undefined
eq 2?(3), undefined
#726
eq calendar?[Date()], undefined
#733
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