jbarnette-johnson 1.0.0.200806240111
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +5 -0
- data/MANIFEST +385 -0
- data/MINGW32.mk +124 -0
- data/README.rdoc +51 -0
- data/Rakefile +166 -0
- data/bin/johnson +107 -0
- data/cross-compile.txt +38 -0
- data/ext/spidermonkey/context.c +122 -0
- data/ext/spidermonkey/context.h +19 -0
- data/ext/spidermonkey/conversions.c +286 -0
- data/ext/spidermonkey/conversions.h +18 -0
- data/ext/spidermonkey/debugger.c +208 -0
- data/ext/spidermonkey/debugger.h +9 -0
- data/ext/spidermonkey/extconf.rb +25 -0
- data/ext/spidermonkey/extensions.c +37 -0
- data/ext/spidermonkey/extensions.h +12 -0
- data/ext/spidermonkey/global.c +40 -0
- data/ext/spidermonkey/global.h +11 -0
- data/ext/spidermonkey/idhash.c +16 -0
- data/ext/spidermonkey/idhash.h +8 -0
- data/ext/spidermonkey/immutable_node.c.erb +522 -0
- data/ext/spidermonkey/immutable_node.h +22 -0
- data/ext/spidermonkey/jroot.h +187 -0
- data/ext/spidermonkey/js_land_proxy.c +609 -0
- data/ext/spidermonkey/js_land_proxy.h +20 -0
- data/ext/spidermonkey/ruby_land_proxy.c +537 -0
- data/ext/spidermonkey/ruby_land_proxy.h +17 -0
- data/ext/spidermonkey/runtime.c +304 -0
- data/ext/spidermonkey/runtime.h +25 -0
- data/ext/spidermonkey/spidermonkey.c +20 -0
- data/ext/spidermonkey/spidermonkey.h +29 -0
- data/js/johnson/browser.js +9 -0
- data/js/johnson/browser/env.js +687 -0
- data/js/johnson/browser/jquery.js +3444 -0
- data/js/johnson/browser/xmlsax.js +1564 -0
- data/js/johnson/browser/xmlw3cdom.js +4189 -0
- data/js/johnson/cli.js +30 -0
- data/js/johnson/prelude.js +80 -0
- data/js/johnson/template.js +29 -0
- data/lib/hoe.rb +748 -0
- data/lib/johnson.rb +46 -0
- data/lib/johnson/cli.rb +7 -0
- data/lib/johnson/cli/options.rb +56 -0
- data/lib/johnson/error.rb +4 -0
- data/lib/johnson/nodes.rb +7 -0
- data/lib/johnson/nodes/binary_node.rb +64 -0
- data/lib/johnson/nodes/for.rb +14 -0
- data/lib/johnson/nodes/for_in.rb +12 -0
- data/lib/johnson/nodes/function.rb +13 -0
- data/lib/johnson/nodes/list.rb +27 -0
- data/lib/johnson/nodes/node.rb +68 -0
- data/lib/johnson/nodes/ternary_node.rb +20 -0
- data/lib/johnson/parser.rb +21 -0
- data/lib/johnson/parser/syntax_error.rb +13 -0
- data/lib/johnson/runtime.rb +55 -0
- data/lib/johnson/spidermonkey/context.rb +10 -0
- data/lib/johnson/spidermonkey/debugger.rb +67 -0
- data/lib/johnson/spidermonkey/immutable_node.rb +280 -0
- data/lib/johnson/spidermonkey/js_land_proxy.rb +62 -0
- data/lib/johnson/spidermonkey/mutable_tree_visitor.rb +233 -0
- data/lib/johnson/spidermonkey/ruby_land_proxy.rb +52 -0
- data/lib/johnson/spidermonkey/runtime.rb +94 -0
- data/lib/johnson/version.rb +4 -0
- data/lib/johnson/visitable.rb +16 -0
- data/lib/johnson/visitors.rb +4 -0
- data/lib/johnson/visitors/dot_visitor.rb +167 -0
- data/lib/johnson/visitors/ecma_visitor.rb +315 -0
- data/lib/johnson/visitors/enumerating_visitor.rb +115 -0
- data/lib/johnson/visitors/sexp_visitor.rb +172 -0
- data/lib/rails/init.rb +37 -0
- data/test/assets/index.html +38 -0
- data/test/assets/jquery_test.html +186 -0
- data/test/helper.rb +58 -0
- data/test/johnson/browser_test.rb +38 -0
- data/test/johnson/conversions/array_test.rb +32 -0
- data/test/johnson/conversions/boolean_test.rb +17 -0
- data/test/johnson/conversions/callable_test.rb +34 -0
- data/test/johnson/conversions/file_test.rb +15 -0
- data/test/johnson/conversions/nil_test.rb +20 -0
- data/test/johnson/conversions/number_test.rb +34 -0
- data/test/johnson/conversions/regexp_test.rb +24 -0
- data/test/johnson/conversions/string_test.rb +26 -0
- data/test/johnson/conversions/struct_test.rb +15 -0
- data/test/johnson/conversions/symbol_test.rb +19 -0
- data/test/johnson/conversions/thread_test.rb +24 -0
- data/test/johnson/error_test.rb +9 -0
- data/test/johnson/extensions_test.rb +56 -0
- data/test/johnson/nodes/array_literal_test.rb +57 -0
- data/test/johnson/nodes/array_node_test.rb +26 -0
- data/test/johnson/nodes/binary_node_test.rb +61 -0
- data/test/johnson/nodes/bracket_access_test.rb +16 -0
- data/test/johnson/nodes/delete_test.rb +11 -0
- data/test/johnson/nodes/do_while_test.rb +12 -0
- data/test/johnson/nodes/dot_accessor_test.rb +15 -0
- data/test/johnson/nodes/export_test.rb +9 -0
- data/test/johnson/nodes/for_test.rb +54 -0
- data/test/johnson/nodes/function_test.rb +71 -0
- data/test/johnson/nodes/if_test.rb +41 -0
- data/test/johnson/nodes/import_test.rb +13 -0
- data/test/johnson/nodes/label_test.rb +19 -0
- data/test/johnson/nodes/object_literal_test.rb +110 -0
- data/test/johnson/nodes/return_test.rb +16 -0
- data/test/johnson/nodes/semi_test.rb +8 -0
- data/test/johnson/nodes/switch_test.rb +55 -0
- data/test/johnson/nodes/ternary_test.rb +25 -0
- data/test/johnson/nodes/throw_test.rb +9 -0
- data/test/johnson/nodes/try_node_test.rb +59 -0
- data/test/johnson/nodes/typeof_test.rb +11 -0
- data/test/johnson/nodes/unary_node_test.rb +23 -0
- data/test/johnson/nodes/void_test.rb +11 -0
- data/test/johnson/nodes/while_test.rb +26 -0
- data/test/johnson/nodes/with_test.rb +10 -0
- data/test/johnson/prelude_test.rb +56 -0
- data/test/johnson/runtime_test.rb +46 -0
- data/test/johnson/spidermonkey/context_test.rb +21 -0
- data/test/johnson/spidermonkey/immutable_node_test.rb +34 -0
- data/test/johnson/spidermonkey/js_land_proxy_test.rb +236 -0
- data/test/johnson/spidermonkey/ruby_land_proxy_test.rb +225 -0
- data/test/johnson/spidermonkey/runtime_test.rb +17 -0
- data/test/johnson/version_test.rb +13 -0
- data/test/johnson/visitors/dot_visitor_test.rb +39 -0
- data/test/johnson/visitors/enumerating_visitor_test.rb +12 -0
- data/test/johnson_test.rb +16 -0
- data/test/jquery_units/test.js +27 -0
- data/test/jquery_units/test_helper.js +197 -0
- data/test/jquery_units/units/ajax.js +795 -0
- data/test/jquery_units/units/core.js +1563 -0
- data/test/jquery_units/units/event.js +299 -0
- data/test/jquery_units/units/fx.js +427 -0
- data/test/jquery_units/units/offset.js +112 -0
- data/test/jquery_units/units/selector.js +224 -0
- data/test/jspec/helper.js +7 -0
- data/test/jspec/jspec.js +192 -0
- data/test/jspec/simple_spec.js +68 -0
- data/test/parser_test.rb +276 -0
- data/todo/.keep +0 -0
- metadata +501 -0
@@ -0,0 +1,16 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "/../../helper"))
|
2
|
+
|
3
|
+
class ReturnTest < Johnson::NodeTestCase
|
4
|
+
def test_return
|
5
|
+
assert_sexp([[:func_expr, "foo", [], [[:return, nil]]]],
|
6
|
+
@parser.parse('function foo() { return; }'))
|
7
|
+
assert_ecma("function foo() {\n return;\n}",
|
8
|
+
@parser.parse('function foo() { return; }'))
|
9
|
+
|
10
|
+
|
11
|
+
assert_sexp([[:func_expr, "foo", [], [[:return, [:lit, 10]]]]],
|
12
|
+
@parser.parse('function foo() { return 10; }'))
|
13
|
+
assert_ecma("function foo() {\n return 10;\n}",
|
14
|
+
@parser.parse('function foo() { return 10; }'))
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "/../../helper"))
|
2
|
+
|
3
|
+
class SwitchTest < Johnson::NodeTestCase
|
4
|
+
def test_empty_switch
|
5
|
+
assert_sexp([[:switch, [:name, "o"], []]],
|
6
|
+
@parser.parse('switch(o) { }')
|
7
|
+
)
|
8
|
+
assert_ecma('switch(o) { }',
|
9
|
+
@parser.parse('switch(o) { }')
|
10
|
+
)
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_switch_with_body
|
14
|
+
assert_sexp([[:switch, [:name, "o"],
|
15
|
+
[
|
16
|
+
[:case, [:name, "j"], [[:name, "foo"]]]
|
17
|
+
]
|
18
|
+
]], @parser.parse('switch(o) { case j: foo; }')
|
19
|
+
)
|
20
|
+
assert_ecma("switch(o) {\n case j: {\n foo;\n}\n}",
|
21
|
+
@parser.parse('switch(o) { case j: foo; }')
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_switch_empty_case
|
26
|
+
assert_ecma("switch(o) {\n case j: { }\n}",
|
27
|
+
@parser.parse('switch(o) { case j: }')
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_switch_with_body_2_case
|
32
|
+
assert_sexp([[:switch, [:name, "o"],
|
33
|
+
[
|
34
|
+
[:case, [:name, "j"], [[:name, "foo"]]],
|
35
|
+
[:case, [:name, "k"], [[:name, "bar"]]]
|
36
|
+
]
|
37
|
+
]], @parser.parse('switch(o) { case j: foo; case k: bar; }')
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_switch_with_default
|
42
|
+
assert_sexp([[:switch, [:name, "o"], [[:default, nil, [[:name, "bar"]]]]]],
|
43
|
+
@parser.parse('switch(o) { default: bar; }')
|
44
|
+
)
|
45
|
+
assert_ecma("switch(o) {\n default: {\n bar;\n}\n}",
|
46
|
+
@parser.parse('switch(o) { default: bar; }')
|
47
|
+
)
|
48
|
+
assert_sexp([[:switch, [:name, "o"], [[:default, nil, []]]]],
|
49
|
+
@parser.parse('switch(o) { default: }')
|
50
|
+
)
|
51
|
+
assert_ecma("switch(o) {\n default: { }\n}",
|
52
|
+
@parser.parse('switch(o) { default: }')
|
53
|
+
)
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "/../../helper"))
|
2
|
+
|
3
|
+
class TernaryNodeTest < Johnson::NodeTestCase
|
4
|
+
def test_ternary
|
5
|
+
assert_sexp([
|
6
|
+
[:var, [[:assign,
|
7
|
+
[:name, "x"],
|
8
|
+
[:ternary,
|
9
|
+
[:lt, [:name, "y"], [:lit, 10]],
|
10
|
+
[:lit, 20],
|
11
|
+
[:lit, 30]
|
12
|
+
]
|
13
|
+
]]]],
|
14
|
+
@parser.parse('var x = y < 10 ? 20 : 30')
|
15
|
+
)
|
16
|
+
assert_ecma('var x = y < 10 ? 20 : 30;',
|
17
|
+
@parser.parse('var x = y < 10 ? 20 : 30')
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_weird_rounding
|
22
|
+
ecma = @parser.parse('(value < 0.00001) ? 0 : value;').to_ecma
|
23
|
+
assert_match(/\(value < 1.0e-[0]*5\) \? 0 : value;/, ecma)
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "/../../helper"))
|
2
|
+
|
3
|
+
class ThrowTest < Johnson::NodeTestCase
|
4
|
+
def test_to_sexp
|
5
|
+
assert_sexp([[:throw, [:lit, 10]]], @parser.parse('throw 10;'))
|
6
|
+
assert_sexp([[:throw, [:lit, 10]]], @parser.parse('throw 10'))
|
7
|
+
assert_ecma("throw 10;", @parser.parse('throw 10;'))
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "/../../helper"))
|
2
|
+
|
3
|
+
class TryTest < Johnson::NodeTestCase
|
4
|
+
def test_try_finally
|
5
|
+
assert_sexp([[:try,
|
6
|
+
[[:var, [[:assign, [:name, "x"], [:lit, 10]]]]],
|
7
|
+
nil,
|
8
|
+
[[:var, [[:assign, [:name, "x"], [:lit, 20]]]]]
|
9
|
+
]],
|
10
|
+
@parser.parse('try { var x = 10; } finally { var x = 20; }'))
|
11
|
+
assert_ecma(
|
12
|
+
"try {\n var x = 10;\n} finally {\n var x = 20;\n}",
|
13
|
+
@parser.parse('try { var x = 10; } finally { var x = 20; }'))
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_try_catch
|
17
|
+
assert_sexp([
|
18
|
+
[:try,
|
19
|
+
[[:var, [[:assign, [:name, "x"], [:lit, 10]]]]],
|
20
|
+
[[:catch, [:name, "a"], nil,
|
21
|
+
[
|
22
|
+
[:var, [[:assign, [:name, "x"], [:lit, 20]]]],
|
23
|
+
[:postfix_inc, [:name, "x"]]
|
24
|
+
]
|
25
|
+
]],
|
26
|
+
nil]],
|
27
|
+
@parser.parse('try { var x = 10; } catch(a) { var x = 20; x++; }'))
|
28
|
+
assert_ecma("try {\n var x = 10;\n} catch(a) {\n var x = 20;\n x++;\n}",
|
29
|
+
@parser.parse('try { var x = 10; } catch(a) { var x = 20; x++; }'))
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_try_multi_catch
|
33
|
+
assert_sexp([
|
34
|
+
[:try,
|
35
|
+
[[:var, [[:assign, [:name, "x"], [:lit, 10]]]]],
|
36
|
+
[
|
37
|
+
[:catch, [:name, "a"], [:true],
|
38
|
+
[
|
39
|
+
[:var, [[:assign, [:name, "x"], [:lit, 20]]]],
|
40
|
+
[:postfix_inc, [:name, "x"]]
|
41
|
+
]],
|
42
|
+
[:catch, [:name, "b"], [:true],
|
43
|
+
[
|
44
|
+
[:var, [[:assign, [:name, "x"], [:lit, 20]]]],
|
45
|
+
[:postfix_inc, [:name, "x"]]
|
46
|
+
]]
|
47
|
+
],
|
48
|
+
nil]],
|
49
|
+
@parser.parse(' try { var x = 10; }
|
50
|
+
catch(a if true) { var x = 20; x++; }
|
51
|
+
catch(b if true) { var x = 20; x++; }
|
52
|
+
'))
|
53
|
+
assert_ecma("try {\n var x = 10;\n} catch(a) {\n var x = 20;\n x++;\n} catch(b) {\n var x = 20;\n x++;\n}",
|
54
|
+
@parser.parse(' try { var x = 10; }
|
55
|
+
catch(a if true) { var x = 20; x++; }
|
56
|
+
catch(b if true) { var x = 20; x++; }
|
57
|
+
'))
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "/../../helper"))
|
2
|
+
|
3
|
+
class TypeofNodeTest < Johnson::NodeTestCase
|
4
|
+
def test_typeof_sexp
|
5
|
+
assert_sexp(
|
6
|
+
[[:typeof, [:name, 'foo']]],
|
7
|
+
@parser.parse('typeof foo;')
|
8
|
+
)
|
9
|
+
assert_ecma('typeof foo;', @parser.parse('typeof foo;'))
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "/../../helper"))
|
2
|
+
|
3
|
+
class UnaryNodeTest < Johnson::NodeTestCase
|
4
|
+
def test_u_positive_sexp
|
5
|
+
assert_sexp([[:u_pos, [:name, 'foo']]], @parser.parse('+foo;'))
|
6
|
+
assert_ecma('+foo;', @parser.parse('+foo'))
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_u_negative_sexp
|
10
|
+
assert_sexp([[:u_neg, [:name, 'foo']]], @parser.parse('-foo;'))
|
11
|
+
assert_ecma('-foo;', @parser.parse('-foo'))
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_u_bit_not_sexp
|
15
|
+
assert_sexp([[:bitwise_not, [:name, 'foo']]], @parser.parse('~foo;'))
|
16
|
+
assert_ecma('~foo;', @parser.parse('~foo'))
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_u_not_sexp
|
20
|
+
assert_sexp([[:not, [:name, 'foo']]], @parser.parse('!foo;'))
|
21
|
+
assert_ecma('!foo;', @parser.parse('!foo'))
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "/../../helper"))
|
2
|
+
|
3
|
+
class VoidNodeTest < Johnson::NodeTestCase
|
4
|
+
def test_delete_sexp
|
5
|
+
assert_sexp(
|
6
|
+
[[:void, [:name, 'foo']]],
|
7
|
+
@parser.parse('void foo;')
|
8
|
+
)
|
9
|
+
assert_ecma('void foo;', @parser.parse('void foo;'))
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "/../../helper"))
|
2
|
+
|
3
|
+
class WhileTest < Johnson::NodeTestCase
|
4
|
+
def test_while
|
5
|
+
assert_sexp([[:while, [:true], [:var, [[:assign, [:name, "x"], [:lit, 10]]]]]],
|
6
|
+
@parser.parse('while(true) var x = 10;'))
|
7
|
+
assert_ecma('while(true) var x = 10;',
|
8
|
+
@parser.parse('while(true) var x = 10;'))
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_break
|
12
|
+
assert_sexp([[:while, [:true], [:break]]],
|
13
|
+
@parser.parse('while(true) break;'))
|
14
|
+
assert_ecma('while(true) break;',
|
15
|
+
@parser.parse('while(true) break;'))
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_continue
|
19
|
+
assert_sexp([[:while, [:true], [:continue]]],
|
20
|
+
@parser.parse('while(true) continue;'))
|
21
|
+
assert_ecma('while(true) continue;',
|
22
|
+
@parser.parse('while(true) continue;'))
|
23
|
+
assert_ecma("while(true) {\n continue;\n}",
|
24
|
+
@parser.parse('while(true) { continue; }'))
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "/../../helper"))
|
2
|
+
|
3
|
+
class WithTest < Johnson::NodeTestCase
|
4
|
+
def test_with
|
5
|
+
assert_sexp([[:with, [:name, "o"], [:name, "x"]]],
|
6
|
+
@parser.parse('with (o) x;')
|
7
|
+
)
|
8
|
+
assert_ecma("with(o) x;", @parser.parse('with (o) x;'))
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "/../helper"))
|
2
|
+
|
3
|
+
module Johnson
|
4
|
+
class PreludeTest < Johnson::TestCase
|
5
|
+
def test_symbols_are_interned
|
6
|
+
assert(@runtime.evaluate("Johnson.symbolize('foo') === Johnson.symbolize('foo')"))
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_strings_had_a_to_symbol_method
|
10
|
+
assert_js_equal(:monkeys, "'monkeys'.toSymbol()")
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_string_to_symbol_is_not_enumerable
|
14
|
+
assert(!@runtime.evaluate(<<-END))
|
15
|
+
var flag = false;
|
16
|
+
for (x in "foo") { if (x == 'toSymbol') flag = true }
|
17
|
+
flag
|
18
|
+
END
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_symbol_to_string
|
22
|
+
assert_equal("monkey", @runtime.evaluate("Johnson.symbolize('monkey').toString()"))
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_symbol_inspect
|
26
|
+
assert_equal(":monkey", @runtime.evaluate("Johnson.symbolize('monkey').inspect()"))
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_all_of_ruby_is_available
|
30
|
+
assert_raise(Johnson::Error) { @runtime.evaluate("Ruby.Set.new()") }
|
31
|
+
|
32
|
+
@runtime.evaluate("Ruby.require('set')")
|
33
|
+
assert_kind_of(Set, @runtime.evaluate("Ruby.Set.new()"))
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_require_an_existing_js_file_without_extension
|
37
|
+
assert_js("Johnson.require('johnson/template')")
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_require_returns_false_the_second_time_around
|
41
|
+
assert_js("Johnson.require('johnson/template')")
|
42
|
+
assert(!@runtime.evaluate("Johnson.require('johnson/template')"))
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_missing_requires_throw_LoadError
|
46
|
+
assert_js(<<-END)
|
47
|
+
var flag = false;
|
48
|
+
|
49
|
+
try { Johnson.require("johnson/__nonexistent"); }
|
50
|
+
catch(ex) { flag = true; }
|
51
|
+
|
52
|
+
flag;
|
53
|
+
END
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "/../helper"))
|
2
|
+
|
3
|
+
module Johnson
|
4
|
+
class RuntimeTest < Johnson::TestCase
|
5
|
+
def test_default_delegate_is_spidermonkey
|
6
|
+
assert_equal(Johnson::SpiderMonkey::Runtime, @runtime.delegate.class)
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_evaluate_returns_nil_for_nil_expression
|
10
|
+
assert_nil(@runtime.evaluate(nil))
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_js_eval
|
14
|
+
assert_equal(1, @runtime.evaluate('eval("1");'))
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_js_throws_compile_errors
|
18
|
+
assert_raises(Johnson::Error) {
|
19
|
+
@runtime.evaluate("var js_lambda = function(x) { return x ** 2; }")
|
20
|
+
}
|
21
|
+
assert_raises(Johnson::Error) {
|
22
|
+
@runtime.compile("var js_lambda = function(x) { return x ** 2; }")
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_breakpoint_gets_called
|
27
|
+
break_times = 0
|
28
|
+
@runtime['some_number'] = 0
|
29
|
+
script = @runtime.compile("some_number++;
|
30
|
+
var x = 0;
|
31
|
+
for(var i = 0; i < 10; i++) {
|
32
|
+
x++;
|
33
|
+
}
|
34
|
+
some_number++;
|
35
|
+
", 'awesome_script')
|
36
|
+
@runtime.break('awesome_script', 4) do
|
37
|
+
break_times += 1
|
38
|
+
assert_equal(@runtime['i'], @runtime['x'])
|
39
|
+
assert_equal(1, @runtime['some_number'])
|
40
|
+
end
|
41
|
+
@runtime.evaluate_compiled_script(script)
|
42
|
+
assert_equal(10, break_times)
|
43
|
+
assert_equal(2, @runtime['some_number'])
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "/../../helper"))
|
2
|
+
|
3
|
+
module Johnson
|
4
|
+
module SpiderMonkey
|
5
|
+
class ContextTest < Johnson::TestCase
|
6
|
+
def setup
|
7
|
+
@runtime = Johnson::Runtime.new(Johnson::SpiderMonkey::Runtime)
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_wraps_global_unfuckedly
|
11
|
+
assert_same(@runtime.global, @runtime.evaluate("this"))
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_provides_basic_runtime_interface
|
15
|
+
assert(@runtime.respond_to?(:evaluate))
|
16
|
+
assert(@runtime.respond_to?(:[]))
|
17
|
+
assert(@runtime.respond_to?(:[]=))
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "/../../helper"))
|
2
|
+
|
3
|
+
require 'stringio'
|
4
|
+
|
5
|
+
module Johnson
|
6
|
+
module SpiderMonkey
|
7
|
+
class ImmutableNodeTest < Johnson::TestCase
|
8
|
+
include Johnson::SpiderMonkey
|
9
|
+
|
10
|
+
def test_initialize
|
11
|
+
node = nil
|
12
|
+
assert_nothing_raised {
|
13
|
+
node = ImmutableNode.new
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_parse_some_shit
|
18
|
+
assert_nothing_raised {
|
19
|
+
node = ImmutableNode.parse_io(StringIO.new('var x = 10;'))
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_index
|
24
|
+
node = ImmutableNode.parse_io(StringIO.new('var x = 10;'))
|
25
|
+
assert_equal(0, node.index)
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_line
|
29
|
+
node = ImmutableNode.parse_io(StringIO.new('var x = 10;'))
|
30
|
+
assert_equal(0, node.line)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,236 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "/../../helper"))
|
2
|
+
|
3
|
+
module Johnson
|
4
|
+
module SpiderMonkey
|
5
|
+
class JSLandProxyTest < Johnson::TestCase
|
6
|
+
module AModule
|
7
|
+
end
|
8
|
+
|
9
|
+
class AClass
|
10
|
+
attr_reader :args
|
11
|
+
|
12
|
+
def initialize(*args)
|
13
|
+
@args = args
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Foo
|
18
|
+
class Inner
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.bar; 10; end
|
22
|
+
|
23
|
+
attr_accessor :bar
|
24
|
+
|
25
|
+
def initialize
|
26
|
+
@bar = 10
|
27
|
+
end
|
28
|
+
|
29
|
+
def x2(x)
|
30
|
+
x * 2
|
31
|
+
end
|
32
|
+
|
33
|
+
def add(*args)
|
34
|
+
args.inject { |m,n| m += n }
|
35
|
+
end
|
36
|
+
|
37
|
+
def xform(arg)
|
38
|
+
yield(arg)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class Indexable
|
43
|
+
def initialize
|
44
|
+
@store = {}
|
45
|
+
end
|
46
|
+
|
47
|
+
def [](key)
|
48
|
+
@store[key]
|
49
|
+
end
|
50
|
+
|
51
|
+
def []=(key, value)
|
52
|
+
@store[key] = value
|
53
|
+
end
|
54
|
+
|
55
|
+
def key?(key)
|
56
|
+
@store.key?(key)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def setup
|
61
|
+
@runtime = Johnson::Runtime.new(Johnson::SpiderMonkey::Runtime)
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_find_constants
|
65
|
+
assert_js_equal($LOAD_PATH, "Ruby['$LOAD_PATH']")
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_proxies_get_reused
|
69
|
+
@runtime["foo"] = @runtime["bar"] = Foo.new
|
70
|
+
assert_js_equal(true, "foo === bar")
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_attributes_get_added_to_ruby
|
74
|
+
foo = @runtime["foo"] = Foo.new
|
75
|
+
assert !foo.respond_to?(:johnson)
|
76
|
+
@runtime.evaluate("foo.johnson = 'explode';")
|
77
|
+
assert foo.respond_to?(:johnson)
|
78
|
+
assert_equal('explode', foo.johnson)
|
79
|
+
assert_js_equal('explode', 'foo.johnson')
|
80
|
+
assert !Foo.new.respond_to?(:johnson)
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_assign_function_as_attribute
|
84
|
+
foo = @runtime["foo"] = Foo.new
|
85
|
+
assert !foo.respond_to?(:johnson)
|
86
|
+
f = @runtime.evaluate("foo.johnson = function() { return 'explode'; }")
|
87
|
+
assert foo.respond_to?(:johnson)
|
88
|
+
assert_equal('explode', foo.johnson)
|
89
|
+
assert_js_equal('explode', 'foo.johnson()')
|
90
|
+
assert_js_equal(f, 'foo.johnson')
|
91
|
+
assert !Foo.new.respond_to?(:johnson)
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_assign_function_as_attribute_with_this
|
95
|
+
foo = @runtime["foo"] = Foo.new
|
96
|
+
@runtime.evaluate("foo.ex_squared = function(x) { return this.x2(x); }")
|
97
|
+
assert_equal(4, foo.ex_squared(2))
|
98
|
+
@runtime.evaluate("foo.ex_squared = 20;")
|
99
|
+
assert_equal(20, foo.ex_squared)
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_use_ruby_global_object
|
103
|
+
func = @runtime.evaluate("function(x) { return this.x2(x); }")
|
104
|
+
foo = Foo.new
|
105
|
+
assert_equal(4, func.call_using(foo, 2))
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_proxies_roundtrip
|
109
|
+
@runtime["foo"] = foo = Foo.new
|
110
|
+
assert_same(foo, @runtime.evaluate("foo"))
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_proxies_classes
|
114
|
+
@runtime["Foo"] = Foo
|
115
|
+
assert_same(Foo, @runtime.evaluate("Foo"))
|
116
|
+
end
|
117
|
+
|
118
|
+
def test_proxies_modules
|
119
|
+
@runtime["AModule"] = AModule
|
120
|
+
assert_same(AModule, @runtime.evaluate("AModule"))
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_proxies_hashes
|
124
|
+
@runtime["beatles"] = { "george" => "guitar" }
|
125
|
+
assert_equal("guitar", @runtime.evaluate("beatles['george']"))
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_getter_calls_0_arity_method
|
129
|
+
@runtime["foo"] = Foo.new
|
130
|
+
assert_js_equal(10, "foo.bar")
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_getter_calls_indexer
|
134
|
+
@runtime["foo"] = indexable = Indexable.new
|
135
|
+
indexable["bar"] = 10
|
136
|
+
|
137
|
+
assert_js_equal(10, "foo.bar")
|
138
|
+
end
|
139
|
+
|
140
|
+
def test_getter_returns_nil_for_unknown_properties
|
141
|
+
@runtime["foo"] = Foo.new
|
142
|
+
assert_js_equal(nil, "foo.quux")
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_setter_calls_key=
|
146
|
+
@runtime["foo"] = foo = Foo.new
|
147
|
+
assert_js_equal(42, "foo.bar = 42")
|
148
|
+
assert_equal(42, foo.bar)
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_setter_calls_indexer
|
152
|
+
@runtime["foo"] = indexable = Indexable.new
|
153
|
+
assert_js_equal(42, "foo.monkey = 42")
|
154
|
+
assert_equal(42, indexable["monkey"])
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_calls_attr_reader
|
158
|
+
@runtime["foo"] = Foo.new
|
159
|
+
assert_js_equal(10, "foo.bar")
|
160
|
+
end
|
161
|
+
|
162
|
+
def test_calls_1_arity_method
|
163
|
+
@runtime["foo"] = Foo.new
|
164
|
+
assert_js_equal(10, "foo.x2(5)")
|
165
|
+
end
|
166
|
+
|
167
|
+
def test_calls_n_arity_method
|
168
|
+
@runtime["foo"] = Foo.new
|
169
|
+
assert_js_equal(10, "foo.add(4, 2, 2, 1, 1)")
|
170
|
+
end
|
171
|
+
|
172
|
+
def test_calls_class_method
|
173
|
+
@runtime["Foo"] = Foo
|
174
|
+
assert_js_equal(Foo.bar, "Foo.bar()")
|
175
|
+
end
|
176
|
+
|
177
|
+
def test_accesses_consts
|
178
|
+
@runtime["Foo"] = Foo
|
179
|
+
assert_same(Foo::Inner, @runtime.evaluate("Foo.Inner"))
|
180
|
+
end
|
181
|
+
|
182
|
+
def test_can_create_new_instances_in_js
|
183
|
+
@runtime["AClass"] = AClass
|
184
|
+
foo = @runtime.evaluate("AClass.new()")
|
185
|
+
assert_kind_of(AClass, foo)
|
186
|
+
end
|
187
|
+
|
188
|
+
def test_class_proxies_provide_a_ctor
|
189
|
+
@runtime["AClass"] = AClass
|
190
|
+
foo = @runtime.evaluate("new AClass()")
|
191
|
+
assert_kind_of(AClass, foo)
|
192
|
+
|
193
|
+
bar = @runtime.evaluate("new AClass(1, 2, 3)")
|
194
|
+
assert_equal([1, 2, 3], bar.args)
|
195
|
+
end
|
196
|
+
|
197
|
+
def test_dwims_blocks
|
198
|
+
@runtime["foo"] = Foo.new
|
199
|
+
assert_js_equal(4, "foo.xform(2, function(x) { return x * 2 })")
|
200
|
+
end
|
201
|
+
|
202
|
+
def test_dwims_blocks_for_0_arity_methods
|
203
|
+
@runtime[:arr] = [1, 2, 3]
|
204
|
+
assert_js_equal([2, 4, 6], "arr.collect(function(x) { return x * 2 })")
|
205
|
+
end
|
206
|
+
|
207
|
+
def test_scope_for_with
|
208
|
+
assert_js_equal(84, "with (rb) { b + b }", :b => 1, :rb => { "b" => 42 })
|
209
|
+
end
|
210
|
+
|
211
|
+
def test_lambdas_for_with
|
212
|
+
assert_js_equal(84, "with (rb) { b(42) }", :rb => { "b" => lambda { |x| x * 2 } })
|
213
|
+
end
|
214
|
+
|
215
|
+
class MethodForWith
|
216
|
+
def b(x); x * 2; end
|
217
|
+
end
|
218
|
+
|
219
|
+
def test_method_for_with
|
220
|
+
assert_js_equal(84, "with (rb) { b(42) }", :rb => MethodForWith.new)
|
221
|
+
end
|
222
|
+
|
223
|
+
def test_raises_string_to_ruby
|
224
|
+
assert_raise(Johnson::Error) { @runtime.evaluate("throw 'my string';") }
|
225
|
+
end
|
226
|
+
|
227
|
+
def test_raises_object_to_ruby
|
228
|
+
assert_raise(Johnson::Error) { @runtime.evaluate("throw { bad: true };") }
|
229
|
+
end
|
230
|
+
|
231
|
+
def test_raises_exception_to_ruby
|
232
|
+
assert_raise(Johnson::Error) { @runtime.evaluate("undefinedValue();") }
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|