2010-12-29 14:06:57 -05:00
|
|
|
# Formatting
|
|
|
|
# ----------
|
|
|
|
|
2011-01-01 23:35:05 -05:00
|
|
|
# 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
|
|
|
|
|
|
|
|
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))()
|
|
|
|
|
2014-01-26 17:06:48 -05:00
|
|
|
# * Line Continuation
|
|
|
|
# * Property Accesss
|
|
|
|
# * Operators
|
|
|
|
# * Array Literals
|
|
|
|
# * Function Invocations
|
|
|
|
# * String Literals
|
2011-01-01 23:35:05 -05:00
|
|
|
|
|
|
|
# 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
|
2013-11-26 22:41:52 -05:00
|
|
|
arrayEq ['c','b','a'],
|
|
|
|
str
|
2011-01-01 23:35:05 -05:00
|
|
|
.split('')
|
|
|
|
.reverse()
|
|
|
|
.reverse()
|
|
|
|
.reverse()
|
2013-11-26 22:41:52 -05:00
|
|
|
arrayEq ['c','b','a'],
|
|
|
|
str.
|
2011-01-01 23:35:05 -05:00
|
|
|
split('')
|
|
|
|
.reverse().
|
|
|
|
reverse()
|
|
|
|
.reverse()
|
|
|
|
|
|
|
|
# Operators
|
|
|
|
|
|
|
|
test "newline suppression for operators", ->
|
|
|
|
six =
|
|
|
|
1 +
|
|
|
|
2 +
|
|
|
|
3
|
|
|
|
eq 6, six
|
|
|
|
|
|
|
|
test "`?.` and `::` should continue lines", ->
|
2013-11-26 22:41:52 -05:00
|
|
|
ok not (
|
|
|
|
Date
|
|
|
|
::
|
|
|
|
?.foo
|
|
|
|
)
|
2011-01-01 23:35:05 -05:00
|
|
|
#eq Object::toString, Date?.
|
|
|
|
#prototype
|
|
|
|
#::
|
|
|
|
#?.foo
|
|
|
|
|
2011-01-22 01:29:07 -05:00
|
|
|
doesNotThrow -> CoffeeScript.compile """
|
|
|
|
oh. yes
|
2011-01-22 01:34:30 -05:00
|
|
|
oh?. true
|
|
|
|
oh:: return
|
2011-01-22 01:29:07 -05:00
|
|
|
"""
|
|
|
|
|
2011-01-22 01:56:14 -05:00
|
|
|
doesNotThrow -> CoffeeScript.compile """
|
|
|
|
a?[b..]
|
|
|
|
a?[...b]
|
|
|
|
a?[b..c]
|
|
|
|
"""
|
|
|
|
|
2011-01-01 23:35:05 -05:00
|
|
|
# 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
|
2011-07-16 10:34:46 -04:00
|
|
|
|
2014-01-26 17:06:48 -05:00
|
|
|
# Chaining - all open calls are closed by property access starting a new line
|
|
|
|
# * chaining after
|
|
|
|
# * indented argument
|
|
|
|
# * function block
|
|
|
|
# * indented object
|
|
|
|
#
|
|
|
|
# * single line arguments
|
|
|
|
# * inline function literal
|
|
|
|
# * inline object literal
|
|
|
|
|
|
|
|
test "chaining after outdent", ->
|
|
|
|
id = (x) -> x
|
|
|
|
|
|
|
|
# indented argument
|
|
|
|
ff = id parseInt "ff",
|
|
|
|
16
|
|
|
|
.toString()
|
|
|
|
eq '255', ff
|
|
|
|
|
|
|
|
# function block
|
|
|
|
str = 'abc'
|
|
|
|
zero = parseInt str.replace /\w/, (letter) ->
|
|
|
|
0
|
|
|
|
.toString()
|
|
|
|
eq '0', zero
|
|
|
|
|
|
|
|
# indented object
|
|
|
|
a = id id
|
|
|
|
a: 1
|
|
|
|
.a
|
|
|
|
eq 1, a
|
|
|
|
|
|
|
|
test "#1495, method call chaining", ->
|
|
|
|
str = 'abc'
|
|
|
|
|
|
|
|
result = str.split ''
|
|
|
|
.join ', '
|
|
|
|
eq 'a, b, c', result
|
|
|
|
|
|
|
|
result = str
|
|
|
|
.split ''
|
|
|
|
.join ', '
|
|
|
|
eq 'a, b, c', result
|
|
|
|
|
|
|
|
eq 'a, b, c', (str
|
|
|
|
.split ''
|
|
|
|
.join ', '
|
|
|
|
)
|
|
|
|
|
|
|
|
eq 'abc',
|
|
|
|
'aaabbbccc'.replace /(\w)\1\1/g, '$1$1'
|
|
|
|
.replace /([abc])\1/g, '$1'
|
|
|
|
|
|
|
|
# Nested calls
|
|
|
|
result = [1..3]
|
|
|
|
.slice Math.max 0, 1
|
|
|
|
.concat [3]
|
|
|
|
arrayEq [2, 3, 3], result
|
|
|
|
|
|
|
|
# Single line function arguments
|
|
|
|
result = [1..6]
|
|
|
|
.map (x) -> x * x
|
|
|
|
.filter (x) -> x % 2 is 0
|
|
|
|
.reverse()
|
|
|
|
arrayEq [36, 16, 4], result
|
|
|
|
|
|
|
|
# Single line implicit objects
|
|
|
|
id = (x) -> x
|
|
|
|
result = id a: 1
|
|
|
|
.a
|
|
|
|
eq 1, result
|
|
|
|
|
|
|
|
# The parens are forced
|
|
|
|
result = str.split(''.
|
|
|
|
split ''
|
|
|
|
.join ''
|
|
|
|
).join ', '
|
|
|
|
eq 'a, b, c', result
|
|
|
|
|
2017-05-03 02:00:21 -04:00
|
|
|
test "chaining should not wrap spilling ternary", ->
|
|
|
|
throws -> CoffeeScript.compile """
|
|
|
|
if 0 then 1 else g
|
|
|
|
a: 42
|
|
|
|
.h()
|
|
|
|
"""
|
|
|
|
|
|
|
|
test "chaining should wrap calls containing spilling ternary", ->
|
|
|
|
f = (x) -> h: x
|
|
|
|
id = (x) -> x
|
|
|
|
result = f if true then 42 else id
|
|
|
|
a: 2
|
|
|
|
.h
|
|
|
|
eq 42, result
|
|
|
|
|
|
|
|
test "chaining should work within spilling ternary", ->
|
|
|
|
f = (x) -> h: x
|
|
|
|
id = (x) -> x
|
|
|
|
result = f if false then 1 else id
|
|
|
|
a: 3
|
|
|
|
.a
|
|
|
|
eq 3, result.h
|
|
|
|
|
2011-07-16 10:34:46 -04:00
|
|
|
# Nested blocks caused by paren unwrapping
|
|
|
|
test "#1492: Nested blocks don't cause double semicolons", ->
|
2011-07-17 16:43:50 -04:00
|
|
|
js = CoffeeScript.compile '(0;0)'
|
2011-07-16 10:34:46 -04:00
|
|
|
eq -1, js.indexOf ';;'
|
2011-09-04 12:18:38 -04:00
|
|
|
|
|
|
|
test "#1195 Ignore trailing semicolons (before newlines or as the last char in a program)", ->
|
2012-02-03 19:08:45 -05:00
|
|
|
preNewline = (numSemicolons) ->
|
|
|
|
"""
|
|
|
|
nonce = {}; nonce2 = {}
|
|
|
|
f = -> nonce#{Array(numSemicolons+1).join(';')}
|
|
|
|
nonce2
|
|
|
|
unless f() is nonce then throw new Error('; before linebreak should = newline')
|
|
|
|
"""
|
|
|
|
CoffeeScript.run(preNewline(n), bare: true) for n in [1,2,3]
|
|
|
|
|
|
|
|
lastChar = '-> lastChar;'
|
|
|
|
doesNotThrow -> CoffeeScript.compile lastChar, bare: true
|
2011-09-16 19:26:04 -04:00
|
|
|
|
|
|
|
test "#1299: Disallow token misnesting", ->
|
|
|
|
try
|
|
|
|
CoffeeScript.compile '''
|
|
|
|
[{
|
|
|
|
]}
|
|
|
|
'''
|
|
|
|
ok no
|
|
|
|
catch e
|
2013-02-25 12:41:34 -05:00
|
|
|
eq 'unmatched ]', e.message
|
2013-06-13 18:21:47 -04:00
|
|
|
|
|
|
|
test "#2981: Enforce initial indentation", ->
|
|
|
|
try
|
2014-01-22 13:30:13 -05:00
|
|
|
CoffeeScript.compile ' a\nb-'
|
2013-06-13 18:21:47 -04:00
|
|
|
ok no
|
|
|
|
catch e
|
|
|
|
eq 'missing indentation', e.message
|
2013-07-31 06:18:50 -04:00
|
|
|
|
|
|
|
test "'single-line' expression containing multiple lines", ->
|
|
|
|
doesNotThrow -> CoffeeScript.compile """
|
|
|
|
(a, b) -> if a
|
|
|
|
-a
|
|
|
|
else if b
|
|
|
|
then -b
|
|
|
|
else null
|
|
|
|
"""
|
2014-01-22 13:30:13 -05:00
|
|
|
|
|
|
|
test "#1275: allow indentation before closing brackets", ->
|
|
|
|
array = [
|
|
|
|
1
|
|
|
|
2
|
|
|
|
3
|
|
|
|
]
|
|
|
|
eq array, array
|
|
|
|
do ->
|
|
|
|
(
|
|
|
|
a = 1
|
|
|
|
)
|
|
|
|
eq 1, a
|