Class: SnapDiff::Config
- Inherits:
-
Object
- Object
- SnapDiff::Config
- Defined in:
- lib/snap_diff/config.rb
Overview
Flat consolidation of every legacy Capybara::Screenshot /
Capybara::Screenshot::Diff setting behind one object:
SnapDiff.config.attr.
Storage ownership (ADR-008 step 1, inverted from the original v2
consolidation): Config IS the single storage. The legacy accessors on
Capybara::Screenshot / Capybara::Screenshot::Diff are thin
delegators generated by snap_diff/legacy_shims from its CONFIG_MAPPING
-- one storage, two views, so a write through either surface is visible
through the other structurally, not by synchronization.
Default timing contract (pinned by config_default_timing_test.rb):
every stored default below is evaluated ONCE, in #initialize, which runs
at require time of this file (the eager Config.new at the bottom) --
the same load moment the old mattr_accessor default blocks evaluated
at. In particular root (from Rails.root / pwd) must never become a
lazy read-time default, memoized or not.
Two values are deliberately LIVE and are not storage at all:
default_options[:wait] stays a method-body read of
Capybara.default_max_wait_time in #default_options, and
fail_if_new falls back to ENV in its reader whenever
nothing explicit was set -- see #fail_if_new for why freezing that
sniff into storage let the environment outrank the user.
Constant Summary collapse
- SETTINGS =
Every setting this object stores, in the order the two legacy holders used to declare them.
screenshot_enabledis the one name that differs from its legacy spelling:Capybara::Screenshot.enabledandCapybara::Screenshot::Diff.enabledare independent settings (see #active?, which reads both) that happened to share a bare name in their own modules. A flat Config can't expose two attributes both calledenabled, so the Screenshot-side one is renamed here; Diff's keeps the bareenabledname since it's the one most existing configuration touches directly. %i[ add_driver_path add_os_path blur_active_element screenshot_enabled hide_caret disable_animations root stability_time_limit window_size save_path use_lfs screenshot_format capybara_screenshot_options delayed area_size_limit record fail_if_new pending_if_new fail_on_difference color_distance_limit enabled shift_distance_limit skip_area driver tolerance perceptual_threshold screenshoter manager ].freeze
- RECORD_MODES =
The record modes, in the order they escalate: do nothing new, refuse to record, record everything. See #record.
%i[once none all].freeze
Instance Attribute Summary collapse
-
#driver ⇒ Object
Returns the value of attribute driver.
-
#fail_on_difference ⇒ Object
Returns the value of attribute fail_on_difference.
-
#pending_if_new ⇒ Object
Returns the value of attribute pending_if_new.
-
#root ⇒ Object
Returns the value of attribute root.
-
#shift_distance_limit ⇒ Object
Returns the value of attribute shift_distance_limit.
Class Method Summary collapse
-
.validate_record_mode!(mode) ⇒ Object
private
Shared by #record= and the per-screenshot
record:option, which is resolved in ScreenshotMatcher.
Instance Method Summary collapse
-
#active? ⇒ Boolean
ex
Capybara::Screenshot.active?. -
#default_options ⇒ Object
ex
Capybara::Screenshot::Diff.default_options: the capture/compare defaults handed to Comparison. -
#fail_if_new ⇒ Object
An explicit setting outranks the environment.
-
#fail_if_new=(value) ⇒ Object
Announces the 2.1 removal.
-
#initialize ⇒ Config
constructor
A new instance of Config.
-
#record ⇒ Object
THE ACCEPT WORKFLOW (#259).
- #record=(mode) ⇒ Object
-
#screenshot_area ⇒ Object
ex
Capybara::Screenshot.screenshot_area: the save_path, optionally segmented per OS and per Capybara driver. -
#screenshot_area_abs ⇒ Object
ex
Capybara::Screenshot.screenshot_area_abs.
Constructor Details
#initialize ⇒ Config
Returns a new instance of Config.
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/snap_diff/config.rb', line 115 def initialize # Every setting gets its ivar up front (nil-defaulted ones included) # so the full set always exists -- test_helper's per-test isolation # snapshots/restores config by instance variable, and an ivar that # only appears on first write would escape that snapshot and leak # between tests. SETTINGS.each { |key| instance_variable_set(:"@#{key}", nil) } # Capybara::Screenshot side. @blur_active_element = true @hide_caret = true # Raw Rails.root (no coercion), matching the old mattr_reader default; # only the writer below coerces. @root = (defined?(Rails) && defined?(Rails.root) && Rails.root) || Pathname("."). @save_path = "doc/screenshots" @screenshot_format = "png" @capybara_screenshot_options = {} # Capybara::Screenshot::Diff side. @delayed = true # No stored default for fail_if_new on purpose -- see the reader. @pending_if_new = false @fail_on_difference = true @enabled = true @driver = :auto @screenshoter = SnapDiff::Screenshoter @manager = SnapDiff::SnapManager end |
Instance Attribute Details
#driver ⇒ Object
Returns the value of attribute driver.
113 114 115 |
# File 'lib/snap_diff/config.rb', line 113 def driver @driver end |
#fail_on_difference ⇒ Object
Returns the value of attribute fail_on_difference.
113 114 115 |
# File 'lib/snap_diff/config.rb', line 113 def fail_on_difference @fail_on_difference end |
#pending_if_new ⇒ Object
Returns the value of attribute pending_if_new.
113 114 115 |
# File 'lib/snap_diff/config.rb', line 113 def pending_if_new @pending_if_new end |
#root ⇒ Object
Returns the value of attribute root.
113 114 115 |
# File 'lib/snap_diff/config.rb', line 113 def root @root end |
#shift_distance_limit ⇒ Object
Returns the value of attribute shift_distance_limit.
113 114 115 |
# File 'lib/snap_diff/config.rb', line 113 def shift_distance_limit @shift_distance_limit end |
Class Method Details
.validate_record_mode!(mode) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Shared by #record= and the per-screenshot record: option, which is
resolved in ScreenshotMatcher. A misspelt mode must not
read back as "nobody said" and silently mean today's behaviour --
that is the exact silent no-op ADR-010 exists to stop.
97 98 99 100 101 102 |
# File 'lib/snap_diff/config.rb', line 97 def self.validate_record_mode!(mode) return mode if mode.nil? || RECORD_MODES.include?(mode) raise ArgumentError, "unknown record mode #{mode.inspect} -- one of #{RECORD_MODES.map(&:inspect).join(", ")} (or nil)" end |
Instance Method Details
#active? ⇒ Boolean
ex Capybara::Screenshot.active?. The two enabled settings are
independent (see SETTINGS): the Screenshot-side one wins whenever it
was set at all, and only a nil there falls through to the Diff-side
one.
247 248 249 |
# File 'lib/snap_diff/config.rb', line 247 def active? screenshot_enabled || (screenshot_enabled.nil? && enabled) end |
#default_options ⇒ Object
ex Capybara::Screenshot::Diff.default_options: the capture/compare
defaults handed to SnapDiff::Comparison. Carries the one literal
that is not a stored setting -- the vips tolerance floor.
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 |
# File 'lib/snap_diff/config.rb', line 268 def { area_size_limit: area_size_limit, color_distance_limit: color_distance_limit, driver: driver, screenshot_format: screenshot_format, capybara_screenshot_options: , perceptual_threshold: perceptual_threshold, shift_distance_limit: shift_distance_limit, skip_area: skip_area, stability_time_limit: stability_time_limit, tolerance: tolerance || ((driver == :vips) ? 0.001 : nil), # Deliberately LIVE (pinned by config_default_timing_test.rb): # read at call time, never frozen into storage. wait: Capybara.default_max_wait_time } end |
#fail_if_new ⇒ Object
An explicit setting outranks the environment. nil means nobody said, and only then does the CI sniff answer -- read live, so a CI variable that appears at any point is honoured, not just one that happened to be exported before the gem was required. Assigning nil hands the setting back to the environment.
This is a precedence rule, not a change of default: failing only under
CI stays (a locally recorded baseline is often worthless across OS).
Storing the sniff instead, as this did, made the two indistinguishable
-- fail_if_new = false and "CI was absent at require time" were the
same false, so the environment could win. Same fix as insta#924
("normally, CLI flags take precedence over environment variables") and
the inverse of jest#12288.
159 160 161 |
# File 'lib/snap_diff/config.rb', line 159 def fail_if_new @fail_if_new.nil? ? !ENV["CI"].to_s.empty? : @fail_if_new end |
#fail_if_new=(value) ⇒ Object
Announces the 2.1 removal. The writer, not the reader: #record reads
fail_if_new on every screenshot for everyone, and #initialize stores
no default at all, so only a user who sets it hears about it.
166 167 168 169 |
# File 'lib/snap_diff/config.rb', line 166 def fail_if_new=(value) Removal.warn_once(:fail_if_new, Removal::FAIL_IF_NEW_REMOVED) @fail_if_new = value end |
#record ⇒ Object
THE ACCEPT WORKFLOW (#259). What to do about a screenshot whose
baseline is missing -- or, for :all, about every screenshot there
is. VCR-shaped: modes in config, because there is no runner to hang a
CLI flag on.
:once:: (default) record a screenshot that has no committed
baseline; compare against the baseline when there is one.
:none:: strict. A missing baseline always fails.
:all:: re-record. Every screenshot is written as the new baseline
and nothing is compared -- the bulk-accept verb, for the
redesign that changed forty screenshots at once. Refused
under CI (see ScreenshotMatcher).
PRECEDENCE: an explicitly set mode outranks fail_if_new; nil means
nobody said, and only then does fail_if_new answer -- so a setup
with no record line behaves EXACTLY as it did before this setting
existed, CI sniff and all. :none is the mode spelling of
fail_if_new = true and :once of = false, which is
why the fallback can express today's behaviour without a special case
anywhere downstream: the matcher branches on the mode alone.
The missing-baseline DEFAULT is deliberately unchanged -- failing only
under CI is what Jest, AVA, Vitest, testthat and jest-image-snapshot
all chose, and a locally recorded screenshot baseline is often
worthless across OS. :none makes strictness an explicit choice
instead; that is the whole point of having the mode.
212 213 214 |
# File 'lib/snap_diff/config.rb', line 212 def record @record || (fail_if_new ? :none : :once) end |
#record=(mode) ⇒ Object
216 217 218 |
# File 'lib/snap_diff/config.rb', line 216 def record=(mode) @record = Config.validate_record_mode!(mode) end |
#screenshot_area ⇒ Object
ex Capybara::Screenshot.screenshot_area: the save_path, optionally
segmented per OS and per Capybara driver.
253 254 255 256 257 258 |
# File 'lib/snap_diff/config.rb', line 253 def screenshot_area parts = [save_path] parts << Os.name if add_os_path parts << Capybara.current_driver.to_s if add_driver_path File.join(*parts) end |
#screenshot_area_abs ⇒ Object
ex Capybara::Screenshot.screenshot_area_abs.
261 262 263 |
# File 'lib/snap_diff/config.rb', line 261 def screenshot_area_abs root / screenshot_area end |