reflexive 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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