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.
Files changed (137) hide show
  1. data/CHANGELOG +5 -0
  2. data/MANIFEST +385 -0
  3. data/MINGW32.mk +124 -0
  4. data/README.rdoc +51 -0
  5. data/Rakefile +166 -0
  6. data/bin/johnson +107 -0
  7. data/cross-compile.txt +38 -0
  8. data/ext/spidermonkey/context.c +122 -0
  9. data/ext/spidermonkey/context.h +19 -0
  10. data/ext/spidermonkey/conversions.c +286 -0
  11. data/ext/spidermonkey/conversions.h +18 -0
  12. data/ext/spidermonkey/debugger.c +208 -0
  13. data/ext/spidermonkey/debugger.h +9 -0
  14. data/ext/spidermonkey/extconf.rb +25 -0
  15. data/ext/spidermonkey/extensions.c +37 -0
  16. data/ext/spidermonkey/extensions.h +12 -0
  17. data/ext/spidermonkey/global.c +40 -0
  18. data/ext/spidermonkey/global.h +11 -0
  19. data/ext/spidermonkey/idhash.c +16 -0
  20. data/ext/spidermonkey/idhash.h +8 -0
  21. data/ext/spidermonkey/immutable_node.c.erb +522 -0
  22. data/ext/spidermonkey/immutable_node.h +22 -0
  23. data/ext/spidermonkey/jroot.h +187 -0
  24. data/ext/spidermonkey/js_land_proxy.c +609 -0
  25. data/ext/spidermonkey/js_land_proxy.h +20 -0
  26. data/ext/spidermonkey/ruby_land_proxy.c +537 -0
  27. data/ext/spidermonkey/ruby_land_proxy.h +17 -0
  28. data/ext/spidermonkey/runtime.c +304 -0
  29. data/ext/spidermonkey/runtime.h +25 -0
  30. data/ext/spidermonkey/spidermonkey.c +20 -0
  31. data/ext/spidermonkey/spidermonkey.h +29 -0
  32. data/js/johnson/browser.js +9 -0
  33. data/js/johnson/browser/env.js +687 -0
  34. data/js/johnson/browser/jquery.js +3444 -0
  35. data/js/johnson/browser/xmlsax.js +1564 -0
  36. data/js/johnson/browser/xmlw3cdom.js +4189 -0
  37. data/js/johnson/cli.js +30 -0
  38. data/js/johnson/prelude.js +80 -0
  39. data/js/johnson/template.js +29 -0
  40. data/lib/hoe.rb +748 -0
  41. data/lib/johnson.rb +46 -0
  42. data/lib/johnson/cli.rb +7 -0
  43. data/lib/johnson/cli/options.rb +56 -0
  44. data/lib/johnson/error.rb +4 -0
  45. data/lib/johnson/nodes.rb +7 -0
  46. data/lib/johnson/nodes/binary_node.rb +64 -0
  47. data/lib/johnson/nodes/for.rb +14 -0
  48. data/lib/johnson/nodes/for_in.rb +12 -0
  49. data/lib/johnson/nodes/function.rb +13 -0
  50. data/lib/johnson/nodes/list.rb +27 -0
  51. data/lib/johnson/nodes/node.rb +68 -0
  52. data/lib/johnson/nodes/ternary_node.rb +20 -0
  53. data/lib/johnson/parser.rb +21 -0
  54. data/lib/johnson/parser/syntax_error.rb +13 -0
  55. data/lib/johnson/runtime.rb +55 -0
  56. data/lib/johnson/spidermonkey/context.rb +10 -0
  57. data/lib/johnson/spidermonkey/debugger.rb +67 -0
  58. data/lib/johnson/spidermonkey/immutable_node.rb +280 -0
  59. data/lib/johnson/spidermonkey/js_land_proxy.rb +62 -0
  60. data/lib/johnson/spidermonkey/mutable_tree_visitor.rb +233 -0
  61. data/lib/johnson/spidermonkey/ruby_land_proxy.rb +52 -0
  62. data/lib/johnson/spidermonkey/runtime.rb +94 -0
  63. data/lib/johnson/version.rb +4 -0
  64. data/lib/johnson/visitable.rb +16 -0
  65. data/lib/johnson/visitors.rb +4 -0
  66. data/lib/johnson/visitors/dot_visitor.rb +167 -0
  67. data/lib/johnson/visitors/ecma_visitor.rb +315 -0
  68. data/lib/johnson/visitors/enumerating_visitor.rb +115 -0
  69. data/lib/johnson/visitors/sexp_visitor.rb +172 -0
  70. data/lib/rails/init.rb +37 -0
  71. data/test/assets/index.html +38 -0
  72. data/test/assets/jquery_test.html +186 -0
  73. data/test/helper.rb +58 -0
  74. data/test/johnson/browser_test.rb +38 -0
  75. data/test/johnson/conversions/array_test.rb +32 -0
  76. data/test/johnson/conversions/boolean_test.rb +17 -0
  77. data/test/johnson/conversions/callable_test.rb +34 -0
  78. data/test/johnson/conversions/file_test.rb +15 -0
  79. data/test/johnson/conversions/nil_test.rb +20 -0
  80. data/test/johnson/conversions/number_test.rb +34 -0
  81. data/test/johnson/conversions/regexp_test.rb +24 -0
  82. data/test/johnson/conversions/string_test.rb +26 -0
  83. data/test/johnson/conversions/struct_test.rb +15 -0
  84. data/test/johnson/conversions/symbol_test.rb +19 -0
  85. data/test/johnson/conversions/thread_test.rb +24 -0
  86. data/test/johnson/error_test.rb +9 -0
  87. data/test/johnson/extensions_test.rb +56 -0
  88. data/test/johnson/nodes/array_literal_test.rb +57 -0
  89. data/test/johnson/nodes/array_node_test.rb +26 -0
  90. data/test/johnson/nodes/binary_node_test.rb +61 -0
  91. data/test/johnson/nodes/bracket_access_test.rb +16 -0
  92. data/test/johnson/nodes/delete_test.rb +11 -0
  93. data/test/johnson/nodes/do_while_test.rb +12 -0
  94. data/test/johnson/nodes/dot_accessor_test.rb +15 -0
  95. data/test/johnson/nodes/export_test.rb +9 -0
  96. data/test/johnson/nodes/for_test.rb +54 -0
  97. data/test/johnson/nodes/function_test.rb +71 -0
  98. data/test/johnson/nodes/if_test.rb +41 -0
  99. data/test/johnson/nodes/import_test.rb +13 -0
  100. data/test/johnson/nodes/label_test.rb +19 -0
  101. data/test/johnson/nodes/object_literal_test.rb +110 -0
  102. data/test/johnson/nodes/return_test.rb +16 -0
  103. data/test/johnson/nodes/semi_test.rb +8 -0
  104. data/test/johnson/nodes/switch_test.rb +55 -0
  105. data/test/johnson/nodes/ternary_test.rb +25 -0
  106. data/test/johnson/nodes/throw_test.rb +9 -0
  107. data/test/johnson/nodes/try_node_test.rb +59 -0
  108. data/test/johnson/nodes/typeof_test.rb +11 -0
  109. data/test/johnson/nodes/unary_node_test.rb +23 -0
  110. data/test/johnson/nodes/void_test.rb +11 -0
  111. data/test/johnson/nodes/while_test.rb +26 -0
  112. data/test/johnson/nodes/with_test.rb +10 -0
  113. data/test/johnson/prelude_test.rb +56 -0
  114. data/test/johnson/runtime_test.rb +46 -0
  115. data/test/johnson/spidermonkey/context_test.rb +21 -0
  116. data/test/johnson/spidermonkey/immutable_node_test.rb +34 -0
  117. data/test/johnson/spidermonkey/js_land_proxy_test.rb +236 -0
  118. data/test/johnson/spidermonkey/ruby_land_proxy_test.rb +225 -0
  119. data/test/johnson/spidermonkey/runtime_test.rb +17 -0
  120. data/test/johnson/version_test.rb +13 -0
  121. data/test/johnson/visitors/dot_visitor_test.rb +39 -0
  122. data/test/johnson/visitors/enumerating_visitor_test.rb +12 -0
  123. data/test/johnson_test.rb +16 -0
  124. data/test/jquery_units/test.js +27 -0
  125. data/test/jquery_units/test_helper.js +197 -0
  126. data/test/jquery_units/units/ajax.js +795 -0
  127. data/test/jquery_units/units/core.js +1563 -0
  128. data/test/jquery_units/units/event.js +299 -0
  129. data/test/jquery_units/units/fx.js +427 -0
  130. data/test/jquery_units/units/offset.js +112 -0
  131. data/test/jquery_units/units/selector.js +224 -0
  132. data/test/jspec/helper.js +7 -0
  133. data/test/jspec/jspec.js +192 -0
  134. data/test/jspec/simple_spec.js +68 -0
  135. data/test/parser_test.rb +276 -0
  136. data/todo/.keep +0 -0
  137. metadata +501 -0
data/test/helper.rb ADDED
@@ -0,0 +1,58 @@
1
+ require "rubygems"
2
+ require "test/unit"
3
+
4
+ %w(../lib ../ext/spidermonkey).each do |path|
5
+ $LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), path)))
6
+ end
7
+
8
+ # If the test isn't running from Rake, make sure the extension's current.
9
+ Rake rescue Dir.chdir(File.dirname(__FILE__) + "/..") { %x(rake extensions) }
10
+
11
+ require "johnson"
12
+
13
+ module Johnson
14
+ class TestCase < Test::Unit::TestCase
15
+ class TestLogger
16
+ def debug(string)
17
+ puts string
18
+ end
19
+ end
20
+
21
+ undef :default_test
22
+
23
+ def setup
24
+ @runtime = Johnson::Runtime.new
25
+ #@runtime.delegate.gc_zeal = 2
26
+ #@runtime.delegate.debugger = Johnson::SpiderMonkey::Debugger.new(TestLogger.new)
27
+ end
28
+
29
+ def assert_js(expression, options={})
30
+ runtime = options[:runtime] || @runtime
31
+ assert(runtime.evaluate(expression), "Expected JS expression [#{expression}] to be true.")
32
+ end
33
+
34
+ def assert_js_equal(expected, expression, options={})
35
+ runtime = options.delete(:runtime) || @runtime
36
+ options.each { |k, v| runtime[k.to_s] = v }
37
+ assert_equal(expected, runtime.evaluate(expression))
38
+ end
39
+ end
40
+
41
+ class NodeTestCase < Test::Unit::TestCase
42
+ include Johnson::Nodes
43
+
44
+ undef :default_test
45
+
46
+ def setup
47
+ @parser = Johnson::Parser
48
+ end
49
+
50
+ def assert_sexp(expected, actual)
51
+ assert_equal(expected, actual.to_sexp)
52
+ end
53
+
54
+ def assert_ecma(expected, actual)
55
+ assert_equal(expected, actual.to_ecma)
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,38 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "/../helper"))
2
+
3
+ require 'net/http'
4
+
5
+ module Johnson
6
+ class BrowserTest < Johnson::TestCase
7
+ def setup
8
+ super
9
+ @runtime.evaluate('Johnson.require("johnson/browser");')
10
+ end
11
+
12
+ def test_set_location_returns_location
13
+ filename = "file://#{File.expand_path(__FILE__)}"
14
+
15
+ may_thread {
16
+ @runtime.evaluate("window.location = '#{filename}'")
17
+ }
18
+
19
+ uri = URI.parse(filename)
20
+ assert_equal(uri.to_s, @runtime.evaluate('window.location').to_s)
21
+ end
22
+
23
+ def test_set_location_with_url
24
+ file = File.expand_path(__FILE__) + "/../../assets/index.html"
25
+ filename = "file://#{File.expand_path(file)}"
26
+ may_thread {
27
+ @runtime.evaluate("window.location = '#{filename}'")
28
+ }
29
+ doc = @runtime.evaluate('window.document')
30
+ assert_not_nil(doc)
31
+ end
32
+
33
+ def may_thread(&block)
34
+ block.call
35
+ (Thread.list - [Thread.main]).each { |t| t.join }
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,32 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "/../../helper"))
2
+
3
+ module Johnson
4
+ module Conversions
5
+ class ArrayTest < Johnson::TestCase
6
+ def test_array_index_get
7
+ @runtime[:list] = [1, 2, 3, 4]
8
+ assert_equal(1, @runtime.evaluate("list[0]"))
9
+ end
10
+
11
+ def test_array_index_set
12
+ @runtime[:list] = []
13
+ @runtime.evaluate("list[0] = 42")
14
+ assert_equal(42, @runtime[:list][0])
15
+ end
16
+
17
+ def test_array_works_with_for_in
18
+ list = [1, 2, 3, 4]
19
+
20
+ @runtime['alert'] = lambda { |x| p x }
21
+ @runtime['list'] = list
22
+ @runtime.evaluate("
23
+ var new_list = [];
24
+ for(x in list) {
25
+ new_list.push(x + 1);
26
+ }
27
+ ")
28
+ assert_equal(list.map { |x| x + 1}, @runtime['new_list'].to_a)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,17 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "/../../helper"))
2
+
3
+ module Johnson
4
+ module Conversions
5
+ class BooleanTest < Johnson::TestCase
6
+ def test_truthiness
7
+ @runtime[:v] = true
8
+ assert_same(true, @runtime.evaluate("v === true"))
9
+ end
10
+
11
+ def test_dirty_lies
12
+ @runtime[:v] = false
13
+ assert_same(false, @runtime.evaluate("v === true"))
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,34 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "/../../helper"))
2
+
3
+ module Johnson
4
+ module Conversions
5
+ class CallableTest < Johnson::TestCase
6
+ def test_proc_works_in_jsland
7
+ @runtime[:squared] = Proc.new { |x| x * x }
8
+ assert_js_equal(4, "squared(2)")
9
+ end
10
+
11
+ def test_procs_roundtrip
12
+ @runtime[:k] = k = lambda { |x| x }
13
+ assert_same(k, @runtime.evaluate("k"))
14
+ end
15
+
16
+ def test_proc_js_function_proxy_gets_reused
17
+ @runtime[:k] = k = lambda { |x| x }
18
+ @runtime[:kk] = k
19
+ assert_js("k === kk")
20
+ end
21
+
22
+ class CallableThing
23
+ def call
24
+ "foo"
25
+ end
26
+ end
27
+
28
+ def test_anything_with_a_call_method_can_be_called_as_a_method
29
+ @runtime[:c] = CallableThing.new
30
+ assert_js_equal("foo", "c()")
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,15 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "/../../helper"))
2
+
3
+ module Johnson
4
+ module Conversions
5
+ class FileTest < Johnson::TestCase
6
+ def test_read_file
7
+ File.open(__FILE__, 'rb') { |f|
8
+ @runtime[:foo] = f
9
+ assert_equal(f, @runtime.evaluate("foo"))
10
+ assert_equal(File.read(__FILE__), @runtime.evaluate("foo.read()"))
11
+ }
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,20 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "/../../helper"))
2
+
3
+ module Johnson
4
+ module Conversions
5
+ class NilTest < Johnson::TestCase
6
+ def test_ruby_nil_is_js_null
7
+ @runtime[:v] = nil
8
+ assert_equal(true, @runtime.evaluate("v == null"))
9
+ end
10
+
11
+ def test_js_null_is_ruby_nil
12
+ assert_nil(@runtime.evaluate("null"))
13
+ end
14
+
15
+ def test_js_undefined_is_ruby_nil
16
+ assert_nil(@runtime.evaluate("undefined"))
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,34 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "/../../helper"))
2
+
3
+ module Johnson
4
+ module Conversions
5
+ class NumberTest < Johnson::TestCase
6
+ def test_ruby_fixnum_in_js
7
+ @runtime[:v] = 42
8
+
9
+ assert_js("v == 42")
10
+ assert_js_equal(42, "v")
11
+ assert_equal(42, @runtime[:v])
12
+ end
13
+
14
+ def test_js_fixnum_in_ruby
15
+ fix = @runtime.evaluate("42")
16
+ assert_equal(42, fix)
17
+ assert_kind_of(Fixnum, fix)
18
+ end
19
+
20
+ def test_ruby_float_in_js
21
+ @runtime[:pi] = pi = 3.141592654
22
+ assert_js_equal(pi, "pi")
23
+ assert_in_delta(pi, @runtime.evaluate("pi"), 2 ** -20)
24
+ end
25
+
26
+ def test_ruby_bignum_in_js
27
+ @runtime[:big] = big = 2 ** 200
28
+
29
+ assert_js_equal(big, "big")
30
+ assert_kind_of(Float, @runtime.evaluate("big"))
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,24 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "/../../helper"))
2
+
3
+ module Johnson
4
+ module Conversions
5
+ class RegexpTest < Johnson::TestCase
6
+ def test_regex_converts
7
+ @runtime[:x] = /aaron/
8
+ @runtime[:y] = /john/i
9
+ assert @runtime.evaluate('"aaron".match(x)')
10
+ assert !@runtime.evaluate('"Aaron".match(x)')
11
+ assert @runtime.evaluate('"john".match(y)')
12
+ assert @runtime.evaluate('"John".match(y)')
13
+ end
14
+
15
+ def test_regex_roundtrips
16
+ @runtime[:x] = /aaron/
17
+ assert_equal(/aaron/, @runtime.evaluate('x'))
18
+
19
+ @runtime[:x] = /aaron/m
20
+ assert_equal(/aaron/m, @runtime.evaluate('x'))
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,26 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "/../../helper"))
2
+
3
+ module Johnson
4
+ module Conversions
5
+ class StringTest < Johnson::TestCase
6
+ def test_ruby_string_in_js
7
+ @runtime[:v] = "foo"
8
+ assert_js("'foo' == v")
9
+ end
10
+
11
+ def test_js_string_in_ruby
12
+ assert_equal("foo", @runtime.evaluate("'foo'"))
13
+ end
14
+
15
+ def test_roundtrip
16
+ @runtime[:v] = v = "hola"
17
+ assert_equal(v, @runtime.evaluate("v"))
18
+ end
19
+
20
+ def test_strings_are_copies
21
+ @runtime[:v] = v = "hola"
22
+ assert_not_same(v, @runtime.evaluate("v"))
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,15 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "/../../helper"))
2
+
3
+ module Johnson
4
+ module Conversions
5
+ class StructTest < Johnson::TestCase
6
+ def test_use_struct
7
+ f = Struct.new(:phil_collins).new
8
+ f.phil_collins = 'awesome'
9
+ @runtime[:foo] = f
10
+ assert_equal(f, @runtime.evaluate('foo'))
11
+ assert_equal('awesome', @runtime.evaluate('foo.phil_collins'))
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,19 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "/../../helper"))
2
+
3
+ module Johnson
4
+ module Conversions
5
+ class SymbolTest < Johnson::TestCase
6
+ def test_symbols_are_interned
7
+ @runtime[:v] = :symbol
8
+ @runtime[:x] = :symbol
9
+
10
+ assert(@runtime.evaluate("v !== null && v === x"))
11
+ end
12
+
13
+ def test_ruby_symbol_roundtrips
14
+ @runtime[:v] = :foo
15
+ assert_equal(:foo, @runtime.evaluate("v"))
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,24 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "/../../helper"))
2
+
3
+ module Johnson
4
+ module Conversions
5
+ class ThreadTest < Johnson::TestCase
6
+ def test_manipulate_thread
7
+ thread = Thread.new { }
8
+ @runtime['thread'] = thread
9
+ assert_js_equal(false, "thread.send('alive?')")
10
+ end
11
+
12
+ def test_new_js_thread
13
+ @runtime.evaluate('function testing() { Ruby.sleep(10); }')
14
+ @runtime.evaluate('new Ruby.Thread(function() { testing(); })')
15
+ end
16
+
17
+ def test_js_thread_read_file
18
+ @runtime['filename'] = File.expand_path(__FILE__)
19
+ @runtime.evaluate('function testing() { Ruby.File.read(filename); }')
20
+ @runtime.evaluate('new Ruby.Thread(function() { testing(); })')
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,9 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "/../helper"))
2
+
3
+ module Johnson
4
+ class ErrorTest < Johnson::TestCase
5
+ def test_inherits_from_standard_error
6
+ assert(Johnson::Error < StandardError)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,56 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "/../helper"))
2
+
3
+ module Johnson
4
+ module Extensions
5
+ class DefinePropertyTest < Johnson::TestCase
6
+ def setup
7
+ super
8
+ @runtime.evaluate("x = {}")
9
+ end
10
+
11
+ def test_object_can_define_property
12
+ @runtime.evaluate("Object.defineProperty(x, 'answer', 42)")
13
+ assert_js_equal(42, "x.answer")
14
+ end
15
+
16
+ def test_object_can_define_unenumerable_property
17
+ @runtime.evaluate("Object.defineProperty(x, 'answer', 42)")
18
+ @runtime.evaluate <<-JS
19
+ y = [];
20
+ for(prop in x) if(prop == "answer") y.push(prop)
21
+ JS
22
+ assert_js("y.length == 0")
23
+ end
24
+
25
+ def test_object_can_define_enumerable_property
26
+ @runtime.evaluate("Object.defineProperty(x, 'answer', 42, Object.ITERABLE)")
27
+ @runtime.evaluate <<-JS
28
+ y = [];
29
+ for(prop in x) if(prop == "answer") y.push(prop)
30
+ JS
31
+ assert_js("y.length == 1")
32
+ end
33
+
34
+ def test_object_can_define_read_only_property
35
+ @runtime.evaluate("Object.defineProperty(x, 'answer', 42, Object.READ_ONLY)")
36
+ @runtime.evaluate("x.answer = 47")
37
+ assert_js_equal(42, "x.answer")
38
+ end
39
+
40
+ def test_object_can_define_non_deletable_property
41
+ @runtime.evaluate("Object.defineProperty(x, 'answer', 42, Object.NON_DELETABLE)")
42
+ @runtime.evaluate("r = (delete x.answer)")
43
+ assert_js_equal(false, "r")
44
+ assert_js_equal(42, "x.answer")
45
+ end
46
+
47
+ def test_object_can_define_mixed_property
48
+ @runtime.evaluate("Object.defineProperty(x, 'answer', 42, Object.NON_DELETABLE | Object.READ_ONLY)")
49
+ @runtime.evaluate("r = (delete x.answer)")
50
+ @runtime.evaluate("x.answer = 47")
51
+ assert_js_equal(false, "r")
52
+ assert_js_equal(42, "x.answer")
53
+ end
54
+ end
55
+ end
56
+ end