Bugs: Browse | Submit New | Admin
It was really tough to get my hands on the verbose output; involved some hacking on RSpec, but: ........................................................................................................................ ........................................................................................................................ ........................................................................................................................ .......................................... Finished in 4.127994 seconds 402 examples, 0 failures ********************************************************************** *** Addressable::URI#extract_mapping loaded with 59 possible mutations ********************************************************************** 59 mutations remaining... Replacing Addressable::URI#extract_mapping with: --- original +++ mutation -def extract_mapping(pattern, processor = nil) +def extract_mapping(pattern, processor = 42) mapping = { } variable_regexp = /\\{([#{Addressable::URI::CharacterClasses::UNRESERVED}]+)\}/ variables = pattern.scan(variable_regexp).flatten variables.each { |v| mapping[v] = "" } escaped_pattern = Regexp.escape(pattern).gsub(/\\\{/, "{").gsub(/\\\}/, "}") regexp = Regexp.new(escaped_pattern.gsub(variable_regexp) do |v| capture_group = "(.*)" unless (processor == nil) then if processor.respond_to?(:match) then name = v.scan(variable_regexp).flatten[0] capture_group = "(#{processor.match(name)})" end end capture_group end) values = self.to_s.scan(regexp).flatten if (variables.size == values.size) then for i in (0...variables.size) (name = variables[i] value = values[i] unless (processor == nil) then value = processor.restore(name, value) if processor.respond_to?(:restore) end mapping[name] = value) end return mapping else return nil end end *** SNIP *** 4 mutations remaining... Replacing Addressable::URI#extract_mapping with: --- original +++ mutation def extract_mapping(pattern, processor = nil) mapping = { } variable_regexp = /\\{([#{Addressable::URI::CharacterClasses::UNRESERVED}]+)\}/ variables = pattern.scan(variable_regexp).flatten variables.each { |v| mapping[v] = "" } escaped_pattern = Regexp.escape(pattern).gsub(/\\\{/, "{").gsub(/\\\}/, "}") regexp = Regexp.new(escaped_pattern.gsub(variable_regexp) do |v| capture_group = "(.*)" unless (processor == nil) then if processor.respond_to?(:match) then name = v.scan(variable_regexp).flatten[0] capture_group = "(#{processor.match(name)})" end end capture_group end) values = self.to_s.scan(regexp).flatten if (variables.size == values.size) then for i in (0...variables.size) (name = variables[i] value = values[i] - unless (processor == nil) then + if (processor == nil) then value = processor.restore(name, value) if processor.respond_to?(:restore) end mapping[name] = value) end return mapping else return nil end end 3 mutations remaining... Replacing Addressable::URI#extract_mapping with: --- original +++ mutation def extract_mapping(pattern, processor = nil) mapping = { } variable_regexp = /\\{([#{Addressable::URI::CharacterClasses::UNRESERVED}]+)\}/ variables = pattern.scan(variable_regexp).flatten variables.each { |v| mapping[v] = "" } escaped_pattern = Regexp.escape(pattern).gsub(/\\\{/, "{").gsub(/\\\}/, "}") regexp = Regexp.new(escaped_pattern.gsub(variable_regexp) do |v| capture_group = "(.*)" unless (processor == nil) then if processor.respond_to?(:match) then name = v.scan(variable_regexp).flatten[0] capture_group = "(#{processor.match(name)})" end end capture_group end) values = self.to_s.scan(regexp).flatten if (variables.size == values.size) then + return nil + else for i in (0...variables.size) (name = variables[i] value = values[i] unless (processor == nil) then value = processor.restore(name, value) if processor.respond_to?(:restore) end mapping[name] = value) end return mapping - else - return nil end end 2 mutations remaining... Replacing Addressable::URI#extract_mapping with: 2 mutations remaining... Replacing Addressable::URI#extract_mapping with: 2 mutations remaining... Replacing Addressable::URI#extract_mapping with: 2 mutations remaining... Replacing Addressable::URI#extract_mapping with: 2 mutations remaining... Replacing Addressable::URI#extract_mapping with: 2 mutations remaining... Replacing Addressable::URI#extract_mapping with: 2 mutations remaining... Replacing Addressable::URI#extract_mapping with: 2 mutations remaining... Replacing Addressable::URI#extract_mapping with: 2 mutations remaining... Replacing Addressable::URI#extract_mapping with: 2 mutations remaining... Replacing Addressable::URI#extract_mapping with: 2 mutations remaining... Replacing Addressable::URI#extract_mapping with:
Add A Comment:
Date: 2012-06-04 21:03 Sender: Ryan Davis Believe it or not, we've moved to github! If you think this issue is still relevant, please re-file it under our project on github ( https://github.com/seattlerb/$projectname ) and provide a link back to this ticket (if there is any comment stream). If not, please close this ticket.
Date: 2009-07-28 22:44 Sender: Bob Aman I haven't the foggiest idea. The code that originally triggered this problem doesn't really exist anymore.
Date: 2009-07-28 21:52 Sender: Ryan Davis I know it has been a long time... but we've addressed a number of these. Does it still happen for you? If not, please close.
Date: 2007-11-03 17:18 Sender: Bob Aman This prevents the infinite loop. I'm not sure it's the right thing to do, but it works. def heckle(exp) exp_copy = exp.deep_clone src = begin RubyToRuby.new.process(exp_copy) rescue => e puts "Error: #{e.message} with: #{klass_name}##{method_name}: #{exp_copy.inspect}" raise e end original = RubyToRuby.new.process(@original_tree.deep_clone) @reporter.replacing(klass_name, method_name, original, src) if @@debug if original == src puts "Mutation was identical to the original." mutatees.each do |mut| if mut.last.size > 0 node = mut.last.delete(mut.last.first) mutation_count[node] += 1 @mutated = true break end end end clean_name = method_name.to_s.gsub(/self\./, '') self.count += 1 new_name = "h#{count}_#{clean_name}" klass = aliasing_class method_name klass.send :remove_method, new_name rescue nil klass.send :alias_method, new_name, clean_name klass.send :remove_method, clean_name rescue nil @klass.class_eval src, "(#{new_name})" end
Date: 2007-11-03 15:44 Sender: Bob Aman The content of mutatees at the point the infinite loop shows up is: {:if=>[], :false=>[], :dasgn=>[], :call=>[[:call, [:lvar, :variables], :each], [:call, [:lvar, :escaped_pattern], :gsub, [:array, [:lvar, :variable_regexp]]]], :until=>[], :lit=>[], :iasgn=>[], :while=>[], :cvasgn=>[], :dasgn_curr=>[], :gasgn=>[], :lasgn=>[], :true=>[], :str=>[]}
Date: 2007-11-03 15:22 Sender: Bob Aman Nevermind, I was wrong. Commenting out that line does not prevent the infinite loop.
Date: 2007-11-03 14:15 Sender: Bob Aman I could be wrong, but I think the first line of this method is what's causing the infinite loop. It looks like maybe the tree never gets reset because the mutation is identical to the original? def reset_tree return unless original_tree != current_tree @mutated = false self.count += 1 clean_name = method_name.to_s.gsub(/self\./, '') new_name = "h#{count}_#{clean_name}" klass = aliasing_class method_name klass.send :undef_method, new_name rescue nil klass.send :alias_method, new_name, clean_name klass.send :alias_method, clean_name, "h1_#{clean_name}" end
Date: 2007-11-02 23:54 Sender: Bob Aman After adding some debug code to heckle, it appears that perhaps the problem is caused by generating a mutation that is exactly identical to the original source.