Skip to content

Commit

Permalink
Add dead_methods rake task
Browse files Browse the repository at this point in the history
  • Loading branch information
kbaum committed Dec 20, 2020
1 parent 17e56d4 commit bfabb9a
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 22 deletions.
11 changes: 7 additions & 4 deletions coverband.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,18 @@ Gem::Specification.new do |spec|
spec.name = "coverband"
spec.version = Coverband::VERSION
spec.authors = ["Dan Mayer", "Karl Baum"]
spec.email = ["dan@mayerdan.com"]
spec.description = "Rack middleware to measure production code usage (LOC runtime usage)"
spec.summary = "Rack middleware to measure production code usage (LOC runtime usage)"
spec.email = %w[dan@mayerdan.com]
spec.description =
"Rack middleware to measure production code usage (LOC runtime usage)"
spec.summary =
"Rack middleware to measure production code usage (LOC runtime usage)"
spec.homepage = "https://github.com/danmayer/coverband"
spec.license = "MIT"

spec.files = `git ls-files`.split("\n").reject { |f| f.start_with?("docs") }
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ["lib"]
spec.require_paths = %w[lib]

spec.add_development_dependency "benchmark-ips"
spec.add_development_dependency "capybara"
Expand All @@ -44,4 +46,5 @@ Gem::Specification.new do |spec|
# quality adapter, I think this is more honest about requirements and reduces confusion
# without this there was a race condition on calling coverband configure before redis was loaded
spec.add_runtime_dependency "redis"
spec.add_dependency "terminal-table"
end
18 changes: 18 additions & 0 deletions lib/coverband/utils/dead_methods.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# frozen_string_literal: ntrue

require "terminal-table"

module Coverband
module Utils
class DeadMethods
Expand All @@ -15,6 +17,22 @@ def self.scan_all
scan(file_path: file_path, coverage: coverage["data"])
end
end

def self.output_all
rows =
scan_all.each_with_object(
[%w[file class method line_number]]
) { |dead_method, rows|
rows <<
[
dead_method.file_path,
dead_method.class_name,
dead_method.name,
dead_method.first_line_number
]
}
puts Terminal::Table.new rows: rows
end
end
end
end
38 changes: 26 additions & 12 deletions lib/coverband/utils/method_definition_scanner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ def initialize(method_definition)
end

def coverage?(file_coverage)
body_coverage = file_coverage[(first_line_number - 1)..(last_line_number - 1)]
body_coverage =
file_coverage[(first_line_number - 1)..(last_line_number - 1)]
body_coverage.map(&:to_i).any?(&:positive?)
end

Expand All @@ -40,13 +41,24 @@ def last_line_number
end

class MethodDefinition
attr_reader :last_line_number, :first_line_number, :name, :class_name
attr_reader :last_line_number,
:first_line_number,
:name,
:class_name,
:file_path

def initialize(first_line_number:, last_line_number:, name:, class_name:)
def initialize(
first_line_number:,
last_line_number:,
name:,
class_name:,
file_path:
)
@first_line_number = first_line_number
@last_line_number = last_line_number
@name = name
@class_name = class_name
@file_path = file_path
end

def body
Expand All @@ -57,24 +69,26 @@ def body
private

def scan_node(node, class_name)
return [] unless node.is_a?(RubyVM::AbstractSyntaxTree::Node)
definitions = []
current_class = class_name
return definitions unless node.is_a?(RubyVM::AbstractSyntaxTree::Node)
current_class = node.type == :CLASS ? node.children.first.children.last : class_name
if node.type == :DEFN
definitions <<
MethodDefinition.new(
first_line_number: node.first_lineno,
last_line_number: node.last_lineno,
name: node.children.first,
class_name: current_class
class_name: current_class,
file_path: path
)
elsif node.type == :CLASS
current_class = node.children.first.children.last
end
definitions +
node.children.flatten.compact.map { |child|
scan_node(child, current_class)
}.flatten
definitions + scan_children(node, current_class)
end

def scan_children(node, current_class)
node.children.flatten.compact.map { |child|
scan_node(child, current_class)
}.flatten
end
end
end
Expand Down
18 changes: 15 additions & 3 deletions lib/coverband/utils/tasks.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,23 @@
Coverband::Reporters::ConsoleReport.report(Coverband.configuration.store)
end

if defined?(RubyVM::AbstractSyntaxTree)
desc "Output all dead methods"
task :dead_methods do
Coverband::Utils::DeadMethods.output_all
end
end

desc "report runtime Coverband code coverage"
task :coverage_server do
Rake.application["environment"].invoke if Rake::Task.task_defined?("environment")
Coverband.configuration.store.merge_mode = true if Coverband.configuration.store.is_a?(Coverband::Adapters::FileStore)
Rack::Server.start app: Coverband::Reporters::Web.new, Port: ENV.fetch("COVERBAND_COVERAGE_PORT", 9022).to_i
if Rake::Task.task_defined?("environment")
Rake.application["environment"].invoke
end
if Coverband.configuration.store.is_a?(Coverband::Adapters::FileStore)
Coverband.configuration.store.merge_mode = true
end
Rack::Server.start app: Coverband::Reporters::Web.new,
Port: ENV.fetch("COVERBAND_COVERAGE_PORT", 9022).to_i
end

###
Expand Down
9 changes: 8 additions & 1 deletion test/coverband/utils/dead_methods_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@ def test_dog_dead_methods
dead_method = dead_methods.first
assert_equal(4, dead_method.first_line_number)
assert_equal(6, dead_method.last_line_number)
assert_equal(file_path, dead_method.file_path)
end

def test_all_dead_methods
file_path = require_unique_file
require_unique_file
@coverband.report_coverage
dead_methods = DeadMethods.scan_all
dead_method = dead_methods.find { |method| method.class_name == :Dog }
Expand All @@ -34,6 +35,12 @@ def test_all_dead_methods
assert_equal(6, dead_method.last_line_number)
end

def test_output_all
require_unique_file
@coverband.report_coverage
DeadMethods.output_all
end

def test_dog_methods_not_dead
file = require_unique_file
coverage = [nil, nil, 1, 1, 1, nil, nil]
Expand Down
6 changes: 4 additions & 2 deletions test/coverband/utils/method_definition_scanner_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ def test_no_method_body_coverage
first_line_number: 4,
last_line_number: 6,
name: :bark,
class_name: :Dog
class_name: :Dog,
file_path: "./test/dog.rb"
)
)
refute(method_body.coverage?([nil, nil, 1, 1, 0, nil, 1]))
Expand All @@ -26,7 +27,8 @@ def test_method_body_coverage
first_line_number: 4,
last_line_number: 6,
name: :bark,
class_name: :Dog
class_name: :Dog,
file_path: "./test/dog.rb"
)
)
assert(method_body.coverage?([nil, nil, 1, 1, 1, nil, 1]))
Expand Down

0 comments on commit bfabb9a

Please sign in to comment.