redparse 0.8.3 → 0.8.4

Sign up to get free protection for your applications and to get access to all the features.
data/test/test_all.rb ADDED
@@ -0,0 +1,3 @@
1
+ require 'test/test_redparse'
2
+ #require 'test/test_xform_tree' #these are broken, gyaaah, not actually used
3
+ #require 'test/test_1.9' #should be enabled eventually, too many broken cases for now
@@ -17,13 +17,19 @@
17
17
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
18
  =end
19
19
 
20
+ $VERBOSE=1
21
+ $Debug=1
20
22
  require 'test/unit'
21
- require 'rubygems'
22
- require 'parse_tree'
23
+ #require 'parse_tree'
23
24
  require 'tempfile'
25
+ begin
26
+ require 'ron'
27
+ rescue LoadError
28
+ #do nothing
29
+ end
24
30
 
25
31
  require "redparse"
26
-
32
+ require "redparse/pthelper"
27
33
  require "rubylexer/test/testcases"
28
34
 
29
35
  $VERBOSE=1
@@ -90,16 +96,29 @@ class Test::Unit::TestCase
90
96
  end
91
97
 
92
98
  #print output immediately on failing test (at end too....)
93
- require 'test/unit/ui/console/testrunner'
94
- class Test::Unit::UI::Console::TestRunner
95
- alias add_fault__no_immed_output add_fault
96
- def add_fault fault
97
- @fault_count||=0
98
- output("\n%3d) %s" % [@fault_count+=1, fault.long_display])
99
- add_fault__no_immed_output fault
99
+ begin
100
+ require 'test/unit/ui/console/testrunner'
101
+ class Test::Unit::UI::Console::TestRunner
102
+ alias add_fault__no_immed_output add_fault
103
+ def add_fault fault
104
+ @fault_count||=0
105
+ output("\n%3d) %s" % [@fault_count+=1, fault.long_display])
106
+ add_fault__no_immed_output fault
107
+ end
100
108
  end
109
+ rescue LoadError; #do nothing; just skip this code if test/unit/ui/console/testrunner not present
101
110
  end
102
111
 
112
+ class MiniTest::Unit
113
+ alias puke__without_immediate_output puke
114
+ def puke klass, meth, e
115
+ result=puke__without_immediate_output klass, meth, e
116
+ puts @report.last
117
+ return result
118
+ end
119
+ end if defined? MiniTest::Unit
120
+
121
+
103
122
  =begin nice idea, don't work yet
104
123
  class Test::Unit::TestResult
105
124
  @@FAILING_CASES=[]
@@ -149,24 +168,24 @@ class Test::Unit::TestResult
149
168
  end
150
169
  =end
151
170
 
171
+ require 'redparse/parse_tree_server'
152
172
  class ParseTree
153
- def put o
154
- o=Marshal.dump o
155
- @@out.write [o.size].pack("N")+o
156
- end
157
- def get
158
- Marshal.load @@in.read(@@in.read(4).unpack("N")[0])
159
- end
160
- def fork_server?
161
- return if defined? @@out
173
+ class<<self
174
+ include ParseTreeComm
175
+ def old_fork_server?
176
+ @in||=nil; @out||=nil
177
+ return if @out
178
+ Process.kill "KILL",@server if @server
179
+ @server=nil
162
180
  si,co=IO::pipe
163
181
  ci,so=IO::pipe
164
- fork{
182
+ @server=fork{
165
183
  begin
166
184
  co.close; ci.close
167
- @@out=so; @@in=si
185
+ @out=so; @in=si
168
186
  warnstash=Tempfile.new "warnstash"
169
187
  STDERR.reopen warnstash
188
+ instance=new
170
189
  while 1
171
190
  str=get
172
191
  exit! if str==:exit!
@@ -175,7 +194,7 @@ class ParseTree
175
194
 
176
195
  tree=
177
196
  begin
178
- parse_tree_for_string(str) #tree
197
+ instance.parse_tree_for_string(str) #tree
179
198
  rescue Exception=>e;
180
199
  tree=e
181
200
  end
@@ -191,19 +210,50 @@ class ParseTree
191
210
  end
192
211
  }
193
212
  si.close; so.close
194
- @@out=co; @@in=ci
195
- at_exit { put :exit! }
213
+ @out=co; @in=ci
214
+ at_exit {
215
+ begin
216
+ put :exit!
217
+ Process.wait(@server)
218
+ rescue Exception
219
+ end
220
+ }
221
+ end
222
+
223
+ def fork_server?
224
+ @in||=nil; @out||=nil; @server||=nil
225
+ return if @out
226
+ Process.kill "KILL",@server if @server
227
+
228
+ ruby=ENV["RUBY1_8"]||"ruby"
229
+ @out=@in=IO::popen("#{ruby} #{ParseTreeServer.path_to_server_command}", "r+")
230
+ @server=@in.pid
231
+ @server_running_187=nil
232
+ server_running_187?
233
+
234
+ at_exit {
235
+ begin
236
+ put :exit!
237
+ Process.wait(@server)
238
+ rescue Exception
239
+ end
240
+ }
196
241
  end
197
242
 
198
243
  #returns +[parse_tree|Exception, +[String.*]]
199
244
  def parse_tree_and_warnings str
200
245
  fork_server?
201
- put str
202
- tree=get
203
- warnings=get
246
+ begin
247
+ put str
248
+ tree=get
249
+ warnings=get
250
+ rescue Exception
251
+ return nil,nil
252
+ end
204
253
  raise tree if Exception===tree
205
254
  return tree,warnings
206
255
  end
256
+ end
207
257
 
208
258
  #this way is bad enough, but there's a fd leak this way,
209
259
  #so I have to use the even more complicated version above
@@ -246,6 +296,18 @@ class RedParseTest<Test::Unit::TestCase
246
296
  FAILURE_EXAMPLES=[
247
297
  ]
248
298
  RUBYBUG_EXAMPLES=[
299
+
300
+ #bugs in ruby itself
301
+ "c do p (110).m end",
302
+ "p = p m %(1)",
303
+ "p = p m %(1) ,&t",
304
+ "p = p m %(1) ,*t",
305
+ "p = p m %(1) ,t",
306
+ "p = p m %(1) do end",
307
+ "p=556;p (e) /a",
308
+ "z{|| p (1).m}",
309
+
310
+ #bugs in ParseTree
249
311
  ' case
250
312
  when 0
251
313
  guecoding
@@ -254,23 +316,84 @@ class RedParseTest<Test::Unit::TestCase
254
316
  guing
255
317
  end
256
318
  end',
257
-
258
319
  'case; when false; else case; when nil; else 5; end; end',
259
- 'def foo(a=b=c={}) end',
260
- "$11111111111111111111111111111111111111111111111111111111111111111111",
261
- "c do p (110).m end",
262
320
  "case F;when G; else;case; when j; end;end",
263
- "p = p m %(1)",
264
- "p = p m %(1) ,&t",
265
- "p = p m %(1) ,*t",
266
- "p = p m %(1) ,t",
267
- "p = p m %(1) do end",
268
- "p=556;p (e) /a",
269
- "z{|| p (1).m}",
321
+ 'def foo(a=b=c={}) end',
270
322
  'def sum(options = {:weights => weights = Hash.new(1)}); options.empty? or options.keys.size > 1; end',
323
+ 'def sum(options = {:weights => weights = Hash}); 1 end',
324
+ 'def foo(a = 1) end; def foo(a=b=c={}) end; def bar(a=b=c=1,d=2) end',
325
+ 'def bar(a=b=1,d=2) end',
326
+ 'def bar a=b=1,d=2; end',
327
+ 'x if /f/../o/',
328
+ 'c while d and a8../2.a?(b)/',
329
+ 'c while d and :a8..:b8',
330
+ 'c while d and :a8..2.a?(b)',
331
+ 'c while d and 8.8..2.a?(b)',
332
+ 'c while d and 8../2.a?(b)/',
333
+ 'c while d and 2.a?(b)..8',
334
+ 'c while d and /8/..2.a?(b)',
335
+ 'c while d and /8/../2.a?(b)/',
336
+ 'a if 1..2',
337
+
338
+ #not sure which, doesn't really matter anyway
339
+ "$11111111111111111111111111111111111111111111111111111111111111111111",
271
340
  ]
272
341
 
273
342
  ONELINERS=[
343
+ 'yield [a_i, *p] '...'',
344
+ '0.113725'...'',
345
+ '0.777777'...'',
346
+ 'if a; b; elsif c; else d end'...'',
347
+ '[a=>b,c=>d]'...'',
348
+ '[a=>b,c=>d,*e]'...'',
349
+ 'class __FILE__::A; b end'...'',
350
+ 'module __FILE__::A; b end'...'',
351
+ 'class __LINE__::A; b end'...'',
352
+ 'module __LINE__::A; b end'...'',
353
+ 'class self::A; b end'...'',
354
+ 'module self::A; b end'...'',
355
+ 'class self::A<B; c end'...'',
356
+ 'module self::A include B; c end'...'',
357
+ 'class a.b.c.d.e.f::Quux; YYY=534 end'...'',
358
+ 'class[Array][0]::Foo; Bazz=556 end'...'',
359
+ '=begin\r\nfoo\r\n=end\r\n'...'',
360
+ 'a!`b'...'',
361
+ 'fetch_named { {} }'...'',
362
+ 'def subject::Builder.foo; bar end'...'',
363
+ 'class subject::Builder<T; foo end'...'',
364
+ 'module subject::Builder include T; foo end'...'',
365
+ 'class subject::Builder; foo end'...'',
366
+ 'module subject::Builder; foo end'...'',
367
+ 'Hasnew{[]}'...'',
368
+ 'foo::Bar'...'',
369
+ 'x{foo=1; foo::Bar}'...'',
370
+ '$foo::Bar'...'',
371
+ '@foo::Bar'...'',
372
+ '@@foo::Bar'...'',
373
+ ' (-6000)..476'...'',
374
+ "case;when 0;ng = 'JIS';else case; when sjis__length; ding = 'EUC-JP' ;end;end"...'',
375
+ 'attribute :invisible do [] end'...'',
376
+ '"#{queect{|w| w.t{|w| w}}}"'...'',
377
+ 'case z; when a=b=1,d=2; yy end'...'',
378
+ 'begin z; rescue a=b=1,d=2; yy end'...'',
379
+ '{5=>a=b=1,d=2=>6}'...'',
380
+ '{a=b=1,d=2}'...'',
381
+ 'a=b=1,d=2'...'',
382
+ 'z=a=b=1,d=2'...'',
383
+ 'p(){|a=b=1,d=2| e}'...'',
384
+ 'p(a=b=1,d=2)'...'',
385
+ 'p a=b=1,d=2'...'',
386
+ 'z[a=b=1,d=2]=5'...'',
387
+ 'z[a=b=1,d=2]'...'',
388
+ '[a=b=1,d=2]'...'',
389
+ 'UnOpNode===arg and /^$/===arg'...'',
390
+ 'a+b=c rescue d'...'',
391
+ 'a=b=c=d=f rescue g'...'',
392
+ 'z+a=b=c=d=f rescue g'...'',
393
+ 'k=z=c,d'...'',
394
+ 'd=a=b do end'...'',
395
+ 't p = m do 666 end'...'',
396
+ 'a if 1'...'',
274
397
  'p (a,b=c,d); a +h'...'',
275
398
  'x{return (a,b=c,d)}'...'',
276
399
  'x{r (a,b=c,d)}'...'',
@@ -279,15 +402,10 @@ class RedParseTest<Test::Unit::TestCase
279
402
  'case; when false; else case; when nil; else 5; end; end'...'',
280
403
  'case;else case; else; end;end'...'',
281
404
  'case; else; end'...'',
282
- 'c while d and 2.a?(b)..8'...'',
283
405
  'c while d and 888888888888888888888888888888888888888888888888888888..2.a?(b)'...'',
284
- 'c while d and 8.8..2.a?(b)'...'',
285
406
  'c while d and 8..2.a?(b)'...'',
286
- 'c while d and :a8..2.a?(b)'...'',
287
- 'c while d and /8/..2.a?(b)'...'',
288
- 'c while d and /8/../2.a?(b)/'...'',
289
- 'c while d and 8../2.a?(b)/'...'',
290
- 'c while d and a8../2.a?(b)/'...'',
407
+ 'c while d and a8..:b8'...'',
408
+ 'c while d and 8..:b8'...'',
291
409
  'z = valueo_s rescue "?"'...'',
292
410
  '"#{publi}#{}>"'...'',
293
411
  'return (@images = @old_imgs)'...'',
@@ -295,6 +413,7 @@ class RedParseTest<Test::Unit::TestCase
295
413
  'doc_status, err_args = Documeh_status{fcgi_state = 3; docespond do doc_response =fcgi_state = 1; end }'...'',
296
414
  'print "coled: " + $! +" wiin #{@ray}\n";'...'',
297
415
  'class A;def b;class <<self;@@p = false end;end;end'...'',
416
+ 'class A;def b;class <<self;"#{@@p = false}" end;end;end'...'',
298
417
  'def d; return (block_given? ? begin; yield f; ensure; f.close; end : f); end'...'',
299
418
  'def sum(options = {:weights => weights = Hash.new(1)}); options.empty? or options.keys.size > 1; end'...'',
300
419
  'def d;e install_dir;end'...'',
@@ -344,8 +463,6 @@ class RedParseTest<Test::Unit::TestCase
344
463
  "begin begin; ync; p1; end;rr end"...'',
345
464
  "begin;mode;rescue;o_chmod rescue nil;end"...'',
346
465
  "%w![ ] { } ( ) | - * . \\\\ ? + ^ $ #!"...'',
347
-
348
- 'def foo(a = 1) end; def foo(a=b=c={}) end; def bar(a=b=c=1,d=2) end'...'',
349
466
  '() until 1'...'',
350
467
  '(a) until 1'...'',
351
468
  '(a) while l 1'...'',
@@ -2013,7 +2130,6 @@ class RedParseTest<Test::Unit::TestCase
2013
2130
  'p(a and b)'...'', #not legal
2014
2131
 
2015
2132
  '1..2'...'',
2016
- 'a if 1..2'...'',
2017
2133
 
2018
2134
  'nc=(nextchar unless eof?)'...'',
2019
2135
  'super'...'',
@@ -2742,9 +2858,6 @@ class RedParseTest<Test::Unit::TestCase
2742
2858
  'a,b=(*c=b,a)'...'',
2743
2859
 
2744
2860
  ]
2745
- NOTWORKINGYET=[
2746
- #later...
2747
- ]
2748
2861
 
2749
2862
 
2750
2863
  PASSTHRU_BSLASHES_ENTIRE=<<'END'
@@ -2819,6 +2932,17 @@ class RedParseTest<Test::Unit::TestCase
2819
2932
  END
2820
2933
 
2821
2934
  STANZAS=PASSTHRU_BSLASHES_ENTIRE+%q[
2935
+ @@anon = Module.new
2936
+ class @@anon::I
2937
+ bindtextd
2938
+ def test2
2939
+ _()
2940
+ end
2941
+ end
2942
+ module @@anon::J
2943
+ bindt
2944
+ end
2945
+
2822
2946
  module
2823
2947
  =begin =end
2824
2948
  =end
@@ -2840,15 +2964,6 @@ module A::
2840
2964
  return @senders[1] =
2841
2965
  2
2842
2966
 
2843
- case
2844
- when 0
2845
- guecoding
2846
- else case
2847
- when eucjp_match_length
2848
- guing
2849
- end
2850
- end
2851
-
2852
2967
  %w[ ac
2853
2968
  df]
2854
2969
 
@@ -3607,45 +3722,52 @@ EOS
3607
3722
 
3608
3723
  WRAPPERS=[ #enable at most 2 or tests take forever!!!
3609
3724
  '(...)', #normal mode, should usually be enabled
3610
- # 'a rescue (...)',
3611
- # "((...))",
3612
- # 'def ((...)).foo; end',
3613
- # 'a0 = (...) rescue b0',
3614
- # 'a0 = ((...)) rescue b0',
3615
- # '(...) #with a comment',
3616
- # "(...)#with comment and newline\n",
3617
- # "(...)\n",
3618
- # "(...);p __LINE__",
3619
- # "defined? (...)",
3620
- # "a=a (...)",
3621
- # "b=1;b (...)",
3622
- # "return (...)"
3725
+ 'a rescue (...)',
3726
+ "((...))",
3727
+ 'def ((...)).foo; end',
3728
+ 'a0 = (...) rescue b0',
3729
+ 'a0 = ((...)) rescue b0',
3730
+ '(...) #with a comment',
3731
+ "(...)#with comment and newline\n",
3732
+ "(...)\n",
3733
+ "(...);p __LINE__",
3734
+ "defined? (...)",
3735
+ "a=a (...)",
3736
+ "b=1;b (...)",
3737
+ "return (...)",
3738
+ '"#{(...)}"',
3623
3739
  ]
3624
3740
  INJECTABLES=[ #take it easy with these too
3625
- # 'p (1..10).method(:each)',
3626
- # 'a0 rescue b0',
3627
- # 'begin; r; t end',
3628
- # 'a=b,c=d',
3741
+ 'p (1..10).method(:each)',
3742
+ 'a0 rescue b0',
3743
+ 'begin; r; t end',
3744
+ 'a=b,c=d',
3629
3745
  ]
3630
- puts "warning: most data fuzzing is disabled for now"
3746
+ if ENV['MANGLE']
3747
+ else
3748
+ WRAPPERS.slice!(1..-1)
3749
+ INJECTABLES.clear
3750
+ puts "warning: most data fuzzing is disabled; set MANGLE to enable"
3751
+ end
3631
3752
 
3632
3753
  RUBYIDENT=/((?:$|@@?)?#{RubyLexer::LETTER}#{RubyLexer::LETTER_DIGIT}*[?!]?)/o
3633
3754
 
3634
3755
  def self.snippet2testmethod(snippet,wrap=nil)
3635
3756
  escaped=snippet.gsub(/[\\']/){"\\"+$&}
3636
3757
  safe=escaped.gsub(/([^ -~])/){
3637
- x=$1[0].to_s(16)
3758
+ x=$1[0]
3759
+ x=x.getbyte(0) if String===x
3760
+ x=x.to_s(16)
3638
3761
  x.size==1 and x="0"+x
3639
3762
  "\\x"+x
3640
3763
  }
3641
3764
  safe.gsub! /\\\\/,"__"
3642
3765
  safe[/[^ -~]|\\\\/] and fail
3643
- cp="check_parsing '#{escaped}',pt"
3766
+ cp="check_parsing '#{escaped}'"
3644
3767
  cp="#{wrap}{#{cp}}" if wrap
3645
3768
  "
3646
3769
  define_method 'test_parsing_of_#{safe}' do
3647
3770
  #puts 'test_parsing_of_#{safe}'
3648
- pt=ParseTree.new
3649
3771
  #{cp}
3650
3772
  end
3651
3773
  "
@@ -3678,7 +3800,7 @@ EOS
3678
3800
  end
3679
3801
  }
3680
3802
  wrapped+injected
3681
- }.to_s
3803
+ }.join
3682
3804
  #puts code.split("\n")[5880..5890].join("\n")
3683
3805
  eval code
3684
3806
 
@@ -3689,7 +3811,7 @@ EOS
3689
3811
  /\A\s*x\s*\{(.*)\}\Z/===xmpl and xmpl=$1
3690
3812
 
3691
3813
  snippet2testmethod(xmpl, :known_ruby_bug)
3692
- }.to_s
3814
+ }.join
3693
3815
  eval error_code
3694
3816
 
3695
3817
  error_code=ERROR_EXAMPLES.map{|xmpl|
@@ -3699,7 +3821,7 @@ EOS
3699
3821
  /\A\s*x\s*\{(.*)\}\Z/===xmpl and xmpl=$1
3700
3822
 
3701
3823
  snippet2testmethod(xmpl, :known_error)
3702
- }.to_s
3824
+ }.join
3703
3825
  eval error_code
3704
3826
 
3705
3827
  failure_code=FAILURE_EXAMPLES.map{|xmpl|
@@ -3709,9 +3831,11 @@ EOS
3709
3831
  /\A\s*x\s*\{(.*)\}\Z/===xmpl and xmpl=$1
3710
3832
 
3711
3833
  snippet2testmethod(xmpl, :known_failure)
3712
- }.to_s
3834
+ }.join
3713
3835
  eval failure_code
3714
3836
 
3837
+ Test::Unit::AssertionFailedError=MiniTest::Assertion unless defined? Test::Unit::AssertionFailedError
3838
+
3715
3839
  def known_ruby_bug
3716
3840
  from=caller.first
3717
3841
  from=from[/ in `.*'\Z/] || from[/\A[^:]*:[^:]*/]
@@ -3739,19 +3863,19 @@ EOS
3739
3863
  def test_case_that_segfaults_ruby185
3740
3864
  assert_equal \
3741
3865
  [[:op_asgn1, [:call, [:vcall, :a], :b], [:zarray], :%, [:vcall, :d]]],
3742
- RedParse.new('a.b[]%=d','-').parse.to_parsetree(:quirks)
3866
+ RedParse.new('a.b[]%=d','(eval)',1,[],:cache_mode=>:none).parse.to_parsetree(:quirks)
3743
3867
  end
3744
3868
 
3745
3869
  def test_case_that_segfaults_ruby186_slash_parsetree211
3746
3870
  assert_equal [[:cdecl, [:colon3, :B], [:lit,1]]],
3747
- RedParse.new('::B=1','-').parse.to_parsetree(:quirks)
3871
+ RedParse.new('::B=1','-',1,[],:cache_mode=>:none).parse.to_parsetree(:quirks)
3748
3872
  assert_equal [[:cdecl, [:colon2, [:const, :A], :B], [:lit,1]]],
3749
- RedParse.new('A::B=1','-').parse.to_parsetree(:quirks)
3873
+ RedParse.new('A::B=1','-',1,[],:cache_mode=>:none).parse.to_parsetree(:quirks)
3750
3874
  end
3751
3875
 
3752
3876
  def test_case_that_segfaults_ruby187_slash_parsetree220
3753
3877
  assert_equal [[:iter, [:fcall, :Proc], [:block_pass, [:dasgn_curr, :b], 0]]],
3754
- RedParse.new('Proc{|&b|}','-').parse.to_parsetree(:quirks)
3878
+ RedParse.new('Proc{|&b|}','-',1,[],:cache_mode=>:none).parse.to_parsetree(:quirks)
3755
3879
  end
3756
3880
 
3757
3881
  def test_cases_misparsed_by_ruby186_slash_parsetree
@@ -3814,7 +3938,7 @@ EOS
3814
3938
 
3815
3939
 
3816
3940
  }.each_pair{|code,tree|
3817
- assert_equal tree,RedParse.new(code,'-').parse.to_parsetree(:quirks)
3941
+ assert_equal tree,RedParse.new(code,'-',1,[],:cache_mode=>:none).parse.to_parsetree(:quirks)
3818
3942
  }
3819
3943
  end
3820
3944
 
@@ -3842,8 +3966,8 @@ EOS
3842
3966
  end
3843
3967
  end
3844
3968
 
3845
- BEGIN{File.unlink "problemexprs" rescue nil}
3846
3969
  def problem_exprs
3970
+ return nil
3847
3971
  @problem_exprs||=nil
3848
3972
  return @problem_exprs if @problem_exprs
3849
3973
 
@@ -3853,9 +3977,26 @@ EOS
3853
3977
  @problem_exprs=$stdout
3854
3978
  end
3855
3979
 
3856
- def check_parsing xmpl,pt=ParseTree.new
3980
+ def ParseTree.server_running_187?
3981
+ #@server_running_187||=nil
3982
+ return @server_running_187 unless @server_running_187.nil?
3983
+ put :version
3984
+ version=get
3985
+ if Exception===version
3986
+ puts "cannot find a ruby 1.8 interpreter with parse_tree available to it. set RUBY1_8 to the path of such an interpreter"
3987
+ puts "you might want to try running #{File.dirname(__FILE__)}/generate_parse_tree_server_rc.rb from your ruby 1.8 interpreter"
3988
+ Process.waitpid @server
3989
+ @server=@in=@out=nil
3990
+ raise version
3991
+ end
3992
+ return @server_running_187= version=="1.8.7"
3993
+ end
3994
+
3995
+ def check_parsing xmpl
3996
+ ParseTree.fork_server?
3997
+ xmpl=xmpl.dup.freeze
3857
3998
  pt_opts=[:quirks]
3858
- pt_opts<<:ruby187 if ::VERSION["1.8.7"]
3999
+ pt_opts<<:ruby187 if ParseTree.server_running_187?
3859
4000
  /unparse/===xmpl and warn 'unparse in parser test data!'
3860
4001
  problem_exprs=problem_exprs()
3861
4002
  nodes=warnings=warnings2=nil
@@ -3878,31 +4019,34 @@ EOS
3878
4019
  # catch(:never_exec_parse_data_try1){
3879
4020
  # catch(:never_exec_parse_data_try2){
3880
4021
  # catch(:never_exec_parse_data_try3){
3881
- tree,warnings=pt.parse_tree_and_warnings(xmpl)
4022
+ tree,warnings=ParseTree.parse_tree_and_warnings(xmpl)
3882
4023
  # }
3883
4024
  # }
3884
4025
  # }
3885
4026
  # break if loops+=1 > 3
3886
4027
  rescue Interrupt; raise
3887
4028
  rescue Exception=>e
3888
- #pp e
3889
- #pp e.backtrace
3890
- #raise "last gasp ParseTree exec catcher failed!"
3891
4029
  tree=e
3892
4030
  tree2=nodes=h=nil
3893
4031
  assert_hopefully_raises_Exception(xmpl){
3894
- nodes=RedParse.new(xmpl,"-").parse
4032
+ nodes=RedParse.new(xmpl,"-",1,[],:cache_mode=>:write_only).parse
3895
4033
  h=nodes.hash
3896
4034
  tree2,warnings2=nodes.to_parsetree_and_warnings(*pt_opts)
3897
4035
  }
3898
4036
  assert_equal h,nodes.hash if h
3899
4037
  else
3900
4038
  begin
3901
- nodes=RedParse.new(xmpl,"-").parse
4039
+ nodes=RedParse.new(xmpl,"-",1,[],:cache_mode=>:write_only).parse
3902
4040
  h=nodes.hash
3903
4041
  tree2,warnings2=nodes.to_parsetree_and_warnings(*pt_opts)
3904
- assert_equal h,nodes.hash
3905
- assert_equal tree, tree2
4042
+ assert_equal h,nodes.hash #Node tree shouldn't be modified by to_parsetree
4043
+ if tree==tree2
4044
+ assert true
4045
+ else
4046
+ assert_equal tree, RedParse.remove_silly_begins(tree2)
4047
+ warn "parse_trees differed by a :begin in #{xmpl}"
4048
+ differed_by_begin=true
4049
+ end
3906
4050
  assert_equal warnings, warnings2 if ENV['WARN_PICKINESS']
3907
4051
  if warnings != warnings2
3908
4052
  if defined? @@mismatched_warnings
@@ -3912,6 +4056,7 @@ EOS
3912
4056
  at_exit{warn "mismatched warnings: #@@mismatched_warnings (set WARN_PICKINESS for details)"}
3913
4057
  end
3914
4058
  end
4059
+ rescue Interrupt; raise
3915
4060
  rescue Exception=>e
3916
4061
  if problem_exprs
3917
4062
  problem_exprs.write xmpl+"\n"
@@ -3927,35 +4072,49 @@ EOS
3927
4072
 
3928
4073
  end #until output.equal? tree
3929
4074
 
3930
- return unless nodes
3931
- begin
3932
- unparsed=nodes.unparse
3933
- if unparsed==xmpl
3934
- assert true
3935
- return
4075
+ if nodes
4076
+ #test reading back form the cache just created
4077
+ nodes2=RedParse.new(xmpl,"-",1,[],:cache_mode=>:read_only).parse
4078
+ assert_equal nodes,nodes2
4079
+
4080
+ begin
4081
+ unparsed=nodes.unparse
4082
+ if unparsed==xmpl
4083
+ assert true
4084
+ done_already=true
4085
+ end
4086
+ rescue Exception
4087
+ raise unless Exception===tree
3936
4088
  end
3937
- reparsed= RedParse.new(unparsed,"-").parse
3938
- if nodes.delete_extraneous_ivars! != reparsed.delete_extraneous_ivars!
3939
- assert_equal nodes.delete_linenums!, reparsed.delete_linenums!
3940
- warn "unparser doesn't preserve linenums perfectly in #{xmpl}"
3941
- if defined? @@unparse_mismatched_linenums
3942
- @@unparse_mismatched_linenums+=1
4089
+ begin
4090
+ reparsed= RedParse.new(unparsed,"-",1,[],:cache_mode=>:none).parse
4091
+ if nodes.delete_extraneous_ivars! != reparsed.delete_extraneous_ivars!
4092
+ assert_equal nodes.delete_linenums!, reparsed.delete_linenums!
4093
+ warn "unparser doesn't preserve linenums perfectly in #{xmpl}"
4094
+ if defined? @@unparse_mismatched_linenums
4095
+ @@unparse_mismatched_linenums+=1
4096
+ else
4097
+ @@unparse_mismatched_linenums=1
4098
+ at_exit{warn "unparse mismatched linenums: #@@unparse_mismatched_linenums"}
4099
+ end
3943
4100
  else
3944
- @@unparse_mismatched_linenums=1
3945
- at_exit{warn "unparse mismatched linenums: #@@unparse_mismatched_linenums"}
4101
+ assert true
3946
4102
  end
3947
- else
3948
- assert true
4103
+ rescue Exception
4104
+ raise unless Exception===tree
4105
+ end unless done_already
4106
+
4107
+ assert_equal nodes, Marshal.load(Marshal.dump(nodes))
4108
+ assert_equal nodes, Ron.load(Ron.dump(nodes)) if defined? Ron
4109
+ assert_equal nodes, nodes.deep_copy
4110
+
4111
+ unless done_already or Exception===tree or differed_by_begin
4112
+ tree3=reparsed.to_parsetree(*pt_opts)
4113
+ assert_equal tree, tree3
4114
+ else #missing a syntax errr, but that's been noted already
3949
4115
  end
3950
- rescue Exception
3951
- raise unless Exception===tree
3952
4116
  end
3953
4117
 
3954
- unless Exception===tree
3955
- tree3=reparsed.to_parsetree(*pt_opts)
3956
- assert_equal tree, tree3
3957
- else #missing a syntax errr, but that's been noted already
3958
- end
3959
4118
 
3960
4119
  # rescue Exception=>e:
3961
4120
  # raise "error: #{e}:#{e.class} while testing '#{xmpl}'"