diff --git a/app/components/check_answers_summary_list_card_component.html.erb b/app/components/check_answers_summary_list_card_component.html.erb index f299674b2..7890d0571 100644 --- a/app/components/check_answers_summary_list_card_component.html.erb +++ b/app/components/check_answers_summary_list_card_component.html.erb @@ -21,7 +21,8 @@ <%= extra_value %> <% end %>
- <% question.get_inferred_answers(log).each do |inferred_answer| %> + <% answer = Answer.new(question:, log:) %> + <% answer.get_inferred_answers.each do |inferred_answer| %> <%= inferred_answer %> <% end %> <% end %> diff --git a/app/components/check_answers_summary_list_card_component.rb b/app/components/check_answers_summary_list_card_component.rb index de7fe9685..9817eaabd 100644 --- a/app/components/check_answers_summary_list_card_component.rb +++ b/app/components/check_answers_summary_list_card_component.rb @@ -13,6 +13,7 @@ class CheckAnswersSummaryListCardComponent < ViewComponent::Base end def get_answer_label(question) - question.answer_label(log).presence || "You didn’t answer this question".html_safe + answer = Answer.new(question:, log:) + answer.answer_label.presence || "You didn’t answer this question".html_safe end end diff --git a/app/helpers/check_answers_helper.rb b/app/helpers/check_answers_helper.rb index 1d4a1a9aa..19f031865 100644 --- a/app/helpers/check_answers_helper.rb +++ b/app/helpers/check_answers_helper.rb @@ -43,7 +43,10 @@ private end def answered_questions(subsection, lettings_log, current_user) - total_applicable_questions(subsection, lettings_log, current_user).select { |q| q.completed?(lettings_log) } + total_applicable_questions(subsection, lettings_log, current_user).select do |question| + answer = Answer.new(question:, log: lettings_log) + answer.completed? + end end def total_count(subsection, lettings_log, current_user) @@ -55,6 +58,7 @@ private end def get_answer_label(question, lettings_log) - question.answer_label(lettings_log).presence || "You didn’t answer this question".html_safe + answer = Answer.new(question:, log: lettings_log) + answer.answer_label.presence || "You didn’t answer this question".html_safe end end diff --git a/app/helpers/interruption_screen_helper.rb b/app/helpers/interruption_screen_helper.rb index 7731d9425..e05f636cf 100644 --- a/app/helpers/interruption_screen_helper.rb +++ b/app/helpers/interruption_screen_helper.rb @@ -5,7 +5,9 @@ module InterruptionScreenHelper translation_params = {} informative_text["arguments"].each do |argument| value = if argument["label"] - pre_casing_value = lettings_log.form.get_question(argument["key"], lettings_log).answer_label(lettings_log) + question = lettings_log.form.get_question(argument["key"], lettings_log) + answer = Answer.new(question:, log: lettings_log) + pre_casing_value = answer.answer_label pre_casing_value.downcase else lettings_log.public_send(argument["key"]) @@ -29,7 +31,9 @@ module InterruptionScreenHelper arguments = title_text["arguments"] || {} arguments.each do |argument| value = if argument["label"] - lettings_log.form.get_question(argument["key"], lettings_log).answer_label(lettings_log).downcase + question = lettings_log.form.get_question(argument["key"], lettings_log) + answer = Answer.new(question:, log: lettings_log) + answer.answer_label.downcase else lettings_log.public_send(argument["key"]) end diff --git a/app/models/answer.rb b/app/models/answer.rb new file mode 100644 index 000000000..f73bc9e42 --- /dev/null +++ b/app/models/answer.rb @@ -0,0 +1,136 @@ +class Answer + attr_reader :question, :log + + delegate :type, to: :question + delegate :id, to: :question + delegate :answer_options, to: :question + delegate :prefix, to: :question + delegate :suffix, to: :question + delegate :inferred_check_answers_value, to: :question + delegate :inferred_answers, to: :question + + delegate :page, to: :question + delegate :subsection, to: :page + delegate :form, to: :subsection + + def initialize(question:, log:) + @question = question + @log = log + end + + def answer_label + return checkbox_answer_label if checkbox? + return log[id]&.to_formatted_s(:govuk_date).to_s if date? + + answer = label_from_value(log[id]) if log[id].present? + answer_label = [prefix, format_value(answer), suffix_label].join("") if answer + + inferred = inferred_check_answers_value["value"] if inferred_check_answers_value && has_inferred_check_answers_value? + + return inferred if inferred.present? + + answer_label + end + + def suffix_label + return "" unless suffix + return suffix if suffix.is_a?(String) + + label = "" + + suffix.each do |s| + condition = s["depends_on"] + next unless condition + + answer = log.send(condition.keys.first) + if answer == condition.values.first + label = s["label"] + end + end + label + end + + def completed? + return answer_options.keys.any? { |key| value_is_yes?(log[key]) } if checkbox? + + log[id].present? || !log.respond_to?(id.to_sym) || has_inferred_display_value? + end + + def get_inferred_answers + return [] unless inferred_answers + + enabled_inferred_answers(inferred_answers).keys.map do |question_id| + question = form.get_question(question_id, log) + if question.present? + question.label_from_value(log[question_id]) + else + Array(question_id.to_s.split(".")).inject(log) { |l, method| l.present? ? l.public_send(*method) : "" } + end + end + end + +private + + def enabled_inferred_answers(inferred_answers) + inferred_answers.filter { |_key, value| value.all? { |condition_key, condition_value| log[condition_key] == condition_value } } + end + + def has_inferred_display_value? + inferred_check_answers_value.present? && log[inferred_check_answers_value["condition"].keys.first] == inferred_check_answers_value["condition"].values.first + end + + def has_inferred_check_answers_value? + return true if selected_answer_option_is_derived? + return inferred_check_answers_value["condition"].values[0] == log[inferred_check_answers_value["condition"].keys[0]] if inferred_check_answers_value.present? + + false + end + + def selected_answer_option_is_derived? + selected_option = answer_options&.dig(log[id].to_s.presence) + selected_option.is_a?(Hash) && selected_option["depends_on"] && form.depends_on_met(selected_option["depends_on"], log) + end + + def format_value(answer_label) + if prefix == "£" + ActionController::Base.helpers.number_to_currency(answer_label, delimiter: ",", format: "%n") + else + answer_label + end + end + + def label_from_value(value) + question.label_from_value(value) + end + + def checkbox? + question.type == "checkbox" + end + + def date? + question.type == "date" + end + + def checkbox_answer_label + answer = [] + return "Yes" if declaration? && value_is_yes?(log["declaration"]) + + answer_options.each { |key, options| value_is_yes?(log[key]) ? answer << options["value"] : nil } + answer.join(", ") + end + + def declaration? + question.id == "declaration" + end + + def value_is_yes?(value) + case type + when "checkbox" + value == 1 + when "radio" + RADIO_YES_VALUE[id.to_sym]&.include?(value) + else + %w[yes].include?(value.downcase) + end + end +end diff --git a/app/models/form/question.rb b/app/models/form/question.rb index 13b1c62c9..96f708e87 100644 --- a/app/models/form/question.rb +++ b/app/models/form/question.rb @@ -13,6 +13,7 @@ class Form::Question def initialize(id, hsh, page) @id = id @page = page + if hsh @check_answer_label = hsh["check_answer_label"] @header = hsh["header"] @@ -44,32 +45,6 @@ class Form::Question delegate :subsection, to: :page delegate :form, to: :subsection - def answer_label(log) - return checkbox_answer_label(log) if type == "checkbox" - return log[id]&.to_formatted_s(:govuk_date).to_s if type == "date" - - answer = label_from_value(log[id]) if log[id].present? - answer_label = [prefix, format_value(answer), suffix_label(log)].join("") if answer - - inferred = inferred_check_answers_value["value"] if inferred_check_answers_value && has_inferred_check_answers_value?(log) - return inferred if inferred.present? - - answer_label - end - - def get_inferred_answers(log) - return [] unless inferred_answers - - enabled_inferred_answers(inferred_answers, log).keys.map do |question_id| - question = form.get_question(question_id, log) - if question.present? - question.label_from_value(log[question_id]) - else - Array(question_id.to_s.split(".")).inject(log) { |l, method| l.present? ? l.public_send(*method) : "" } - end - end - end - def get_extra_check_answer_value(_log) nil end @@ -127,12 +102,6 @@ class Form::Question "/#{log.model_name.param_key.dasherize}s/#{log.id}/#{page_id.to_s.dasherize}?referrer=check_answers" end - def completed?(log) - return answer_options.keys.any? { |key| value_is_yes?(log[key]) } if type == "checkbox" - - log[id].present? || !log.respond_to?(id.to_sym) || has_inferred_display_value?(log) - end - def value_from_label(label) return unless label @@ -205,24 +174,6 @@ class Form::Question I18n.t("validations.not_answered", question: display_label.downcase) end - def suffix_label(log) - return "" unless suffix - return suffix if suffix.is_a?(String) - - label = "" - - suffix.each do |s| - condition = s["depends_on"] - next unless condition - - answer = log.send(condition.keys.first) - if answer == condition.values.first - label = s["label"] - end - end - label - end - def answer_option_synonyms(resource) return unless resource.respond_to?(:synonyms) @@ -262,18 +213,6 @@ private selected_option.is_a?(Hash) && selected_option["depends_on"] && form.depends_on_met(selected_option["depends_on"], log) end - def has_inferred_display_value?(log) - inferred_check_answers_value.present? && log[inferred_check_answers_value["condition"].keys.first] == inferred_check_answers_value["condition"].values.first - end - - def checkbox_answer_label(log) - answer = [] - return "Yes" if id == "declaration" && value_is_yes?(log["declaration"]) - - answer_options.each { |key, options| value_is_yes?(log[key]) ? answer << options["value"] : nil } - answer.join(", ") - end - def format_value(answer_label) prefix == "£" ? ActionController::Base.helpers.number_to_currency(answer_label, delimiter: ",", format: "%n") : answer_label end @@ -297,10 +236,6 @@ private end end - def enabled_inferred_answers(inferred_answers, log) - inferred_answers.filter { |_key, value| value.all? { |condition_key, condition_value| log[condition_key] == condition_value } } - end - RADIO_YES_VALUE = { renewal: [1], postcode_known: [1], diff --git a/app/models/form/subsection.rb b/app/models/form/subsection.rb index 07e7fe65c..a88115000 100644 --- a/app/models/form/subsection.rb +++ b/app/models/form/subsection.rb @@ -31,7 +31,10 @@ class Form::Subsection qs = applicable_questions(log) qs_optional_removed = qs.reject { |q| log.optional_fields.include?(q.id) } return :not_started if qs.count.positive? && qs.all? { |question| log[question.id].blank? || question.read_only? || question.derived? } - return :completed if qs_optional_removed.all? { |question| question.completed?(log) } + return :completed if qs_optional_removed.all? do |question| + answer = Answer.new(question:, log:) + answer.completed? + end :in_progress end diff --git a/app/views/form/_check_answers_summary_list.html.erb b/app/views/form/_check_answers_summary_list.html.erb index 68a9cf00a..89b523095 100644 --- a/app/views/form/_check_answers_summary_list.html.erb +++ b/app/views/form/_check_answers_summary_list.html.erb @@ -9,7 +9,8 @@ <%= extra_value %> <% end %>
- <% question.get_inferred_answers(@log).each do |inferred_answer| %> + <% answer = Answer.new(log: @log, question:) %> + <% answer.get_inferred_answers.each do |inferred_answer| %> <%= inferred_answer %> <% end %> <% end %> diff --git a/app/views/form/_numeric_output_question.html.erb b/app/views/form/_numeric_output_question.html.erb index b96e7b53d..8fa73d3da 100644 --- a/app/views/form/_numeric_output_question.html.erb +++ b/app/views/form/_numeric_output_question.html.erb @@ -17,7 +17,9 @@ name="lettings_log[tcharge]" for="<%= question.fields_added.present? ? question.fields_added.map { |x| "lettings-log-#{x}-field" }.join(" ") : "" %>"> <%= lettings_log[question.id] %> - <%= question.suffix_label(lettings_log) %> + + <% answer = Answer.new(log: lettings_log, question:) %> + <%= answer.suffix_label %> diff --git a/app/views/form/_numeric_question.html.erb b/app/views/form/_numeric_question.html.erb index 0aeb63801..29f965e6b 100644 --- a/app/views/form/_numeric_question.html.erb +++ b/app/views/form/_numeric_question.html.erb @@ -1,5 +1,6 @@ <%= render partial: "form/guidance/#{question.guidance_partial}" if question.top_guidance? %> +<% answer = Answer.new(log: @log, question:) %> <%= f.govuk_number_field question.id.to_sym, caption: caption(caption_text, page_header, conditional), label: legend(question, page_header, conditional), @@ -8,7 +9,7 @@ width: question.width, readonly: question.read_only?, prefix_text: question.prefix.to_s, - suffix_text: question.suffix_label(@log), + suffix_text: answer.suffix_label, **stimulus_html_attributes(question) %> <%= render partial: "form/guidance/#{question.guidance_partial}" if question.bottom_guidance? %> diff --git a/spec/components/check_answers_summary_list_card_component_spec.rb b/spec/components/check_answers_summary_list_card_component_spec.rb index 6273da69d..2f324aedb 100644 --- a/spec/components/check_answers_summary_list_card_component_spec.rb +++ b/spec/components/check_answers_summary_list_card_component_spec.rb @@ -10,7 +10,8 @@ RSpec.describe CheckAnswersSummaryListCardComponent, type: :component do it "renders a summary list card for the answers to those questions" do result = render_inline(described_class.new(questions:, log:, user:)) - expect(result).to have_content(questions.first.answer_label(log)) + answer = Answer.new(log:, question: questions.first) + expect(result).to have_content(answer.answer_label) end it "applicable questions doesn't return questions that are hidden in check answers" do diff --git a/spec/helpers/interruption_screen_helper_spec.rb b/spec/helpers/interruption_screen_helper_spec.rb index 4984a0450..7598d21c3 100644 --- a/spec/helpers/interruption_screen_helper_spec.rb +++ b/spec/helpers/interruption_screen_helper_spec.rb @@ -35,8 +35,15 @@ RSpec.describe InterruptionScreenHelper do }, ], } + + ecstat_question = lettings_log.form.get_question("ecstat1", lettings_log) + ecstat_answer = Answer.new(log: lettings_log, question: ecstat_question) + + earnings_question = lettings_log.form.get_question("earnings", lettings_log) + earnings_answer = Answer.new(log: lettings_log, question: earnings_question) + expect(display_informative_text(informative_text, lettings_log)) - .to eq(I18n.t("soft_validations.net_income.hint_text", ecstat1: lettings_log.form.get_question("ecstat1", lettings_log).answer_label(lettings_log).downcase, earnings: lettings_log.form.get_question("earnings", lettings_log).answer_label(lettings_log))) + .to eq(I18n.t("soft_validations.net_income.hint_text", ecstat1: ecstat_answer.answer_label.downcase, earnings: earnings_answer.answer_label)) end end @@ -52,8 +59,12 @@ RSpec.describe InterruptionScreenHelper do }, ], } + + question = lettings_log.form.get_question("ecstat1", lettings_log) + answer = Answer.new(question:, log: lettings_log) + expect(display_informative_text(informative_text, lettings_log)) - .to eq(I18n.t("test.one_argument", ecstat1: lettings_log.form.get_question("ecstat1", lettings_log).answer_label(lettings_log).downcase)) + .to eq(I18n.t("test.one_argument", ecstat1: answer.answer_label.downcase)) end end @@ -74,8 +85,12 @@ RSpec.describe InterruptionScreenHelper do }, ], } + + question = lettings_log.form.get_question("ecstat1", lettings_log) + answer = Answer.new(question:, log: lettings_log) + expect(display_informative_text(informative_text, lettings_log)) - .to eq(I18n.t("test.one_argument", ecstat1: lettings_log.form.get_question("ecstat1", lettings_log).answer_label(lettings_log).downcase)) + .to eq(I18n.t("test.one_argument", ecstat1: answer.answer_label.downcase)) end end @@ -118,8 +133,12 @@ RSpec.describe InterruptionScreenHelper do }, ], } + + question = lettings_log.form.get_question("ecstat1", lettings_log) + answer = Answer.new(log: lettings_log, question:) + expect(display_title_text(title_text, lettings_log)) - .to eq(I18n.t("test.title_text.one_argument", ecstat1: lettings_log.form.get_question("ecstat1", lettings_log).answer_label(lettings_log).downcase)) + .to eq(I18n.t("test.title_text.one_argument", ecstat1: answer.answer_label.downcase)) end end diff --git a/spec/models/answer_spec.rb b/spec/models/answer_spec.rb new file mode 100644 index 000000000..00feb232c --- /dev/null +++ b/spec/models/answer_spec.rb @@ -0,0 +1,115 @@ +require "rails_helper" + +RSpec.describe Answer, type: :model do + subject(:answer) { described_class.new(question:, log:) } + + let(:log) { FactoryBot.build(:lettings_log, :in_progress) } + let(:form) { log.form } + let(:question_id) { "incfreq" } + let(:section_id) { "rent_and_charges" } + let(:section_definition) { form.form_definition["sections"][section_id] } + let(:section) { Form::Section.new(section_id, section_definition, form) } + let(:subsection_id) { "income_and_benefits" } + let(:subsection_definition) { section_definition["subsections"][subsection_id] } + let(:subsection) { Form::Subsection.new(subsection_id, subsection_definition, section) } + let(:page_definition) { subsection_definition["pages"][page_id] } + let(:question_definition) { page_definition["questions"][question_id] } + let(:page) { Form::Page.new(page_id, page_definition, subsection) } + let(:page_id) { "net_income" } + let(:question) { Form::Question.new(question_id, question_definition, page) } + + describe "#answer_label" do + context "with a lettings log" do + it "has an answer label" do + log.incfreq = 1 + + expect(answer.answer_label).to eql("Weekly") + end + end + + context "when type is date" do + let(:section_id) { "local_authority" } + let(:subsection_id) { "local_authority" } + let(:page_id) { "property_major_repairs" } + let(:question_id) { "mrcdate" } + + it "displays a formatted answer label" do + log.mrcdate = Time.zone.local(2021, 10, 11) + expect(answer.answer_label).to eql("11 October 2021") + end + + it "can handle nils" do + log.mrcdate = nil + expect(answer.answer_label).to eql("") + end + end + + context "when type is checkbox" do + let(:section_id) { "household" } + let(:subsection_id) { "household_needs" } + let(:page_id) { "accessibility_requirements" } + let(:question_id) { "accessibility_requirements" } + + it "has a joined answers label" do + log.housingneeds_a = 1 + log.housingneeds_c = 1 + expected_answer_label = "Fully wheelchair accessible housing, Level access housing" + expect(answer.answer_label).to eql(expected_answer_label) + end + end + + context "when answers have a suffix dependent on another answer" do + let(:section_id) { "rent_and_charges" } + let(:subsection_id) { "income_and_benefits" } + let(:page_id) { "net_income" } + let(:question_id) { "earnings" } + + it "displays the correct label for given suffix and answer the suffix depends on" do + log.incfreq = 1 + log.earnings = 500 + expect(answer.answer_label).to eql("£500.00 every week") + log.incfreq = 2 + expect(answer.answer_label).to eql("£500.00 every month") + log.incfreq = 3 + expect(answer.answer_label).to eql("£500.00 every year") + end + end + + context "with inferred_check_answers_value" do + context "when Lettings form" do + let(:section_id) { "household" } + let(:subsection_id) { "household_needs" } + let(:page_id) { "armed_forces" } + let(:question_id) { "armedforces" } + + it "returns the inferred label value" do + log.armedforces = 3 + expect(answer.answer_label).to eql("Prefers not to say") + end + end + + context "when Sales form" do + let(:log) { FactoryBot.create(:sales_log, :completed, ethnic_group: 17) } + let(:question) { log.form.get_question("ethnic_group", log) } + + it "returns the inferred label value" do + expect(answer.answer_label).to eql("Prefers not to say") + end + end + end + end + + describe "#completed?" do + context "when the question has inferred value only for check answers display" do + let(:section_id) { "tenancy_and_property" } + let(:subsection_id) { "property_information" } + let(:page_id) { "property_postcode" } + let(:question_id) { "postcode_full" } + + it "returns true" do + log["postcode_known"] = 0 + expect(answer.completed?).to be(true) + end + end + end +end diff --git a/spec/models/form/question_spec.rb b/spec/models/form/question_spec.rb index 637407bc1..cc83bfb11 100644 --- a/spec/models/form/question_spec.rb +++ b/spec/models/form/question_spec.rb @@ -225,11 +225,6 @@ RSpec.describe Form::Question, type: :model do let(:lettings_log) { FactoryBot.build(:lettings_log, :in_progress) } let(:question_id) { "incfreq" } - it "has an answer label" do - lettings_log.incfreq = 1 - expect(question.answer_label(lettings_log)).to eq("Weekly") - end - it "has an update answer link text helper" do expect(question.action_text(lettings_log)).to match(/Answer/) lettings_log["incfreq"] = 0 @@ -267,37 +262,6 @@ RSpec.describe Form::Question, type: :model do end end - context "when type is date" do - let(:section_id) { "local_authority" } - let(:subsection_id) { "local_authority" } - let(:page_id) { "property_major_repairs" } - let(:question_id) { "mrcdate" } - - it "displays a formatted answer label" do - lettings_log.mrcdate = Time.zone.local(2021, 10, 11) - expect(question.answer_label(lettings_log)).to eq("11 October 2021") - end - - it "can handle nils" do - lettings_log.mrcdate = nil - expect(question.answer_label(lettings_log)).to eq("") - end - end - - context "when type is checkbox" do - let(:section_id) { "household" } - let(:subsection_id) { "household_needs" } - let(:page_id) { "accessibility_requirements" } - let(:question_id) { "accessibility_requirements" } - - it "has a joined answers label" do - lettings_log.housingneeds_a = 1 - lettings_log.housingneeds_c = 1 - expected_answer_label = "Fully wheelchair accessible housing, Level access housing" - expect(question.answer_label(lettings_log)).to eq(expected_answer_label) - end - end - context "when a condition is present" do let(:page_id) { "housing_benefit" } let(:question_id) { "conditional_question" } @@ -323,60 +287,6 @@ RSpec.describe Form::Question, type: :model do end end end - - context "when answers have a suffix dependent on another answer" do - let(:section_id) { "rent_and_charges" } - let(:subsection_id) { "income_and_benefits" } - let(:page_id) { "net_income" } - let(:question_id) { "earnings" } - - it "displays the correct label for given suffix and answer the suffix depends on" do - lettings_log.incfreq = 1 - lettings_log.earnings = 500 - expect(question.answer_label(lettings_log)).to eq("£500.00 every week") - lettings_log.incfreq = 2 - expect(question.answer_label(lettings_log)).to eq("£500.00 every month") - lettings_log.incfreq = 3 - expect(question.answer_label(lettings_log)).to eq("£500.00 every year") - end - end - - context "with inferred_check_answers_value" do - context "when Lettings form" do - let(:section_id) { "household" } - let(:subsection_id) { "household_needs" } - let(:page_id) { "armed_forces" } - let(:question_id) { "armedforces" } - - it "returns the inferred label value" do - lettings_log.armedforces = 3 - expect(question.answer_label(lettings_log)).to eq("Prefers not to say") - end - end - - context "when Sales form" do - let(:sales_log) { FactoryBot.create(:sales_log, :completed, ethnic_group: 17) } - let(:question) { sales_log.form.get_question("ethnic_group", sales_log) } - - it "returns the inferred label value" do - expect(question.answer_label(sales_log)).to eq("Prefers not to say") - end - end - end - end - - describe ".completed?" do - context "when the question has inferred value only for check answers display" do - let(:section_id) { "tenancy_and_property" } - let(:subsection_id) { "property_information" } - let(:page_id) { "property_postcode" } - let(:question_id) { "postcode_full" } - - it "returns true" do - lettings_log["postcode_known"] = 0 - expect(question.completed?(lettings_log)).to be(true) - end - end end context "when the question has a hidden in check answers attribute with dependencies" do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 462471744..25429adc8 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -62,13 +62,14 @@ RSpec.configure do |config| # The settings below are suggested to provide a good initial experience # with RSpec, but feel free to customize to your heart's content. - # # This allows you to limit a spec run to individual examples or groups - # # you care about by tagging them with `:focus` metadata. When nothing - # # is tagged with `:focus`, all examples get run. RSpec also provides - # # aliases for `it`, `describe`, and `context` that include `:focus` - # # metadata: `fit`, `fdescribe` and `fcontext`, respectively. - # config.filter_run_when_matching :focus - # + + # This allows you to limit a spec run to individual examples or groups + # you care about by tagging them with `:focus` metadata. When nothing + # is tagged with `:focus`, all examples get run. RSpec also provides + # aliases for `it`, `describe`, and `context` that include `:focus` + # metadata: `fit`, `fdescribe` and `fcontext`, respectively. + config.filter_run_when_matching :focus + # # Allows RSpec to persist some state between runs in order to support # # the `--only-failures` and `--next-failure` CLI options. We recommend # # you configure your source control system to ignore this file.