reflexive 0.0.3 → 0.0.4

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 (142) hide show
  1. data/Gemfile +16 -0
  2. data/Rakefile +31 -0
  3. data/config.ru +3 -0
  4. data/reflexive.gemspec +1 -1
  5. data/spec/coderay_html_encoder_spec.rb +57 -0
  6. data/spec/coderay_ruby_scanner_spec.rb +194 -0
  7. data/spec/io_interceptor.rb +64 -0
  8. data/spec/method_lookup_spec.rb +0 -0
  9. data/spec/methods_spec.rb +202 -0
  10. data/spec/rails_integration_spec.rb +139 -0
  11. data/spec/rails_integration_spec_helper.rb +115 -0
  12. data/spec/reflexive_ripper_spec.rb +351 -0
  13. data/spec/reflexive_spec.rb +98 -0
  14. data/spec/ripper_events_recorder.rb +50 -0
  15. data/spec/ripper_spec.rb +758 -0
  16. data/spec/sexp_builder_with_scanner_events.rb +39 -0
  17. data/spec/shell_out.rb +417 -0
  18. data/spec/spec_helper.rb +4 -0
  19. data/spec/test_apps/rails2_test_app/README +243 -0
  20. data/spec/test_apps/rails2_test_app/Rakefile +10 -0
  21. data/spec/test_apps/rails2_test_app/app/controllers/application_controller.rb +10 -0
  22. data/spec/test_apps/rails2_test_app/app/controllers/posts_controller.rb +85 -0
  23. data/spec/test_apps/rails2_test_app/app/helpers/application_helper.rb +3 -0
  24. data/spec/test_apps/rails2_test_app/app/helpers/posts_helper.rb +2 -0
  25. data/spec/test_apps/rails2_test_app/app/models/post.rb +5 -0
  26. data/spec/test_apps/rails2_test_app/app/views/layouts/posts.html.erb +17 -0
  27. data/spec/test_apps/rails2_test_app/app/views/posts/edit.html.erb +12 -0
  28. data/spec/test_apps/rails2_test_app/app/views/posts/index.html.erb +18 -0
  29. data/spec/test_apps/rails2_test_app/app/views/posts/new.html.erb +11 -0
  30. data/spec/test_apps/rails2_test_app/app/views/posts/show.html.erb +3 -0
  31. data/spec/test_apps/rails2_test_app/config/boot.rb +110 -0
  32. data/spec/test_apps/rails2_test_app/config/database.yml +22 -0
  33. data/spec/test_apps/rails2_test_app/config/environment.rb +43 -0
  34. data/spec/test_apps/rails2_test_app/config/environments/development.rb +17 -0
  35. data/spec/test_apps/rails2_test_app/config/environments/production.rb +28 -0
  36. data/spec/test_apps/rails2_test_app/config/environments/test.rb +28 -0
  37. data/spec/test_apps/rails2_test_app/config/initializers/backtrace_silencers.rb +7 -0
  38. data/spec/test_apps/rails2_test_app/config/initializers/inflections.rb +10 -0
  39. data/spec/test_apps/rails2_test_app/config/initializers/mime_types.rb +5 -0
  40. data/spec/test_apps/rails2_test_app/config/initializers/new_rails_defaults.rb +21 -0
  41. data/spec/test_apps/rails2_test_app/config/initializers/session_store.rb +15 -0
  42. data/spec/test_apps/rails2_test_app/config/locales/en.yml +5 -0
  43. data/spec/test_apps/rails2_test_app/config/routes.rb +45 -0
  44. data/spec/test_apps/rails2_test_app/db/development.sqlite3 +0 -0
  45. data/spec/test_apps/rails2_test_app/db/migrate/20100512073155_create_posts.rb +12 -0
  46. data/spec/test_apps/rails2_test_app/db/schema.rb +19 -0
  47. data/spec/test_apps/rails2_test_app/db/seeds.rb +7 -0
  48. data/spec/test_apps/rails2_test_app/doc/README_FOR_APP +2 -0
  49. data/spec/test_apps/rails2_test_app/log/development.log +251 -0
  50. data/spec/test_apps/rails2_test_app/log/production.log +0 -0
  51. data/spec/test_apps/rails2_test_app/log/server.log +0 -0
  52. data/spec/test_apps/rails2_test_app/log/test.log +0 -0
  53. data/spec/test_apps/rails2_test_app/public/404.html +30 -0
  54. data/spec/test_apps/rails2_test_app/public/422.html +30 -0
  55. data/spec/test_apps/rails2_test_app/public/500.html +30 -0
  56. data/spec/test_apps/rails2_test_app/public/favicon.ico +0 -0
  57. data/spec/test_apps/rails2_test_app/public/images/rails.png +0 -0
  58. data/spec/test_apps/rails2_test_app/public/index.html +275 -0
  59. data/spec/test_apps/rails2_test_app/public/javascripts/application.js +2 -0
  60. data/spec/test_apps/rails2_test_app/public/javascripts/controls.js +963 -0
  61. data/spec/test_apps/rails2_test_app/public/javascripts/dragdrop.js +973 -0
  62. data/spec/test_apps/rails2_test_app/public/javascripts/effects.js +1128 -0
  63. data/spec/test_apps/rails2_test_app/public/javascripts/prototype.js +4320 -0
  64. data/spec/test_apps/rails2_test_app/public/robots.txt +5 -0
  65. data/spec/test_apps/rails2_test_app/public/stylesheets/1.css +0 -0
  66. data/spec/test_apps/rails2_test_app/public/stylesheets/scaffold.css +54 -0
  67. data/spec/test_apps/rails2_test_app/script/about +4 -0
  68. data/spec/test_apps/rails2_test_app/script/console +3 -0
  69. data/spec/test_apps/rails2_test_app/script/dbconsole +3 -0
  70. data/spec/test_apps/rails2_test_app/script/destroy +3 -0
  71. data/spec/test_apps/rails2_test_app/script/generate +3 -0
  72. data/spec/test_apps/rails2_test_app/script/performance/benchmarker +3 -0
  73. data/spec/test_apps/rails2_test_app/script/performance/profiler +3 -0
  74. data/spec/test_apps/rails2_test_app/script/plugin +3 -0
  75. data/spec/test_apps/rails2_test_app/script/runner +3 -0
  76. data/spec/test_apps/rails2_test_app/script/server +3 -0
  77. data/spec/test_apps/rails2_test_app/test/fixtures/posts.yml +7 -0
  78. data/spec/test_apps/rails2_test_app/test/functional/posts_controller_test.rb +45 -0
  79. data/spec/test_apps/rails2_test_app/test/performance/browsing_test.rb +9 -0
  80. data/spec/test_apps/rails2_test_app/test/test_helper.rb +38 -0
  81. data/spec/test_apps/rails2_test_app/test/unit/helpers/posts_helper_test.rb +4 -0
  82. data/spec/test_apps/rails2_test_app/test/unit/post_test.rb +8 -0
  83. data/spec/test_apps/rails3_test_app/Gemfile +28 -0
  84. data/spec/test_apps/rails3_test_app/README +244 -0
  85. data/spec/test_apps/rails3_test_app/Rakefile +10 -0
  86. data/spec/test_apps/rails3_test_app/app/controllers/application_controller.rb +4 -0
  87. data/spec/test_apps/rails3_test_app/app/controllers/posts_controller.rb +83 -0
  88. data/spec/test_apps/rails3_test_app/app/helpers/application_helper.rb +2 -0
  89. data/spec/test_apps/rails3_test_app/app/helpers/posts_helper.rb +2 -0
  90. data/spec/test_apps/rails3_test_app/app/models/post.rb +2 -0
  91. data/spec/test_apps/rails3_test_app/app/views/layouts/application.html.erb +14 -0
  92. data/spec/test_apps/rails3_test_app/app/views/posts/_form.html.erb +16 -0
  93. data/spec/test_apps/rails3_test_app/app/views/posts/edit.html.erb +6 -0
  94. data/spec/test_apps/rails3_test_app/app/views/posts/index.html.erb +21 -0
  95. data/spec/test_apps/rails3_test_app/app/views/posts/new.html.erb +5 -0
  96. data/spec/test_apps/rails3_test_app/app/views/posts/show.html.erb +5 -0
  97. data/spec/test_apps/rails3_test_app/config/application.rb +49 -0
  98. data/spec/test_apps/rails3_test_app/config/boot.rb +6 -0
  99. data/spec/test_apps/rails3_test_app/config/database.yml +22 -0
  100. data/spec/test_apps/rails3_test_app/config/environment.rb +5 -0
  101. data/spec/test_apps/rails3_test_app/config/environments/development.rb +19 -0
  102. data/spec/test_apps/rails3_test_app/config/environments/production.rb +42 -0
  103. data/spec/test_apps/rails3_test_app/config/environments/test.rb +32 -0
  104. data/spec/test_apps/rails3_test_app/config/initializers/backtrace_silencers.rb +7 -0
  105. data/spec/test_apps/rails3_test_app/config/initializers/inflections.rb +10 -0
  106. data/spec/test_apps/rails3_test_app/config/initializers/mime_types.rb +5 -0
  107. data/spec/test_apps/rails3_test_app/config/initializers/secret_token.rb +7 -0
  108. data/spec/test_apps/rails3_test_app/config/initializers/session_store.rb +8 -0
  109. data/spec/test_apps/rails3_test_app/config/locales/en.yml +5 -0
  110. data/spec/test_apps/rails3_test_app/config/routes.rb +60 -0
  111. data/spec/test_apps/rails3_test_app/config.ru +4 -0
  112. data/spec/test_apps/rails3_test_app/db/development.sqlite3 +0 -0
  113. data/spec/test_apps/rails3_test_app/db/migrate/20100512075428_create_posts.rb +12 -0
  114. data/spec/test_apps/rails3_test_app/db/schema.rb +19 -0
  115. data/spec/test_apps/rails3_test_app/db/seeds.rb +7 -0
  116. data/spec/test_apps/rails3_test_app/doc/README_FOR_APP +2 -0
  117. data/spec/test_apps/rails3_test_app/log/development.log +349 -0
  118. data/spec/test_apps/rails3_test_app/log/production.log +0 -0
  119. data/spec/test_apps/rails3_test_app/log/server.log +0 -0
  120. data/spec/test_apps/rails3_test_app/log/test.log +0 -0
  121. data/spec/test_apps/rails3_test_app/public/404.html +26 -0
  122. data/spec/test_apps/rails3_test_app/public/422.html +26 -0
  123. data/spec/test_apps/rails3_test_app/public/500.html +26 -0
  124. data/spec/test_apps/rails3_test_app/public/favicon.ico +0 -0
  125. data/spec/test_apps/rails3_test_app/public/images/rails.png +0 -0
  126. data/spec/test_apps/rails3_test_app/public/index.html +279 -0
  127. data/spec/test_apps/rails3_test_app/public/javascripts/application.js +2 -0
  128. data/spec/test_apps/rails3_test_app/public/javascripts/controls.js +965 -0
  129. data/spec/test_apps/rails3_test_app/public/javascripts/dragdrop.js +974 -0
  130. data/spec/test_apps/rails3_test_app/public/javascripts/effects.js +1123 -0
  131. data/spec/test_apps/rails3_test_app/public/javascripts/prototype.js +4874 -0
  132. data/spec/test_apps/rails3_test_app/public/javascripts/rails.js +118 -0
  133. data/spec/test_apps/rails3_test_app/public/robots.txt +5 -0
  134. data/spec/test_apps/rails3_test_app/public/stylesheets/scaffold.css +60 -0
  135. data/spec/test_apps/rails3_test_app/script/rails +9 -0
  136. data/spec/test_apps/rails3_test_app/test/fixtures/posts.yml +11 -0
  137. data/spec/test_apps/rails3_test_app/test/functional/posts_controller_test.rb +49 -0
  138. data/spec/test_apps/rails3_test_app/test/performance/browsing_test.rb +9 -0
  139. data/spec/test_apps/rails3_test_app/test/test_helper.rb +13 -0
  140. data/spec/test_apps/rails3_test_app/test/unit/helpers/posts_helper_test.rb +4 -0
  141. data/spec/test_apps/rails3_test_app/test/unit/post_test.rb +8 -0
  142. metadata +142 -2
@@ -0,0 +1,758 @@
1
+ require "ripper"
2
+
3
+ require File.expand_path("../sexp_builder_with_scanner_events", __FILE__)
4
+
5
+ describe Ripper do
6
+ def events_tree(src)
7
+ parser = SexpBuilderWithScannerEvents.new(src)
8
+ parser.parse
9
+ end
10
+
11
+ Rspec::Matchers.define :parse_as do |*expected_events_tree|
12
+ match do |source|
13
+ events_tree(source)[1][0] == expected_events_tree
14
+ end
15
+
16
+ failure_message_for_should do |source|
17
+ require "pp"
18
+ "expected \"#{ source }\" to generate events:\n" <<
19
+ "#{ expected_events_tree.pretty_inspect }" <<
20
+ "got:\n#{ events_tree(source)[1][0].pretty_inspect }"
21
+ end
22
+ end
23
+
24
+ BODYSTMT_VOID = [:bodystmt, [[:void_stmt]], nil, nil, nil].freeze
25
+ PARAMS_VOID = [:params, nil, nil, nil, nil, nil].freeze
26
+
27
+ describe "parser events" do
28
+ specify "class definition (class)" do
29
+ "class C < D; end".should parse_as(:class,
30
+ [:const_ref, {:const=>"C"}],
31
+ [:var_ref, {:const=>"D"}],
32
+ BODYSTMT_VOID)
33
+ end
34
+
35
+ specify "singleton class definition (sclass)" do
36
+ "class << self; end".should parse_as(:sclass,
37
+ [:var_ref, {:kw=>"self"}],
38
+ BODYSTMT_VOID)
39
+ end
40
+
41
+ specify "module definition (module)" do
42
+ "module M; end".should parse_as(:module,
43
+ [:const_ref, {:const=>"M"}],
44
+ BODYSTMT_VOID)
45
+ end
46
+
47
+ specify "method definition (def)" do
48
+ "def m; end".should parse_as(:def,
49
+ {:ident=>"m"},
50
+ PARAMS_VOID,
51
+ BODYSTMT_VOID)
52
+ end
53
+
54
+ specify "method definition complete (def)" do
55
+ "def m(a,o=1,*r,a2,&b); rescue E1,E2 => e; 1; rescue E3; 1; else v = 1; v = 1; ensure 1; end".should(parse_as(
56
+ :def,
57
+ {:ident=>"m"},
58
+ [:paren,
59
+ [:params,
60
+ [{:ident=>"a"}],
61
+ [[{:ident=>"o"}, {:int=>"1"}]],
62
+ [:rest_param, {:ident=>"r"}],
63
+ [{:ident=>"a2"}],
64
+ [:blockarg, {:ident=>"b"}]]],
65
+ [:bodystmt,
66
+ [[:void_stmt]],
67
+ [:rescue,
68
+ [:mrhs_new_from_args,
69
+ [[:var_ref, {:const=>"E1"}]],
70
+ [:var_ref, {:const=>"E2"}]],
71
+ [:var_field, {:ident=>"e"}],
72
+ [{:int=>"1"}],
73
+ [:rescue, [[:var_ref, {:const=>"E3"}]], nil, [{:int=>"1"}], nil]],
74
+ [:else,
75
+ [[:assign, [:var_field, {:ident=>"v"}], {:int=>"1"}],
76
+ [:assign, [:var_field, {:ident=>"v"}], {:int=>"1"}]]],
77
+ [:ensure, [{:int=>"1"}]]]))
78
+ end
79
+
80
+ specify "singleton method definition (defs)" do
81
+ "def self.m; end".should parse_as(:defs,
82
+ [:var_ref, {:kw=>"self"}],
83
+ {:period=>"."},
84
+ {:ident=>"m"},
85
+ PARAMS_VOID,
86
+ BODYSTMT_VOID)
87
+ end
88
+
89
+ specify "do block definition (do_block)" do
90
+ "m do end".should parse_as(:method_add_block,
91
+ [:method_add_arg, [:fcall, {:ident=>"m"}], []],
92
+ [:do_block, nil, [[:void_stmt]]])
93
+ end
94
+
95
+ specify "brace block definition (brace_block)" do
96
+ "m { }".should parse_as(:method_add_block,
97
+ [:method_add_arg, [:fcall, {:ident=>"m"}], []],
98
+ [:brace_block, nil, [[:void_stmt]]])
99
+ end
100
+
101
+ def f_arg
102
+ [{:ident=>"a"}]
103
+ end
104
+
105
+ def f_arg2
106
+ [{:ident=>"a2"}]
107
+ end
108
+
109
+ def f_block_optarg
110
+ [[{:ident=>"o"}, {:int=>"1"}]]
111
+ end
112
+
113
+ def f_optarg
114
+ [[{:ident=>"o"}, {:int=>"1"}]]
115
+ end
116
+
117
+ def f_rest_arg
118
+ [:rest_param, {:ident=>"r"}]
119
+ end
120
+
121
+ def opt_f_block_arg
122
+ [:blockarg, {:ident=>"b"}]
123
+ end
124
+
125
+ describe "block variables according to parse.y" do
126
+ def block_variables(src, *variables)
127
+ variables = nil if variables == [nil]
128
+ src.should(parse_as(*[:method_add_block,
129
+ [:method_add_arg, [:fcall, {:ident=>"m"}], []],
130
+ [:do_block,
131
+ [:block_var, PARAMS_VOID, variables],
132
+ [[:void_stmt]]]]))
133
+ end
134
+
135
+ def block_params_and_variables(src, params, variables)
136
+ src.should(parse_as(*[:method_add_block,
137
+ [:method_add_arg, [:fcall, {:ident=>"m"}], []],
138
+ [:do_block,
139
+ [:block_var, [:params, *params], variables],
140
+ [[:void_stmt]]]]))
141
+ end
142
+
143
+ specify "'|' opt_bv_decl '|' => blockvar_new(params_new(Qnil,Qnil,Qnil,Qnil,Qnil), escape_Qundef($2))" do
144
+ block_variables("m do |;v1| end",
145
+ {:ident=>"v1"})
146
+ block_variables("m do |;v1,v2| end",
147
+ {:ident=>"v1"}, {:ident=>"v2"})
148
+ end
149
+
150
+ specify "tOROP => blockvar_new(params_new(Qnil,Qnil,Qnil,Qnil,Qnil), Qnil);" do
151
+ block_variables("m do || end", nil)
152
+ end
153
+
154
+ specify "'|' block_param opt_bv_decl '|' => blockvar_new(escape_Qundef($2), escape_Qundef($3));" do
155
+ block_params_and_variables("m do |a,o=1,*r,a2,&b;v1,v2| end",
156
+ [f_arg, f_block_optarg, f_rest_arg, f_arg2, opt_f_block_arg],
157
+ [{:ident=>"v1"}, {:ident=>"v2"}])
158
+ end
159
+ end
160
+
161
+ describe "block params according to parse.y" do
162
+ def block_params(src, *params)
163
+ src.should(parse_as(*[:method_add_block,
164
+ [:method_add_arg, [:fcall, {:ident=>"m"}], []],
165
+ [:do_block,
166
+ [:block_var, [:params, *params], nil], # ???
167
+ [[:void_stmt]]]]))
168
+ end
169
+
170
+ specify "f_arg ',' f_block_optarg ',' f_rest_arg ',' f_arg opt_f_block_arg => params_new($1, $3, $5, $7, escape_Qundef($8));" do
171
+ block_params("m do |a,o=1,*r,a2,&b| end",
172
+ f_arg, f_block_optarg, f_rest_arg, f_arg2, opt_f_block_arg)
173
+ end
174
+
175
+ # the rest are mere combinations
176
+
177
+ specify "f_arg ',' f_block_optarg ',' f_rest_arg opt_f_block_arg => params_new($1, $3, $5, Qnil, escape_Qundef($6));" do
178
+ block_params("m do |a,o=1,*r,&b| end",
179
+ f_arg, f_block_optarg, f_rest_arg, nil, opt_f_block_arg)
180
+ end
181
+
182
+ specify "f_arg ',' f_block_optarg opt_f_block_arg => params_new($1, $3, Qnil, Qnil, escape_Qundef($4));" do
183
+ block_params("m do |a,o=1,&b| end",
184
+ f_arg, f_block_optarg, nil, nil, opt_f_block_arg)
185
+ end
186
+
187
+ specify "f_arg ',' f_block_optarg ',' f_arg opt_f_block_arg => params_new($1, $3, Qnil, $5, escape_Qundef($6));" do
188
+ block_params("m do |a,o=1,a2,&b| end",
189
+ f_arg, f_block_optarg, nil, f_arg2, opt_f_block_arg)
190
+ end
191
+
192
+ specify "f_arg ',' f_rest_arg opt_f_block_arg => params_new($1, Qnil, $3, Qnil, escape_Qundef($4));" do
193
+ block_params("m do |a,*r,&b| end",
194
+ f_arg, nil, f_rest_arg, nil, opt_f_block_arg)
195
+ end
196
+
197
+ specify "f_arg ',' => params_new($1, Qnil, Qnil, Qnil, Qnil);" do
198
+ block_params("m do |a,| end",
199
+ f_arg, nil, nil, nil, nil)
200
+ end
201
+
202
+ specify "f_arg ',' f_rest_arg ',' f_arg opt_f_block_arg => params_new($1, Qnil, $3, $5, escape_Qundef($6));" do
203
+ block_params("m do |a,*r,a2,&b| end",
204
+ f_arg, nil, f_rest_arg, f_arg2, opt_f_block_arg)
205
+ end
206
+
207
+ specify "f_arg opt_f_block_arg => params_new($1, Qnil, Qnil, Qnil, escape_Qundef($2));" do
208
+ block_params("m do |a,&b| end",
209
+ f_arg, nil, nil, nil, opt_f_block_arg)
210
+ end
211
+
212
+ specify "f_block_optarg ',' f_rest_arg opt_f_block_arg => params_new(Qnil, $1, $3, Qnil, escape_Qundef($4));" do
213
+ block_params("m do |o=1,*r,&b| end",
214
+ nil, f_block_optarg, f_rest_arg, nil, opt_f_block_arg)
215
+ end
216
+
217
+ specify "f_block_optarg ',' f_rest_arg ',' f_arg opt_f_block_arg => params_new(Qnil, $1, $3, $5, escape_Qundef($6));" do
218
+ block_params("m do |o=1,*r,a2,&b| end",
219
+ nil, f_block_optarg, f_rest_arg, f_arg2, opt_f_block_arg)
220
+ end
221
+
222
+ specify "f_block_optarg opt_f_block_arg => params_new(Qnil, $1, Qnil, Qnil,escape_Qundef($2));" do
223
+ block_params("m do |o=1,&b| end",
224
+ nil, f_block_optarg, nil, nil, opt_f_block_arg)
225
+ end
226
+
227
+ specify "f_block_optarg ',' f_arg opt_f_block_arg => params_new(Qnil, $1, Qnil, $3, escape_Qundef($4));" do
228
+ block_params("m do |o=1,a2,&b| end",
229
+ nil, f_block_optarg, nil, f_arg2, opt_f_block_arg)
230
+ end
231
+
232
+ specify "f_rest_arg opt_f_block_arg => params_new(Qnil, Qnil, $1, Qnil, escape_Qundef($2));" do
233
+ block_params("m do |*r,&b| end",
234
+ nil, nil, f_rest_arg, nil, opt_f_block_arg)
235
+ end
236
+
237
+
238
+ specify "f_rest_arg ',' f_arg opt_f_block_arg => params_new(Qnil, Qnil, $1, $3, escape_Qundef($4));" do
239
+ block_params("m do |*r,a2,&b| end",
240
+ nil, nil, f_rest_arg, f_arg2, opt_f_block_arg)
241
+ end
242
+
243
+ specify "f_block_arg => params_new(Qnil, Qnil, Qnil, Qnil, $1);" do
244
+ block_params("m do |&b| end",
245
+ nil, nil, nil, nil, opt_f_block_arg)
246
+ end
247
+
248
+ specify "none" do
249
+ block_params("m do || end",
250
+ nil, nil, nil, nil, nil)
251
+ end
252
+ end
253
+
254
+ describe "method params according to parse.y" do
255
+ def def_params(src, *params)
256
+ src.should(parse_as(*[:def,
257
+ {:ident=>"m"},
258
+ [:paren, [:params, *params]],
259
+ BODYSTMT_VOID]))
260
+ end
261
+
262
+ specify "f_arg ',' f_optarg ',' f_rest_arg ',' f_arg opt_f_block_arg => params_new($1, $3, $5, $7, escape_Qundef($8));" do
263
+ def_params("def m(a,o=1,*r,a2,&b); end",
264
+ f_arg, f_optarg, f_rest_arg, f_arg2, opt_f_block_arg)
265
+ end
266
+
267
+ # the rest are mere combinations
268
+
269
+ specify "f_arg ',' f_optarg ',' f_rest_arg opt_f_block_arg => params_new($1, $3, $5, Qnil, escape_Qundef($6))" do
270
+ def_params("def m(a,o=1,*r,&b); end",
271
+ f_arg, f_optarg, f_rest_arg, nil, opt_f_block_arg)
272
+ end
273
+
274
+ specify "f_arg ',' f_optarg opt_f_block_arg => params_new($1, $3, Qnil, Qnil, escape_Qundef($4));" do
275
+ def_params("def m(a,o=1,&b); end",
276
+ f_arg, f_optarg, nil, nil, opt_f_block_arg)
277
+ end
278
+
279
+ specify "f_arg ',' f_optarg ',' f_arg opt_f_block_arg => params_new($1, $3, Qnil, $5, escape_Qundef($6));" do
280
+ def_params("def m(a,o=1,a2,&b); end",
281
+ f_arg, f_optarg, nil, f_arg2, opt_f_block_arg)
282
+ end
283
+
284
+ specify "f_arg ',' f_rest_arg opt_f_block_arg => params_new($1, Qnil, $3, Qnil, escape_Qundef($4));" do
285
+ def_params("def m(a,*r,&b); end",
286
+ f_arg, nil, f_rest_arg, nil, opt_f_block_arg)
287
+ end
288
+
289
+ specify "f_arg ',' f_rest_arg ',' f_arg opt_f_block_arg => params_new($1, Qnil, $3, $5, escape_Qundef($6));" do
290
+ def_params("def m(a,*r,a2,&b); end",
291
+ f_arg, nil, f_rest_arg, f_arg2, opt_f_block_arg)
292
+ end
293
+
294
+ specify "f_arg opt_f_block_arg => params_new($1, Qnil, Qnil, Qnil, escape_Qundef($2));" do
295
+ def_params("def m(a,&b); end",
296
+ f_arg, nil, nil, nil, opt_f_block_arg)
297
+ end
298
+
299
+ specify "f_optarg ',' f_rest_arg opt_f_block_arg => params_new(Qnil, $1, $3, Qnil, escape_Qundef($4));" do
300
+ def_params("def m(o=1,*r,&b); end",
301
+ nil, f_optarg, f_rest_arg, nil, opt_f_block_arg)
302
+ end
303
+
304
+ specify "f_optarg ',' f_rest_arg ',' f_arg opt_f_block_arg => params_new(Qnil, $1, $3, $5, escape_Qundef($6));" do
305
+ def_params("def m(o=1,*r,a2,&b); end",
306
+ nil, f_optarg, f_rest_arg, f_arg2, opt_f_block_arg)
307
+ end
308
+
309
+ specify "f_optarg opt_f_block_arg => params_new(Qnil, $1, Qnil, Qnil, escape_Qundef($2));" do
310
+ def_params("def m(o=1,&b); end",
311
+ nil, f_optarg, nil, nil, opt_f_block_arg)
312
+ end
313
+
314
+ specify "f_optarg ',' f_arg opt_f_block_arg => params_new(Qnil, $1, Qnil, $3, escape_Qundef($4));" do
315
+ def_params("def m(o=1,a2,&b); end",
316
+ nil, f_optarg, nil, f_arg2, opt_f_block_arg)
317
+ end
318
+
319
+ specify "f_rest_arg opt_f_block_arg => params_new(Qnil, Qnil, $1, Qnil,escape_Qundef($2));" do
320
+ def_params("def m(*r,&b); end",
321
+ nil, nil, f_rest_arg, nil, opt_f_block_arg)
322
+ end
323
+
324
+ specify "f_rest_arg ',' f_arg opt_f_block_arg => params_new(Qnil, Qnil, $1, $3, escape_Qundef($4));" do
325
+ def_params("def m(*r,a2,&b); end",
326
+ nil, nil, f_rest_arg, f_arg2, opt_f_block_arg)
327
+ end
328
+
329
+ specify "f_block_arg => params_new(Qnil, Qnil, Qnil, Qnil, $1);" do
330
+ def_params("def m(&b); end",
331
+ nil, nil, nil, nil, opt_f_block_arg)
332
+ end
333
+
334
+ specify "/* none */ => params_new(Qnil, Qnil, Qnil, Qnil, Qnil);" do
335
+ def_params("def m(); end",
336
+ nil, nil, nil, nil, nil)
337
+ end
338
+ end
339
+
340
+ describe "assignment according to parse.y" do
341
+ describe "lhs '=' command_call => dispatch2(assign, $1, $3);" do
342
+ specify "constant to local variable" do
343
+ "v = 1".should parse_as(:assign,
344
+ [:var_field, {:ident=>"v"}],
345
+ {:int=>"1"})
346
+ end
347
+
348
+ specify "result of method call to local variable" do
349
+ "v = m()".should parse_as(:assign,
350
+ [:var_field, {:ident=>"v"}],
351
+ [:method_add_arg, [:fcall, {:ident=>"m"}], [:arg_paren, nil]])
352
+ end
353
+
354
+ specify "variable to local variable" do
355
+ "v = v2".should parse_as(:assign,
356
+ [:var_field, {:ident=>"v"}],
357
+ [:var_ref, {:ident=>"v2"}])
358
+ end
359
+ end
360
+
361
+ describe "mlhs '=' command_call => dispatch2(massign, $1, $3);" do
362
+ specify "constants to multiple local variables" do
363
+ "v1, v2 = 1, 2".should parse_as(:massign,
364
+ [{:ident=>"v1"}, {:ident=>"v2"}],
365
+ [:mrhs_new_from_args, [{:int=>"1"}], {:int=>"2"}])
366
+ end
367
+
368
+ specify "result ot method calls to multiple local variables" do
369
+ "v1, v2 = m1, m2".should parse_as(:massign,
370
+ [{:ident=>"v1"}, {:ident=>"v2"}],
371
+ [:mrhs_new_from_args,
372
+ [[:var_ref, {:ident=>"m1"}]],
373
+ [:var_ref, {:ident=>"m2"}]])
374
+
375
+ "v1, v2, v3 = m1, m2, m3".should parse_as(:massign,
376
+ [{:ident=>"v1"}, {:ident=>"v2"}, {:ident=>"v3"}],
377
+ [:mrhs_new_from_args,
378
+ [[:var_ref, {:ident=>"m1"}], [:var_ref, {:ident=>"m2"}]],
379
+ [:var_ref, {:ident=>"m3"}]])
380
+ end
381
+
382
+ specify "result ot star method calls to multiple local variables" do
383
+ "v1, v2, v3 = *m".should parse_as(:massign,
384
+ [{:ident=>"v1"}, {:ident=>"v2"}, {:ident=>"v3"}],
385
+ [:mrhs_add_star, [], [:var_ref, {:ident=>"m"}]]) # command_call, value_expr
386
+ end
387
+ end
388
+
389
+ describe "var_lhs tOP_ASGN command_call => dispatch3(opassign, $1, $2, $3);" do
390
+ specify "operator assignment (like a += 1)" do
391
+ "v += 1".should parse_as(:opassign,
392
+ [:var_field, {:ident=>"v"}],
393
+ {:op=>"+="}, # operator
394
+ {:int=>"1"}) # command_call
395
+ end
396
+ end
397
+
398
+ specify "primary_value '[' opt_call_args rbracket tOP_ASGN command_call => \
399
+ dispatch2(aref_field, $1, escape_Qundef($3)); dispatch3(opassign, $$, $5, $6);" do
400
+ "v[1] += 1".should parse_as(:opassign,
401
+ [:aref_field, # opt_call_args
402
+ [:var_ref, {:ident=>"v"}],
403
+ [:args_add_block, [{:int=>"1"}], false]], # ?
404
+ {:op=>"+="}, # operator
405
+ {:int=>"1"}) # command_call
406
+ end
407
+
408
+ specify "primary_value '.' tIDENTIFIER tOP_ASGN command_call => \
409
+ $$ = dispatch3(field, $1, ripper_id2sym('.'), $3); dispatch3(opassign, $$, $4, $5);" do
410
+ "v.q += 1".should parse_as(:opassign,
411
+ [:field,
412
+ [:var_ref, {:ident=>"v"}], :".", {:ident=>"q"}],
413
+ {:op=>"+="},
414
+ {:int=>"1"})
415
+ end
416
+
417
+ specify "primary_value '.' tCONSTANT tOP_ASGN command_call => \
418
+ $$ = dispatch3(field, $1, ripper_id2sym('.'), $3); dispatch3(opassign, $$, $4, $5);" do
419
+ "v.C += 1".should parse_as(:opassign,
420
+ [:field, [:var_ref, {:ident=>"v"}], :".", {:const=>"C"}],
421
+ {:op=>"+="},
422
+ {:int=>"1"})
423
+ end
424
+
425
+ specify "primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call =>\
426
+ $$ = dispatch3(field, $1, ripper_intern('::'), $3); dispatch3(opassign, $$, $4, $5);" do
427
+ "v::i += 1".should parse_as(:opassign,
428
+ [:field, [:var_ref, {:ident=>"v"}], :"::", {:ident=>"i"}],
429
+ {:op=>"+="},
430
+ {:int=>"1"})
431
+ end
432
+
433
+ specify "lhs '=' mrhs => dispatch2(assign, $1, $3);" do
434
+ "v::i += 1".should parse_as(:opassign,
435
+ [:field, [:var_ref, {:ident=>"v"}], :"::", {:ident=>"i"}],
436
+ {:op=>"+="},
437
+ {:int=>"1"})
438
+ end
439
+
440
+ specify "result ot star method calls to multiple local variables (lhs '=' mrhs)" do
441
+ "v1, v2, v3 = *m".should parse_as(:massign,
442
+ [{:ident=>"v1"}, {:ident=>"v2"}, {:ident=>"v3"}],
443
+ [:mrhs_add_star, [], [:var_ref, {:ident=>"m"}]]) # command_call, value_expr
444
+ end
445
+
446
+ specify "lhs '=' arg modifier_rescue arg => dispatch2(assign, $1, dispatch2(rescue_mod, $3, $5));" do
447
+ "v = a rescue b".should parse_as(:assign,
448
+ [:var_field, {:ident=>"v"}],
449
+ [:rescue_mod, [:var_ref, {:ident=>"a"}], [:var_ref, {:ident=>"b"}]])
450
+ end
451
+
452
+ # assign(lhs, something)
453
+ end
454
+
455
+ describe "method calls" do
456
+ specify "command" do
457
+ "r 'f', &ba".should parse_as(:command,
458
+ {:ident=>"r"},
459
+ [:args_add_block,
460
+ [[:string_literal, [:string_content, {:tstring_content=>"f"}]]],
461
+ [:var_ref, {:ident=>"ba"}]])
462
+ end
463
+
464
+ specify "command with paren" do
465
+ "r('f', &ba)".should parse_as(:method_add_arg,
466
+ [:fcall, {:ident=>"r"}],
467
+ [:arg_paren,
468
+ [:args_add_block,
469
+ [[:string_literal, [:string_content, {:tstring_content=>"f"}]]],
470
+ [:var_ref, {:ident=>"ba"}]]])
471
+ end
472
+
473
+ specify "block_call '.' operation2 command_args" do
474
+ "m do end.o(a).m(a)".should parse_as(:method_add_arg,
475
+ [:call,
476
+ [:method_add_arg,
477
+ [:call,
478
+ [:method_add_block,
479
+ [:method_add_arg, [:fcall, {:ident=>"m"}], []],
480
+ [:do_block, nil, [[:void_stmt]]]],
481
+ :".",
482
+ {:ident=>"o"}],
483
+ [:arg_paren, [:args_add_block, [[:var_ref, {:ident=>"a"}]], false]]],
484
+ :".",
485
+ {:ident=>"m"}],
486
+ [:arg_paren, [:args_add_block, [[:var_ref, {:ident=>"a"}]], false]])
487
+
488
+ end
489
+
490
+ specify "block_call tCOLON2 operation2 command_args" do
491
+ "m1 do end::o(a)::m2(a)".should parse_as(:method_add_arg,
492
+ [:call,
493
+ [:method_add_arg,
494
+ [:call,
495
+ [:method_add_block,
496
+ [:method_add_arg, [:fcall, {:ident=>"m1"}], []],
497
+ [:do_block, nil, [[:void_stmt]]]],
498
+ :".",
499
+ {:ident=>"o"}],
500
+ [:arg_paren, [:args_add_block, [[:var_ref, {:ident=>"a"}]], false]]],
501
+ :".",
502
+ {:ident=>"m2"}],
503
+ [:arg_paren, [:args_add_block, [[:var_ref, {:ident=>"a"}]], false]])
504
+ end
505
+
506
+ describe "block_call :" do
507
+ specify "command do_block" do
508
+ "m do end".should parse_as(:method_add_block,
509
+ [:method_add_arg, [:fcall, {:ident=>"m"}], []],
510
+ [:do_block, nil, [[:void_stmt]]])
511
+ end
512
+
513
+ specify "block_call '.' operation2 opt_paren_args" do
514
+ "m1 do end.m2(a)".should parse_as(:method_add_arg,
515
+ [:call,
516
+ [:method_add_block,
517
+ [:method_add_arg, [:fcall, {:ident=>"m1"}], []],
518
+ [:do_block, nil, [[:void_stmt]]]],
519
+ :".",
520
+ {:ident=>"m2"}],
521
+ [:arg_paren, [:args_add_block, [[:var_ref, {:ident=>"a"}]], false]])
522
+ end
523
+
524
+ specify "block_call tCOLON2 operation2 opt_paren_args" do
525
+ "m() { }::m(a)".should parse_as(:method_add_arg,
526
+ [:call,
527
+ [:method_add_block,
528
+ [:method_add_arg, [:fcall, {:ident=>"m"}], [:arg_paren, nil]],
529
+ [:brace_block, nil, [[:void_stmt]]]],
530
+ :".",
531
+ {:ident=>"m"}],
532
+ [:arg_paren, [:args_add_block, [[:var_ref, {:ident=>"a"}]], false]])
533
+ end
534
+
535
+ specify "subclasses.each { }" do
536
+ "subclasses.each { }".should parse_as(:method_add_block,
537
+ [:call, [:var_ref, {:ident=>"subclasses"}], :".", {:ident=>"each"}],
538
+ [:brace_block, nil, [[:void_stmt]]])
539
+ end
540
+
541
+ specify ":command_call event" do
542
+ "A::B.c d unless 1".should parse_as(:unless_mod,
543
+ {:int=>"1"},
544
+ [:command_call,
545
+ [:const_path_ref, [:var_ref, {:const=>"A"}], {:const=>"B"}],
546
+ :".",
547
+ {:ident=>"c"},
548
+ [:args_add_block, [[:var_ref, {:ident=>"d"}]], false]])
549
+ end
550
+
551
+ specify ":command_call event" do
552
+ "::B.c d unless 1".should parse_as(:unless_mod,
553
+ {:int=>"1"},
554
+ [:command_call,
555
+ [:top_const_ref, {:const=>"B"}],
556
+ :".",
557
+ {:ident=>"c"},
558
+ [:args_add_block, [[:var_ref, {:ident=>"d"}]], false]])
559
+ end
560
+
561
+ specify ":command_call event" do
562
+ "a(c).c d unless 1".should parse_as(:unless_mod,
563
+ {:int=>"1"},
564
+ [:command_call,
565
+ [:method_add_arg,
566
+ [:fcall, {:ident=>"a"}],
567
+ [:arg_paren, [:args_add_block, [[:var_ref, {:ident=>"c"}]], false]]],
568
+ :".",
569
+ {:ident=>"c"},
570
+ [:args_add_block, [[:var_ref, {:ident=>"d"}]], false]])
571
+ end
572
+
573
+ pending "operation command_args cmd_brace_block" do
574
+ # wrong!
575
+ # |
576
+ # {
577
+ # /*%%%*/
578
+ # block_dup_check($2,$3);
579
+ # $3->nd_iter = NEW_FCALL($1, $2);
580
+ # $$ = $3;
581
+ # fixpos($$, $2);
582
+ # /*%
583
+ # $$ = dispatch2(command, $1, $2);
584
+ # $$ = method_add_block($$, $3);
585
+ # %*/
586
+ # }
587
+ "q next i { 42 }".should parse_as(:command,
588
+ {:const=>"C"},
589
+ [[:next,
590
+ [:args_add_block,
591
+ [[:method_add_block,
592
+ [:method_add_arg, [:fcall, {:ident=>"i"}], []],
593
+ [:brace_block, nil, [{:int=>"42"}]]]],
594
+ false]]])
595
+ end
596
+
597
+ pending "primary_value '.' operation2 command_args %prec tLOWEST" do
598
+ # | primary_value '.' operation2 command_args %prec tLOWEST
599
+ # {
600
+ # /*%%%*/
601
+ # $$ = NEW_CALL($1, $3, $4);
602
+ # fixpos($$, $1);
603
+ # /*%
604
+ # $$ = dispatch4(command_call, $1, ripper_id2sym('.'), $3, $4);
605
+ # %*/
606
+ # }
607
+ "yield.pv.o(a)".should parse_as()
608
+ end
609
+
610
+ # specify "" do
611
+ # "".should parse_as()
612
+ # end
613
+
614
+ pending "primary_value '.' operation2 command_args cmd_brace_block" do
615
+ # | primary_value '.' operation2 command_args cmd_brace_block
616
+ # {
617
+ # /*%%%*/
618
+ # block_dup_check($4,$5);
619
+ # $5->nd_iter = NEW_CALL($1, $3, $4);
620
+ # $$ = $5;
621
+ # fixpos($$, $1);
622
+ # /*%
623
+ # $$ = dispatch4(command_call, $1, ripper_id2sym('.'), $3, $4);
624
+ # $$ = method_add_block($$, $5);
625
+ # %*/
626
+ # }
627
+ "".should parse_as(:void_stmt)
628
+ end
629
+
630
+ pending "primary_value tCOLON2 operation2 command_args %prec tLOWEST" do
631
+ # | primary_value tCOLON2 operation2 command_args %prec tLOWEST
632
+ # {
633
+ # /*%%%*/
634
+ # $$ = NEW_CALL($1, $3, $4);
635
+ # fixpos($$, $1);
636
+ # /*%
637
+ # $$ = dispatch4(command_call, $1, ripper_intern("::"), $3, $4);
638
+ # %*/
639
+ # }
640
+ "".should parse_as(:void_stmt)
641
+ end
642
+
643
+ pending "primary_value tCOLON2 operation2 command_args cmd_brace_block" do
644
+ # | primary_value tCOLON2 operation2 command_args cmd_brace_block
645
+ # {
646
+ # /*%%%*/
647
+ # block_dup_check($4,$5);
648
+ # $5->nd_iter = NEW_CALL($1, $3, $4);
649
+ # $$ = $5;
650
+ # fixpos($$, $1);
651
+ # /*%
652
+ # $$ = dispatch4(command_call, $1, ripper_intern("::"), $3, $4);
653
+ # $$ = method_add_block($$, $5);
654
+ # %*/
655
+ # }
656
+ "".should parse_as(:void_stmt)
657
+ end
658
+ end
659
+
660
+ specify "primary : literal" do
661
+ "m!".should parse_as(:method_add_arg, [:fcall, {:ident=>"m!"}], [])
662
+ end
663
+
664
+ specify "| operation brace_block" do
665
+ "m! { }".should parse_as(:method_add_block,
666
+ [:method_add_arg, [:fcall, {:ident=>"m!"}], []],
667
+ [:brace_block, nil, [[:void_stmt]]])
668
+ end
669
+
670
+ specify "" do
671
+ "".should parse_as(:void_stmt)
672
+ end
673
+
674
+ specify "" do
675
+
676
+ # else if (is_local_id(id)) {
677
+ # if (dyna_in_block() && dvar_defined(id)) return NEW_DVAR(id);
678
+ # if (local_id(id)) return NEW_LVAR(id);
679
+ # /* method call without arguments */
680
+ # return NEW_VCALL(id);
681
+ # }
682
+ # else if (is_global_id(id)) {
683
+ # return NEW_GVAR(id);
684
+ # }
685
+ # else if (is_instance_id(id)) {
686
+ # return NEW_IVAR(id);
687
+ # }
688
+ # else if (is_const_id(id)) {
689
+ # return NEW_CONST(id);
690
+ # }
691
+ # else if (is_class_id(id)) {
692
+ # return NEW_CVAR(id);
693
+ # }
694
+
695
+ # | var_lhs tOP_ASGN command_call
696
+ #
697
+ # may result in
698
+ # $$->nd_value = NEW_CALL(gettable(vid), $2, NEW_LIST($3));
699
+ # while dispatching only
700
+ # $$ = dispatch3(opassign, $1, $2, $3);
701
+
702
+ # | var_lhs tOP_ASGN arg
703
+ # $$ = NEW_OP_ASGN_OR(gettable(vid), $1);
704
+
705
+ # | var_lhs tOP_ASGN arg modifier_rescue arg
706
+ # $$ = NEW_OP_ASGN_OR(gettable(vid), $1);
707
+
708
+ #var_ref : variable
709
+ # {
710
+ # /*%%%*/
711
+ # if( ! ($$ = gettable($1)) )
712
+ # $$ = NEW_BEGIN(0);
713
+ # /*%
714
+ # $$ = dispatch1(var_ref, $1);
715
+ # %*/
716
+ # }
717
+ # ;
718
+
719
+
720
+ # | tUMINUS_NUM tINTEGER tPOW arg
721
+ # {
722
+ # /*%%%*/
723
+ # $$ = NEW_CALL(call_bin_op($2, tPOW, $4), tUMINUS, 0);
724
+ # /*%
725
+ # $$ = dispatch3(binary, $2, ripper_intern("**"), $4);
726
+ # $$ = dispatch2(unary, ripper_intern("-@"), $$);
727
+
728
+ # | tUMINUS_NUM tFLOAT tPOW arg
729
+ # {
730
+ # /*%%%*/
731
+ # $$ = NEW_CALL(call_bin_op($2, tPOW, $4), tUMINUS, 0);
732
+ # /*%
733
+ # $$ = dispatch3(binary, $2, ripper_intern("**"), $4);
734
+ # $$ = dispatch2(unary, ripper_intern("-@"), $$);
735
+ # %*/
736
+ # }
737
+
738
+ # | primary_value '[' opt_call_args rbracket
739
+ # {
740
+ # /*%%%*/
741
+ # if ($1 && nd_type($1) == NODE_SELF)
742
+ # $$ = NEW_FCALL(tAREF, $3);
743
+ # else
744
+ # $$ = NEW_CALL($1, tAREF, $3);
745
+ # fixpos($$, $1);
746
+ # /*%
747
+ # $$ = dispatch2(aref, $1, escape_Qundef($3));
748
+ # %*/
749
+ # }
750
+
751
+ end
752
+ end
753
+
754
+ describe "variable reference" do
755
+
756
+ end
757
+ end
758
+ end