Module: SnapDiff::LegacyShims Private

Defined in:
lib/snap_diff/legacy_shims.rb

This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.

Constant Summary collapse

REQUIRE_PATHS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

The handful of replacements whose file name does not follow the gem's own convention (SnapDiff::AreaCalculator -> snap_diff/area_calculator).

{
  "SnapDiff::Minitest::Assertions" => "snap_diff/integrations/minitest"
}.freeze
CONFIG_MAPPING =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

config attr name => [legacy module, legacy accessor name]. The keys are exactly SnapDiff::Config::SETTINGS; this hash only says which of the two legacy holders each one used to hang off, and under what name (only screenshot_enabled differs -- see Config::SETTINGS).

{
  # Capybara::Screenshot
  add_driver_path: [Capybara::Screenshot, :add_driver_path],
  add_os_path: [Capybara::Screenshot, :add_os_path],
  blur_active_element: [Capybara::Screenshot, :blur_active_element],
  screenshot_enabled: [Capybara::Screenshot, :enabled],
  hide_caret: [Capybara::Screenshot, :hide_caret],
  disable_animations: [Capybara::Screenshot, :disable_animations],
  root: [Capybara::Screenshot, :root],
  stability_time_limit: [Capybara::Screenshot, :stability_time_limit],
  window_size: [Capybara::Screenshot, :window_size],
  save_path: [Capybara::Screenshot, :save_path],
  use_lfs: [Capybara::Screenshot, :use_lfs],
  screenshot_format: [Capybara::Screenshot, :screenshot_format],
  capybara_screenshot_options: [Capybara::Screenshot, :capybara_screenshot_options],
  # Capybara::Screenshot::Diff
  delayed: [Capybara::Screenshot::Diff, :delayed],
  area_size_limit: [Capybara::Screenshot::Diff, :area_size_limit],
  # New in 2.0 and it has no v1 history, but it is storage on the one
  # Config like everything else, and the two-views invariant is
  # all-or-nothing: an unmapped setting is storage the v1 surface cannot
  # see. Mapping it also means a user still on the old namespace reaches
  # the accept workflow without migrating first.
  record: [Capybara::Screenshot::Diff, :record],
  fail_if_new: [Capybara::Screenshot::Diff, :fail_if_new],
  pending_if_new: [Capybara::Screenshot::Diff, :pending_if_new],
  fail_on_difference: [Capybara::Screenshot::Diff, :fail_on_difference],
  color_distance_limit: [Capybara::Screenshot::Diff, :color_distance_limit],
  enabled: [Capybara::Screenshot::Diff, :enabled],
  shift_distance_limit: [Capybara::Screenshot::Diff, :shift_distance_limit],
  skip_area: [Capybara::Screenshot::Diff, :skip_area],
  driver: [Capybara::Screenshot::Diff, :driver],
  tolerance: [Capybara::Screenshot::Diff, :tolerance],
  perceptual_threshold: [Capybara::Screenshot::Diff, :perceptual_threshold],
  screenshoter: [Capybara::Screenshot::Diff, :screenshoter],
  manager: [Capybara::Screenshot::Diff, :manager]
}.freeze

Class Method Summary collapse

Class Method Details

.install(namespace, old_prefix, mapping) ⇒ 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.

Installs a warn-then-forward const_missing on namespace.

Parameters:

  • namespace (Module)

    the old namespace to hook

  • old_prefix (String)

    how the old constant path reads to a human

  • mapping (Hash{Symbol => String})

    old leaf name => new full name



98
99
100
101
102
103
104
105
106
# File 'lib/snap_diff/legacy_shims.rb', line 98

def self.install(namespace, old_prefix, mapping)
  namespace.define_singleton_method(:const_missing) do |name|
    target = mapping[name]
    return super(name) unless target

    Deprecation.warn("#{old_prefix}::#{name}", target)
    LegacyShims.resolve("#{old_prefix}::#{name}", target)
  end
end

.install_config_accessorsObject

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.

Installs the old mattr_accessor surface onto the legacy modules, delegating to the single storage in SnapDiff.config. mattr_accessor used to define both singleton and instance accessors (the instance ones are what include Capybara::Screenshot::Diff picks up), so both are installed. root keeps its historical asymmetry -- readable everywhere, writable only at module level (it was mattr_reader plus a custom module-level writer) -- with the Pathname coercion living in Config#root=.



192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/snap_diff/legacy_shims.rb', line 192

def self.install_config_accessors
  CONFIG_MAPPING.each do |name, (mod, mattr)|
    [mod, mod.singleton_class].each do |target|
      target.define_method(mattr) do
        Deprecation.notice
        SnapDiff.config.public_send(name)
      end
      next if name == :root && target == mod

      target.define_method(:"#{mattr}=") do |value|
        Deprecation.notice
        SnapDiff.config.public_send(:"#{name}=", value)
      end
    end
  end
end

.install_include_notice(mod) ⇒ 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.

include Capybara::Screenshot::Diff is the third way into the v1 surface (it picks up the instance-level accessors installed above) and resolves no deprecated constant of its own, so it needs its own hook for the once-per-process notice.



213
214
215
216
217
218
# File 'lib/snap_diff/legacy_shims.rb', line 213

def self.install_include_notice(mod)
  mod.define_singleton_method(:included) do |base|
    Deprecation.notice
    super(base)
  end
end

.require_unit(target) ⇒ 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.



130
131
132
133
134
135
136
137
138
139
140
# File 'lib/snap_diff/legacy_shims.rb', line 130

def self.require_unit(target)
  require(REQUIRE_PATHS[target] || target
    .gsub("::", "/")
    .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
    .gsub(/([a-z\d])([A-Z])/, '\1_\2')
    .downcase)
rescue LoadError
  # No file of its own -- the name lives inside another unit
  # (SnapDiff::RED_RGBA, ::BacktraceFilter). The const_get above decides
  # whether it is already loaded.
end

.resolve(old_name, target) ⇒ 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.

Resolving an old name has to LOAD the replacement, not merely name it. The v1 entry points required the whole gem, so v1 code could say Capybara::Screenshot::Diff::Utils with nothing else required; the canonical entry points are lean, so the shim used to resolve its mapping and then die on a bare "uninitialized constant SnapDiff::Utils" -- an internal name the reader has no way to act on.



120
121
122
123
124
125
126
127
128
# File 'lib/snap_diff/legacy_shims.rb', line 120

def self.resolve(old_name, target)
  require_unit(target) unless Object.const_defined?(target)
  Object.const_get(target)
rescue NameError
  # Deliberately does NOT advise "reference #{target} directly": we just
  # failed to load it, so that name does not exist either.
  raise NameError, "`#{old_name}` maps to `#{target}`, which this process cannot load. " \
    "See docs/UPGRADING.md for the v1 -> SnapDiff name map."
end