class RSpecApprovals::Matchers::Base
A base matcher for approvals
Attributes
Public Class Methods
# File lib/rspec_approvals/matchers/base.rb, line 8 def initialize(approval_name=nil) @before = nil @approval_name = approval_name end
Public Instance Methods
Returns the path to the approval file
# File lib/rspec_approvals/matchers/base.rb, line 96 def approval_file "#{approvals_dir}/#{approval_name}" end
Returns the path to the approvals directory. Default: `spec/approvals`
# File lib/rspec_approvals/matchers/base.rb, line 91 def approvals_dir RSpec.configuration.approvals_path end
Enables the ability to adjust the actual string before checking for matches: `expect(a).to match_approval(f).before ->(actual) { actual.gsub /one/, 'two' }`
# File lib/rspec_approvals/matchers/base.rb, line 47 def before(proc) @before ||= [] @before << proc self end
Enables the ability to do something like: `expect(string).to match_approval(file).diff(10) The distance argument is the max allowed Levenshtein Distance.
# File lib/rspec_approvals/matchers/base.rb, line 31 def diff(distance) @distance = distance self end
Lets RSpec know these matchers support diffing
# File lib/rspec_approvals/matchers/base.rb, line 72 def diffable? true end
Enables the ability to do something like: `expect(string).to match_approval(file).except(/d+/)
# File lib/rspec_approvals/matchers/base.rb, line 38 def except(regex, replace = '...') before ->(str) do str.gsub regex, replace end end
Returns the expected value, from an approval file
# File lib/rspec_approvals/matchers/base.rb, line 54 def expected @expected ||= expected! end
Called by RSpec when there is a failure
# File lib/rspec_approvals/matchers/base.rb, line 59 def failure_message return "actual string is empty" if actual.empty? result = "expected: #{actual}\nto match: #{expected}" if distance result = "#{result}\n(actual distance is #{actual_distance} instead of the expected #{distance})" end result end
Returns true if RSpec is configured to allow interactivity. By default, interactivity is enabled unless the environment variable `CI` is set.
# File lib/rspec_approvals/matchers/base.rb, line 85 def interactive? RSpec.configuration.interactive_approvals end
Called by RSpec. This will be overridden by child matchers.
# File lib/rspec_approvals/matchers/base.rb, line 14 def matches?(actual) @actual ||= actual return false if @actual.empty? @actual = sanitize @actual success = strings_match? if success or !interactive? success else approve_approval end end
Returns true if RSpec is configured to sanitize (remove ANSI escape codes) from the actual strings before proceeeding to comparing them.
# File lib/rspec_approvals/matchers/base.rb, line 78 def sanitize? RSpec.configuration.strip_ansi_escape end
Protected Instance Methods
Asks for user approval. Used by child classes.
# File lib/rspec_approvals/matchers/base.rb, line 103 def approve_approval approval_handler = ApprovalHandler.new approval_handler.run expected, actual, approval_file end
Returns the actual approval file content.
# File lib/rspec_approvals/matchers/base.rb, line 109 def expected! File.exist?(approval_file) ? File.read(approval_file) : '' end
Returns the input string stripped of ANSI escape codes if the strip_ansi_escape configuration setting was set to true
# File lib/rspec_approvals/matchers/base.rb, line 142 def sanitize(string) sanitize? ? Strings::ANSI.sanitize(string) : string end
Do the actual test.
-
If .before() was used, we foreward the actual output to the proc for processing first.
-
If before_approval proc was configured, forward the acual output to the proc for processing.
-
If .diff() was used, then distance will be set and then we “levenshtein it”.
-
Otherwise, compare with ==
# File lib/rspec_approvals/matchers/base.rb, line 121 def strings_match? if @before @before.each do |proc| @actual = proc.call actual end end if RSpec.configuration.before_approval.is_a? Proc @actual = RSpec.configuration.before_approval.call actual end if distance @actual_distance = String::Similarity.levenshtein_distance expected, actual @actual_distance <= distance else actual == expected end end