final waypoint; remaining files to be sorted:

* _test_existence.coffee
  * _test_pattern_matching.coffee
This commit is contained in:
Michael Ficarra
2011-01-01 23:35:05 -05:00
parent 8692a5fd06
commit ccae9ea6a8
8 changed files with 224 additions and 195 deletions

View File

@@ -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'

View File

@@ -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

View File

@@ -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))()

View File

@@ -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()

View File

@@ -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

View File

@@ -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

View File

@@ -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]

View File

@@ -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