2010-12-31 03:48:31 +00:00
|
|
|
|
# Compilation
|
|
|
|
|
# -----------
|
|
|
|
|
|
2017-09-15 13:58:18 +00:00
|
|
|
|
# Helper to pipe the CoffeeScript compiler’s output through a transpiler.
|
|
|
|
|
transpile = (method, code, options = {}) ->
|
|
|
|
|
# `method` should be 'compile' or 'eval' or 'run'
|
|
|
|
|
options.bare = yes
|
|
|
|
|
options.transpile =
|
|
|
|
|
# Target Internet Explorer 6, which supports no ES2015+ features.
|
2018-09-09 20:41:49 +00:00
|
|
|
|
presets: [['@babel/env', {targets: browsers: ['ie 6']}]]
|
2017-09-15 13:58:18 +00:00
|
|
|
|
CoffeeScript[method] code, options
|
|
|
|
|
|
2010-12-31 03:48:31 +00:00
|
|
|
|
|
2011-03-12 02:59:17 +00:00
|
|
|
|
test "ensure that carriage returns don't break compilation on Windows", ->
|
2019-12-16 05:16:55 +00:00
|
|
|
|
doesNotThrowCompileError 'one\r\ntwo', bare: on
|
2010-12-31 03:48:31 +00:00
|
|
|
|
|
2013-10-20 19:21:06 +00:00
|
|
|
|
test "#3089 - don't mutate passed in options to compile", ->
|
|
|
|
|
opts = {}
|
|
|
|
|
CoffeeScript.compile '1 + 1', opts
|
2016-11-08 07:40:01 +00:00
|
|
|
|
ok !opts.scope
|
2013-10-20 19:21:06 +00:00
|
|
|
|
|
2011-04-29 19:53:30 +00:00
|
|
|
|
test "--bare", ->
|
|
|
|
|
eq -1, CoffeeScript.compile('x = y', bare: on).indexOf 'function'
|
2011-03-12 02:59:17 +00:00
|
|
|
|
ok 'passed' is CoffeeScript.eval '"passed"', bare: on, filename: 'test'
|
2010-12-31 03:48:31 +00:00
|
|
|
|
|
2012-01-10 17:54:21 +00:00
|
|
|
|
test "header (#1778)", ->
|
|
|
|
|
header = "// Generated by CoffeeScript #{CoffeeScript.VERSION}\n"
|
|
|
|
|
eq 0, CoffeeScript.compile('x = y', header: on).indexOf header
|
|
|
|
|
|
2012-01-10 19:03:48 +00:00
|
|
|
|
test "header is disabled by default", ->
|
|
|
|
|
header = "// Generated by CoffeeScript #{CoffeeScript.VERSION}\n"
|
|
|
|
|
eq -1, CoffeeScript.compile('x = y').indexOf header
|
|
|
|
|
|
2011-03-12 02:59:17 +00:00
|
|
|
|
test "multiple generated references", ->
|
2010-12-31 03:48:31 +00:00
|
|
|
|
a = {b: []}
|
|
|
|
|
a.b[true] = -> this == a.b
|
|
|
|
|
c = 0
|
|
|
|
|
d = []
|
|
|
|
|
ok a.b[0<++c<2] d...
|
|
|
|
|
|
2011-03-12 02:59:17 +00:00
|
|
|
|
test "splat on a line by itself is invalid", ->
|
2019-12-16 05:16:55 +00:00
|
|
|
|
throwsCompileError "x 'a'\n...\n"
|
2011-03-12 02:59:17 +00:00
|
|
|
|
|
|
|
|
|
test "Issue 750", ->
|
2010-12-31 03:48:31 +00:00
|
|
|
|
|
2019-12-16 05:16:55 +00:00
|
|
|
|
throwsCompileError 'f(->'
|
2010-12-31 03:48:31 +00:00
|
|
|
|
|
2019-12-16 05:16:55 +00:00
|
|
|
|
throwsCompileError 'a = (break)'
|
2010-12-31 03:48:31 +00:00
|
|
|
|
|
2019-12-16 05:16:55 +00:00
|
|
|
|
throwsCompileError 'a = (return 5 for item in list)'
|
2010-12-31 03:48:31 +00:00
|
|
|
|
|
2019-12-16 05:16:55 +00:00
|
|
|
|
throwsCompileError 'a = (return 5 while condition)'
|
2010-12-31 03:48:31 +00:00
|
|
|
|
|
2019-12-16 05:16:55 +00:00
|
|
|
|
throwsCompileError 'a = for x in y\n return 5'
|
2010-12-31 03:48:31 +00:00
|
|
|
|
|
2011-03-12 02:59:17 +00:00
|
|
|
|
test "Issue #986: Unicode identifiers", ->
|
|
|
|
|
λ = 5
|
|
|
|
|
eq λ, 5
|
2010-12-31 03:48:31 +00:00
|
|
|
|
|
2015-01-06 20:32:14 +00:00
|
|
|
|
test "#2516: Unicode spaces should not be part of identifiers", ->
|
|
|
|
|
a = (x) -> x * 2
|
|
|
|
|
b = 3
|
|
|
|
|
eq 6, a b # U+00A0 NO-BREAK SPACE
|
|
|
|
|
eq 6, a b # U+1680 OGHAM SPACE MARK
|
|
|
|
|
eq 6, a b # U+2000 EN QUAD
|
|
|
|
|
eq 6, a b # U+2001 EM QUAD
|
|
|
|
|
eq 6, a b # U+2002 EN SPACE
|
|
|
|
|
eq 6, a b # U+2003 EM SPACE
|
|
|
|
|
eq 6, a b # U+2004 THREE-PER-EM SPACE
|
|
|
|
|
eq 6, a b # U+2005 FOUR-PER-EM SPACE
|
|
|
|
|
eq 6, a b # U+2006 SIX-PER-EM SPACE
|
|
|
|
|
eq 6, a b # U+2007 FIGURE SPACE
|
|
|
|
|
eq 6, a b # U+2008 PUNCTUATION SPACE
|
|
|
|
|
eq 6, a b # U+2009 THIN SPACE
|
|
|
|
|
eq 6, a b # U+200A HAIR SPACE
|
|
|
|
|
eq 6, a b # U+202F NARROW NO-BREAK SPACE
|
|
|
|
|
eq 6, a b # U+205F MEDIUM MATHEMATICAL SPACE
|
|
|
|
|
eq 6, a b # U+3000 IDEOGRAPHIC SPACE
|
|
|
|
|
|
|
|
|
|
# #3560: Non-breaking space (U+00A0) (before `'c'`)
|
|
|
|
|
eq 5, {c: 5}[ 'c' ]
|
|
|
|
|
|
|
|
|
|
# A line where every space in non-breaking
|
2016-09-20 21:06:44 +00:00
|
|
|
|
eq 1 + 1, 2
|
2015-01-06 20:32:14 +00:00
|
|
|
|
|
2010-12-31 03:48:31 +00:00
|
|
|
|
test "don't accidentally stringify keywords", ->
|
|
|
|
|
ok (-> this == 'this')() is false
|
2011-01-11 04:19:31 +00:00
|
|
|
|
|
2015-02-23 23:39:05 +00:00
|
|
|
|
test "#1026: no if/else/else allowed", ->
|
2019-12-16 05:16:55 +00:00
|
|
|
|
throwsCompileError '''
|
2011-01-11 04:19:31 +00:00
|
|
|
|
if a
|
|
|
|
|
b
|
|
|
|
|
else
|
|
|
|
|
c
|
|
|
|
|
else
|
|
|
|
|
d
|
|
|
|
|
'''
|
2011-01-19 04:10:09 +00:00
|
|
|
|
|
2015-02-23 23:39:05 +00:00
|
|
|
|
test "#1050: no closing asterisk comments from within block comments", ->
|
2019-12-16 05:16:55 +00:00
|
|
|
|
throwsCompileError "### */ ###"
|
2011-04-28 01:36:29 +00:00
|
|
|
|
|
2013-11-27 12:58:14 +00:00
|
|
|
|
test "#1273: escaping quotes at the end of heredocs", ->
|
2019-12-16 05:16:55 +00:00
|
|
|
|
throwsCompileError '"""\\"""' # """\"""
|
|
|
|
|
throwsCompileError '"""\\\\\\"""' # """\\\"""
|
2013-11-27 12:58:14 +00:00
|
|
|
|
|
2011-04-28 01:36:29 +00:00
|
|
|
|
test "#1106: __proto__ compilation", ->
|
|
|
|
|
object = eq
|
2011-04-28 01:57:22 +00:00
|
|
|
|
@["__proto__"] = true
|
2011-04-28 01:36:29 +00:00
|
|
|
|
ok __proto__
|
2011-11-14 16:18:45 +00:00
|
|
|
|
|
|
|
|
|
test "reference named hasOwnProperty", ->
|
|
|
|
|
CoffeeScript.compile 'hasOwnProperty = 0; a = 1'
|
2013-03-05 08:10:56 +00:00
|
|
|
|
|
2013-03-05 08:28:29 +00:00
|
|
|
|
test "#1055: invalid keys in real (but not work-product) objects", ->
|
2019-12-16 05:16:55 +00:00
|
|
|
|
throwsCompileError "@key: value"
|
2013-03-05 08:28:29 +00:00
|
|
|
|
|
|
|
|
|
test "#1066: interpolated strings are not implicit functions", ->
|
2019-12-16 05:16:55 +00:00
|
|
|
|
throwsCompileError '"int#{er}polated" arg'
|
2013-03-25 17:56:24 +00:00
|
|
|
|
|
|
|
|
|
test "#2846: while with empty body", ->
|
2013-04-21 10:27:30 +00:00
|
|
|
|
CoffeeScript.compile 'while 1 then', {sourceMap: true}
|
|
|
|
|
|
|
|
|
|
test "#2944: implicit call with a regex argument", ->
|
2013-05-25 22:29:26 +00:00
|
|
|
|
CoffeeScript.compile 'o[key] /regex/'
|
|
|
|
|
|
|
|
|
|
test "#3001: `own` shouldn't be allowed in a `for`-`in` loop", ->
|
2019-12-16 05:16:55 +00:00
|
|
|
|
throwsCompileError "a for own b in c"
|
2013-07-30 15:24:46 +00:00
|
|
|
|
|
|
|
|
|
test "#2994: single-line `if` requires `then`", ->
|
2019-12-16 05:16:55 +00:00
|
|
|
|
throwsCompileError "if b else x"
|
2017-09-15 13:58:18 +00:00
|
|
|
|
|
|
|
|
|
test "transpile option, for Node API CoffeeScript.compile", ->
|
|
|
|
|
return if global.testingBrowser
|
|
|
|
|
ok transpile('compile', "import fs from 'fs'").includes 'require'
|
|
|
|
|
|
|
|
|
|
test "transpile option, for Node API CoffeeScript.eval", ->
|
|
|
|
|
return if global.testingBrowser
|
|
|
|
|
ok transpile 'eval', "import path from 'path'; path.sep in ['/', '\\\\']"
|
|
|
|
|
|
|
|
|
|
test "transpile option, for Node API CoffeeScript.run", ->
|
|
|
|
|
return if global.testingBrowser
|
|
|
|
|
doesNotThrow -> transpile 'run', "import fs from 'fs'"
|
|
|
|
|
|
|
|
|
|
test "transpile option has merged source maps", ->
|
|
|
|
|
return if global.testingBrowser
|
|
|
|
|
untranspiledOutput = CoffeeScript.compile "import path from 'path'\nconsole.log path.sep", sourceMap: yes
|
|
|
|
|
transpiledOutput = transpile 'compile', "import path from 'path'\nconsole.log path.sep", sourceMap: yes
|
|
|
|
|
untranspiledOutput.v3SourceMap = JSON.parse untranspiledOutput.v3SourceMap
|
|
|
|
|
transpiledOutput.v3SourceMap = JSON.parse transpiledOutput.v3SourceMap
|
|
|
|
|
ok untranspiledOutput.v3SourceMap.mappings isnt transpiledOutput.v3SourceMap.mappings
|
|
|
|
|
# Babel adds `'use strict';` to the top of files with the modules transform.
|
|
|
|
|
eq transpiledOutput.js.indexOf('use strict'), 1
|
|
|
|
|
# The `'use strict';` followed by two newlines results in the first two lines
|
|
|
|
|
# of the source map mappings being two blank/skipped lines.
|
|
|
|
|
eq transpiledOutput.v3SourceMap.mappings.indexOf(';;'), 0
|
|
|
|
|
# The number of lines in the transpiled code should match the number of lines
|
|
|
|
|
# in the source map.
|
|
|
|
|
eq transpiledOutput.js.split('\n').length, transpiledOutput.v3SourceMap.mappings.split(';').length
|
|
|
|
|
|
|
|
|
|
test "using transpile from the Node API requires an object", ->
|
|
|
|
|
try
|
|
|
|
|
CoffeeScript.compile '', transpile: yes
|
|
|
|
|
catch exception
|
|
|
|
|
eq exception.message, 'The transpile option must be given an object with options to pass to Babel'
|
2017-10-05 00:49:59 +00:00
|
|
|
|
|
|
|
|
|
test "transpile option applies to imported .coffee files", ->
|
|
|
|
|
return if global.testingBrowser
|
|
|
|
|
doesNotThrow -> transpile 'run', "import { getSep } from './test/importing/transpile_import'\ngetSep()"
|
2018-01-31 05:09:50 +00:00
|
|
|
|
|
|
|
|
|
test "#3306: trailing comma in a function call in the last line", ->
|
|
|
|
|
eqJS '''
|
|
|
|
|
foo bar,
|
|
|
|
|
''', '''
|
|
|
|
|
foo(bar);
|
2018-09-09 20:41:49 +00:00
|
|
|
|
'''
|