removed ruby tests, and started the process of converting the CoffeeScript tests over to use Node's assert() module
This commit is contained in:
parent
448ed36cd2
commit
b41afe79b4
|
@ -1,8 +1,9 @@
|
|||
# Custom build scripts, replacing the Rakefile. To invoke (for example):
|
||||
#
|
||||
# bin/node_coffee -r build.coffee -- parser
|
||||
# bin/node_coffee -r tasks.coffee -- parser
|
||||
|
||||
fs: require 'fs'
|
||||
coffee: require 'coffee-script'
|
||||
|
||||
# Run a CoffeeScript through our node/coffee interpreter.
|
||||
run: (args) ->
|
||||
|
@ -11,7 +12,7 @@ run: (args) ->
|
|||
|
||||
# Print the usage message for the build scripts.
|
||||
usage: ->
|
||||
puts "build.coffee usage goes here..."
|
||||
puts "tasks.coffee usage goes here..."
|
||||
|
||||
# Build the CoffeeScript source code -- if you're editing the parser, run
|
||||
# this before you run "build parser".
|
||||
|
@ -28,9 +29,20 @@ build_parser: ->
|
|||
fs.open(parser_path, process.O_CREAT | process.O_WRONLY | process.O_TRUNC, parseInt('0755', 8)).addCallback (fd) ->
|
||||
fs.write(fd, js)
|
||||
|
||||
# Run the CoffeeScript test suite.
|
||||
run_tests: ->
|
||||
process.mixin require 'assert'
|
||||
fs.readdir('test').addCallback (files) ->
|
||||
for file in files
|
||||
fs.cat('test/' + file).addCallback (source) ->
|
||||
js: coffee.compile source
|
||||
process.compile js, file
|
||||
|
||||
|
||||
switch process.ARGV[0]
|
||||
when undefined then usage()
|
||||
when 'compiler' then build_compiler()
|
||||
when 'parser' then build_parser()
|
||||
when 'test' then run_tests()
|
||||
when 'highlighter' then build_highlighter()
|
||||
when 'underscore' then build_underscore()
|
|
@ -1,37 +0,0 @@
|
|||
area: (x, y, x1, y1) ->
|
||||
(x - x1) * (x - y1)
|
||||
|
||||
x: y: 10
|
||||
x1: y1: 20
|
||||
|
||||
puts area(x, y, x1, y1) is 100
|
||||
|
||||
puts(area(x, y,
|
||||
x1, y1) is 100)
|
||||
|
||||
puts(area(
|
||||
x
|
||||
y
|
||||
x1
|
||||
y1
|
||||
) is 100)
|
||||
|
||||
|
||||
# Arguments are turned into arrays.
|
||||
curried: ->
|
||||
puts area.apply(this, arguments.concat(20, 20)) is 100
|
||||
|
||||
curried 10, 10
|
||||
|
||||
|
||||
# Arguments is not a special keyword -- it can be assigned to:
|
||||
func: ->
|
||||
arguments: 25
|
||||
arguments
|
||||
|
||||
puts func(100) is 25
|
||||
|
||||
|
||||
# Arguments can be accessed as a property.
|
||||
this.arguments: 10
|
||||
puts @arguments is 10
|
|
@ -1,48 +0,0 @@
|
|||
nums: n * n for n in [1, 2, 3] when n % 2 isnt 0
|
||||
results: n * 2 for n in nums
|
||||
|
||||
puts results.join(',') is '2,18'
|
||||
|
||||
|
||||
obj: {one: 1, two: 2, three: 3}
|
||||
names: prop + '!' for prop of obj
|
||||
odds: prop + '!' for prop, value of obj when value % 2 isnt 0
|
||||
|
||||
puts names.join(' ') is "one! two! three!"
|
||||
puts odds.join(' ') is "one! three!"
|
||||
|
||||
|
||||
evens: for num in [1, 2, 3, 4, 5, 6] when num % 2 is 0
|
||||
num *= -1
|
||||
num -= 2
|
||||
num * -1
|
||||
|
||||
puts evens.join(', ') is '4, 6, 8'
|
||||
|
||||
|
||||
# Make sure that the "in" operator still works.
|
||||
|
||||
puts 2 in evens
|
||||
|
||||
|
||||
# When functions are being defined within the body of a comprehension, make
|
||||
# sure that their safely wrapped in a closure to preserve local variables.
|
||||
|
||||
obj: {}
|
||||
|
||||
methods: ['one', 'two', 'three']
|
||||
|
||||
for method in methods
|
||||
name: method
|
||||
obj[name]: ->
|
||||
"I'm " + name
|
||||
|
||||
puts obj.one() is "I'm one"
|
||||
puts obj.two() is "I'm two"
|
||||
puts obj.three() is "I'm three"
|
||||
|
||||
|
||||
# Steps should work for array comprehensions.
|
||||
|
||||
array: [0..10]
|
||||
puts num % 2 is 0 for num in array by 2
|
|
@ -1,14 +0,0 @@
|
|||
# The cornerstone, an each implementation.
|
||||
# Handles objects implementing forEach, arrays, and raw objects.
|
||||
_.each: (obj, iterator, context) ->
|
||||
index: 0
|
||||
try
|
||||
if obj.forEach
|
||||
obj.forEach(iterator, context)
|
||||
else if _.isArray(obj) or _.isArguments(obj)
|
||||
iterator.call(context, item, i, obj) for item, i in obj
|
||||
else
|
||||
iterator.call(context, obj[key], key, obj) for key in _.keys(obj)
|
||||
catch e
|
||||
throw e if e isnt breaker
|
||||
obj
|
|
@ -1 +0,0 @@
|
|||
[[:COMMENT, [" The cornerstone, an each implementation.", " Handles objects implementing forEach, arrays, and raw objects."]], ["\n", "\n"], [:IDENTIFIER, "_"], [:PROPERTY_ACCESS, "."], [:IDENTIFIER, "each"], [:ASSIGN, ":"], [:PARAM_START, "("], [:PARAM, "obj"], [",", ","], [:PARAM, "iterator"], [",", ","], [:PARAM, "context"], [:PARAM_END, ")"], ["->", "->"], [:INDENT, 2], [:IDENTIFIER, "index"], [:ASSIGN, ":"], [:NUMBER, "0"], ["\n", "\n"], [:TRY, "try"], [:INDENT, 2], [:IF, "if"], [:IDENTIFIER, "obj"], [:PROPERTY_ACCESS, "."], [:IDENTIFIER, "forEach"], [:INDENT, 2], [:IDENTIFIER, "obj"], [:PROPERTY_ACCESS, "."], [:IDENTIFIER, "forEach"], [:CALL_START, "("], [:IDENTIFIER, "iterator"], [",", ","], [:IDENTIFIER, "context"], [:CALL_END, ")"], [:OUTDENT, 2], [:ELSE, "else"], [:IF, "if"], [:IDENTIFIER, "_"], [:PROPERTY_ACCESS, "."], [:IDENTIFIER, "isArray"], [:CALL_START, "("], [:IDENTIFIER, "obj"], [:CALL_END, ")"], [:OR, "or"], [:IDENTIFIER, "_"], [:PROPERTY_ACCESS, "."], [:IDENTIFIER, "isArguments"], [:CALL_START, "("], [:IDENTIFIER, "obj"], [:CALL_END, ")"], [:INDENT, 2], [:IDENTIFIER, "iterator"], [:PROPERTY_ACCESS, "."], [:IDENTIFIER, "call"], [:CALL_START, "("], [:IDENTIFIER, "context"], [",", ","], [:IDENTIFIER, "item"], [",", ","], [:IDENTIFIER, "i"], [",", ","], [:IDENTIFIER, "obj"], [:CALL_END, ")"], [:FOR, "for"], [:IDENTIFIER, "item"], [",", ","], [:IDENTIFIER, "i"], [:IN, "in"], [:IDENTIFIER, "obj"], [:OUTDENT, 2], [:ELSE, "else"], [:INDENT, 2], [:IDENTIFIER, "iterator"], [:PROPERTY_ACCESS, "."], [:IDENTIFIER, "call"], [:CALL_START, "("], [:IDENTIFIER, "context"], [",", ","], [:IDENTIFIER, "obj"], [:INDEX_START, "["], [:IDENTIFIER, "key"], [:INDEX_END, "]"], [",", ","], [:IDENTIFIER, "key"], [",", ","], [:IDENTIFIER, "obj"], [:CALL_END, ")"], [:FOR, "for"], [:IDENTIFIER, "key"], [:IN, "in"], [:IDENTIFIER, "_"], [:PROPERTY_ACCESS, "."], [:IDENTIFIER, "keys"], [:CALL_START, "("], [:IDENTIFIER, "obj"], [:CALL_END, ")"], [:OUTDENT, 2], [:OUTDENT, 2], [:CATCH, "catch"], [:IDENTIFIER, "e"], [:INDENT, 2], [:THROW, "throw"], [:IDENTIFIER, "e"], [:IF, "if"], [:IDENTIFIER, "e"], [:ISNT, "isnt"], [:IDENTIFIER, "breaker"], [:OUTDENT, 2], ["\n", "\n"], [:IDENTIFIER, "obj"], [:OUTDENT, 2], ["\n", "\n"]]
|
|
@ -1,15 +0,0 @@
|
|||
object: {
|
||||
a: 1
|
||||
# Comments between the elements.
|
||||
b: 2
|
||||
# Like this.
|
||||
c: 3
|
||||
}
|
||||
|
||||
array: [
|
||||
1
|
||||
# Comments between the elements.
|
||||
2
|
||||
# Like this.
|
||||
3
|
||||
]
|
|
@ -1,16 +0,0 @@
|
|||
(function(){
|
||||
var array, object;
|
||||
object = {
|
||||
a: 1,
|
||||
// Comments between the elements.
|
||||
b: 2,
|
||||
// Like this.
|
||||
c: 3
|
||||
};
|
||||
array = [1,
|
||||
// Comments between the elements.
|
||||
2,
|
||||
// Like this.
|
||||
3
|
||||
];
|
||||
})();
|
|
@ -1,16 +0,0 @@
|
|||
# Everything should be able to be an expression.
|
||||
|
||||
result: while sunny?
|
||||
go_outside()
|
||||
|
||||
puts(3 + try
|
||||
nonexistent.no_way
|
||||
catch error
|
||||
puts(error)
|
||||
3
|
||||
)
|
||||
|
||||
func: (x) ->
|
||||
return throw x
|
||||
|
||||
puts(x * x for x in [1..100])
|
|
@ -1,20 +0,0 @@
|
|||
# test
|
||||
f1: (x) ->
|
||||
x * x
|
||||
f2: (y) ->
|
||||
y * x
|
||||
f3: 3
|
||||
|
||||
# Parens can close on the proper level.
|
||||
elements.each((el) ->
|
||||
el.click((event) ->
|
||||
el.reset()
|
||||
el.show() if event.active
|
||||
)
|
||||
)
|
||||
|
||||
# Or, parens can close blocks early.
|
||||
elements.each((el) ->
|
||||
el.click((event) ->
|
||||
el.reset()
|
||||
el.show() if event.active))
|
|
@ -0,0 +1,34 @@
|
|||
area: (x, y, x1, y1) ->
|
||||
(x - x1) * (x - y1)
|
||||
|
||||
x: y: 10
|
||||
x1: y1: 20
|
||||
|
||||
ok area(x, y, x1, y1) is 100, 'basic arguments'
|
||||
|
||||
ok(area(x, y,
|
||||
x1, y1) is 100, 'arguments on split lines')
|
||||
|
||||
ok(area(
|
||||
x
|
||||
y
|
||||
x1
|
||||
y1
|
||||
) is 100, 'newline delimited arguments')
|
||||
|
||||
|
||||
curried: ->
|
||||
ok area.apply(this, arguments.concat(20, 20)) is 100, 'arguments converted into an array'
|
||||
|
||||
curried 10, 10
|
||||
|
||||
|
||||
func: ->
|
||||
arguments: 25
|
||||
arguments
|
||||
|
||||
ok func(100) is 25, 'arguments as a regular identifier'
|
||||
|
||||
|
||||
this.arguments: 10
|
||||
ok @arguments is 10, 'arguments accessed as a property'
|
|
@ -0,0 +1,42 @@
|
|||
nums: n * n for n in [1, 2, 3] when n % 2 isnt 0
|
||||
results: n * 2 for n in nums
|
||||
|
||||
ok results.join(',') is '2,18', 'basic array comprehension'
|
||||
|
||||
|
||||
obj: {one: 1, two: 2, three: 3}
|
||||
names: prop + '!' for prop of obj
|
||||
odds: prop + '!' for prop, value of obj when value % 2 isnt 0
|
||||
|
||||
ok names.join(' ') is "one! two! three!", 'basic object comprehension'
|
||||
ok odds.join(' ') is "one! three!", 'object comprehension with a filter'
|
||||
|
||||
|
||||
evens: for num in [1, 2, 3, 4, 5, 6] when num % 2 is 0
|
||||
num *= -1
|
||||
num -= 2
|
||||
num * -1
|
||||
|
||||
ok evens.join(', ') is '4, 6, 8', 'multiline array comprehension with filter'
|
||||
|
||||
|
||||
ok 2 in evens, 'the in operator still works, standalone'
|
||||
|
||||
|
||||
# Ensure that the closure wrapper preserves local variables.
|
||||
obj: {}
|
||||
|
||||
methods: ['one', 'two', 'three']
|
||||
|
||||
for method in methods
|
||||
name: method
|
||||
obj[name]: ->
|
||||
"I'm " + name
|
||||
|
||||
ok obj.one() is "I'm one"
|
||||
ok obj.two() is "I'm two"
|
||||
ok obj.three() is "I'm three"
|
||||
|
||||
|
||||
array: [0..10]
|
||||
ok(num % 2 is 0 for num in array by 2, 'naked ranges are expanded into arrays')
|
|
@ -1,5 +0,0 @@
|
|||
require 'lib/coffee-script'
|
||||
|
||||
class Test::Unit::TestCase
|
||||
include CoffeeScript
|
||||
end
|
|
@ -1,48 +0,0 @@
|
|||
require 'test_helper'
|
||||
|
||||
class ExecutionTest < Test::Unit::TestCase
|
||||
|
||||
NO_WARNINGS = "0 error(s), 0 warning(s)"
|
||||
|
||||
SOURCES = [
|
||||
'test/fixtures/execution/*.coffee',
|
||||
'examples/beautiful_code/*.coffee',
|
||||
'examples/computer_science/*.coffee'
|
||||
]
|
||||
|
||||
# This is by far the most important test. It evaluates all of the
|
||||
# CoffeeScript in test/fixtures/execution, as well as examples/beautiful_code,
|
||||
# ensuring that all our syntax actually works.
|
||||
def test_execution_of_coffeescript
|
||||
(`bin/coffee -r #{SOURCES.join(' ')}`).split("\n").each do |line|
|
||||
assert line == "true"
|
||||
end
|
||||
end
|
||||
|
||||
# Test all of the code examples under Narwhal as well.
|
||||
def test_execution_with_narwhal
|
||||
(`bin/coffee -r --narwhal #{SOURCES.join(' ')}`).split("\n").each do |line|
|
||||
assert line == "true"
|
||||
end
|
||||
end
|
||||
|
||||
def test_lintless_tests
|
||||
no_warnings `bin/coffee -l test/fixtures/*/*.coffee`
|
||||
end
|
||||
|
||||
def test_lintless_examples
|
||||
no_warnings `bin/coffee -l examples/*.coffee`
|
||||
end
|
||||
|
||||
def test_lintless_documentation
|
||||
no_warnings `bin/coffee -l documentation/coffee/*.coffee`
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
def no_warnings(output)
|
||||
output.split("\n").each {|line| assert line == NO_WARNINGS }
|
||||
end
|
||||
|
||||
end
|
|
@ -1,59 +0,0 @@
|
|||
require 'test_helper'
|
||||
|
||||
class LexerTest < Test::Unit::TestCase
|
||||
|
||||
def setup
|
||||
@lex = Lexer.new
|
||||
end
|
||||
|
||||
def test_lexing_an_empty_string
|
||||
assert @lex.tokenize("") == []
|
||||
end
|
||||
|
||||
def test_lexing_basic_assignment
|
||||
code = "a: 'one'\nb: [1, 2]"
|
||||
assert @lex.tokenize(code) == [[:IDENTIFIER, "a"], [:ASSIGN, ":"],
|
||||
[:STRING, "'one'"], ["\n", "\n"], [:IDENTIFIER, "b"], [:ASSIGN, ":"],
|
||||
["[", "["], [:NUMBER, "1"], [",", ","], [:NUMBER, "2"], ["]", "]"],
|
||||
["\n", "\n"]]
|
||||
end
|
||||
|
||||
def test_lexing_object_literal
|
||||
code = "{one : 1}"
|
||||
assert @lex.tokenize(code) == [["{", "{"], [:IDENTIFIER, "one"], [:ASSIGN, ":"],
|
||||
[:NUMBER, "1"], ["}", "}"], ["\n", "\n"]]
|
||||
end
|
||||
|
||||
def test_lexing_function_definition
|
||||
code = "(x, y) -> x * y"
|
||||
assert @lex.tokenize(code) == [[:PARAM_START, "("], [:PARAM, "x"],
|
||||
[",", ","], [:PARAM, "y"], [:PARAM_END, ")"],
|
||||
["->", "->"], [:INDENT, 2], [:IDENTIFIER, "x"], ["*", "*"],
|
||||
[:IDENTIFIER, "y"], [:OUTDENT, 2], ["\n", "\n"]]
|
||||
end
|
||||
|
||||
def test_lexing_if_statement
|
||||
code = "clap_your_hands() if happy"
|
||||
assert @lex.tokenize(code) == [[:IDENTIFIER, "clap_your_hands"], [:CALL_START, "("],
|
||||
[:CALL_END, ")"], [:IF, "if"], [:IDENTIFIER, "happy"], ["\n", "\n"]]
|
||||
end
|
||||
|
||||
def test_lexing_comment
|
||||
code = "a: 1\n# comment\n# on two lines\nb: 2"
|
||||
assert @lex.tokenize(code) == [[:IDENTIFIER, "a"], [:ASSIGN, ":"], [:NUMBER, "1"],
|
||||
["\n", "\n"], [:COMMENT, [" comment", " on two lines"]], ["\n", "\n"],
|
||||
[:IDENTIFIER, "b"], [:ASSIGN, ":"], [:NUMBER, "2"], ["\n", "\n"]]
|
||||
end
|
||||
|
||||
def test_lexing_newline_escaper
|
||||
code = "two: 1 + \\\n\n 1"
|
||||
assert @lex.tokenize(code) == [[:IDENTIFIER, "two"], [:ASSIGN, ":"],
|
||||
[:NUMBER, "1"], ["+", "+"], [:NUMBER, "1"], ["\n", "\n"]]
|
||||
end
|
||||
|
||||
def test_lexing
|
||||
tokens = @lex.tokenize(File.read('test/fixtures/generation/each.coffee'))
|
||||
assert tokens.inspect == File.read('test/fixtures/generation/each.tokens')
|
||||
end
|
||||
|
||||
end
|
|
@ -1,74 +0,0 @@
|
|||
require 'test_helper'
|
||||
|
||||
class ParserTest < Test::Unit::TestCase
|
||||
|
||||
def setup
|
||||
@par = Parser.new
|
||||
end
|
||||
|
||||
def test_parsing_an_empty_string
|
||||
nodes = @par.parse("")
|
||||
assert nodes.is_a?(Expressions)
|
||||
assert nodes.expressions.empty?
|
||||
end
|
||||
|
||||
def test_parsing_a_basic_assignment
|
||||
nodes = @par.parse("a: 'one'").expressions
|
||||
assert nodes.length == 1
|
||||
assign = nodes.first
|
||||
assert assign.is_a?(AssignNode)
|
||||
assert assign.variable.base == 'a'
|
||||
end
|
||||
|
||||
def test_parsing_an_object_literal
|
||||
nodes = @par.parse("{one : 1\ntwo : 2}").expressions
|
||||
obj = nodes.first.base
|
||||
assert obj.is_a?(ObjectNode)
|
||||
assert obj.properties.first.variable.base.value == "one"
|
||||
assert obj.properties.last.variable.base.value == "two"
|
||||
end
|
||||
|
||||
def test_parsing_an_function_definition
|
||||
code = @par.parse("(x, y) -> x * y").expressions.first
|
||||
assert code.params == ['x', 'y']
|
||||
body = code.body.expressions.first
|
||||
assert body.is_a?(OpNode)
|
||||
assert body.operator == '*'
|
||||
end
|
||||
|
||||
def test_parsing_if_statement
|
||||
the_if = @par.parse("clap_your_hands() if happy").expressions.first
|
||||
assert the_if.is_a?(IfNode)
|
||||
assert the_if.condition.base == 'happy'
|
||||
assert the_if.body.is_a?(CallNode)
|
||||
assert the_if.body.variable.base == 'clap_your_hands'
|
||||
end
|
||||
|
||||
def test_parsing_array_comprehension
|
||||
nodes = @par.parse("i for x, i in [10, 9, 8, 7, 6, 5] when i % 2 is 0").expressions
|
||||
assert nodes.first.is_a?(ForNode)
|
||||
assert nodes.first.body.base == 'i'
|
||||
assert nodes.first.filter.operator == '==='
|
||||
assert nodes.first.source.base.objects.last.base.value == "5"
|
||||
end
|
||||
|
||||
def test_parsing_comment
|
||||
nodes = @par.parse("a: 1\n# comment\nb: 2").expressions
|
||||
assert nodes[1].is_a?(CommentNode)
|
||||
end
|
||||
|
||||
def test_parsing_inner_comments
|
||||
nodes = @par.parse(File.read('test/fixtures/generation/inner_comments.coffee'))
|
||||
assert nodes.compile == File.read('test/fixtures/generation/inner_comments.js')
|
||||
end
|
||||
|
||||
def test_parsing
|
||||
nodes = @par.parse(File.read('test/fixtures/generation/each.coffee'))
|
||||
assign = nodes.expressions[1]
|
||||
assert assign.is_a?(AssignNode)
|
||||
assert assign.variable.base == '_'
|
||||
assert assign.value.is_a?(CodeNode)
|
||||
assert assign.value.params == ['obj', 'iterator', 'context']
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in New Issue