diff --git a/spec/example_filter_spec.cr b/spec/example_filter_spec.cr new file mode 100644 index 0000000..a4a991d --- /dev/null +++ b/spec/example_filter_spec.cr @@ -0,0 +1,85 @@ +require "./spec_helper" + +def new_filter(criterion) + criteria = ["BOGUS", -1, criterion, /^$/, Spectator::Source.new(__FILE__, __LINE__)] + Spectator::ExampleFilter.new(criteria) +end + +describe Spectator::ExampleFilter do + describe "#includes?" do + context "with a matching Regex" do + it "is true" do + example = new_runnable_example + regex = Regex.new(Regex.escape(example.what)) + filter = new_filter(regex) + filter.includes?(example).should be_true + end + end + + context "with a non-matching Regex" do + it "is false" do + example = new_runnable_example + regex = /BOGUS/ + filter = new_filter(regex) + filter.includes?(example).should be_false + end + end + + context "with a String equal to the name" do + it "is true" do + example = new_runnable_example + filter = new_filter(example.to_s) + filter.includes?(example).should be_true + end + end + + context "with a String different than the name" do + it "is false" do + example = new_runnable_example + filter = new_filter("FAKE") + filter.includes?(example).should be_false + end + end + + context "with a matching source location" do + it "is true" do + example = new_runnable_example + filter = new_filter(example.source) + filter.includes?(example).should be_true + end + end + + context "with a non-matching source location" do + it "is false" do + example = new_runnable_example + source = Spectator::Source.new(__FILE__, __LINE__) + filter = new_filter(source) + filter.includes?(example).should be_false + end + end + + context "with a matching source line" do + it "is true" do + example = new_runnable_example + filter = new_filter(example.source.line) + filter.includes?(example).should be_true + end + end + + context "with a non-matching source line" do + it "is false" do + example = new_runnable_example + line = example.source.line + 5 + filter = new_filter(line) + filter.includes?(example).should be_false + end + end + + context "with an empty criteria" do + it "is true" do + filter = Spectator::ExampleFilter.new + filter.includes?(new_runnable_example).should be_true + end + end + end +end diff --git a/src/spectator/example_filter.cr b/src/spectator/example_filter.cr new file mode 100644 index 0000000..f4de2b9 --- /dev/null +++ b/src/spectator/example_filter.cr @@ -0,0 +1,24 @@ +module Spectator + # Checks examples to determine which should be run. + class ExampleFilter + # The criteria for filtering examples can be multiple types. + # A `String` will exact-match an example's name. + # A `Regex` will perform a regular expression match on the example's name. + # A `Source` will check if the example is in the specified file on a given line. + # An `Int32` will check if an example is on a given line. + alias Type = String | Regex | Source | Int32 + + # Creates the example filter. + # The *criteria* should be a list of what to filter on. + def initialize(@criteria = [] of Type) + end + + # Checks if an example is in the filter, and should be run. + def includes?(example) + return true if @criteria.empty? + @criteria.any? do |criterion| + example === criterion + end + end + end +end diff --git a/src/spectator/includes.cr b/src/spectator/includes.cr index ae58bfd..1e6be59 100644 --- a/src/spectator/includes.cr +++ b/src/spectator/includes.cr @@ -28,6 +28,7 @@ require "./config" require "./config_builder" require "./config_source" require "./command_line_arguments_config_source" +require "./example_filter" require "./example_failed" require "./expectation_failed"