Skip to content

Commit

Permalink
wrapping LineNumbers in the MetricFu namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
Jake Scruggs committed Nov 13, 2010
1 parent 4742cee commit d0fcfaa
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 61 deletions.
99 changes: 50 additions & 49 deletions lib/base/line_numbers.rb
@@ -1,65 +1,66 @@
require 'ruby_parser'
module MetricFu
class LineNumbers

class LineNumbers

def initialize(contents)
rp = RubyParser.new
file_sexp = rp.parse(contents)
@locations = {}
case file_sexp[0]
when :class
process_class(file_sexp)
when :module
process_module(file_sexp)
when :block
file_sexp.each_of_type(:class) { |sexp| process_class(sexp) }
else
def initialize(contents)
rp = RubyParser.new
file_sexp = rp.parse(contents)
@locations = {}
case file_sexp[0]
when :class
process_class(file_sexp)
when :module
process_module(file_sexp)
when :block
file_sexp.each_of_type(:class) { |sexp| process_class(sexp) }
else
end
end
end

def in_method? line_number
!!@locations.detect do |method_name, line_number_range|
line_number_range.include?(line_number)
def in_method? line_number
!!@locations.detect do |method_name, line_number_range|
line_number_range.include?(line_number)
end
end
end

def method_at_line line_number
found_method_and_range = @locations.detect do |method_name, line_number_range|
line_number_range.include?(line_number)
def method_at_line line_number
found_method_and_range = @locations.detect do |method_name, line_number_range|
line_number_range.include?(line_number)
end
return nil unless found_method_and_range
found_method_and_range.first
end
return nil unless found_method_and_range
found_method_and_range.first
end

private
private

def process_module(sexp)
module_name = sexp[1]
sexp.each_of_type(:class) do |sexp|
process_class(sexp, module_name)
hide_methods_from_next_round(sexp)
def process_module(sexp)
module_name = sexp[1]
sexp.each_of_type(:class) do |sexp|
process_class(sexp, module_name)
hide_methods_from_next_round(sexp)
end
process_class(sexp)
end
process_class(sexp)
end

def process_class(sexp, module_name=nil)
class_name = sexp[1]
process_class_self_blocks(sexp, class_name)
module_name_string = module_name ? "#{module_name}::" : nil
sexp.each_of_type(:defn) { |s| @locations["#{module_name_string}#{class_name}##{s[1]}"] = (s.line)..(s.last.line) }
sexp.each_of_type(:defs) { |s| @locations["#{module_name_string}#{class_name}::#{s[2]}"] = (s.line)..(s.last.line) }
end
def process_class(sexp, module_name=nil)
class_name = sexp[1]
process_class_self_blocks(sexp, class_name)
module_name_string = module_name ? "#{module_name}::" : nil
sexp.each_of_type(:defn) { |s| @locations["#{module_name_string}#{class_name}##{s[1]}"] = (s.line)..(s.last.line) }
sexp.each_of_type(:defs) { |s| @locations["#{module_name_string}#{class_name}::#{s[2]}"] = (s.line)..(s.last.line) }
end

def process_class_self_blocks(sexp, class_name)
sexp.each_of_type(:sclass) do |sexp_in_class_self_block|
sexp_in_class_self_block.each_of_type(:defn) { |s| @locations["#{class_name}::#{s[1]}"] = (s.line)..(s.last.line) }
hide_methods_from_next_round(sexp_in_class_self_block)
def process_class_self_blocks(sexp, class_name)
sexp.each_of_type(:sclass) do |sexp_in_class_self_block|
sexp_in_class_self_block.each_of_type(:defn) { |s| @locations["#{class_name}::#{s[1]}"] = (s.line)..(s.last.line) }
hide_methods_from_next_round(sexp_in_class_self_block)
end
end
end

def hide_methods_from_next_round(sexp)
sexp.find_and_replace_all(:defn, :ignore_me)
sexp.find_and_replace_all(:defs, :ignore_me)
end
def hide_methods_from_next_round(sexp)
sexp.find_and_replace_all(:defn, :ignore_me)
sexp.find_and_replace_all(:defs, :ignore_me)
end

end
end
2 changes: 1 addition & 1 deletion lib/generators/rcov.rb
Expand Up @@ -65,7 +65,7 @@ def add_method_data
end

begin
line_numbers = LineNumbers.new(file_contents)
line_numbers = MetricFu::LineNumbers.new(file_contents)
rescue StandardError => e
raise e unless e.message =~ /you shouldn't be able to get here/
puts "ruby_parser blew up while trying to parse #{file_path}. You won't have method level Rcov information for this file."
Expand Down
22 changes: 11 additions & 11 deletions spec/base/line_numbers_spec.rb
@@ -1,58 +1,58 @@
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")

describe LineNumbers do
describe MetricFu::LineNumbers do

describe "in_method?" do
it "should know if a line is NOT in a method" do
ln = LineNumbers.new(File.read(File.dirname(__FILE__) + "/../resources/line_numbers/foo.rb"))
ln = MetricFu::LineNumbers.new(File.read(File.dirname(__FILE__) + "/../resources/line_numbers/foo.rb"))
ln.in_method?(2).should == false
end

it "should know if a line is in an instance method" do
ln = LineNumbers.new(File.read(File.dirname(__FILE__) + "/../resources/line_numbers/foo.rb"))
ln = MetricFu::LineNumbers.new(File.read(File.dirname(__FILE__) + "/../resources/line_numbers/foo.rb"))
ln.in_method?(8).should == true
end

it "should know if a line is in an class method" do
ln = LineNumbers.new(File.read(File.dirname(__FILE__) + "/../resources/line_numbers/foo.rb"))
ln = MetricFu::LineNumbers.new(File.read(File.dirname(__FILE__) + "/../resources/line_numbers/foo.rb"))
ln.in_method?(3).should == true
end
end

describe "method_at_line" do
it "should know the name of an instance method at a particular line" do
ln = LineNumbers.new(File.read(File.dirname(__FILE__) + "/../resources/line_numbers/foo.rb"))
ln = MetricFu::LineNumbers.new(File.read(File.dirname(__FILE__) + "/../resources/line_numbers/foo.rb"))
ln.method_at_line(8).should == "Foo#what"
end

it "should know the name of a class method at a particular line" do
ln = LineNumbers.new(File.read(File.dirname(__FILE__) + "/../resources/line_numbers/foo.rb"))
ln = MetricFu::LineNumbers.new(File.read(File.dirname(__FILE__) + "/../resources/line_numbers/foo.rb"))
ln.method_at_line(3).should == "Foo::awesome"
end

it "should know the name of a private method at a particular line" do
ln = LineNumbers.new(File.read(File.dirname(__FILE__) + "/../resources/line_numbers/foo.rb"))
ln = MetricFu::LineNumbers.new(File.read(File.dirname(__FILE__) + "/../resources/line_numbers/foo.rb"))
ln.method_at_line(28).should == "Foo#whoop"
end

it "should know the name of a class method defined in a 'class << self block at a particular line" do
ln = LineNumbers.new(File.read(File.dirname(__FILE__) + "/../resources/line_numbers/foo.rb"))
ln = MetricFu::LineNumbers.new(File.read(File.dirname(__FILE__) + "/../resources/line_numbers/foo.rb"))
ln.method_at_line(23).should == "Foo::neat"
end

it "should know the name of an instance method at a particular line in a file with two classes" do
ln = LineNumbers.new(File.read(File.dirname(__FILE__) + "/../resources/line_numbers/two_classes.rb"))
ln = MetricFu::LineNumbers.new(File.read(File.dirname(__FILE__) + "/../resources/line_numbers/two_classes.rb"))
ln.method_at_line(3).should == "Foo#stuff"
ln.method_at_line(9).should == "Bar#stuff"
end

it "should work with modules" do
ln = LineNumbers.new(File.read(File.dirname(__FILE__) + "/../resources/line_numbers/module.rb"))
ln = MetricFu::LineNumbers.new(File.read(File.dirname(__FILE__) + "/../resources/line_numbers/module.rb"))
ln.method_at_line(4).should == 'KickAss#get_beat_up?'
end

it "should work with module surrounding class" do
ln = LineNumbers.new(File.read(File.dirname(__FILE__) + "/../resources/line_numbers/module_surrounds_class.rb"))
ln = MetricFu::LineNumbers.new(File.read(File.dirname(__FILE__) + "/../resources/line_numbers/module_surrounds_class.rb"))
ln.method_at_line(5).should == "StuffModule::ThingClass#do_it"
# ln.method_at_line(12).should == "StuffModule#blah" #why no work?
end
Expand Down

0 comments on commit d0fcfaa

Please sign in to comment.