redparse 0.8.3 → 0.8.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.
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}'"