require 'precheck/rule' module Precheck # abstract class that defines a default way to check for the presence of a list of words within a block of text class AbstractTextMatchRule < TextRule WORD_SEARCH_TYPES = { fail_on_inclusion: "fail_on_inclusion", fail_on_exclusion: "fail_on_exclusion" } attr_accessor :lowercased_words_to_look_for def lowercased_words_to_look_for not_implemented(__method__) end def pass_if_empty? return true end def word_search_type WORD_SEARCH_TYPES[:fail_on_inclusion] end # rule block that checks text for any instance of each string in lowercased_words_to_look_for def rule_block return lambda { |text| text = text.to_s.strip.downcase if text.empty? if pass_if_empty? return RuleReturn.new(validation_state: Precheck::VALIDATION_STATES[:passed]) else return RuleReturn.new(validation_state: VALIDATION_STATES[:failed], failure_data: "missing text") end end matches = lowercased_words_to_look_for.each_with_object([]) do |word, found_words| if text.include?(word) found_words << word end end if matches.length > 0 && word_search_type == WORD_SEARCH_TYPES[:fail_on_inclusion] # we are supposed to fail if any of the words are found friendly_matches = matches.join(', ') UI.verbose "😭 #{self.class.name.split('::').last ||= self.class.name} found words \"#{friendly_matches}\"" return RuleReturn.new(validation_state: VALIDATION_STATES[:failed], failure_data: "found: #{friendly_matches}") elsif matches.length < lowercased_words_to_look_for.length && word_search_type == WORD_SEARCH_TYPES[:fail_on_exclusion] # we are supposed to fail if any of the words are not found (like current copyright date in the copyright field) search_data_set = lowercased_words_to_look_for.to_set search_data_set.subtract(matches) missing_words = search_data_set.to_a.join(', ') UI.verbose "😭 #{self.class.name.split('::').last ||= self.class.name} didn't find words \"#{missing_words}\"" return RuleReturn.new(validation_state: VALIDATION_STATES[:failed], failure_data: "missing: #{missing_words}") else return RuleReturn.new(validation_state: VALIDATION_STATES[:passed]) end } end end end