From 59f4b554094e0922baf231e0a11da92695312d32 Mon Sep 17 00:00:00 2001 From: Eric Kessler Date: Sat, 6 Apr 2019 22:25:33 -0400 Subject: [PATCH] Adding configuration to a linter Made configurable the step threshold for the TestWithTooManyStepsLinter. --- environments/rspec_env.rb | 1 + .../test_with_too_many_steps_linter.rb | 11 ++- .../linters/test_with_too_many_steps.feature | 22 +++++- .../cucumber/step_definitions/action_steps.rb | 2 +- .../cucumber/step_definitions/setup_steps.rb | 4 + .../linters/configurable_linter_unit_specs.rb | 11 +++ ...st_with_too_many_steps_linter_unit_spec.rb | 73 +++++++++++++++++++ 7 files changed, 119 insertions(+), 5 deletions(-) create mode 100644 testing/rspec/spec/unit/linters/configurable_linter_unit_specs.rb diff --git a/environments/rspec_env.rb b/environments/rspec_env.rb index 2ed7f0b..719c7ed 100644 --- a/environments/rspec_env.rb +++ b/environments/rspec_env.rb @@ -7,6 +7,7 @@ require 'yaml' require_relative '../testing/rspec/spec/unit/formatters/formatter_unit_specs' +require_relative '../testing/rspec/spec/unit/linters/configurable_linter_unit_specs' require_relative '../testing/rspec/spec/unit/linters/linter_unit_specs' require_relative '../testing/rspec/spec/integration/formatters/formatter_integration_specs' require_relative '../testing/rspec/spec/integration/linters/linter_integration_specs' diff --git a/lib/cuke_linter/linters/test_with_too_many_steps_linter.rb b/lib/cuke_linter/linters/test_with_too_many_steps_linter.rb index d191df3..a35a158 100644 --- a/lib/cuke_linter/linters/test_with_too_many_steps_linter.rb +++ b/lib/cuke_linter/linters/test_with_too_many_steps_linter.rb @@ -9,14 +9,19 @@ def name 'TestWithTooManyStepsLinter' end + def configure(options) + @step_threshold = options['StepThreshold'] if options['StepThreshold'] + end + # Lints the given model and returns linting data about said model def lint(model) return [] unless model.is_a?(CukeModeler::Scenario) || model.is_a?(CukeModeler::Outline) - step_count = model.steps.nil? ? 0 : model.steps.count + step_count = model.steps.nil? ? 0 : model.steps.count + step_threshold = @step_threshold || 10 - if step_count > 10 - [{ problem: "Test has too many steps. #{step_count} steps found (max 10)", location: "#{model.get_ancestor(:feature_file).path}:#{model.source_line}" }] + if step_count > step_threshold + [{ problem: "Test has too many steps. #{step_count} steps found (max #{step_threshold})", location: "#{model.get_ancestor(:feature_file).path}:#{model.source_line}" }] else [] end diff --git a/testing/cucumber/features/linters/test_with_too_many_steps.feature b/testing/cucumber/features/linters/test_with_too_many_steps.feature index 0cea357..491e332 100644 --- a/testing/cucumber/features/linters/test_with_too_many_steps.feature +++ b/testing/cucumber/features/linters/test_with_too_many_steps.feature @@ -32,5 +32,25 @@ Feature: Test with too many steps linter | linter | problem | location | | TestWithTooManyStepsLinter | Test has too many steps. 11 steps found (max 10) | :3 | - @wip Scenario: Configuration of step count threshold + Given a linter for tests with too many steps has been registered + And the following configuration file: + """ + TestWithTooManyStepsLinter: + StepThreshold: 3 + """ + And the following feature: + """ + Feature: + + Scenario: + * step 1 + * step 2 + * step 3 + * step one too many... + """ + When the configuration file is loaded + And the feature is linted + Then an error is reported + | linter | problem | location | + | TestWithTooManyStepsLinter | Test has too many steps. 4 steps found (max 3) | :3 | diff --git a/testing/cucumber/step_definitions/action_steps.rb b/testing/cucumber/step_definitions/action_steps.rb index 72ea5d2..a55b2f5 100644 --- a/testing/cucumber/step_definitions/action_steps.rb +++ b/testing/cucumber/step_definitions/action_steps.rb @@ -16,7 +16,7 @@ @results = CukeLinter.lint(options) end -When(/^the configuration file is used$/) do +When(/^the configuration file is (?:used|loaded)$/) do CukeLinter.load_configuration(config_file_path: @configuration_file_path) end diff --git a/testing/cucumber/step_definitions/setup_steps.rb b/testing/cucumber/step_definitions/setup_steps.rb index 29acb93..b26113e 100644 --- a/testing/cucumber/step_definitions/setup_steps.rb +++ b/testing/cucumber/step_definitions/setup_steps.rb @@ -41,6 +41,10 @@ @linter = CukeLinter::TestWithTooManyStepsLinter.new end +Given(/^a linter for tests with too many steps has been registered$/) do + CukeLinter.register_linter(linter: CukeLinter::TestWithTooManyStepsLinter.new, name: 'TestWithTooManyStepsLinter') +end + Given(/^the following configuration file(?: "([^"]*)")?:$/) do |file_name, text| file_name ||= '.cuke_linter' diff --git a/testing/rspec/spec/unit/linters/configurable_linter_unit_specs.rb b/testing/rspec/spec/unit/linters/configurable_linter_unit_specs.rb new file mode 100644 index 0000000..ab3dd1d --- /dev/null +++ b/testing/rspec/spec/unit/linters/configurable_linter_unit_specs.rb @@ -0,0 +1,11 @@ +shared_examples_for 'a configurable linter at the unit level' do + + it 'is configurable' do + expect(subject).to respond_to(:configure) + end + + it 'is configured via a set of options' do + expect(subject.method(:configure).arity).to eq(1) + end + +end diff --git a/testing/rspec/spec/unit/linters/test_with_too_many_steps_linter_unit_spec.rb b/testing/rspec/spec/unit/linters/test_with_too_many_steps_linter_unit_spec.rb index b05171c..f431642 100644 --- a/testing/rspec/spec/unit/linters/test_with_too_many_steps_linter_unit_spec.rb +++ b/testing/rspec/spec/unit/linters/test_with_too_many_steps_linter_unit_spec.rb @@ -29,6 +29,7 @@ it_should_behave_like 'a linter at the unit level' + it_should_behave_like 'a configurable linter at the unit level' it 'has a name' do @@ -139,6 +140,78 @@ end + + describe 'configuration' do + + context 'with no configuration' do + + let(:default_step_threshhold) { 10 } + + context 'because configuration never happened' do + + let(:unconfigured_test_model) do + model = CukeLinter::ModelFactory.send("generate_#{model_type}_model") + model.steps = [] + (default_step_threshhold + 1).times { model.steps << :a_step } + + model + end + + it 'defaults to a step threshold of 10 steps' do + results = subject.lint(unconfigured_test_model) + + expect(results.first[:problem]).to match(/^Test has too many steps. #{unconfigured_test_model.steps.count} steps found \(max 10\)/) + end + + end + + context 'because configuration did not set a step threshold' do + let(:configuration) { {} } + let(:configured_test_model) do + model = CukeLinter::ModelFactory.send("generate_#{model_type}_model") + model.steps = [] + (default_step_threshhold + 1).times { model.steps << :a_step } + + subject.configure(configuration) + + model + end + + it 'defaults to a step threshold of 10 steps' do + results = subject.lint(configured_test_model) + + expect(results.first[:problem]).to match(/^Test has too many steps. #{configured_test_model.steps.count} steps found \(max 10\)/) + end + + end + + end + + + context 'with configuration' do + + let(:step_threshhold) { 3 } + let(:configuration) { { 'StepThreshold' => step_threshhold } } + let(:configured_test_model) do + model = CukeLinter::ModelFactory.send("generate_#{model_type}_model") + model.steps = [] + (step_threshhold + 1).times { model.steps << :a_step } + + subject.configure(configuration) + + model + end + + it 'the step threshold used is the configured value' do + results = subject.lint(configured_test_model) + + expect(results.first[:problem]).to match(/^Test has too many steps. #{configured_test_model.steps.count} steps found \(max #{step_threshhold}\)/) + end + + end + + end + end context 'a non-test model' do