snap_diff-capybara 2.0.0.beta3 → 2.0.0.beta4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +438 -0
  3. data/README.md +330 -0
  4. data/docs/UPGRADING.md +232 -34
  5. data/docs/architecture.md +9 -7
  6. data/docs/ci-integration.md +42 -11
  7. data/docs/configuration.md +176 -10
  8. data/docs/drivers.md +48 -5
  9. data/docs/framework-setup.md +10 -3
  10. data/docs/migration-guide.md +24 -13
  11. data/docs/reporters.md +70 -1
  12. data/docs/snapdiff.md +41 -8
  13. data/docs/thread_safety.md +77 -86
  14. data/lib/capybara/screenshot/diff/annotation_service.rb +1 -3
  15. data/lib/capybara/screenshot/diff/area_calculator.rb +1 -3
  16. data/lib/capybara/screenshot/diff/browser_helpers.rb +1 -3
  17. data/lib/capybara/screenshot/diff/config_legacy.rb +15 -60
  18. data/lib/capybara/screenshot/diff/difference.rb +1 -4
  19. data/lib/capybara/screenshot/diff/drivers/chunky_png_driver.rb +3 -3
  20. data/lib/capybara/screenshot/diff/drivers/vips_driver.rb +2 -3
  21. data/lib/capybara/screenshot/diff/drivers.rb +4 -5
  22. data/lib/capybara/screenshot/diff/image_compare.rb +11 -22
  23. data/lib/capybara/screenshot/diff/image_preprocessor.rb +1 -3
  24. data/lib/capybara/screenshot/diff/os.rb +4 -11
  25. data/lib/capybara/screenshot/diff/region.rb +2 -2
  26. data/lib/capybara/screenshot/diff/reporters/default.rb +4 -17
  27. data/lib/capybara/screenshot/diff/screenshot_matcher.rb +1 -3
  28. data/lib/capybara/screenshot/diff/screenshoter.rb +1 -3
  29. data/lib/capybara/screenshot/diff/stable_screenshoter.rb +1 -3
  30. data/lib/capybara/screenshot/diff/utils.rb +1 -3
  31. data/lib/capybara/screenshot/diff/vcs.rb +1 -3
  32. data/lib/capybara/screenshot/diff/version.rb +8 -13
  33. data/lib/capybara-screenshot-diff.rb +10 -1
  34. data/lib/capybara_screenshot_diff/attempts_reporter.rb +1 -3
  35. data/lib/capybara_screenshot_diff/dsl.rb +5 -0
  36. data/lib/capybara_screenshot_diff/error_with_filtered_backtrace.rb +1 -4
  37. data/lib/capybara_screenshot_diff/reporters/html.rb +1 -3
  38. data/lib/capybara_screenshot_diff/screenshot_namer.rb +1 -3
  39. data/lib/capybara_screenshot_diff/snap.rb +1 -3
  40. data/lib/capybara_screenshot_diff/snap_manager.rb +1 -3
  41. data/lib/capybara_screenshot_diff.rb +17 -21
  42. data/lib/snap_diff/browser_helpers.rb +26 -5
  43. data/lib/snap_diff/capture/viewport.rb +2 -5
  44. data/lib/snap_diff/comparison.rb +54 -3
  45. data/lib/snap_diff/comparison_result.rb +3 -1
  46. data/lib/snap_diff/config.rb +189 -93
  47. data/lib/snap_diff/deprecation.rb +89 -28
  48. data/lib/snap_diff/driver.rb +18 -0
  49. data/lib/snap_diff/drivers/vips_driver.rb +12 -6
  50. data/lib/snap_diff/drivers.rb +94 -12
  51. data/lib/snap_diff/dsl.rb +45 -47
  52. data/lib/snap_diff/integrations/cucumber.rb +1 -1
  53. data/lib/snap_diff/integrations/minitest.rb +45 -9
  54. data/lib/snap_diff/integrations/rspec.rb +11 -0
  55. data/lib/snap_diff/legacy_shims.rb +285 -27
  56. data/lib/snap_diff/removal.rb +159 -0
  57. data/lib/snap_diff/reporters/default.rb +86 -23
  58. data/lib/snap_diff/reporters/html.rb +29 -13
  59. data/lib/snap_diff/reporting.rb +329 -3
  60. data/lib/snap_diff/screenshot_assertion.rb +28 -23
  61. data/lib/snap_diff/screenshot_matcher.rb +121 -14
  62. data/lib/snap_diff/screenshot_namer.rb +1 -19
  63. data/lib/snap_diff/screenshoter.rb +5 -7
  64. data/lib/snap_diff/snap.rb +6 -1
  65. data/lib/snap_diff/snap_manager.rb +2 -3
  66. data/lib/snap_diff/stable_screenshoter.rb +2 -2
  67. data/lib/snap_diff/static.rb +1 -1
  68. data/lib/snap_diff/utils.rb +35 -17
  69. data/lib/snap_diff/vcs.rb +40 -7
  70. data/lib/snap_diff/version.rb +1 -1
  71. data/lib/snap_diff-capybara.rb +33 -3
  72. data/lib/snap_diff.rb +27 -37
  73. metadata +12 -10
  74. data/CODE_OF_CONDUCT.md +0 -129
  75. data/Rakefile +0 -65
  76. data/capybara-screenshot-diff.gemspec +0 -29
  77. data/docs/RELEASE_PREP.md +0 -44
  78. data/docs/docker-testing.md +0 -24
  79. data/gems.rb +0 -39
@@ -1,100 +1,91 @@
1
- # Thread Safety Guide for Parallel Testing
1
+ # Parallel and Thread Safety Guide
2
+
3
+ How `snap_diff` behaves when your test suite runs tests concurrently — Rails
4
+ `parallelize`, `parallel_tests`, or CI sharding.
5
+
6
+ ## Summary
7
+
8
+ | How the suite runs | Assertions and results | HTML report |
9
+ | --- | --- | --- |
10
+ | Serial | Correct | Written, complete |
11
+ | `parallelize(with: :threads)` — also the default on JRuby | **Correct — fully supported** | Written, complete |
12
+ | `parallelize(workers: N)` — Rails' default, forks | Correct | Written, complete — merged from every worker ([how](reporters.md#parallel-test-runs)) |
13
+ | One process per worker (`parallel_tests`, RSpec, CI sharding) | Correct | Written, but only the last process to finish is in it |
14
+
15
+ Two rules make all of these safe:
16
+
17
+ 1. **Set configuration once, before tests run.** There is one `SnapDiff::Config`
18
+ per process and nothing guards it.
19
+ 2. **Give every screenshot a name no other test uses.** See
20
+ [Screenshot names must be unique](#screenshot-names-must-be-unique-across-tests)
21
+ — this one is not cosmetic.
22
+
23
+ ## What is shared, and what protects it
24
+
25
+ | State | Scope | Protection |
26
+ | --- | --- | --- |
27
+ | `SnapDiff.config` — every setting | One instance per process | None. Set it before tests start; do not mutate it during the run |
28
+ | `SnapDiff.session` — the assertion registry, the new-screenshot list, and the `ScreenshotNamer` (section, group, counter) | Per fiber (`Thread.current[]` is fiber-local) | Isolation — threads never share one |
29
+ | `SnapDiff::SnapManager.instance` and its tracked-snapshot set | Per fiber, memoized; rebuilt when the manager class or screenshot root changes | Isolation |
30
+ | `SnapDiff::Reporting.reporters` | One list per process | A mutex: `register` appends under it, `notify`/`finalize!` iterate a snapshot taken under it |
31
+ | `SnapDiff::Reporters::HTML` totals and failures | One reporter per process | Its own mutex around `record` and `finalize` |
32
+ | Deprecation "warn once" memos | Per process | A mutex. Note "once per process" means once *per fork worker* — expect N copies under forking parallelism |
33
+ | `SnapDiff::Vcs` repository-root memo | One hash per process | None. Values are idempotent (same directory, same answer), so a lost write costs one extra `git rev-parse`, but a plain Hash is not a concurrent container on JRuby or TruffleRuby |
34
+ | Screenshot files: `<name>.png`, `<name>.base.png`, `<name>.attempt_NN.png`, `<name>.diff.png`, … | On disk, shared by every thread and every process | **None — the paths derive from the screenshot name alone** |
35
+
36
+ ## Screenshot names must be unique across tests
37
+
38
+ Every artifact path is built from the screenshot name and nothing else — not the
39
+ test name, not the worker, not the thread. Two tests using the same name share
40
+ every file involved in the comparison.
41
+
42
+ Serially that is merely wasteful: the tests overwrite each other in order. In
43
+ parallel it is dangerous. When two concurrently running tests share a name, one
44
+ test's post-pass baseline archiving moves the baseline that the other just
45
+ checked out, and the second test then finds no baseline. A run of 64 concurrent
46
+ assertions sharing 8 names measured between 18 and 34 comparisons lost this way,
47
+ alongside a scatter of loud errors from the same collisions (truncated PNG reads,
48
+ `mv` failures).
49
+
50
+ Losing the baseline used to be **silent**: the screenshot was recorded as *new*
51
+ and the test passed green having compared nothing. It is now an error — "no
52
+ baseline was ever committed" (legitimate, warned about) is told apart from "the
53
+ baseline I just checked out has disappeared" (impossible in a correct run):
2
54
 
3
- This document explains how `snap_diff` behaves under Rails parallel tests with the `:thread` strategy.
4
-
5
- ## Overview
6
-
7
- `snap_diff` is thread safe for parallel test execution as long as global configuration is set before tests run. Per-thread state is isolated, and shared state is protected where it matters.
8
-
9
- ## Architecture Summary
10
-
11
- ### Per-thread Assertion Registry
12
-
13
- Each thread gets its own `AssertionRegistry` stored in thread-local storage:
14
-
15
- ```ruby
16
- def registry
17
- Thread.current[:capybara_screenshot_diff_registry] ||= AssertionRegistry.new
18
- end
19
55
  ```
20
-
21
- This prevents cross-thread leakage for assertions and screenshot naming.
22
-
23
- ### Reporters Snapshot on Notify
24
-
25
- Reporters are notified using a snapshot protected by an eagerly initialized mutex:
26
-
27
- ```ruby
28
- @reporters_mutex = Mutex.new
29
-
30
- def notify_reporters(assertions)
31
- reporters_snapshot = reporters_mutex.synchronize { reporters.dup }
32
- reporters_snapshot.each { |reporter| reporter.record(assertions) }
33
- end
34
- ```
35
-
36
- This ensures a stable list while notifying without forcing a global lock around reporter work.
37
-
38
- ### HTML Reporter Internal Lock
39
-
40
- The HTML reporter protects `@failures`, `@total`, and `@finalized` with a mutex so `record` and `finalize` can run safely:
41
-
42
- ```ruby
43
- @mutex.synchronize do
44
- return if @finalized
45
- @total += total
46
- @failures.concat(failures)
47
- end
56
+ The baseline for 'dashboard' was checked out and then disappeared before it could be compared -- nothing was verified.
48
57
  ```
49
58
 
50
- `@finalized` is set only after `write_report` succeeds, so a failed write can be retried.
51
-
52
- ### Screenshot Naming Isolation
53
-
54
- Each thread gets its own `ScreenshotNamer` via the per-thread registry, so counters, sections, and groups do not collide.
55
-
56
- ### SnapManager Per Call
57
-
58
- `SnapManager` returns a new instance for each call, avoiding shared mutable state.
59
+ Use `screenshot_section` / `screenshot_group`, or name screenshots after the test,
60
+ so no two tests can collide.
59
61
 
60
- ## Global Configuration
62
+ ## Configuration
61
63
 
62
- Configuration uses `mattr_accessor` and should be set once before tests run. Do not mutate config during parallel execution.
63
-
64
- ## Parallel Test Lifecycle
65
-
66
- - Setup: per-thread registry is created, config is read
67
- - Execution: assertions are added to the thread-local registry
68
- - Teardown: `verify` and `reset` operate on the thread-local registry, reporters are notified
69
- - Exit: reporters finalize once per process (using mutex-protected snapshot)
70
-
71
- ## Usage Examples
64
+ Configure once, in `test_helper.rb` / `spec_helper.rb`, before any test runs:
72
65
 
73
66
  ```ruby
74
- parallelize(workers: :number_of_processors, with: :threads)
75
-
76
- Capybara::Screenshot::Diff.configure do |screenshot, diff|
77
- screenshot.window_size = [1280, 1024]
78
- screenshot.save_path = "doc/screenshots"
79
- diff.tolerance = 0.001
67
+ SnapDiff.configure do |config|
68
+ config.window_size = [1280, 1024]
69
+ config.save_path = "doc/screenshots"
70
+ config.tolerance = 0.001
80
71
  end
81
72
  ```
82
73
 
83
- ## Do and Do Not
84
-
85
- Do:
86
- - Set config once in test helper
87
- - Pass per-screenshot options in the call
88
-
89
- Do not:
90
- - Change global config inside tests
91
- - Manually mutate registry internals
92
-
93
- ## File System Notes
94
-
95
- - Paths are unique per screenshot name and counter
96
- - `FileUtils.mv` is atomic on most file systems
97
- - Directory creation uses `mkpath`
74
+ Pass anything that varies per screenshot as an argument instead
75
+ (`assert_matches_screenshot("name", tolerance: 0.02)`) rather than reassigning
76
+ config mid-run: one process's config is shared by all of its threads, so a test
77
+ that mutates it changes what every concurrently running test sees.
78
+
79
+ ## Test lifecycle
80
+
81
+ - **Setup** the fiber-local session is created on first use.
82
+ - **Execution** assertions accumulate in the fiber's own registry.
83
+ - **Teardown** — `verify` and `reset` act on that fiber's registry, then hand its
84
+ assertions to the process's reporters.
85
+ - **End of suite** — reporters finalize once per process, from the framework's
86
+ end-of-suite hook (`Minitest.after_run`, RSpec `after(:suite)`, Cucumber
87
+ `AfterAll`). Forked workers are the exception: see
88
+ [Parallel test runs](reporters.md#parallel-test-runs).
98
89
 
99
90
  ## Load-time thread safety
100
91
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Forwarder (ADR-004 v2 step 6): Capybara::Screenshot::Diff::AnnotationService
4
- # now resolves lazily via snap_diff/legacy_shims' const_missing, with a
5
- # deprecation warning pointing at SnapDiff::AnnotationService.
3
+ # Legacy-name forwarder: the old constant resolves via snap_diff/legacy_shims.
6
4
  require "snap_diff/annotation_service"
7
5
  require "snap_diff/legacy_shims"
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Forwarder (ADR-004 v2 step 6): Capybara::Screenshot::Diff::AreaCalculator
4
- # now resolves lazily via snap_diff/legacy_shims' const_missing, with a
5
- # deprecation warning pointing at SnapDiff::AreaCalculator.
3
+ # Legacy-name forwarder: the old constant resolves via snap_diff/legacy_shims.
6
4
  require "snap_diff/area_calculator"
7
5
  require "snap_diff/legacy_shims"
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Forwarder (ADR-004 v2 step 6): Capybara::Screenshot::BrowserHelpers now
4
- # resolves lazily via snap_diff/legacy_shims' const_missing, with a
5
- # deprecation warning pointing at SnapDiff::BrowserHelpers.
3
+ # Legacy-name forwarder: the old constant resolves via snap_diff/legacy_shims.
6
4
  require "snap_diff/browser_helpers"
7
5
  require "snap_diff/legacy_shims"
@@ -2,66 +2,21 @@
2
2
 
3
3
  # Legacy Capybara::Screenshot / Capybara::Screenshot::Diff config surface.
4
4
  #
5
- # Since ADR-008 step 1 the storage lives in SnapDiff::Config -- the require
6
- # leaf of the config graph (see its own header) -- and since step 7b the
7
- # DERIVED values (active?, screenshot_area, default_options) live there
8
- # too. snap_diff/config.rb also generates the old accessor names as thin
9
- # delegators from SnapDiff::Config::MAPPING, so nothing but forwarders is
10
- # left here. The v1 surface (Capybara::Screenshot.window_size = ...,
11
- # Diff.configure { ... }, Diff.compare) keeps working unchanged: one
12
- # storage, two views.
5
+ # Nothing but requires is left here. The storage is SnapDiff::Config
6
+ # (ADR-008 step 1, the require leaf of the config graph); the derived values
7
+ # (active?, screenshot_area, default_options) live there too since step 7b;
8
+ # and the old accessor names, Diff.configure/.compare, SnapDiff.start and
9
+ # the AVAILABLE_DRIVERS alias are generated by snap_diff/legacy_shims -- the
10
+ # one file that holds the v1 surface as code, so that the canonical core
11
+ # needs nothing from this tree and 3.0 can delete both together. The v1
12
+ # surface (Capybara::Screenshot.window_size = ..., Diff.configure { ... },
13
+ # Diff.compare) keeps working unchanged: one storage, two views.
13
14
  #
14
15
  # Load order: requiring snap_diff/config first also eagerly evaluates the
15
- # require-time defaults (ENV["CI"] for fail_if_new, Rails.root/pwd for
16
- # root) at this same load moment, exactly when the old mattr_accessor
17
- # default blocks used to run. snap_diff/config never requires back here,
18
- # so the graph stays acyclic.
16
+ # require-time defaults (Rails.root/pwd for root) at this same load moment,
17
+ # exactly when the old mattr_accessor default blocks used to run.
18
+ # fail_if_new is the exception -- its ENV["CI"] fallback is read live, so an
19
+ # explicit setting outranks the environment whenever the variable appears.
20
+ # Neither file requires back here, so the graph stays acyclic.
19
21
  require "snap_diff/config"
20
- # AVAILABLE_DRIVERS below is evaluated at class-body eval time, so Utils
21
- # must be a real, already-loaded module before this module body runs.
22
- require "snap_diff/utils"
23
-
24
- module Capybara
25
- module Screenshot
26
- class << self
27
- def active?
28
- SnapDiff.config.active?
29
- end
30
-
31
- def screenshot_area
32
- SnapDiff.config.screenshot_area
33
- end
34
-
35
- def screenshot_area_abs
36
- SnapDiff.config.screenshot_area_abs
37
- end
38
- end
39
-
40
- # Module to track screenshot changes
41
- module Diff
42
- AVAILABLE_DRIVERS = SnapDiff::Utils.detect_available_drivers.freeze
43
-
44
- # Configure screenshot and diff settings in one block.
45
- #
46
- # Capybara::Screenshot::Diff.configure do |screenshot, diff|
47
- # screenshot.window_size = [1280, 1024]
48
- # screenshot.stability_time_limit = 1
49
- # diff.driver = :vips
50
- # diff.tolerance = 0.0005
51
- # end
52
- # The bare `yield` (rather than an explicit &block) keeps this
53
- # method's published arity byte-identical to what it always had.
54
- def self.configure
55
- SnapDiff.start { |screenshot, diff| yield screenshot, diff }
56
- end
57
-
58
- def self.compare(baseline_path, current_path, **options)
59
- SnapDiff.compare(baseline_path, current_path, **options)
60
- end
61
-
62
- def self.default_options
63
- SnapDiff.config.default_options
64
- end
65
- end
66
- end
67
- end
22
+ require "snap_diff/legacy_shims"
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Forwarder (ADR-004 v2 step 6): the comparison-result value object lives at
4
- # SnapDiff::ComparisonResult (ex-Difference); the old name now resolves
5
- # lazily via snap_diff/legacy_shims' const_missing, with a deprecation
6
- # warning.
3
+ # Legacy-name forwarder: the old constant resolves via snap_diff/legacy_shims.
7
4
  require "snap_diff/comparison_result"
8
5
  require "snap_diff/legacy_shims"
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Forwarder (ADR-004 v2 step 4): ChunkyPNGDriver lives in SnapDiff::Drivers
4
- # now; the module alias in capybara/screenshot/diff/drivers.rb makes it
5
- # reachable as Capybara::Screenshot::Diff::Drivers::ChunkyPNGDriver.
3
+ # Legacy-name forwarder: the module alias in capybara/screenshot/diff/drivers.rb
4
+ # makes ChunkyPNGDriver reachable as
5
+ # Capybara::Screenshot::Diff::Drivers::ChunkyPNGDriver.
6
6
  require "capybara/screenshot/diff/drivers"
7
7
  require "snap_diff/drivers/chunky_png_driver"
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Forwarder (ADR-004 v2 step 4): VipsDriver lives in SnapDiff::Drivers now;
4
- # the module alias in capybara/screenshot/diff/drivers.rb makes it reachable
5
- # as Capybara::Screenshot::Diff::Drivers::VipsDriver.
3
+ # Legacy-name forwarder: the module alias in capybara/screenshot/diff/drivers.rb
4
+ # makes VipsDriver reachable as Capybara::Screenshot::Diff::Drivers::VipsDriver.
6
5
  require "capybara/screenshot/diff/drivers"
7
6
  require "snap_diff/drivers/vips_driver"
@@ -1,9 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Forwarder (ADR-004 v2 step 6): Capybara::Screenshot::Diff::Drivers now
4
- # resolves lazily via snap_diff/legacy_shims' const_missing, with a
5
- # deprecation warning pointing at SnapDiff::Drivers. The forwarded module is
6
- # the same object, so Drivers.for and the Drivers::VipsDriver /
7
- # Drivers::ChunkyPNGDriver constants keep resolving through the old name.
3
+ # Legacy-name forwarder: the old constant resolves via snap_diff/legacy_shims.
4
+ # The forwarded module is the same object, so Drivers.for and the
5
+ # Drivers::VipsDriver / Drivers::ChunkyPNGDriver constants keep resolving
6
+ # through the old name.
8
7
  require "snap_diff/drivers"
9
8
  require "snap_diff/legacy_shims"
@@ -1,27 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Forwarder (ADR-004 v2 step 6): the comparison class lives at
4
- # SnapDiff::Comparison (ex-ImageCompare); the old name now resolves lazily
5
- # via snap_diff/legacy_shims' const_missing, with a deprecation warning.
6
- # snap_diff/comparison itself pulls in the ComparisonResult and Drivers
7
- # units, and the shims keep the old ::Difference / ::Drivers names
8
- # resolvable, so this path still provides everything the pre-move
9
- # image_compare.rb did. The images-holder struct lives at
10
- # SnapDiff::Comparison::Images and the driver cache at
11
- # SnapDiff::Drivers.loaded, with LOADED_DRIVERS kept as an eager same-object
12
- # alias by legacy_shims (ADR-008 step 5).
3
+ # Legacy-name forwarder for SnapDiff::Comparison (ex-ImageCompare). Requiring
4
+ # this path must keep providing everything the pre-move image_compare.rb did:
5
+ # snap_diff/comparison pulls in the ComparisonResult and Drivers units, and the
6
+ # shims keep ::Difference, ::Drivers, ::Comparison (the images struct) and
7
+ # LOADED_DRIVERS resolvable.
13
8
  require "snap_diff/comparison"
14
9
  require "snap_diff/legacy_shims"
15
10
 
16
- # Deliberately EAGER and silent (v2 step 6 exception): Comparison is a
17
- # documented user-facing struct, so adopters feature-detect it with
18
- # defined?/const_defined? -- neither of which triggers const_missing, so a
19
- # lazy shim reported it permanently absent. See snap_diff/legacy_shims.rb
20
- # for the full exception list.
21
- module Capybara
22
- module Screenshot
23
- module Diff
24
- Comparison = SnapDiff::Comparison::Images
25
- end
26
- end
27
- end
11
+ # Capybara::Screenshot::Diff::Comparison (the images-holder struct) is a
12
+ # documented user-facing name that adopters feature-detect with
13
+ # defined?/const_defined?, so it is assigned EAGERLY rather than shimmed --
14
+ # const_defined? never triggers const_missing. That assignment now lives in
15
+ # snap_diff/legacy_shims (required above), with the rest of the v1 surface,
16
+ # so `require "snap_diff"` alone provides it too.
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Forwarder (ADR-004 v2 step 6): Capybara::Screenshot::Diff::ImagePreprocessor
4
- # now resolves lazily via snap_diff/legacy_shims' const_missing, with a
5
- # deprecation warning pointing at SnapDiff::ImagePreprocessor.
3
+ # Legacy-name forwarder: the old constant resolves via snap_diff/legacy_shims.
6
4
  require "snap_diff/image_preprocessor"
7
5
  require "snap_diff/legacy_shims"
@@ -1,14 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # Legacy-name forwarder. `Capybara::Screenshot::Os` is an EAGER same-object
4
+ # alias assigned in snap_diff/legacy_shims -- the one file every entry point
5
+ # loads, canonical ones included, so a half-migrated app keeps the name.
3
6
  require "snap_diff/os"
4
-
5
- # Deliberately EAGER and silent (v2 step 6 exception): Os is an advertised
6
- # entry-point constant probed with Object.const_defined? by
7
- # support_load_probe_test.rb, and const_defined? never triggers
8
- # const_missing -- a lazy shim would break that contract. See
9
- # snap_diff/legacy_shims.rb for the full exception list.
10
- module Capybara
11
- module Screenshot
12
- Os = SnapDiff::Os
13
- end
14
- end
7
+ require "snap_diff/legacy_shims"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Forwarder (ADR-008 step 3): Region now lives at SnapDiff::Region;
4
- # snap_diff/region also defines the eager top-level `Region` alias.
3
+ # Legacy-name forwarder: snap_diff/region also defines the eager top-level
4
+ # `Region` alias.
5
5
  require "snap_diff/region"
@@ -1,21 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Forwarder (ADR-008 step 4): the default reporter lives at
4
- # SnapDiff::Reporters::Default.
3
+ # Legacy-name forwarder for SnapDiff::Reporters::Default.
4
+ # `Capybara::Screenshot::Diff::Reporters::Default` is an EAGER same-object
5
+ # alias assigned in snap_diff/legacy_shims -- the one file every entry point
6
+ # loads, canonical ones included, so a half-migrated app keeps the name.
5
7
  require "snap_diff/reporters/default"
6
8
  require "snap_diff/legacy_shims"
7
-
8
- # Deliberately EAGER and silent (v2 step 6 exception): Default is a
9
- # documented subclassing extension point, so adopters feature-detect it with
10
- # defined?/const_defined? -- neither of which triggers const_missing, so a
11
- # lazy shim reported it permanently absent. See snap_diff/legacy_shims.rb
12
- # for the full exception list.
13
- module Capybara
14
- module Screenshot
15
- module Diff
16
- module Reporters
17
- Default = SnapDiff::Reporters::Default
18
- end
19
- end
20
- end
21
- end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Forwarder (ADR-004 v2 step 6): Capybara::Screenshot::Diff::ScreenshotMatcher
4
- # now resolves lazily via snap_diff/legacy_shims' const_missing, with a
5
- # deprecation warning pointing at SnapDiff::ScreenshotMatcher.
3
+ # Legacy-name forwarder: the old constant resolves via snap_diff/legacy_shims.
6
4
  require "snap_diff/screenshot_matcher"
7
5
  require "snap_diff/legacy_shims"
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Forwarder (ADR-004 v2 step 6): Capybara::Screenshot::Screenshoter now
4
- # resolves lazily via snap_diff/legacy_shims' const_missing, with a
5
- # deprecation warning pointing at SnapDiff::Screenshoter.
3
+ # Legacy-name forwarder: the old constant resolves via snap_diff/legacy_shims.
6
4
  require "snap_diff/screenshoter"
7
5
  require "snap_diff/legacy_shims"
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Forwarder (ADR-004 v2 step 6): Capybara::Screenshot::Diff::StableScreenshoter
4
- # now resolves lazily via snap_diff/legacy_shims' const_missing, with a
5
- # deprecation warning pointing at SnapDiff::StableScreenshoter.
3
+ # Legacy-name forwarder: the old constant resolves via snap_diff/legacy_shims.
6
4
  require "snap_diff/stable_screenshoter"
7
5
  require "snap_diff/legacy_shims"
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Forwarder (ADR-004 v2 step 6): Capybara::Screenshot::Diff::Utils now
4
- # resolves lazily via snap_diff/legacy_shims' const_missing, with a
5
- # deprecation warning pointing at SnapDiff::Utils.
3
+ # Legacy-name forwarder: the old constant resolves via snap_diff/legacy_shims.
6
4
  require "snap_diff/utils"
7
5
  require "snap_diff/legacy_shims"
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Forwarder (ADR-004 v2 step 6): Capybara::Screenshot::Diff::Vcs now
4
- # resolves lazily via snap_diff/legacy_shims' const_missing, with a
5
- # deprecation warning pointing at SnapDiff::Vcs.
3
+ # Legacy-name forwarder: the old constant resolves via snap_diff/legacy_shims.
6
4
  require "snap_diff/vcs"
7
5
  require "snap_diff/legacy_shims"
@@ -1,15 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "snap_diff/version"
4
-
5
- # Deliberately EAGER and silent (v2 step 6 exception): the gemspec resolves
6
- # Capybara::Screenshot::Diff::VERSION at build time, so a lazy warning shim
7
- # would make every `gem build` warn. See snap_diff/legacy_shims.rb for the
8
- # full exception list.
9
- module Capybara
10
- module Screenshot
11
- module Diff
12
- VERSION = SnapDiff::VERSION
13
- end
14
- end
15
- end
3
+ # Capybara::Screenshot::Diff::VERSION is a documented name adopters read
4
+ # directly, so it is assigned EAGERLY rather than shimmed -- const_defined?
5
+ # never triggers const_missing. That assignment lives in
6
+ # snap_diff/legacy_shims (required below) with the rest of the v1 surface,
7
+ # because this file is no longer on any entry point's require path: the core
8
+ # reads SnapDiff::VERSION, and so does the gemspec. Assigning it here too
9
+ # would be a duplicate-constant warning, not a second safety net.
10
+ require "snap_diff/legacy_shims"
@@ -1,3 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "capybara_screenshot_diff/minitest"
3
+ # Bundler.require entry point for `gem "capybara-screenshot-diff"` -- the v1
4
+ # gem name, deleted in 3.0. The surviving name owns the logic (including the
5
+ # minitest feature detection this door needs just as much).
6
+ #
7
+ # The marker goes BEFORE that require: snap_diff-capybara claims the process
8
+ # as canonical, and a marker after it would be swallowed.
9
+ require "snap_diff/deprecation"
10
+ SnapDiff::Deprecation.legacy_entry_point!
11
+
12
+ require "snap_diff-capybara"
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Forwarder (ADR-004 v2 step 6): CapybaraScreenshotDiff::AttemptsReporter now
4
- # resolves lazily via snap_diff/legacy_shims' const_missing, with a
5
- # deprecation warning pointing at SnapDiff::AttemptsReporter.
3
+ # Legacy-name forwarder: the old constant resolves via snap_diff/legacy_shims.
6
4
  require "snap_diff/attempts_reporter"
7
5
  require "snap_diff/legacy_shims"
@@ -1,5 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # The one legacy entry point that does NOT go through the umbrella, so it
4
+ # carries its own marker.
5
+ require "snap_diff/deprecation"
6
+ SnapDiff::Deprecation.legacy_entry_point!
7
+
3
8
  require "snap_diff/dsl"
4
9
 
5
10
  # Deliberately EAGER and silent (v2 step 6 exception): DSL is an advertised
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Forwarder (ADR-004 v2 step 6): CapybaraScreenshotDiff::BacktraceFilter and
4
- # CapybaraScreenshotDiff::ErrorWithFilteredBacktrace now resolve lazily via
5
- # snap_diff/legacy_shims' const_missing, with deprecation warnings pointing
6
- # at their SnapDiff:: replacements.
3
+ # Legacy-name forwarder: the old constant resolves via snap_diff/legacy_shims.
7
4
  require "snap_diff/error_with_filtered_backtrace"
8
5
  require "snap_diff/legacy_shims"
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Forwarder (ADR-004 v2 step 6): CapybaraScreenshotDiff::Reporters::HTML now
4
- # resolves lazily via snap_diff/legacy_shims' const_missing, with a
5
- # deprecation warning pointing at SnapDiff::Reporters::HTML.
3
+ # Legacy-name forwarder: the old constant resolves via snap_diff/legacy_shims.
6
4
  require "snap_diff/reporters/html"
7
5
  require "snap_diff/legacy_shims"
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Forwarder (ADR-004 v2 step 6): CapybaraScreenshotDiff::ScreenshotNamer now
4
- # resolves lazily via snap_diff/legacy_shims' const_missing, with a
5
- # deprecation warning pointing at SnapDiff::ScreenshotNamer.
3
+ # Legacy-name forwarder: the old constant resolves via snap_diff/legacy_shims.
6
4
  require "snap_diff/screenshot_namer"
7
5
  require "snap_diff/legacy_shims"
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Forwarder (ADR-004 v2 step 6): CapybaraScreenshotDiff::Snap now resolves
4
- # lazily via snap_diff/legacy_shims' const_missing, with a deprecation
5
- # warning pointing at SnapDiff::Snap.
3
+ # Legacy-name forwarder: the old constant resolves via snap_diff/legacy_shims.
6
4
  require "snap_diff/snap"
7
5
  require "snap_diff/legacy_shims"
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Forwarder (ADR-004 v2 step 6): CapybaraScreenshotDiff::SnapManager now
4
- # resolves lazily via snap_diff/legacy_shims' const_missing, with a
5
- # deprecation warning pointing at SnapDiff::SnapManager.
3
+ # Legacy-name forwarder: the old constant resolves via snap_diff/legacy_shims.
6
4
  require "snap_diff/snap_manager"
7
5
  require "snap_diff/legacy_shims"