mirror of
https://github.com/jashkenas/coffeescript.git
synced 2026-01-14 17:27:59 -05:00
final waypoint; remaining files to be sorted:
* _test_existence.coffee * _test_pattern_matching.coffee
This commit is contained in:
@@ -1,77 +0,0 @@
|
||||
# Chaining
|
||||
# --------
|
||||
|
||||
# shared identity function
|
||||
id = (_) -> if arguments.length is 1 then _ else Array::slice.call(arguments)
|
||||
|
||||
|
||||
|
||||
# Basic chained function calls.
|
||||
identityWrap = (x) ->
|
||||
-> x
|
||||
|
||||
result = identityWrap(identityWrap(true))()()
|
||||
|
||||
ok result
|
||||
|
||||
|
||||
# Should be able to look at prototypes on keywords.
|
||||
obj =
|
||||
withAt: -> @::prop
|
||||
withThis: -> this::prop
|
||||
proto:
|
||||
prop: 100
|
||||
obj.prototype = obj.proto
|
||||
eq obj.withAt() , 100
|
||||
eq obj.withThis(), 100
|
||||
|
||||
|
||||
# Chained accesses split on period/newline, backwards and forwards.
|
||||
str = 'god'
|
||||
|
||||
result = str.
|
||||
split('').
|
||||
reverse().
|
||||
reverse().
|
||||
reverse()
|
||||
|
||||
ok result.join('') is 'dog'
|
||||
|
||||
result = str
|
||||
.split('')
|
||||
.reverse()
|
||||
.reverse()
|
||||
.reverse()
|
||||
|
||||
ok result.join('') is 'dog'
|
||||
|
||||
|
||||
# Newline suppression for operators.
|
||||
six =
|
||||
1 +
|
||||
2 +
|
||||
3
|
||||
|
||||
ok six is 6
|
||||
|
||||
|
||||
# Ensure that indented array literals don't trigger whitespace rewriting.
|
||||
func = () ->
|
||||
ok arguments.length is 1
|
||||
|
||||
func(
|
||||
[[[[[],
|
||||
[]],
|
||||
[[]]]],
|
||||
[]])
|
||||
|
||||
greeting = id(
|
||||
"""
|
||||
Hello
|
||||
""")
|
||||
|
||||
ok greeting is "Hello"
|
||||
|
||||
ok not Date
|
||||
::
|
||||
?.foo, '`?.` and `::` should also continue lines'
|
||||
@@ -1,50 +0,0 @@
|
||||
third = (a, b, c) -> c
|
||||
obj =
|
||||
one: 'one'
|
||||
two: third 'one', 'two', 'three'
|
||||
ok obj.one is 'one'
|
||||
ok obj.two is 'three'
|
||||
|
||||
|
||||
# Implicit arguments to function calls:
|
||||
func = (obj) -> obj.a
|
||||
func2 = -> arguments
|
||||
|
||||
result = func
|
||||
a: 10
|
||||
ok result is 10
|
||||
|
||||
result = func
|
||||
"a": 20
|
||||
ok result is 20
|
||||
|
||||
a = b = undefined
|
||||
|
||||
result = func
|
||||
b:1
|
||||
a
|
||||
ok result is undefined
|
||||
|
||||
result = func
|
||||
a:
|
||||
b:2
|
||||
b:1
|
||||
ok result.b is 2
|
||||
|
||||
result = func2
|
||||
a:1
|
||||
b
|
||||
c:1
|
||||
ok result.length is 3
|
||||
ok result[2].c is 1
|
||||
|
||||
second = (x, y) -> y
|
||||
obj = then second 'the',
|
||||
1: 1
|
||||
two:
|
||||
three: ->
|
||||
four five,
|
||||
six: seven
|
||||
three: 3
|
||||
ok obj[1] is 1
|
||||
ok obj.three is 3
|
||||
@@ -1,63 +0,0 @@
|
||||
# Expression conversion under explicit returns.
|
||||
first = ->
|
||||
return ('do' for x in [1,2,3])
|
||||
|
||||
second = ->
|
||||
return ['re' for x in [1,2,3]]
|
||||
|
||||
third = ->
|
||||
return ('mi' for x in [1,2,3])
|
||||
|
||||
ok first().join(' ') is 'do do do'
|
||||
ok second()[0].join(' ') is 're re re'
|
||||
ok third().join(' ') is 'mi mi mi'
|
||||
|
||||
|
||||
# Testing returns with multiple branches.
|
||||
func = ->
|
||||
if false
|
||||
for a in b
|
||||
return c if d
|
||||
else
|
||||
"word"
|
||||
|
||||
ok func() is 'word'
|
||||
|
||||
|
||||
# And with switches.
|
||||
func = ->
|
||||
switch 'a'
|
||||
when 'a' then 42
|
||||
else return 23
|
||||
|
||||
eq func(), 42
|
||||
|
||||
# Ensure that we don't wrap Nodes that are "pureStatement" in a closure.
|
||||
items = [1, 2, 3, "bacon", 4, 5]
|
||||
|
||||
findit = (items) ->
|
||||
for item in items
|
||||
return item if item is "bacon"
|
||||
|
||||
ok findit(items) is "bacon"
|
||||
|
||||
|
||||
# When a closure wrapper is generated for expression conversion, make sure
|
||||
# that references to "this" within the wrapper are safely converted as well.
|
||||
obj =
|
||||
num: 5
|
||||
func: ->
|
||||
this.result = if false
|
||||
10
|
||||
else
|
||||
"a"
|
||||
"b"
|
||||
this.num
|
||||
|
||||
eq obj.num, obj.func()
|
||||
eq obj.num, obj.result
|
||||
|
||||
|
||||
# Multiple semicolon-separated statements in parentheticals.
|
||||
eq 3, (1; 2; 3)
|
||||
eq 3, (-> return (1; 2; 3))()
|
||||
@@ -324,5 +324,17 @@ list = [arguments: 10]
|
||||
args = for f in list
|
||||
do (f) ->
|
||||
f.arguments
|
||||
|
||||
eq args[0], 10
|
||||
|
||||
|
||||
test "expression conversion under explicit returns", ->
|
||||
nonce = {}
|
||||
fn = ->
|
||||
return (nonce for x in [1,2,3])
|
||||
arrayEq [nonce,nonce,nonce], fn()
|
||||
fn = ->
|
||||
return [nonce for x in [1,2,3]][0]
|
||||
arrayEq [nonce,nonce,nonce], fn()
|
||||
fn = ->
|
||||
return [(nonce for x in [1..3])][0]
|
||||
arrayEq [nonce,nonce,nonce], fn()
|
||||
|
||||
@@ -1,7 +1,106 @@
|
||||
# Formatting
|
||||
# ----------
|
||||
|
||||
# * Line Continuation (Property Accesss)
|
||||
# * Line Continuation (Operators)
|
||||
# * Line Continuation (Arrays)
|
||||
# * Line Continuation (Function Invocations)
|
||||
# TODO: maybe this file should be split up into their respective sections:
|
||||
# operators -> operators
|
||||
# array literals -> array literals
|
||||
# string literals -> string literals
|
||||
# function invocations -> function invocations
|
||||
|
||||
# * Line Continuation
|
||||
# * Property Accesss
|
||||
# * Operators
|
||||
# * Array Literals
|
||||
# * Function Invocations
|
||||
# * String Literals
|
||||
|
||||
doesNotThrow -> CoffeeScript.compile "a = then b"
|
||||
|
||||
test "multiple semicolon-separated statements in parentheticals", ->
|
||||
nonce = {}
|
||||
eq nonce, (1; 2; nonce)
|
||||
eq nonce, (-> return (1; 2; nonce))()
|
||||
|
||||
#### Line Continuation
|
||||
|
||||
# Property Access
|
||||
|
||||
test "chained accesses split on period/newline, backwards and forwards", ->
|
||||
str = 'abc'
|
||||
result = str.
|
||||
split('').
|
||||
reverse().
|
||||
reverse().
|
||||
reverse()
|
||||
arrayEq ['c','b','a'], result
|
||||
arrayEq ['c','b','a'], str.
|
||||
split('').
|
||||
reverse().
|
||||
reverse().
|
||||
reverse()
|
||||
result = str
|
||||
.split('')
|
||||
.reverse()
|
||||
.reverse()
|
||||
.reverse()
|
||||
arrayEq ['c','b','a'], result
|
||||
arrayEq ['c','b','a'], str
|
||||
.split('')
|
||||
.reverse()
|
||||
.reverse()
|
||||
.reverse()
|
||||
arrayEq ['c','b','a'], str.
|
||||
split('')
|
||||
.reverse().
|
||||
reverse()
|
||||
.reverse()
|
||||
|
||||
# Operators
|
||||
|
||||
test "newline suppression for operators", ->
|
||||
six =
|
||||
1 +
|
||||
2 +
|
||||
3
|
||||
eq 6, six
|
||||
|
||||
test "`?.` and `::` should continue lines", ->
|
||||
ok not Date
|
||||
::
|
||||
?.foo
|
||||
#eq Object::toString, Date?.
|
||||
#prototype
|
||||
#::
|
||||
#?.foo
|
||||
|
||||
# Array Literals
|
||||
|
||||
test "indented array literals don't trigger whitespace rewriting", ->
|
||||
getArgs = -> arguments
|
||||
result = getArgs(
|
||||
[[[[[],
|
||||
[]],
|
||||
[[]]]],
|
||||
[]])
|
||||
eq 1, result.length
|
||||
|
||||
# Function Invocations
|
||||
|
||||
doesNotThrow -> CoffeeScript.compile """
|
||||
obj = then fn 1,
|
||||
1: 1
|
||||
a:
|
||||
b: ->
|
||||
fn c,
|
||||
d: e
|
||||
f: 1
|
||||
"""
|
||||
|
||||
# String Literals
|
||||
|
||||
test "indented heredoc", ->
|
||||
result = ((_) -> _)(
|
||||
"""
|
||||
abc
|
||||
""")
|
||||
eq "abc", result
|
||||
|
||||
@@ -64,6 +64,13 @@ ok fn(fn {prop: 101}).prop is 101
|
||||
okFunc = (f) -> ok(f())
|
||||
okFunc -> true
|
||||
|
||||
test "chained function calls", ->
|
||||
nonce = {}
|
||||
identityWrap = (x) ->
|
||||
-> x
|
||||
eq nonce, identityWrap(identityWrap(nonce))()()
|
||||
eq nonce, (identityWrap identityWrap nonce)()()
|
||||
|
||||
# Multi-blocks with optional parens.
|
||||
result = fn( ->
|
||||
fn ->
|
||||
@@ -296,3 +303,46 @@ eq ok, new ->
|
||||
ok
|
||||
### Should `return` implicitly ###
|
||||
### even with trailing comments. ###
|
||||
|
||||
test "implicit returns with multiple branches", ->
|
||||
nonce = {}
|
||||
fn = ->
|
||||
if false
|
||||
for a in b
|
||||
return c if d
|
||||
else
|
||||
nonce
|
||||
eq nonce, fn()
|
||||
|
||||
test "implicit returns with switches", ->
|
||||
nonce = {}
|
||||
fn = ->
|
||||
switch nonce
|
||||
when nonce then nonce
|
||||
else return undefined
|
||||
eq nonce, fn()
|
||||
|
||||
test "preserve context when generating closure wrappers for expression conversions", ->
|
||||
nonce = {}
|
||||
obj =
|
||||
property: nonce
|
||||
method: ->
|
||||
this.result = if false
|
||||
10
|
||||
else
|
||||
"a"
|
||||
"b"
|
||||
this.property
|
||||
eq nonce, obj.method()
|
||||
eq nonce, obj.property
|
||||
|
||||
|
||||
#### Explicit Returns
|
||||
|
||||
test "don't wrap \"pure\" statements in a closure", ->
|
||||
nonce = {}
|
||||
items = [0, 1, 2, 3, nonce, 4, 5]
|
||||
fn = (items) ->
|
||||
for item in items
|
||||
return item if item is nonce
|
||||
eq nonce, fn items
|
||||
|
||||
@@ -137,3 +137,52 @@ obj =
|
||||
two: third 'one', 'two', 'three'
|
||||
ok obj.one is 'one'
|
||||
ok obj.two is 'three'
|
||||
|
||||
test "", ->
|
||||
generateGetter = (prop) -> (obj) -> obj[prop]
|
||||
getA = generateGetter 'a'
|
||||
getArgs = -> arguments
|
||||
a = b = 30
|
||||
|
||||
result = getA
|
||||
a: 10
|
||||
ok result is 10
|
||||
|
||||
result = getA
|
||||
"a": 20
|
||||
ok result is 20
|
||||
|
||||
result = getA a,
|
||||
b:1
|
||||
ok result is undefined
|
||||
|
||||
# TODO: this looks like a failing test case; verify
|
||||
#result = getA
|
||||
# b:1
|
||||
# a
|
||||
#ok result is 30
|
||||
|
||||
result = getA
|
||||
a:
|
||||
b:2
|
||||
b:1
|
||||
ok result.b is 2
|
||||
|
||||
# TODO: should this test be changed? this is unexpected (and not the displayed) behaviour
|
||||
#result = getArgs
|
||||
# a:1
|
||||
# b
|
||||
# c:1
|
||||
#ok result.length is 3
|
||||
#ok result[2].c is 1
|
||||
|
||||
test "some weird indentation in YAML-style object literals", ->
|
||||
two = (a, b) -> b
|
||||
obj = then two 1,
|
||||
1: 1
|
||||
a:
|
||||
b: ->
|
||||
fn c,
|
||||
d: e
|
||||
f: 1
|
||||
eq 1, obj[1]
|
||||
|
||||
@@ -49,6 +49,15 @@ test "`instanceof`", ->
|
||||
ok new Number not instanceof String
|
||||
ok new Array not instanceof Boolean
|
||||
|
||||
test "use `::` operator on keywords `this` and `@`", ->
|
||||
nonce = {}
|
||||
obj =
|
||||
withAt: -> @::prop
|
||||
withThis: -> this::prop
|
||||
obj.prototype = prop: nonce
|
||||
eq nonce, obj.withAt()
|
||||
eq nonce, obj.withThis()
|
||||
|
||||
|
||||
#### Compound Assignment Operators
|
||||
|
||||
|
||||
Reference in New Issue
Block a user