modulr 0.1.0

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 (217) hide show
  1. data/LICENSE +22 -0
  2. data/README.markdown +62 -0
  3. data/Rakefile +55 -0
  4. data/VERSION +1 -0
  5. data/assets/modulr.js +58 -0
  6. data/bin/modulrize +39 -0
  7. data/example/foo/bar.js +1 -0
  8. data/example/foo/foo.js +3 -0
  9. data/example/increment.js +6 -0
  10. data/example/inspect.js +3 -0
  11. data/example/math.js +7 -0
  12. data/example/program.js +9 -0
  13. data/lib/modulr/collector.rb +60 -0
  14. data/lib/modulr/js_module.rb +88 -0
  15. data/lib/modulr/version.rb +6 -0
  16. data/lib/modulr.rb +21 -0
  17. data/vendor/rkelly/CHANGELOG.rdoc +13 -0
  18. data/vendor/rkelly/Manifest.txt +198 -0
  19. data/vendor/rkelly/README.rdoc +58 -0
  20. data/vendor/rkelly/Rakefile +39 -0
  21. data/vendor/rkelly/lib/parser.y +870 -0
  22. data/vendor/rkelly/lib/rkelly/constants.rb +3 -0
  23. data/vendor/rkelly/lib/rkelly/generated_parser.rb +3237 -0
  24. data/vendor/rkelly/lib/rkelly/js/array.rb +15 -0
  25. data/vendor/rkelly/lib/rkelly/js/base.rb +91 -0
  26. data/vendor/rkelly/lib/rkelly/js/boolean.rb +21 -0
  27. data/vendor/rkelly/lib/rkelly/js/function.rb +39 -0
  28. data/vendor/rkelly/lib/rkelly/js/function_prototype.rb +15 -0
  29. data/vendor/rkelly/lib/rkelly/js/global_object.rb +52 -0
  30. data/vendor/rkelly/lib/rkelly/js/math.rb +10 -0
  31. data/vendor/rkelly/lib/rkelly/js/nan.rb +18 -0
  32. data/vendor/rkelly/lib/rkelly/js/number.rb +22 -0
  33. data/vendor/rkelly/lib/rkelly/js/object.rb +30 -0
  34. data/vendor/rkelly/lib/rkelly/js/object_prototype.rb +14 -0
  35. data/vendor/rkelly/lib/rkelly/js/property.rb +20 -0
  36. data/vendor/rkelly/lib/rkelly/js/scope.rb +6 -0
  37. data/vendor/rkelly/lib/rkelly/js/string.rb +21 -0
  38. data/vendor/rkelly/lib/rkelly/js.rb +14 -0
  39. data/vendor/rkelly/lib/rkelly/lexeme.rb +18 -0
  40. data/vendor/rkelly/lib/rkelly/nodes/binary_node.rb +18 -0
  41. data/vendor/rkelly/lib/rkelly/nodes/bracket_accessor_node.rb +11 -0
  42. data/vendor/rkelly/lib/rkelly/nodes/case_clause_node.rb +11 -0
  43. data/vendor/rkelly/lib/rkelly/nodes/comma_node.rb +11 -0
  44. data/vendor/rkelly/lib/rkelly/nodes/conditional_node.rb +11 -0
  45. data/vendor/rkelly/lib/rkelly/nodes/dot_accessor_node.rb +11 -0
  46. data/vendor/rkelly/lib/rkelly/nodes/for_in_node.rb +12 -0
  47. data/vendor/rkelly/lib/rkelly/nodes/for_node.rb +13 -0
  48. data/vendor/rkelly/lib/rkelly/nodes/function_call_node.rb +16 -0
  49. data/vendor/rkelly/lib/rkelly/nodes/function_decl_node.rb +6 -0
  50. data/vendor/rkelly/lib/rkelly/nodes/function_expr_node.rb +12 -0
  51. data/vendor/rkelly/lib/rkelly/nodes/if_node.rb +12 -0
  52. data/vendor/rkelly/lib/rkelly/nodes/label_node.rb +11 -0
  53. data/vendor/rkelly/lib/rkelly/nodes/new_expr_node.rb +11 -0
  54. data/vendor/rkelly/lib/rkelly/nodes/node.rb +88 -0
  55. data/vendor/rkelly/lib/rkelly/nodes/not_strict_equal_node.rb +6 -0
  56. data/vendor/rkelly/lib/rkelly/nodes/op_equal_node.rb +16 -0
  57. data/vendor/rkelly/lib/rkelly/nodes/postfix_node.rb +11 -0
  58. data/vendor/rkelly/lib/rkelly/nodes/prefix_node.rb +6 -0
  59. data/vendor/rkelly/lib/rkelly/nodes/property_node.rb +13 -0
  60. data/vendor/rkelly/lib/rkelly/nodes/resolve_node.rb +19 -0
  61. data/vendor/rkelly/lib/rkelly/nodes/strict_equal_node.rb +6 -0
  62. data/vendor/rkelly/lib/rkelly/nodes/try_node.rb +13 -0
  63. data/vendor/rkelly/lib/rkelly/nodes/var_decl_node.rb +15 -0
  64. data/vendor/rkelly/lib/rkelly/nodes.rb +25 -0
  65. data/vendor/rkelly/lib/rkelly/parser.rb +104 -0
  66. data/vendor/rkelly/lib/rkelly/runtime/ruby_function.rb +13 -0
  67. data/vendor/rkelly/lib/rkelly/runtime/scope_chain.rb +57 -0
  68. data/vendor/rkelly/lib/rkelly/runtime.rb +36 -0
  69. data/vendor/rkelly/lib/rkelly/syntax_error.rb +4 -0
  70. data/vendor/rkelly/lib/rkelly/token.rb +15 -0
  71. data/vendor/rkelly/lib/rkelly/tokenizer.rb +122 -0
  72. data/vendor/rkelly/lib/rkelly/visitable.rb +16 -0
  73. data/vendor/rkelly/lib/rkelly/visitors/dot_visitor.rb +228 -0
  74. data/vendor/rkelly/lib/rkelly/visitors/ecma_visitor.rb +314 -0
  75. data/vendor/rkelly/lib/rkelly/visitors/enumerable_visitor.rb +18 -0
  76. data/vendor/rkelly/lib/rkelly/visitors/evaluation_visitor.rb +419 -0
  77. data/vendor/rkelly/lib/rkelly/visitors/function_visitor.rb +46 -0
  78. data/vendor/rkelly/lib/rkelly/visitors/pointcut_visitor.rb +31 -0
  79. data/vendor/rkelly/lib/rkelly/visitors/real_sexp_visitor.rb +16 -0
  80. data/vendor/rkelly/lib/rkelly/visitors/sexp_visitor.rb +373 -0
  81. data/vendor/rkelly/lib/rkelly/visitors/visitor.rb +136 -0
  82. data/vendor/rkelly/lib/rkelly/visitors.rb +4 -0
  83. data/vendor/rkelly/lib/rkelly.rb +14 -0
  84. data/vendor/rkelly/rkelly.gemspec +34 -0
  85. data/vendor/rkelly/test/ecma_script_test_case.rb +21 -0
  86. data/vendor/rkelly/test/execute_test_case.rb +16 -0
  87. data/vendor/rkelly/test/execution_contexts/test_10_1_3-1.rb +32 -0
  88. data/vendor/rkelly/test/expressions/test_11_3_1.rb +64 -0
  89. data/vendor/rkelly/test/expressions/test_11_3_2.rb +64 -0
  90. data/vendor/rkelly/test/expressions/test_11_4_2.rb +13 -0
  91. data/vendor/rkelly/test/expressions/test_11_4_3.rb +52 -0
  92. data/vendor/rkelly/test/expressions/test_11_4_4.rb +68 -0
  93. data/vendor/rkelly/test/expressions/test_11_4_5.rb +69 -0
  94. data/vendor/rkelly/test/expressions/test_11_4_6.rb +88 -0
  95. data/vendor/rkelly/test/expressions/test_11_4_8.rb +28 -0
  96. data/vendor/rkelly/test/expressions/test_11_4_9.rb +103 -0
  97. data/vendor/rkelly/test/expressions/test_11_5_1.rb +51 -0
  98. data/vendor/rkelly/test/expressions/test_11_5_2.rb +80 -0
  99. data/vendor/rkelly/test/expressions/test_11_5_3.rb +88 -0
  100. data/vendor/rkelly/test/expressions/test_11_6_1-1.rb +19 -0
  101. data/vendor/rkelly/test/expressions/test_11_9_1.rb +19 -0
  102. data/vendor/rkelly/test/function/test_15_3_1_1-1.rb +34 -0
  103. data/vendor/rkelly/test/global_object/test_15_1_1_1.rb +29 -0
  104. data/vendor/rkelly/test/global_object/test_15_1_1_2.rb +17 -0
  105. data/vendor/rkelly/test/global_object/test_15_1_1_3.rb +9 -0
  106. data/vendor/rkelly/test/helper.rb +5 -0
  107. data/vendor/rkelly/test/node_test_case.rb +11 -0
  108. data/vendor/rkelly/test/object/test_15_2_1_1.rb +257 -0
  109. data/vendor/rkelly/test/object/test_15_2_1_2.rb +21 -0
  110. data/vendor/rkelly/test/object/test_15_2_2_1.rb +52 -0
  111. data/vendor/rkelly/test/statements/test_12_5-1.rb +27 -0
  112. data/vendor/rkelly/test/test_add_node.rb +8 -0
  113. data/vendor/rkelly/test/test_arguments_node.rb +8 -0
  114. data/vendor/rkelly/test/test_array_node.rb +9 -0
  115. data/vendor/rkelly/test/test_assign_expr_node.rb +8 -0
  116. data/vendor/rkelly/test/test_automatic_semicolon_insertion.rb +137 -0
  117. data/vendor/rkelly/test/test_bit_and_node.rb +8 -0
  118. data/vendor/rkelly/test/test_bit_or_node.rb +8 -0
  119. data/vendor/rkelly/test/test_bit_x_or_node.rb +8 -0
  120. data/vendor/rkelly/test/test_bitwise_not_node.rb +8 -0
  121. data/vendor/rkelly/test/test_block_node.rb +14 -0
  122. data/vendor/rkelly/test/test_bracket_accessor_node.rb +16 -0
  123. data/vendor/rkelly/test/test_break_node.rb +11 -0
  124. data/vendor/rkelly/test/test_case_block_node.rb +11 -0
  125. data/vendor/rkelly/test/test_case_clause_node.rb +15 -0
  126. data/vendor/rkelly/test/test_comma_node.rb +13 -0
  127. data/vendor/rkelly/test/test_comments.rb +44 -0
  128. data/vendor/rkelly/test/test_conditional_node.rb +17 -0
  129. data/vendor/rkelly/test/test_const_statement_node.rb +14 -0
  130. data/vendor/rkelly/test/test_continue_node.rb +11 -0
  131. data/vendor/rkelly/test/test_delete_node.rb +8 -0
  132. data/vendor/rkelly/test/test_divide_node.rb +8 -0
  133. data/vendor/rkelly/test/test_do_while_node.rb +13 -0
  134. data/vendor/rkelly/test/test_dot_accessor_node.rb +9 -0
  135. data/vendor/rkelly/test/test_ecma_visitor.rb +192 -0
  136. data/vendor/rkelly/test/test_element_node.rb +8 -0
  137. data/vendor/rkelly/test/test_empty_statement_node.rb +8 -0
  138. data/vendor/rkelly/test/test_equal_node.rb +8 -0
  139. data/vendor/rkelly/test/test_evaluation_visitor.rb +66 -0
  140. data/vendor/rkelly/test/test_expression_statement_node.rb +10 -0
  141. data/vendor/rkelly/test/test_false_node.rb +8 -0
  142. data/vendor/rkelly/test/test_for_in_node.rb +17 -0
  143. data/vendor/rkelly/test/test_for_node.rb +24 -0
  144. data/vendor/rkelly/test/test_function_body_node.rb +8 -0
  145. data/vendor/rkelly/test/test_function_call_node.rb +10 -0
  146. data/vendor/rkelly/test/test_function_decl_node.rb +16 -0
  147. data/vendor/rkelly/test/test_function_expr_node.rb +16 -0
  148. data/vendor/rkelly/test/test_function_visitor.rb +26 -0
  149. data/vendor/rkelly/test/test_getter_property_node.rb +10 -0
  150. data/vendor/rkelly/test/test_global_object.rb +49 -0
  151. data/vendor/rkelly/test/test_greater_node.rb +8 -0
  152. data/vendor/rkelly/test/test_greater_or_equal_node.rb +8 -0
  153. data/vendor/rkelly/test/test_if_node.rb +17 -0
  154. data/vendor/rkelly/test/test_in_node.rb +8 -0
  155. data/vendor/rkelly/test/test_instance_of_node.rb +8 -0
  156. data/vendor/rkelly/test/test_label_node.rb +13 -0
  157. data/vendor/rkelly/test/test_left_shift_node.rb +8 -0
  158. data/vendor/rkelly/test/test_less_node.rb +8 -0
  159. data/vendor/rkelly/test/test_less_or_equal_node.rb +8 -0
  160. data/vendor/rkelly/test/test_line_number.rb +23 -0
  161. data/vendor/rkelly/test/test_logical_and_node.rb +8 -0
  162. data/vendor/rkelly/test/test_logical_not_node.rb +8 -0
  163. data/vendor/rkelly/test/test_logical_or_node.rb +8 -0
  164. data/vendor/rkelly/test/test_modulus_node.rb +8 -0
  165. data/vendor/rkelly/test/test_multiply_node.rb +8 -0
  166. data/vendor/rkelly/test/test_new_expr_node.rb +9 -0
  167. data/vendor/rkelly/test/test_not_equal_node.rb +8 -0
  168. data/vendor/rkelly/test/test_not_strict_equal_node.rb +8 -0
  169. data/vendor/rkelly/test/test_null_node.rb +8 -0
  170. data/vendor/rkelly/test/test_number_node.rb +8 -0
  171. data/vendor/rkelly/test/test_object_literal_node.rb +9 -0
  172. data/vendor/rkelly/test/test_op_and_equal_node.rb +10 -0
  173. data/vendor/rkelly/test/test_op_divide_equal_node.rb +10 -0
  174. data/vendor/rkelly/test/test_op_equal_node.rb +10 -0
  175. data/vendor/rkelly/test/test_op_l_shift_equal_node.rb +10 -0
  176. data/vendor/rkelly/test/test_op_minus_equal_node.rb +10 -0
  177. data/vendor/rkelly/test/test_op_mod_equal_node.rb +10 -0
  178. data/vendor/rkelly/test/test_op_multiply_equal_node.rb +10 -0
  179. data/vendor/rkelly/test/test_op_or_equal_node.rb +10 -0
  180. data/vendor/rkelly/test/test_op_plus_equal_node.rb +10 -0
  181. data/vendor/rkelly/test/test_op_r_shift_equal_node.rb +10 -0
  182. data/vendor/rkelly/test/test_op_u_r_shift_equal_node.rb +10 -0
  183. data/vendor/rkelly/test/test_op_x_or_equal_node.rb +10 -0
  184. data/vendor/rkelly/test/test_parameter_node.rb +8 -0
  185. data/vendor/rkelly/test/test_parser.rb +1361 -0
  186. data/vendor/rkelly/test/test_pointcut_visitor.rb +34 -0
  187. data/vendor/rkelly/test/test_postfix_node.rb +8 -0
  188. data/vendor/rkelly/test/test_prefix_node.rb +8 -0
  189. data/vendor/rkelly/test/test_property_node.rb +8 -0
  190. data/vendor/rkelly/test/test_regexp_node.rb +8 -0
  191. data/vendor/rkelly/test/test_resolve_node.rb +22 -0
  192. data/vendor/rkelly/test/test_return_node.rb +11 -0
  193. data/vendor/rkelly/test/test_right_shift_node.rb +8 -0
  194. data/vendor/rkelly/test/test_rkelly.rb +19 -0
  195. data/vendor/rkelly/test/test_runtime.rb +12 -0
  196. data/vendor/rkelly/test/test_scope_chain.rb +50 -0
  197. data/vendor/rkelly/test/test_setter_property_node.rb +10 -0
  198. data/vendor/rkelly/test/test_source_elements.rb +9 -0
  199. data/vendor/rkelly/test/test_strict_equal_node.rb +8 -0
  200. data/vendor/rkelly/test/test_string_node.rb +8 -0
  201. data/vendor/rkelly/test/test_subtract_node.rb +8 -0
  202. data/vendor/rkelly/test/test_switch_node.rb +12 -0
  203. data/vendor/rkelly/test/test_this_node.rb +8 -0
  204. data/vendor/rkelly/test/test_throw_node.rb +7 -0
  205. data/vendor/rkelly/test/test_tokenizer.rb +148 -0
  206. data/vendor/rkelly/test/test_true_node.rb +8 -0
  207. data/vendor/rkelly/test/test_try_node.rb +59 -0
  208. data/vendor/rkelly/test/test_type_of_node.rb +8 -0
  209. data/vendor/rkelly/test/test_unary_minus_node.rb +8 -0
  210. data/vendor/rkelly/test/test_unary_plus_node.rb +8 -0
  211. data/vendor/rkelly/test/test_unsigned_right_shift_node.rb +8 -0
  212. data/vendor/rkelly/test/test_var_decl_node.rb +21 -0
  213. data/vendor/rkelly/test/test_var_statement_node.rb +14 -0
  214. data/vendor/rkelly/test/test_void_node.rb +8 -0
  215. data/vendor/rkelly/test/test_while_node.rb +15 -0
  216. data/vendor/rkelly/test/test_with_node.rb +8 -0
  217. metadata +271 -0
@@ -0,0 +1,34 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class PointcutVisitorTest < Test::Unit::TestCase
4
+ include RKelly::Visitors
5
+ include RKelly::Nodes
6
+
7
+ def setup
8
+ @parser = RKelly::Parser.new
9
+ end
10
+
11
+ def test_visit_NumberNode
12
+ ast = @parser.parse('Element.update(10, 10)')
13
+ assert_equal(2, ast.pointcut('10').matches.length)
14
+ end
15
+
16
+ def test_visit_RegexpNode
17
+ ast = @parser.parse('Element.update(/asdf/, /asdf/)')
18
+ assert_equal(2, ast.pointcut('/asdf/').matches.length)
19
+ end
20
+
21
+ def test_visit_ContinueNode
22
+ ast = @parser.parse('function foo() { continue; }')
23
+ cut = ast.pointcut('continue')
24
+ assert_equal(1, cut.matches.length)
25
+ assert cut.matches.first.is_a?(ContinueNode)
26
+ end
27
+
28
+ def test_try_catch
29
+ ast = @parser.parse('try { Element.update(10, 10); } catch(e) { }')
30
+ assert_equal(1, ast.pointcut('Element.update(10, 10)').matches.length)
31
+ ast = @parser.parse('try { Element.update("foo", "bar"); } catch(e) { }')
32
+ assert_equal(1, ast.pointcut('Element.update(String, String)').matches.length)
33
+ end
34
+ end
@@ -0,0 +1,8 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class PostfixNodeTest < NodeTestCase
4
+ def test_to_sexp
5
+ node = PostfixNode.new(NumberNode.new(10), '++')
6
+ assert_sexp([:postfix, [:lit, 10], '++'], node)
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class PrefixNodeTest < NodeTestCase
4
+ def test_to_sexp
5
+ node = PrefixNode.new(NumberNode.new(10), '++')
6
+ assert_sexp([:prefix, [:lit, 10], '++'], node)
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class PropertyNodeTest < NodeTestCase
4
+ def test_to_sexp
5
+ node = PropertyNode.new('foo', NumberNode.new(10))
6
+ assert_sexp([:property, :foo, [:lit, 10]], node)
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class RegexpNodeTest < NodeTestCase
4
+ def test_to_sexp
5
+ node = RegexpNode.new('/yay!/')
6
+ assert_sexp [:lit, '/yay!/'], node
7
+ end
8
+ end
@@ -0,0 +1,22 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class ResolveNodeTest < NodeTestCase
4
+ def test_to_sexp
5
+ node = ResolveNode.new('foo')
6
+ assert_sexp [:resolve, 'foo'], node
7
+ end
8
+
9
+ def test_match
10
+ node = ResolveNode.new('foo')
11
+ node2 = ResolveNode.new('foo')
12
+ assert(node =~ node2)
13
+
14
+ assert(node !~ NumberNode.new(10))
15
+ end
16
+
17
+ def test_is_a
18
+ node = ResolveNode.new('foo')
19
+ node3 = ResolveNode.new('String')
20
+ assert(node3 =~ node)
21
+ end
22
+ end
@@ -0,0 +1,11 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class ReturnNodeTest < NodeTestCase
4
+ def test_to_sexp
5
+ node = ReturnNode.new(nil)
6
+ assert_sexp([:return], node)
7
+
8
+ node = ReturnNode.new(NumberNode.new(10))
9
+ assert_sexp([:return, [:lit, 10]], node)
10
+ end
11
+ end
@@ -0,0 +1,8 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class RightShiftNodeTest < NodeTestCase
4
+ def test_to_sexp
5
+ node = RightShiftNode.new(NumberNode.new(5), NumberNode.new(10))
6
+ assert_sexp([:rshift, [:lit, 5], [:lit, 10]], node)
7
+ end
8
+ end
@@ -0,0 +1,19 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class RKellyTest < Test::Unit::TestCase
4
+ def test_array_access
5
+ assert_sexp(
6
+ [
7
+ [:var,
8
+ [[:var_decl, :a,
9
+ [:assign, [:bracket_access, [:resolve, "foo"], [:lit, 10]]],
10
+ ]]
11
+ ]
12
+ ],
13
+ RKelly.parse('var a = foo[10];'))
14
+ end
15
+
16
+ def assert_sexp(expected, node)
17
+ assert_equal(expected, node.to_sexp)
18
+ end
19
+ end
@@ -0,0 +1,12 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class RuntimeTest < Test::Unit::TestCase
4
+ def setup
5
+ @runtime = RKelly::Runtime.new
6
+ end
7
+
8
+ def test_call_function
9
+ @runtime.execute("function foo(a) { return a + 2; }")
10
+ assert_equal(12, @runtime.call_function("foo", 10))
11
+ end
12
+ end
@@ -0,0 +1,50 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class TestScopeChain < Test::Unit::TestCase
4
+ def setup
5
+ @scope_chain = RKelly::Runtime::ScopeChain.new
6
+ scope_1 = RKelly::JS::Scope.new
7
+ scope_1.properties[:foo] = 1
8
+ scope_2 = RKelly::JS::Scope.new
9
+ scope_2.properties[:bar] = 10
10
+ @scope_chain << scope_1
11
+ @scope_chain << scope_2
12
+ end
13
+
14
+ def test_global_object_in_chain
15
+ assert @scope_chain.has_property?('NaN')
16
+ end
17
+
18
+ def test_has_property
19
+ assert @scope_chain.has_property?(:foo)
20
+ assert @scope_chain.has_property?(:bar)
21
+ assert !@scope_chain.has_property?(:baz)
22
+ @scope_chain.pop
23
+ assert @scope_chain.has_property?(:bar).nil?
24
+ end
25
+
26
+ def test_find_property
27
+ assert_equal(10, @scope_chain[:bar])
28
+ assert_equal(1, @scope_chain[:foo])
29
+ @scope_chain.pop
30
+ assert(!@scope_chain.has_property?(:bar))
31
+ end
32
+
33
+ def test_add_property
34
+ assert !@scope_chain.has_property?(:baz)
35
+ @scope_chain[:baz] = 10
36
+ assert @scope_chain.has_property?(:baz)
37
+ @scope_chain.pop
38
+ assert !@scope_chain.has_property?(:baz)
39
+ end
40
+
41
+ def test_chain_in_block
42
+ assert !@scope_chain.has_property?(:baz)
43
+ @scope_chain.new_scope { |chain|
44
+ chain[:baz] = 10
45
+ assert @scope_chain.has_property?(:baz)
46
+ assert chain.has_property?(:baz)
47
+ }
48
+ assert @scope_chain.has_property?(:baz).nil?
49
+ end
50
+ end
@@ -0,0 +1,10 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class SetterPropertyNodeTest < NodeTestCase
4
+ def test_to_sexp
5
+ body = FunctionBodyNode.new(SourceElementsNode.new([]))
6
+ function = FunctionExprNode.new(nil, body)
7
+ node = SetterPropertyNode.new('foo', function)
8
+ assert_sexp([:setter, :foo, [:func_expr, nil, [], [:func_body, []]]], node)
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class SourceElementListTest < NodeTestCase
4
+ def test_to_sexp
5
+ num = NumberNode.new(10)
6
+ node = SourceElementsNode.new([num, num])
7
+ assert_sexp [[:lit, 10], [:lit, 10]], node
8
+ end
9
+ end
@@ -0,0 +1,8 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class StrictEqualNodeTest < NodeTestCase
4
+ def test_to_sexp
5
+ node = StrictEqualNode.new(NumberNode.new(5), NumberNode.new(10))
6
+ assert_sexp([:strict_equal, [:lit, 5], [:lit, 10]], node)
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class StringNodeTest < NodeTestCase
4
+ def test_to_sexp
5
+ node = StringNode.new('"asdf"')
6
+ assert_sexp [:str, '"asdf"'], node
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class SubtractNodeTest < NodeTestCase
4
+ def test_subtract
5
+ node = SubtractNode.new(NumberNode.new(5), NumberNode.new(10))
6
+ assert_sexp([:subtract, [:lit, 5], [:lit, 10]], node)
7
+ end
8
+ end
@@ -0,0 +1,12 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class SwitchNodeTest < NodeTestCase
4
+ def test_to_sexp
5
+ clause = CaseClauseNode.new( ResolveNode.new('foo'),
6
+ SourceElementsNode.new([ResolveNode.new('bar')]))
7
+ block = CaseBlockNode.new([clause])
8
+ node = SwitchNode.new(ResolveNode.new('o'), block)
9
+ assert_sexp([:switch, [:resolve, 'o'],[:case_block, [[:case, [:resolve, 'foo'], [[:resolve, 'bar']]]]]],
10
+ node)
11
+ end
12
+ end
@@ -0,0 +1,8 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class ThisNodeTest < NodeTestCase
4
+ def test_to_sexp
5
+ node = ThisNode.new('this')
6
+ assert_sexp([:this], node)
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class ThrowNodeTest < NodeTestCase
4
+ def test_to_sexp
5
+ assert_sexp([:throw, [:lit, 10]], ThrowNode.new(NumberNode.new(10)))
6
+ end
7
+ end
@@ -0,0 +1,148 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class TokenizerTest < Test::Unit::TestCase
4
+ def setup
5
+ @tokenizer = RKelly::Tokenizer.new
6
+ end
7
+
8
+ def test_comments
9
+ tokens = @tokenizer.tokenize("/** Fooo */")
10
+ assert_tokens([[:COMMENT, '/** Fooo */']], tokens)
11
+ end
12
+
13
+ def test_string_single_quote
14
+ tokens = @tokenizer.tokenize("foo = 'hello world';")
15
+ assert_tokens([
16
+ [:IDENT, 'foo'],
17
+ ['=', '='],
18
+ [:STRING, "'hello world'"],
19
+ [';', ';'],
20
+ ], tokens)
21
+ end
22
+
23
+ def test_string_double_quote
24
+ tokens = @tokenizer.tokenize('foo = "hello world";')
25
+ assert_tokens([
26
+ [:IDENT, 'foo'],
27
+ ['=', '='],
28
+ [:STRING, '"hello world"'],
29
+ [';', ';'],
30
+ ], tokens)
31
+ end
32
+
33
+ def test_number_parse
34
+ tokens = @tokenizer.tokenize('3.')
35
+ assert_tokens([[:NUMBER, 3.0]], tokens)
36
+
37
+ tokens = @tokenizer.tokenize('3.e1')
38
+ assert_tokens([[:NUMBER, 30]], tokens)
39
+
40
+ tokens = @tokenizer.tokenize('.001')
41
+ assert_tokens([[:NUMBER, 0.001]], tokens)
42
+
43
+ tokens = @tokenizer.tokenize('3.e-1')
44
+ assert_tokens([[:NUMBER, 0.30]], tokens)
45
+ end
46
+
47
+ def test_identifier
48
+ tokens = @tokenizer.tokenize("foo")
49
+ assert_tokens([[:IDENT, 'foo']], tokens)
50
+ end
51
+
52
+ def test_ignore_identifier
53
+ tokens = @tokenizer.tokenize("0foo")
54
+ assert_tokens([[:NUMBER, 0], [:IDENT, 'foo']], tokens)
55
+ end
56
+
57
+ def test_increment
58
+ tokens = @tokenizer.tokenize("foo += 1;")
59
+ assert_tokens([
60
+ [:IDENT, 'foo'],
61
+ [:PLUSEQUAL, '+='],
62
+ [:NUMBER, 1],
63
+ [';', ';'],
64
+ ], tokens)
65
+ end
66
+
67
+ def test_regex
68
+ tokens = @tokenizer.tokenize("foo = /=asdf/;")
69
+ assert_tokens([
70
+ [:IDENT, 'foo'],
71
+ ['=', '='],
72
+ [:REGEXP, '/=asdf/'],
73
+ [';', ';'],
74
+ ], tokens)
75
+ end
76
+
77
+ def test_regular_expression_escape
78
+ tokens = @tokenizer.tokenize('foo = /\/asdf/gi;')
79
+ assert_tokens([
80
+ [:IDENT, 'foo'],
81
+ ['=', '='],
82
+ [:REGEXP, '/\/asdf/gi'],
83
+ [';', ';'],
84
+ ], tokens)
85
+ end
86
+
87
+ def test_comment_assign
88
+ tokens = @tokenizer.tokenize("foo = /**/;")
89
+ assert_tokens([
90
+ [:IDENT, 'foo'],
91
+ ['=', '='],
92
+ [:COMMENT, '/**/'],
93
+ [';', ';'],
94
+ ], tokens)
95
+
96
+ tokens = @tokenizer.tokenize("foo = //;")
97
+ assert_tokens([
98
+ [:IDENT, 'foo'],
99
+ ['=', '='],
100
+ [:COMMENT, '//;'],
101
+ ], tokens)
102
+ end
103
+
104
+ def assert_tokens(expected, actual)
105
+ assert_equal(expected, actual.select { |x| x[0] != :S })
106
+ end
107
+
108
+ %w{
109
+ break case catch continue default delete do else finally for function
110
+ if in instanceof new return switch this throw try typeof var void while
111
+ with
112
+
113
+ const true false null debugger
114
+ }.each do |kw|
115
+ define_method(:"test_keyword_#{kw}") do
116
+ tokens = @tokenizer.tokenize(kw)
117
+ assert_equal 1, tokens.length
118
+ assert_equal([[kw.upcase.to_sym, kw]], tokens)
119
+ end
120
+ end
121
+ {
122
+ '==' => :EQEQ,
123
+ '!=' => :NE,
124
+ '===' => :STREQ,
125
+ '!==' => :STRNEQ,
126
+ '<=' => :LE,
127
+ '>=' => :GE,
128
+ '||' => :OR,
129
+ '&&' => :AND,
130
+ '++' => :PLUSPLUS,
131
+ '--' => :MINUSMINUS,
132
+ '<<' => :LSHIFT,
133
+ '>>' => :RSHIFT,
134
+ '>>>' => :URSHIFT,
135
+ '+=' => :PLUSEQUAL,
136
+ '-=' => :MINUSEQUAL,
137
+ '*=' => :MULTEQUAL,
138
+ 'null' => :NULL,
139
+ 'true' => :TRUE,
140
+ 'false' => :FALSE,
141
+ }.each do |punctuator, sym|
142
+ define_method(:"test_punctuator_#{sym}") do
143
+ tokens = @tokenizer.tokenize(punctuator)
144
+ assert_equal 1, tokens.length
145
+ assert_equal([[sym, punctuator]], tokens)
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,8 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class TrueNodeTest < NodeTestCase
4
+ def test_to_sexp
5
+ node = TrueNode.new('true')
6
+ assert_sexp [:true], node
7
+ end
8
+ end
@@ -0,0 +1,59 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class TryNodeTest < NodeTestCase
4
+ def test_failure
5
+ var_foo = VarStatementNode.new([
6
+ VarDeclNode.new('foo', AssignExprNode.new(NumberNode.new(10)))
7
+ ])
8
+
9
+ var_bar = VarStatementNode.new([
10
+ VarDeclNode.new('bar', AssignExprNode.new(NumberNode.new(20)))
11
+ ])
12
+
13
+ var_baz = VarStatementNode.new([
14
+ VarDeclNode.new('baz', AssignExprNode.new(NumberNode.new(69)))
15
+ ])
16
+
17
+ try_block = BlockNode.new(SourceElementsNode.new([var_baz]))
18
+ catch_block = BlockNode.new(SourceElementsNode.new([var_bar]))
19
+ finally_block = BlockNode.new(SourceElementsNode.new([var_foo]))
20
+
21
+ node = TryNode.new(try_block, nil, nil, finally_block)
22
+ assert_sexp([ :try,
23
+ [:block,
24
+ [[:var, [[:var_decl, :baz, [:assign, [:lit, 69]]]]]]
25
+ ],
26
+ nil,
27
+ nil,
28
+ [:block,
29
+ [[:var, [[:var_decl, :foo, [:assign, [:lit, 10]]]]]]
30
+ ]
31
+ ], node)
32
+
33
+ node = TryNode.new(try_block, 'a', catch_block)
34
+ assert_sexp([ :try,
35
+ [:block,
36
+ [[:var, [[:var_decl, :baz, [:assign, [:lit, 69]]]]]]
37
+ ],
38
+ 'a',
39
+ [:block,
40
+ [[:var, [[:var_decl, :bar, [:assign, [:lit, 20]]]]]]
41
+ ],
42
+ nil,
43
+ ], node)
44
+
45
+ node = TryNode.new(try_block, 'a', catch_block, finally_block)
46
+ assert_sexp([ :try,
47
+ [:block,
48
+ [[:var, [[:var_decl, :baz, [:assign, [:lit, 69]]]]]]
49
+ ],
50
+ 'a',
51
+ [:block,
52
+ [[:var, [[:var_decl, :bar, [:assign, [:lit, 20]]]]]]
53
+ ],
54
+ [:block,
55
+ [[:var, [[:var_decl, :foo, [:assign, [:lit, 10]]]]]]
56
+ ]
57
+ ], node)
58
+ end
59
+ end
@@ -0,0 +1,8 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class TypeOfNodeTest < NodeTestCase
4
+ def test_to_sexp
5
+ node = TypeOfNode.new(ResolveNode.new('foo'))
6
+ assert_sexp([:typeof, [:resolve, 'foo']], node)
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class UnaryMinusNodeTest < NodeTestCase
4
+ def test_to_sexp
5
+ node = UnaryMinusNode.new(NumberNode.new(10))
6
+ assert_sexp([:u_minus, [:lit, 10]], node)
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class UnaryPlusNodeTest < NodeTestCase
4
+ def test_to_sexp
5
+ node = UnaryPlusNode.new(NumberNode.new(10))
6
+ assert_sexp([:u_plus, [:lit, 10]], node)
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class UnsignedRightShiftNodeTest < NodeTestCase
4
+ def test_to_sexp
5
+ node = UnsignedRightShiftNode.new(NumberNode.new(5), NumberNode.new(10))
6
+ assert_sexp([:urshift, [:lit, 5], [:lit, 10]], node)
7
+ end
8
+ end
@@ -0,0 +1,21 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class VarDeclNodeTest < NodeTestCase
4
+ def test_to_sexp
5
+ initializer = AssignExprNode.new(NumberNode.new(10))
6
+ node = VarDeclNode.new('foo', initializer)
7
+ assert_sexp [:var_decl, :foo, [:assign, [:lit, 10]]], node
8
+
9
+ node = VarDeclNode.new('foo', nil)
10
+ assert_sexp [:var_decl, :foo, nil], node
11
+ end
12
+
13
+ def test_const_to_sexp
14
+ initializer = AssignExprNode.new(NumberNode.new(10))
15
+ node = VarDeclNode.new('foo', initializer, true)
16
+ assert_sexp [:const_decl, :foo, [:assign, [:lit, 10]]], node
17
+
18
+ node = VarDeclNode.new('foo', nil, true)
19
+ assert_sexp [:const_decl, :foo, nil], node
20
+ end
21
+ end
@@ -0,0 +1,14 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class VarStatementNodeTest < NodeTestCase
4
+ def test_to_sexp
5
+ initializer = AssignExprNode.new(NumberNode.new(10))
6
+ decl = VarDeclNode.new('foo', initializer)
7
+ stmt = VarStatementNode.new([decl])
8
+
9
+ assert_sexp(
10
+ [:var, [[:var_decl, :foo, [:assign, [:lit, 10]]]]],
11
+ stmt
12
+ )
13
+ end
14
+ end
@@ -0,0 +1,8 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class VoidNodeTest < NodeTestCase
4
+ def test_to_sexp
5
+ node = VoidNode.new(ResolveNode.new('foo'))
6
+ assert_sexp([:void, [:resolve, 'foo']], node)
7
+ end
8
+ end
@@ -0,0 +1,15 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class WhileNodeTest < NodeTestCase
4
+ def test_to_sexp
5
+ initializer = AssignExprNode.new(NumberNode.new(10))
6
+ decl = VarDeclNode.new('foo', initializer)
7
+ stmt = VarStatementNode.new([decl])
8
+ node = WhileNode.new(TrueNode.new('true'), stmt)
9
+
10
+ assert_sexp([:while,
11
+ [:true],
12
+ [:var, [[:var_decl, :foo, [:assign, [:lit, 10]]]]],
13
+ ], node)
14
+ end
15
+ end
@@ -0,0 +1,8 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class WithNodeTest < NodeTestCase
4
+ def test_to_sexp
5
+ node = WithNode.new(ResolveNode.new('foo'), ResolveNode.new('bar'))
6
+ assert_sexp([:with, [:resolve, 'foo'], [:resolve, 'bar']], node)
7
+ end
8
+ end