When I upgraded my Ubuntu 6.06.1 system from its stock ruby-1.8.4 to ruby-1.8.6-p110, I found that the previously working rcov-0.8.0.2 was raising REXML exceptions when it tried to generate its output (*)
I needed to make a couple of patches to REXML to fix this. The first patch is because rcov passes Fixnums as attribute values, e.g.
This could have been fixed at the rcov side, but since it *did* used to work with rexml, I consider this a backwards-compatibility failure. The fix is trivial:
--- rexml/text.rb.orig 2007-10-22 08:00:04.000000000 +0100 +++ rexml/text.rb 2007-10-22 08:00:33.000000000 +0100 @@ -286,7 +286,7 @@ EREFERENCE = /&(?!#{Entity::NAME};)/ # Escapes all possible entities def Text::normalize( input, doctype=nil, entity_filter=nil ) - copy = input + copy = input.to_s # Doing it like this rather than in a loop improves the speed #copy = copy.gsub( EREFERENCE, '&' ) copy = copy.gsub( "&", "&" )
(Note that there are other places in this file which might benefit from a to_s as well)
The second is almost certainly a bug in REXML: it's a misnamed local variable.
--- rexml/document.rb.orig 2007-10-22 08:02:36.000000000 +0100 +++ rexml/document.rb 2007-10-22 08:03:01.000000000 +0100 @@ -183,7 +183,7 @@ output = Output.new( output, xml_decl.encoding ) end formatter = if indent > -1 - if transitive + if trans REXML::Formatters::Transitive.new( indent, ie_hack ) else REXML::Formatters::Pretty.new( indent, ie_hack )
After these changes, rcov seems to run happily.
I wasn't sure where best to post this problem and its solution: ruby-core (since REXML is in the ruby standard library), the REXML home site, or the rcov home site. So I'm posting it here instead :-)
Regards,
Brian.
(*) The exception I saw initially was:
/usr/local/lib/ruby/1.8/rexml/text.rb:292:in `normalize': private method `gsub' called for 0:Fixnum (NoMethodError) from /usr/local/lib/ruby/1.8/rexml/element.rb:1084:in `[]=' from /usr/local/lib/ruby/1.8/rexml/element.rb:586:in `add_attribute' from (eval):490:in `table_' from (eval):490:in `each' from (eval):490:in `table_' from (eval):490:in `each' from (eval):490:in `table_' from /usr/local/lib/ruby/gems/1.8/gems/rcov-0.8.0.2/lib/rcov/report.rb:702:in `format_overview' ... 61 levels...
After I fixed this by adding to_s in Text::normalize, I got
/usr/local/lib/ruby/1.8/rexml/document.rb:186:in `write': undefined local variable or method `transitive' for <UNDEFINED> ... </>:REXML::Document (NameError) from (eval):93:in `pretty' from /usr/local/lib/ruby/gems/1.8/gems/rcov-0.8.0.2/lib/rcov/report.rb:727:in `format_overview' from /usr/local/lib/ruby/gems/1.8/gems/rcov-0.8.0.2/lib/rcov/report.rb:758:in `create_index' from (eval):104:in `create' from (eval):80:in `tracking_additions' from (eval):103:in `create' from (eval):372:in `x_' from /usr/local/lib/ruby/gems/1.8/gems/rcov-0.8.0.2/lib/rcov/report.rb:758:in `create_index' ... 21 levels...
/usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:131:in `[]': no implicit conversion from nil to integer (TypeError) from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:131:in `wrap' from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:131:in `wrap' from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:90:in `write_text' from /usr/local/lib/ruby/1.8/rexml/formatters/default.rb:50:in `write' from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:75:in `write_element' from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:73:in `each' from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:73:in `write_element' from /usr/local/lib/ruby/1.8/rexml/formatters/default.rb:31:in `write' ... 16 levels...
rcov outputs the index.html file and the first few controller files, so I can trace it to which file it's getting choked on, but were there any other fixes you had to put in?
Thanks,
Sean
On 10/22/07, Brian Candler <B.Cand...@pobox.com> wrote:
> On Mon, Oct 22, 2007 at 08:50:24AM +0100, Brian Candler wrote: > > The second is almost certainly a bug in REXML: it's a misnamed local > > variable.
Ive also applied both fixes and Im seeing exactly the same problem. Any updates on this?
/usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:131:in `[]': no
> implicit conversion from nil to integer (TypeError) > from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:131:in `wrap' > from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:131:in `wrap' > from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:90:in > `write_text' > from /usr/local/lib/ruby/1.8/rexml/formatters/default.rb:50:in `write' > from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:75:in > `write_element' > from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:73:in `each' > from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:73:in > `write_element' > from /usr/local/lib/ruby/1.8/rexml/formatters/default.rb:31:in `write' > ... 16 levels...
Thanks,
On Oct 30, 6:09 pm, "Sean Hussey" <seanhus...@gmail.com> wrote:
> /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:131:in `[]': no > implicit conversion from nil to integer (TypeError) > from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:131:in `wrap' > from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:131:in `wrap' > from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:90:in > `write_text' > from /usr/local/lib/ruby/1.8/rexml/formatters/default.rb:50:in `write' > from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:75:in > `write_element' > from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:73:in `each' > from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:73:in > `write_element' > from /usr/local/lib/ruby/1.8/rexml/formatters/default.rb:31:in `write' > ... 16 levels...
> rcov outputs the index.html file and the first few controller files, > so I can trace it to which file it's getting choked on, but were there > any other fixes you had to put in?
> Thanks,
> Sean
> On 10/22/07, Brian Candler <B.Cand...@pobox.com> wrote:
> > On Mon, Oct 22, 2007 at 08:50:24AM +0100, Brian Candler wrote: > > > The second is almost certainly a bug in REXML: it's a misnamed local > > > variable.
Plus the files already patched by this point. It seems like if your stack trace says formatters/default.rb instead of formatters/pretty.rb then that is the file you need to patch.
My formatters/pretty.rb patch looks like the following:
> place = string.rindex(' ', width) || width # Position in string with last ' ' before cutoff
< place = string.rindex(' ', width) # Position in string with last ' ' before cutoff
My rake/verify_rcov.rb patch looks like:
> if line =~ /<tt class='coverage_total'> (\d+\.\d+)% <\/tt> <\/td>/
< if line =~ /<tt.*?>(\d+\.\d+)%<\/tt> <\/td>/
Hope that helps someone, Susan
unknown wrote: > Ive also applied both fixes and Im seeing exactly the same problem. > Any updates on this?
> /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:131:in `[]': no >> `write_element' >> from /usr/local/lib/ruby/1.8/rexml/formatters/default.rb:31:in `write' >> ... 16 levels...
For the record, I'm running "rake test:functionals" on a Rails 2.1 project using:
ruby 1.8.7-p22 from Macports 1.600 on OS X (Tiger) rcov 0.8.1.2.0
and getting the error: /opt/local/lib/ruby/1.8/rexml/formatters/pretty.rb:131:in `[]': no implicit conversion from nil to integer (TypeError)
until I applied the patch below to pretty.rb
S. Potter wrote: > My formatters/pretty.rb patch looks like the following: >> place = string.rindex(' ', width) || width # Position in string with last ' ' before cutoff
> Plus the files already patched by this point. It seems like if your > stack trace says formatters/default.rb instead of formatters/pretty.rb > then that is the file you need to patch.
> My formatters/pretty.rb patch looks like the following: >> place = string.rindex(' ', width) || width # Position in string with last ' ' before cutoff > < place = string.rindex(' ', width) # Position in string with last ' ' > before cutoff
> My rake/verify_rcov.rb patch looks like: >> if line =~ /<tt class='coverage_total'> (\d+\.\d+)% <\/tt> <\/td>/ > < if line =~ /<tt.*?>(\d+\.\d+)%<\/tt> <\/td>/
> Hope that helps someone, > Susan
> unknown wrote: >> Ive also applied both fixes and Im seeing exactly the same problem. >> Any updates on this?
>> /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:131:in `[]': no >>> `write_element' >>> from /usr/local/lib/ruby/1.8/rexml/formatters/default.rb:31:in `write' >>> ... 16 levels...
>> Thanks,
I have done all the fixes except for the fix to: ...prefix.../ruby/gems/1.8/gems/rspec-1.0.8/lib/spec/rake/verify_rcov.rb
Cant find the right file to modify to try that fix...
After doing the fix to: ...prefix.../ruby/1.8/rexml/formatters/pretty.rb I am now getting this for an error: 572 tests, 115117 assertions, 0 failures, 0 errors /usr/lib/ruby/1.8/rexml/formatters/pretty.rb:131:in `wrap': stack level too deep (SystemStackError) from /usr/lib/ruby/1.8/rexml/formatters/pretty.rb:131:in `wrap' from /usr/lib/ruby/1.8/rexml/formatters/pretty.rb:90:in `write_text' from /usr/lib/ruby/1.8/rexml/formatters/default.rb:50:in `write' from /usr/lib/ruby/1.8/rexml/formatters/pretty.rb:75:in `write_element' from /usr/lib/ruby/1.8/rexml/formatters/pretty.rb:73:in `each' from /usr/lib/ruby/1.8/rexml/formatters/pretty.rb:73:in `write_element' from /usr/lib/ruby/1.8/rexml/formatters/default.rb:31:in `write' from /usr/lib/ruby/1.8/rexml/formatters/pretty.rb:75:in `write_element' ... 12 levels... from /usr/lib/ruby/1.8/rcov.rb:628:in `each' from /usr/lib/ruby/1.8/rcov.rb:628:in `dump_coverage_info' from /usr/bin/rcov:405 from /usr/lib/ruby/1.8/test/unit.rb:278
> /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:131:in `[]': no > implicit conversion from nil to integer (TypeError)
Hey Sean, it looks like the rexml code is assuming that there'll be a ' ' somewhere in the code to wrap on. I was able to fix this with the following patch to the pretty.rb file :
def wrap(string, width) # Recursively wrap string at width. return string if string.length <= width place = string.rindex(' ', width) # Position in string with last ' ' before cutoff + return string if place.nil? # there aren't any ' 's before cutoff, nothing to split on. return string[0,place] + "\n" + wrap(string[place+1..-1], width) end
Roy Truelove wrote: > Sean Hussey wrote: >> Nice catch!
>> After applying both fixes, I now get this:
>> /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:131:in `[]': no >> implicit conversion from nil to integer (TypeError)
> Hey Sean, it looks like the rexml code is assuming that there'll be a ' > ' somewhere in the code to wrap on. I was able to fix this with the > following patch to the pretty.rb file :
> def wrap(string, width) > # Recursively wrap string at width. > return string if string.length <= width > place = string.rindex(' ', width) # Position in string with > last ' ' before cutoff > + return string if place.nil? # there aren't any ' 's before > cutoff, nothing to split on. > return string[0,place] + "\n" + wrap(string[place+1..-1], > width) > end
> end > end
There might still be spaces in the string, how about,
--- pretty.rb.old 2009-05-06 10:50:37.000000000 +1000 +++ pretty.rb 2009-05-06 10:55:37.000000000 +1000 @@ -128,6 +128,8 @@ # Recursively wrap string at width. return string if string.length <= width place = string.rindex(' ', width) # Position in string with last ' ' before cutoff + place = string.index(' ') if place.nil? + return string if place.nil? # there aren't any ' 's before cutoff, nothing to split on. return string[0,place] + "\n" + wrap(string[place+1..-1], width) end