From a0b14a17e78609929eb4e6a9888de3ef9775495d Mon Sep 17 00:00:00 2001 From: Jonathan Steel Date: Fri, 16 Jun 2017 14:34:05 -0400 Subject: [PATCH] Allow for regular expression filters Fixes #514 --- lib/simplecov/configuration.rb | 6 ++---- lib/simplecov/defaults.rb | 4 ++-- lib/simplecov/filter.rb | 20 ++++++++++++++++++++ lib/simplecov/source_file.rb | 6 ++++++ spec/filters_spec.rb | 30 ++++++++++++++++++++++++++++++ spec/source_file_spec.rb | 4 ++++ 6 files changed, 64 insertions(+), 6 deletions(-) diff --git a/lib/simplecov/configuration.rb b/lib/simplecov/configuration.rb index b4308cbf..4f709c49 100644 --- a/lib/simplecov/configuration.rb +++ b/lib/simplecov/configuration.rb @@ -293,12 +293,10 @@ def add_group(group_name, filter_argument = nil, &filter_proc) def parse_filter(filter_argument = nil, &filter_proc) if filter_argument.is_a?(SimpleCov::Filter) filter_argument - elsif filter_argument.is_a?(String) - SimpleCov::StringFilter.new(filter_argument) elsif filter_proc SimpleCov::BlockFilter.new(filter_proc) - elsif filter_argument.is_a?(Array) - SimpleCov::ArrayFilter.new(filter_argument) + elsif filter_argument + SimpleCov::Filter.class_for_argument(filter_argument).new(filter_argument) else raise ArgumentError, "Please specify either a string or a block to filter with" end diff --git a/lib/simplecov/defaults.rb b/lib/simplecov/defaults.rb index b8f1c888..ad4264e1 100644 --- a/lib/simplecov/defaults.rb +++ b/lib/simplecov/defaults.rb @@ -25,8 +25,8 @@ SimpleCov.profiles.define "rails" do load_profile "test_frameworks" - add_filter "/config/" - add_filter "/db/" + add_filter %r{^/config/} + add_filter %r{/^/db/} add_group "Controllers", "app/controllers" add_group "Channels", "app/channels" if defined?(ActionCable) diff --git a/lib/simplecov/filter.rb b/lib/simplecov/filter.rb index b6c11a29..9b2bfaac 100644 --- a/lib/simplecov/filter.rb +++ b/lib/simplecov/filter.rb @@ -24,6 +24,18 @@ def passes?(source_file) warn "#{Kernel.caller.first}: [DEPRECATION] #passes? is deprecated. Use #matches? instead." matches?(source_file) end + + def self.class_for_argument(filter_argument) + if filter_argument.is_a?(String) + SimpleCov::StringFilter + elsif filter_argument.is_a?(Regexp) + SimpleCov::RegexFilter + elsif filter_argument.is_a?(Array) + SimpleCov::ArrayFilter + else + raise ArgumentError, "You have provided an unrecognized filter type" + end + end end class StringFilter < SimpleCov::Filter @@ -34,6 +46,14 @@ def matches?(source_file) end end + class RegexFilter < SimpleCov::Filter + # Returns true when the given source file's filename matches the + # regex configured when initializing this Filter with RegexFilter.new(/someregex/) + def matches?(source_file) + (source_file.project_filename =~ filter_argument) + end + end + class BlockFilter < SimpleCov::Filter # Returns true if the block given when initializing this filter with BlockFilter.new {|src_file| ... } # returns true for the given source file. diff --git a/lib/simplecov/source_file.rb b/lib/simplecov/source_file.rb index 37b6c947..abe4875a 100644 --- a/lib/simplecov/source_file.rb +++ b/lib/simplecov/source_file.rb @@ -80,6 +80,12 @@ def initialize(filename, coverage) @coverage = coverage end + # The path to this source file relative to the projects directory + def project_filename + project_dir = File.dirname(File.expand_path(File.basename(__FILE__))) + @filename.sub(/^#{project_dir}/, "") + end + # The source code for this file. Aliased as :source def src # We intentionally read source code lazily to diff --git a/spec/filters_spec.rb b/spec/filters_spec.rb index 87bba2e0..ed81b60a 100644 --- a/spec/filters_spec.rb +++ b/spec/filters_spec.rb @@ -26,6 +26,22 @@ expect(SimpleCov::StringFilter.new("sample.rb")).to be_matches subject end + it "matches a new SimpleCov::StringFilter '/fixtures/'" do + expect(SimpleCov::StringFilter.new("sample.rb")).to be_matches subject + end + + it "matches a new SimpleCov::RegexFilter /\/fixtures\//" do + expect(SimpleCov::RegexFilter.new(/\/fixtures\//)).to be_matches subject + end + + it "doesn't match a new SimpleCov::RegexFilter /^\/fixtures\//" do + expect(SimpleCov::RegexFilter.new(/^\/fixtures\//)).not_to be_matches subject + end + + it "matches a new SimpleCov::RegexFilter /^\/spec\//" do + expect(SimpleCov::RegexFilter.new(/^\/spec\//)).to be_matches subject + end + it "doesn't match a new SimpleCov::BlockFilter that is not applicable" do expect(SimpleCov::BlockFilter.new(proc { |s| File.basename(s.filename) == "foo.rb" })).not_to be_matches subject end @@ -94,5 +110,19 @@ expect(SimpleCov.filtered(subject)).to be_a SimpleCov::FileList end end + + describe ".class_for_argument" do + it "returns SimpleCov::StringFilter for a string" do + expect(SimpleCov::Filter.class_for_argument("filestring")).to eq(SimpleCov::StringFilter) + end + + it "returns SimpleCov::RegexFilter for a string" do + expect(SimpleCov::Filter.class_for_argument(/regex/)).to eq(SimpleCov::RegexFilter) + end + + it "returns SimpleCov::RegexFilter for a string" do + expect(SimpleCov::Filter.class_for_argument(%w[file1 file2])).to eq(SimpleCov::ArrayFilter) + end + end end end diff --git a/spec/source_file_spec.rb b/spec/source_file_spec.rb index 2bebff63..c8809786 100644 --- a/spec/source_file_spec.rb +++ b/spec/source_file_spec.rb @@ -16,6 +16,10 @@ expect(subject.src).to eq(subject.source) end + it "has a project filename which removes the project directory" do + expect(subject.project_filename).to eq("/spec/fixtures/sample.rb") + end + it "has source_lines equal to lines" do expect(subject.lines).to eq(subject.source_lines) end