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.
table_(:cellpadding => 0, :cellspacing => 0, :align => "right")
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...
Oh, I see there's a fix for this in trunk already, committed 9 days ago:
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rexml/document.rb?r1=13597&r2=13686
(but I don't think it has been merged to branches/ruby_1_8_6)
I can't see a fix for Fixnum attribute values though.
Regards,
Brian.
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)
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
..prefix.../ruby/gems/1.8/gems/rspec-1.0.8/lib/spec/rake/verify_rcov.rb
..prefix.../ruby/1.8/rexml/formatters/pretty.rb
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,
--
Posted via http://www.ruby-forum.com/.
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
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
Any suggestions or help you guys can give me?
I'm having the same issues as Jeff but am running ruby 1.8.7
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 :
--- /opt/ruby-1.8.7-p72/lib/ruby/1.8/rexml/formatters/pretty.rb.OLD
2009-02-15 14:47:32.000000000 -0600
+++ /opt/ruby-1.8.7-p72/lib/ruby/1.8/rexml/formatters/pretty.rb
2009-02-15 14:48:50.000000000 -0600
@@ -126,10 +126,11 @@
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