stimulus_spec 0.6.0 → 0.8.0
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.
- checksums.yaml +4 -4
- data/.yardopts +8 -0
- data/CHANGELOG.md +20 -1
- data/README.md +7 -0
- data/ROADMAP.md +1 -25
- data/docs/cookbook.md +152 -0
- data/docs/migration_guide.md +84 -0
- data/lib/stimulus_spec/capybara/matchers/have_stimulus_action.rb +11 -0
- data/lib/stimulus_spec/capybara/matchers/have_stimulus_class.rb +15 -0
- data/lib/stimulus_spec/capybara/matchers/have_stimulus_controller.rb +13 -0
- data/lib/stimulus_spec/capybara/matchers/have_stimulus_outlet.rb +15 -0
- data/lib/stimulus_spec/capybara/matchers/have_stimulus_target.rb +13 -0
- data/lib/stimulus_spec/capybara/matchers/have_stimulus_value.rb +15 -0
- data/lib/stimulus_spec/capybara/matchers.rb +1 -0
- data/lib/stimulus_spec/configuration.rb +2 -0
- data/lib/stimulus_spec/matchers/have_stimulus_action.rb +13 -0
- data/lib/stimulus_spec/matchers/have_stimulus_class.rb +17 -0
- data/lib/stimulus_spec/matchers/have_stimulus_controller.rb +18 -0
- data/lib/stimulus_spec/matchers/have_stimulus_outlet.rb +17 -0
- data/lib/stimulus_spec/matchers/have_stimulus_target.rb +13 -0
- data/lib/stimulus_spec/matchers/have_stimulus_value.rb +17 -0
- data/lib/stimulus_spec/version.rb +1 -1
- data/lib/stimulus_spec.rb +25 -0
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6b9e26e1184c0d81c9ebcdffd070ab00c4822f76de661fc229178e2989497588
|
|
4
|
+
data.tar.gz: 91e8c98384c15baba42e7bb5022a47eb14756a236ea6f2b340cf85ecc9bb4db7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3bbf987dbddff7265d933f041e11d2e1223bfd923d855c8836721cc3b5379534b8100e099d7e3952cfba280d26feee50f07000aae6910ccf2c3c86c9cc71eac9
|
|
7
|
+
data.tar.gz: 2d9372a0337c758b3f41eee17f6b650b285bc38e109b972017b41befdc2462f9bd0a9ac1adbcf8be1da2e7615c1cdfd1c1bf9c3b0ab3e017b4156ec84a5bbc54
|
data/.yardopts
ADDED
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.8.0] - 2026-06-23
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- `bin/benchmark` script for measuring matcher overhead
|
|
15
|
+
- Version spec enforcing semver format on `StimulusSpec::VERSION`
|
|
16
|
+
- `docs/migration_guide.md` for migrating from turbo_rspec's Stimulus matchers
|
|
17
|
+
- Guiding principles section in README
|
|
18
|
+
|
|
19
|
+
## [0.7.0] - 2026-06-23
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- Full YARD documentation (`@param`, `@return`, `@example`) on all public methods and classes
|
|
24
|
+
- `docs/cookbook.md` with common patterns: request specs, system specs, multi-controller, scoped matching, typed values, outlets
|
|
25
|
+
- `.yardopts` configuration file
|
|
26
|
+
|
|
10
27
|
## [0.6.0] - 2026-06-23
|
|
11
28
|
|
|
12
29
|
### Added
|
|
@@ -53,7 +70,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
53
70
|
- `have_stimulus_action(descriptor)` matcher — full descriptor (`~=`) and shorthand without event (`*=`)
|
|
54
71
|
- `have_stimulus_target(controller, target)` matcher — asserts `[data-{controller}-target~="target"]`
|
|
55
72
|
|
|
56
|
-
[Unreleased]: https://github.com/eclectic-coding/stimulus_spec/compare/v0.
|
|
73
|
+
[Unreleased]: https://github.com/eclectic-coding/stimulus_spec/compare/v0.8.0...HEAD
|
|
74
|
+
[0.8.0]: https://github.com/eclectic-coding/stimulus_spec/releases/tag/v0.8.0
|
|
75
|
+
[0.7.0]: https://github.com/eclectic-coding/stimulus_spec/releases/tag/v0.7.0
|
|
57
76
|
[0.6.0]: https://github.com/eclectic-coding/stimulus_spec/releases/tag/v0.6.0
|
|
58
77
|
[0.5.0]: https://github.com/eclectic-coding/stimulus_spec/releases/tag/v0.5.0
|
|
59
78
|
[0.4.0]: https://github.com/eclectic-coding/stimulus_spec/releases/tag/v0.4.0
|
data/README.md
CHANGED
|
@@ -15,6 +15,13 @@ Drop-in RSpec matchers for [hotwired/stimulus-rails](https://github.com/hotwired
|
|
|
15
15
|
|
|
16
16
|
Companion gem to [turbo_rspec](https://github.com/eclectic-coding/turbo_rspec) — together they cover the full Hotwire testing stack.
|
|
17
17
|
|
|
18
|
+
## Guiding principles
|
|
19
|
+
|
|
20
|
+
- **Zero magic by default.** Auto-include only when it's unambiguous (Rails request specs with `stimulus-rails` present). Everything else is opt-in.
|
|
21
|
+
- **Fail loudly with useful output.** A cryptic failure message is a bug. Show what was expected, what was found, and the relevant HTML.
|
|
22
|
+
- **Stay close to Stimulus conventions.** Matcher names and arguments mirror Stimulus's `data-*` attribute conventions so the docs cross-reference naturally.
|
|
23
|
+
- **Pure test helper.** No Rails engine, no generators, no runtime code — just matchers you include in your specs.
|
|
24
|
+
|
|
18
25
|
## Table of Contents
|
|
19
26
|
|
|
20
27
|
- [Installation](#installation)
|
data/ROADMAP.md
CHANGED
|
@@ -1,27 +1,3 @@
|
|
|
1
1
|
# stimulus_spec Roadmap
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
## Guiding principles
|
|
6
|
-
|
|
7
|
-
- **Zero magic by default.** Auto-include only when it's unambiguous (Rails request specs with `stimulus-rails` present). Everything else is opt-in.
|
|
8
|
-
- **Fail loudly with useful output.** A cryptic failure message is a bug. Show what was expected, what was found, and the relevant HTML.
|
|
9
|
-
- **Stay close to Stimulus conventions.** Matcher names and arguments mirror Stimulus's `data-*` attribute conventions so the docs cross-reference naturally.
|
|
10
|
-
- **Pure test helper.** No Rails engine, no generators, no runtime code — just matchers you include in your specs.
|
|
11
|
-
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
## 0.7.0 — Documentation and Polish
|
|
15
|
-
|
|
16
|
-
- Full YARD documentation on all public methods and classes
|
|
17
|
-
- `docs/cookbook.md` — common patterns: request specs, system specs, multi-controller elements, typed values, outlets
|
|
18
|
-
- Graceful no-op when `stimulus-rails` is not bundled (no `LoadError`)
|
|
19
|
-
|
|
20
|
-
---
|
|
21
|
-
|
|
22
|
-
## 1.0.0 — Stable API
|
|
23
|
-
|
|
24
|
-
- API freeze — public method signatures are part of the semver contract
|
|
25
|
-
- `bin/benchmark` — matcher overhead measurement
|
|
26
|
-
- Version spec (semver format enforced)
|
|
27
|
-
- `docs/migration_guide.md` — migrating from turbo_rspec's Stimulus matchers to stimulus_spec
|
|
3
|
+
All planned milestones through 0.8.0 have been completed. Gathering user feedback before a 1.0.0 release.
|
data/docs/cookbook.md
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# StimulusSpec Cookbook
|
|
2
|
+
|
|
3
|
+
Common patterns for testing Stimulus wiring with `stimulus_spec`.
|
|
4
|
+
|
|
5
|
+
## Request specs
|
|
6
|
+
|
|
7
|
+
```ruby
|
|
8
|
+
RSpec.describe "Search", type: :request do
|
|
9
|
+
describe "GET /search" do
|
|
10
|
+
before { get search_path }
|
|
11
|
+
|
|
12
|
+
it "wires up the search controller" do
|
|
13
|
+
expect(response).to have_stimulus_controller("search")
|
|
14
|
+
expect(response).to have_stimulus_action("input->search#query")
|
|
15
|
+
expect(response).to have_stimulus_target("search", "input")
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "sets the URL value" do
|
|
19
|
+
expect(response).to have_stimulus_value("search", "url", "/results")
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## System specs
|
|
26
|
+
|
|
27
|
+
```ruby
|
|
28
|
+
RSpec.describe "Search", type: :system do
|
|
29
|
+
it "has the search controller wired up" do
|
|
30
|
+
visit search_path
|
|
31
|
+
|
|
32
|
+
expect(page).to have_stimulus_controller("search")
|
|
33
|
+
expect(page).to have_stimulus_action("input->search#query")
|
|
34
|
+
expect(page).to have_stimulus_target("search", "input")
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Multi-controller elements
|
|
40
|
+
|
|
41
|
+
When a single element declares multiple Stimulus controllers, assert them all at once:
|
|
42
|
+
|
|
43
|
+
```ruby
|
|
44
|
+
# Assert both controllers are on the same element
|
|
45
|
+
expect(response).to have_stimulus_controller("dropdown", "keyboard-nav")
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Or assert them individually:
|
|
49
|
+
|
|
50
|
+
```ruby
|
|
51
|
+
expect(response).to have_stimulus_controller("dropdown")
|
|
52
|
+
expect(response).to have_stimulus_controller("keyboard-nav")
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Scoped matching
|
|
56
|
+
|
|
57
|
+
Use `.within(selector)` to restrict matching to a specific part of the page. Useful when the same controller appears in multiple places:
|
|
58
|
+
|
|
59
|
+
```ruby
|
|
60
|
+
# Only match within the sidebar
|
|
61
|
+
expect(response).to have_stimulus_controller("nav").within(".sidebar")
|
|
62
|
+
|
|
63
|
+
# Assert a target exists within a specific form
|
|
64
|
+
expect(response).to have_stimulus_target("search", "input").within("#search-form")
|
|
65
|
+
|
|
66
|
+
# Works with all matchers
|
|
67
|
+
expect(response).to have_stimulus_action("click->tabs#select").within(".tab-bar")
|
|
68
|
+
expect(response).to have_stimulus_value("editor", "language", "ruby").within(".code-panel")
|
|
69
|
+
expect(response).to have_stimulus_class("menu", "active", "bg-blue-500").within("nav")
|
|
70
|
+
expect(response).to have_stimulus_outlet("search", "results", "#results-list").within(".search-form")
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Scoped matching works the same way with Capybara matchers in system/feature specs:
|
|
74
|
+
|
|
75
|
+
```ruby
|
|
76
|
+
expect(page).to have_stimulus_controller("nav").within(".sidebar")
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Typed values
|
|
80
|
+
|
|
81
|
+
Stimulus values are always stored as strings in the DOM. Pass the expected string representation:
|
|
82
|
+
|
|
83
|
+
```ruby
|
|
84
|
+
# Boolean value
|
|
85
|
+
expect(response).to have_stimulus_value("toggle", "open", "true")
|
|
86
|
+
|
|
87
|
+
# Numeric value
|
|
88
|
+
expect(response).to have_stimulus_value("pagination", "page", "1")
|
|
89
|
+
|
|
90
|
+
# JSON value
|
|
91
|
+
expect(response).to have_stimulus_value("chart", "data", '{"labels":["Jan","Feb"]}')
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
To assert a value attribute exists without checking its content, use the two-argument form:
|
|
95
|
+
|
|
96
|
+
```ruby
|
|
97
|
+
expect(response).to have_stimulus_value("search", "url")
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## CSS classes
|
|
101
|
+
|
|
102
|
+
Assert Stimulus CSS class attributes (`data-{controller}-{name}-class`):
|
|
103
|
+
|
|
104
|
+
```ruby
|
|
105
|
+
# Assert the class attribute exists
|
|
106
|
+
expect(response).to have_stimulus_class("search", "loading")
|
|
107
|
+
|
|
108
|
+
# Assert a specific class value
|
|
109
|
+
expect(response).to have_stimulus_class("search", "loading", "opacity-50")
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Outlets
|
|
113
|
+
|
|
114
|
+
Assert Stimulus outlet attributes (`data-{controller}-{outlet}-outlet`):
|
|
115
|
+
|
|
116
|
+
```ruby
|
|
117
|
+
# Assert the outlet attribute exists
|
|
118
|
+
expect(response).to have_stimulus_outlet("search", "results")
|
|
119
|
+
|
|
120
|
+
# Assert a specific CSS selector
|
|
121
|
+
expect(response).to have_stimulus_outlet("search", "results", "#results-list")
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Negation
|
|
125
|
+
|
|
126
|
+
All matchers support `not_to`:
|
|
127
|
+
|
|
128
|
+
```ruby
|
|
129
|
+
expect(response).not_to have_stimulus_controller("admin")
|
|
130
|
+
expect(response).not_to have_stimulus_action("click->admin#delete")
|
|
131
|
+
expect(response).not_to have_stimulus_target("admin", "panel")
|
|
132
|
+
expect(response).not_to have_stimulus_value("admin", "role")
|
|
133
|
+
expect(response).not_to have_stimulus_class("admin", "active")
|
|
134
|
+
expect(response).not_to have_stimulus_outlet("admin", "panel")
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Disabling auto-include
|
|
138
|
+
|
|
139
|
+
By default, matchers are auto-included when `stimulus-rails` is in your bundle. To disable:
|
|
140
|
+
|
|
141
|
+
```ruby
|
|
142
|
+
# spec/support/stimulus_spec.rb
|
|
143
|
+
StimulusSpec.configure do |config|
|
|
144
|
+
config.auto_include = false
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# Then include manually where needed
|
|
148
|
+
RSpec.configure do |config|
|
|
149
|
+
config.include StimulusSpec::Matchers, type: :request
|
|
150
|
+
config.include StimulusSpec::Capybara::Matchers, type: :system
|
|
151
|
+
end
|
|
152
|
+
```
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Migrating from turbo_rspec to stimulus_spec
|
|
2
|
+
|
|
3
|
+
[turbo_rspec](https://github.com/eclectic-coding/turbo_rspec) includes basic Stimulus matchers: `have_stimulus_controller`, `have_stimulus_action`, and `have_stimulus_target`. **stimulus_spec** provides the same three matchers plus `have_stimulus_value`, `have_stimulus_class`, `have_stimulus_outlet`, multi-controller assertions, and scoped matching.
|
|
4
|
+
|
|
5
|
+
Both gems can coexist — they use separate namespaces (`TurboRspec::Matchers` vs `StimulusSpec::Matchers`) and won't conflict. You can migrate incrementally.
|
|
6
|
+
|
|
7
|
+
## Step 1: Add stimulus_spec
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
# Gemfile
|
|
11
|
+
group :test do
|
|
12
|
+
gem "stimulus_spec"
|
|
13
|
+
end
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
bundle install
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
With `stimulus-rails` in your bundle, `stimulus_spec` auto-includes its matchers into request, controller, system, and feature specs. No configuration needed.
|
|
21
|
+
|
|
22
|
+
## Step 2: Verify existing tests pass
|
|
23
|
+
|
|
24
|
+
Your existing turbo_rspec Stimulus matchers (`TurboRspec::Matchers`) will continue to work alongside `StimulusSpec::Matchers`. Run your test suite to confirm nothing breaks:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
bundle exec rspec
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Step 3: Switch namespaces (optional)
|
|
31
|
+
|
|
32
|
+
If you manually include turbo_rspec's Stimulus matchers, update to the stimulus_spec equivalents:
|
|
33
|
+
|
|
34
|
+
```ruby
|
|
35
|
+
# Before
|
|
36
|
+
config.include TurboRspec::Matchers, type: :request
|
|
37
|
+
|
|
38
|
+
# After
|
|
39
|
+
config.include StimulusSpec::Matchers, type: :request
|
|
40
|
+
config.include StimulusSpec::Capybara::Matchers, type: :system
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
If you rely on auto-include (the default for both gems), this step is unnecessary — both sets of matchers are already available.
|
|
44
|
+
|
|
45
|
+
## Step 4: Use new matchers
|
|
46
|
+
|
|
47
|
+
With stimulus_spec installed, you now have access to matchers that turbo_rspec doesn't provide:
|
|
48
|
+
|
|
49
|
+
```ruby
|
|
50
|
+
# Value assertions
|
|
51
|
+
expect(response).to have_stimulus_value("search", "url", "/results")
|
|
52
|
+
|
|
53
|
+
# CSS class assertions
|
|
54
|
+
expect(response).to have_stimulus_class("search", "loading", "opacity-50")
|
|
55
|
+
|
|
56
|
+
# Outlet assertions
|
|
57
|
+
expect(response).to have_stimulus_outlet("search", "results", "#results-list")
|
|
58
|
+
|
|
59
|
+
# Multi-controller on a single element
|
|
60
|
+
expect(response).to have_stimulus_controller("hello", "clipboard")
|
|
61
|
+
|
|
62
|
+
# Scoped matching
|
|
63
|
+
expect(response).to have_stimulus_controller("search").within(".search-form")
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Matcher comparison
|
|
67
|
+
|
|
68
|
+
| Matcher | turbo_rspec | stimulus_spec |
|
|
69
|
+
|---|---|---|
|
|
70
|
+
| `have_stimulus_controller` | Single name | Single or multiple names |
|
|
71
|
+
| `have_stimulus_action` | Full or shorthand | Full or shorthand |
|
|
72
|
+
| `have_stimulus_target` | Controller + target | Controller + target |
|
|
73
|
+
| `have_stimulus_value` | — | Existence or equality |
|
|
74
|
+
| `have_stimulus_class` | — | Existence or equality |
|
|
75
|
+
| `have_stimulus_outlet` | — | Existence or selector |
|
|
76
|
+
| `.within(selector)` | — | All matchers |
|
|
77
|
+
| Capybara variants | Controller, action, target | All six matchers |
|
|
78
|
+
| Failure messages | Basic | Shows found values and HTML context |
|
|
79
|
+
|
|
80
|
+
## Step 5: Remove turbo_rspec Stimulus matchers (optional)
|
|
81
|
+
|
|
82
|
+
If you want to fully consolidate, you can stop including turbo_rspec's Stimulus matchers. turbo_rspec's Turbo-specific matchers (`have_turbo_frame`, `have_turbo_stream`, etc.) are unaffected — only the Stimulus matchers overlap.
|
|
83
|
+
|
|
84
|
+
If you use turbo_rspec solely for Turbo matchers, no changes are needed. Both gems coexist cleanly.
|
|
@@ -3,16 +3,25 @@
|
|
|
3
3
|
module StimulusSpec
|
|
4
4
|
module Capybara
|
|
5
5
|
module Matchers
|
|
6
|
+
# Capybara matcher for +data-action+ attributes.
|
|
7
|
+
#
|
|
8
|
+
# @example
|
|
9
|
+
# expect(page).to have_stimulus_action("click->hello#greet")
|
|
6
10
|
class HaveStimulusAction
|
|
11
|
+
# @param descriptor [String] action descriptor
|
|
7
12
|
def initialize(descriptor)
|
|
8
13
|
@descriptor = descriptor.to_s
|
|
9
14
|
end
|
|
10
15
|
|
|
16
|
+
# @param selector [String] CSS selector for the scope element
|
|
17
|
+
# @return [self]
|
|
11
18
|
def within(selector)
|
|
12
19
|
@scope = selector
|
|
13
20
|
self
|
|
14
21
|
end
|
|
15
22
|
|
|
23
|
+
# @param page [Capybara::Session, Capybara::Node::Simple]
|
|
24
|
+
# @return [Boolean]
|
|
16
25
|
def matches?(page)
|
|
17
26
|
@page = page
|
|
18
27
|
page.has_css?(scoped_selector, wait: 0)
|
|
@@ -46,6 +55,8 @@ module StimulusSpec
|
|
|
46
55
|
end
|
|
47
56
|
end
|
|
48
57
|
|
|
58
|
+
# @param descriptor [String] action descriptor
|
|
59
|
+
# @return [HaveStimulusAction]
|
|
49
60
|
def have_stimulus_action(descriptor)
|
|
50
61
|
HaveStimulusAction.new(descriptor)
|
|
51
62
|
end
|
|
@@ -3,7 +3,14 @@
|
|
|
3
3
|
module StimulusSpec
|
|
4
4
|
module Capybara
|
|
5
5
|
module Matchers
|
|
6
|
+
# Capybara matcher for +data-{controller}-{name}-class+ attributes.
|
|
7
|
+
#
|
|
8
|
+
# @example
|
|
9
|
+
# expect(page).to have_stimulus_class("search", "loading", "opacity-50")
|
|
6
10
|
class HaveStimulusClass
|
|
11
|
+
# @param controller [String] controller name
|
|
12
|
+
# @param name [String] class name
|
|
13
|
+
# @param expected [String, nil] expected attribute value
|
|
7
14
|
def initialize(controller, name, expected = nil)
|
|
8
15
|
@controller = controller.to_s
|
|
9
16
|
@name = name.to_s
|
|
@@ -11,11 +18,15 @@ module StimulusSpec
|
|
|
11
18
|
@attr = "data-#{@controller}-#{@name}-class"
|
|
12
19
|
end
|
|
13
20
|
|
|
21
|
+
# @param selector [String] CSS selector for the scope element
|
|
22
|
+
# @return [self]
|
|
14
23
|
def within(selector)
|
|
15
24
|
@scope = selector
|
|
16
25
|
self
|
|
17
26
|
end
|
|
18
27
|
|
|
28
|
+
# @param page [Capybara::Session, Capybara::Node::Simple]
|
|
29
|
+
# @return [Boolean]
|
|
19
30
|
def matches?(page)
|
|
20
31
|
@page = page
|
|
21
32
|
element = page.first(scoped_selector, minimum: 0, wait: 0)
|
|
@@ -61,6 +72,10 @@ module StimulusSpec
|
|
|
61
72
|
end
|
|
62
73
|
end
|
|
63
74
|
|
|
75
|
+
# @param controller [String] controller name
|
|
76
|
+
# @param name [String] class name
|
|
77
|
+
# @param expected [String, nil] expected class value
|
|
78
|
+
# @return [HaveStimulusClass]
|
|
64
79
|
def have_stimulus_class(controller, name, expected = nil)
|
|
65
80
|
HaveStimulusClass.new(controller, name, expected)
|
|
66
81
|
end
|
|
@@ -3,16 +3,27 @@
|
|
|
3
3
|
module StimulusSpec
|
|
4
4
|
module Capybara
|
|
5
5
|
module Matchers
|
|
6
|
+
# Capybara matcher for +data-controller+ attributes.
|
|
7
|
+
#
|
|
8
|
+
# @example
|
|
9
|
+
# expect(page).to have_stimulus_controller("hello")
|
|
10
|
+
# @example Multiple controllers
|
|
11
|
+
# expect(page).to have_stimulus_controller("hello", "clipboard")
|
|
6
12
|
class HaveStimulusController
|
|
13
|
+
# @param names [Array<String>] one or more controller names
|
|
7
14
|
def initialize(*names)
|
|
8
15
|
@names = names.map(&:to_s)
|
|
9
16
|
end
|
|
10
17
|
|
|
18
|
+
# @param selector [String] CSS selector for the scope element
|
|
19
|
+
# @return [self]
|
|
11
20
|
def within(selector)
|
|
12
21
|
@scope = selector
|
|
13
22
|
self
|
|
14
23
|
end
|
|
15
24
|
|
|
25
|
+
# @param page [Capybara::Session, Capybara::Node::Simple] Capybara page object
|
|
26
|
+
# @return [Boolean]
|
|
16
27
|
def matches?(page)
|
|
17
28
|
@page = page
|
|
18
29
|
page.has_css?(scoped_selector, wait: 0)
|
|
@@ -46,6 +57,8 @@ module StimulusSpec
|
|
|
46
57
|
end
|
|
47
58
|
end
|
|
48
59
|
|
|
60
|
+
# @param names [Array<String>] one or more controller names
|
|
61
|
+
# @return [HaveStimulusController]
|
|
49
62
|
def have_stimulus_controller(*names)
|
|
50
63
|
HaveStimulusController.new(*names)
|
|
51
64
|
end
|
|
@@ -3,7 +3,14 @@
|
|
|
3
3
|
module StimulusSpec
|
|
4
4
|
module Capybara
|
|
5
5
|
module Matchers
|
|
6
|
+
# Capybara matcher for +data-{controller}-{outlet}-outlet+ attributes.
|
|
7
|
+
#
|
|
8
|
+
# @example
|
|
9
|
+
# expect(page).to have_stimulus_outlet("search", "results", "#results-list")
|
|
6
10
|
class HaveStimulusOutlet
|
|
11
|
+
# @param controller [String] controller name
|
|
12
|
+
# @param outlet [String] outlet name
|
|
13
|
+
# @param selector [String, nil] expected CSS selector value
|
|
7
14
|
def initialize(controller, outlet, selector = nil)
|
|
8
15
|
@controller = controller.to_s
|
|
9
16
|
@outlet = outlet.to_s
|
|
@@ -11,11 +18,15 @@ module StimulusSpec
|
|
|
11
18
|
@attr = "data-#{@controller}-#{@outlet}-outlet"
|
|
12
19
|
end
|
|
13
20
|
|
|
21
|
+
# @param selector [String] CSS selector for the scope element
|
|
22
|
+
# @return [self]
|
|
14
23
|
def within(selector)
|
|
15
24
|
@scope = selector
|
|
16
25
|
self
|
|
17
26
|
end
|
|
18
27
|
|
|
28
|
+
# @param page [Capybara::Session, Capybara::Node::Simple]
|
|
29
|
+
# @return [Boolean]
|
|
19
30
|
def matches?(page)
|
|
20
31
|
@page = page
|
|
21
32
|
element = page.first(scoped_selector, minimum: 0, wait: 0)
|
|
@@ -61,6 +72,10 @@ module StimulusSpec
|
|
|
61
72
|
end
|
|
62
73
|
end
|
|
63
74
|
|
|
75
|
+
# @param controller [String] controller name
|
|
76
|
+
# @param outlet [String] outlet name
|
|
77
|
+
# @param selector [String, nil] expected CSS selector value
|
|
78
|
+
# @return [HaveStimulusOutlet]
|
|
64
79
|
def have_stimulus_outlet(controller, outlet, selector = nil)
|
|
65
80
|
HaveStimulusOutlet.new(controller, outlet, selector)
|
|
66
81
|
end
|
|
@@ -3,17 +3,27 @@
|
|
|
3
3
|
module StimulusSpec
|
|
4
4
|
module Capybara
|
|
5
5
|
module Matchers
|
|
6
|
+
# Capybara matcher for +data-{controller}-target+ attributes.
|
|
7
|
+
#
|
|
8
|
+
# @example
|
|
9
|
+
# expect(page).to have_stimulus_target("hello", "name")
|
|
6
10
|
class HaveStimulusTarget
|
|
11
|
+
# @param controller [String] controller name
|
|
12
|
+
# @param target [String] target name
|
|
7
13
|
def initialize(controller, target)
|
|
8
14
|
@controller = controller.to_s
|
|
9
15
|
@target = target.to_s
|
|
10
16
|
end
|
|
11
17
|
|
|
18
|
+
# @param selector [String] CSS selector for the scope element
|
|
19
|
+
# @return [self]
|
|
12
20
|
def within(selector)
|
|
13
21
|
@scope = selector
|
|
14
22
|
self
|
|
15
23
|
end
|
|
16
24
|
|
|
25
|
+
# @param page [Capybara::Session, Capybara::Node::Simple]
|
|
26
|
+
# @return [Boolean]
|
|
17
27
|
def matches?(page)
|
|
18
28
|
@page = page
|
|
19
29
|
page.has_css?(scoped_selector, wait: 0)
|
|
@@ -43,6 +53,9 @@ module StimulusSpec
|
|
|
43
53
|
end
|
|
44
54
|
end
|
|
45
55
|
|
|
56
|
+
# @param controller [String] controller name
|
|
57
|
+
# @param target [String] target name
|
|
58
|
+
# @return [HaveStimulusTarget]
|
|
46
59
|
def have_stimulus_target(controller, target)
|
|
47
60
|
HaveStimulusTarget.new(controller, target)
|
|
48
61
|
end
|
|
@@ -3,7 +3,14 @@
|
|
|
3
3
|
module StimulusSpec
|
|
4
4
|
module Capybara
|
|
5
5
|
module Matchers
|
|
6
|
+
# Capybara matcher for +data-{controller}-{name}-value+ attributes.
|
|
7
|
+
#
|
|
8
|
+
# @example
|
|
9
|
+
# expect(page).to have_stimulus_value("search", "url", "/results")
|
|
6
10
|
class HaveStimulusValue
|
|
11
|
+
# @param controller [String] controller name
|
|
12
|
+
# @param name [String] value name
|
|
13
|
+
# @param expected [String, nil] expected attribute value
|
|
7
14
|
def initialize(controller, name, expected = nil)
|
|
8
15
|
@controller = controller.to_s
|
|
9
16
|
@name = name.to_s
|
|
@@ -11,11 +18,15 @@ module StimulusSpec
|
|
|
11
18
|
@attr = "data-#{@controller}-#{@name}-value"
|
|
12
19
|
end
|
|
13
20
|
|
|
21
|
+
# @param selector [String] CSS selector for the scope element
|
|
22
|
+
# @return [self]
|
|
14
23
|
def within(selector)
|
|
15
24
|
@scope = selector
|
|
16
25
|
self
|
|
17
26
|
end
|
|
18
27
|
|
|
28
|
+
# @param page [Capybara::Session, Capybara::Node::Simple]
|
|
29
|
+
# @return [Boolean]
|
|
19
30
|
def matches?(page)
|
|
20
31
|
@page = page
|
|
21
32
|
element = page.first(scoped_selector, minimum: 0, wait: 0)
|
|
@@ -61,6 +72,10 @@ module StimulusSpec
|
|
|
61
72
|
end
|
|
62
73
|
end
|
|
63
74
|
|
|
75
|
+
# @param controller [String] controller name
|
|
76
|
+
# @param name [String] value name
|
|
77
|
+
# @param expected [String, nil] expected value
|
|
78
|
+
# @return [HaveStimulusValue]
|
|
64
79
|
def have_stimulus_value(controller, name, expected = nil)
|
|
65
80
|
HaveStimulusValue.new(controller, name, expected)
|
|
66
81
|
end
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module StimulusSpec
|
|
4
|
+
# Controls auto-include behavior for RSpec integration.
|
|
4
5
|
class Configuration
|
|
6
|
+
# @return [Boolean] whether matchers are auto-included into RSpec groups (default: +true+)
|
|
5
7
|
attr_accessor :auto_include
|
|
6
8
|
|
|
7
9
|
def initialize
|
|
@@ -2,16 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
module StimulusSpec
|
|
4
4
|
module Matchers
|
|
5
|
+
# Asserts that rendered HTML contains a +data-action+ attribute with the given descriptor.
|
|
6
|
+
#
|
|
7
|
+
# @example Full descriptor
|
|
8
|
+
# expect(response).to have_stimulus_action("click->hello#greet")
|
|
9
|
+
# @example Shorthand (any event)
|
|
10
|
+
# expect(response).to have_stimulus_action("hello#greet")
|
|
5
11
|
class HaveStimulusAction
|
|
12
|
+
# @param descriptor [String] full (+event->controller#method+) or shorthand (+controller#method+) descriptor
|
|
6
13
|
def initialize(descriptor)
|
|
7
14
|
@descriptor = descriptor.to_s
|
|
8
15
|
end
|
|
9
16
|
|
|
17
|
+
# @param selector [String] CSS selector for the scope element
|
|
18
|
+
# @return [self]
|
|
10
19
|
def within(selector)
|
|
11
20
|
@scope = selector
|
|
12
21
|
self
|
|
13
22
|
end
|
|
14
23
|
|
|
24
|
+
# @param subject [#body, String] response object or HTML string
|
|
25
|
+
# @return [Boolean]
|
|
15
26
|
def matches?(subject)
|
|
16
27
|
@body = extract_body(subject)
|
|
17
28
|
@doc = Nokogiri::HTML5.fragment(@body)
|
|
@@ -66,6 +77,8 @@ module StimulusSpec
|
|
|
66
77
|
end
|
|
67
78
|
end
|
|
68
79
|
|
|
80
|
+
# @param descriptor [String] action descriptor
|
|
81
|
+
# @return [HaveStimulusAction]
|
|
69
82
|
def have_stimulus_action(descriptor)
|
|
70
83
|
HaveStimulusAction.new(descriptor)
|
|
71
84
|
end
|
|
@@ -2,7 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
module StimulusSpec
|
|
4
4
|
module Matchers
|
|
5
|
+
# Asserts that rendered HTML contains a +data-{controller}-{name}-class+ attribute.
|
|
6
|
+
#
|
|
7
|
+
# @example Existence check
|
|
8
|
+
# expect(response).to have_stimulus_class("search", "loading")
|
|
9
|
+
# @example Equality check
|
|
10
|
+
# expect(response).to have_stimulus_class("search", "loading", "opacity-50")
|
|
5
11
|
class HaveStimulusClass
|
|
12
|
+
# @param controller [String] controller name
|
|
13
|
+
# @param name [String] class name
|
|
14
|
+
# @param expected [String, nil] expected attribute value (omit for existence check)
|
|
6
15
|
def initialize(controller, name, expected = nil)
|
|
7
16
|
@controller = controller.to_s
|
|
8
17
|
@name = name.to_s
|
|
@@ -10,11 +19,15 @@ module StimulusSpec
|
|
|
10
19
|
@attr = "data-#{@controller}-#{@name}-class"
|
|
11
20
|
end
|
|
12
21
|
|
|
22
|
+
# @param selector [String] CSS selector for the scope element
|
|
23
|
+
# @return [self]
|
|
13
24
|
def within(selector)
|
|
14
25
|
@scope = selector
|
|
15
26
|
self
|
|
16
27
|
end
|
|
17
28
|
|
|
29
|
+
# @param subject [#body, String] response object or HTML string
|
|
30
|
+
# @return [Boolean]
|
|
18
31
|
def matches?(subject)
|
|
19
32
|
@body = extract_body(subject)
|
|
20
33
|
@doc = Nokogiri::HTML5.fragment(@body)
|
|
@@ -72,6 +85,10 @@ module StimulusSpec
|
|
|
72
85
|
end
|
|
73
86
|
end
|
|
74
87
|
|
|
88
|
+
# @param controller [String] controller name
|
|
89
|
+
# @param name [String] class name
|
|
90
|
+
# @param expected [String, nil] expected class value
|
|
91
|
+
# @return [HaveStimulusClass]
|
|
75
92
|
def have_stimulus_class(controller, name, expected = nil)
|
|
76
93
|
HaveStimulusClass.new(controller, name, expected)
|
|
77
94
|
end
|
|
@@ -1,17 +1,33 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module StimulusSpec
|
|
4
|
+
# Matchers for request and controller specs (Nokogiri-based HTML parsing).
|
|
4
5
|
module Matchers
|
|
6
|
+
# Asserts that rendered HTML contains a +data-controller+ attribute with the given name(s).
|
|
7
|
+
#
|
|
8
|
+
# @example Single controller
|
|
9
|
+
# expect(response).to have_stimulus_controller("hello")
|
|
10
|
+
# @example Multiple controllers on one element
|
|
11
|
+
# expect(response).to have_stimulus_controller("hello", "clipboard")
|
|
12
|
+
# @example Scoped
|
|
13
|
+
# expect(response).to have_stimulus_controller("search").within(".search-form")
|
|
5
14
|
class HaveStimulusController
|
|
15
|
+
# @param names [Array<String>] one or more controller names to match
|
|
6
16
|
def initialize(*names)
|
|
7
17
|
@names = names.map(&:to_s)
|
|
8
18
|
end
|
|
9
19
|
|
|
20
|
+
# Restricts matching to descendants of the given CSS selector.
|
|
21
|
+
#
|
|
22
|
+
# @param selector [String] CSS selector for the scope element
|
|
23
|
+
# @return [self]
|
|
10
24
|
def within(selector)
|
|
11
25
|
@scope = selector
|
|
12
26
|
self
|
|
13
27
|
end
|
|
14
28
|
|
|
29
|
+
# @param subject [#body, String] response object or HTML string
|
|
30
|
+
# @return [Boolean]
|
|
15
31
|
def matches?(subject)
|
|
16
32
|
@body = extract_body(subject)
|
|
17
33
|
@doc = Nokogiri::HTML5.fragment(@body)
|
|
@@ -68,6 +84,8 @@ module StimulusSpec
|
|
|
68
84
|
end
|
|
69
85
|
end
|
|
70
86
|
|
|
87
|
+
# @param names [Array<String>] one or more controller names
|
|
88
|
+
# @return [HaveStimulusController]
|
|
71
89
|
def have_stimulus_controller(*names)
|
|
72
90
|
HaveStimulusController.new(*names)
|
|
73
91
|
end
|
|
@@ -2,7 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
module StimulusSpec
|
|
4
4
|
module Matchers
|
|
5
|
+
# Asserts that rendered HTML contains a +data-{controller}-{outlet}-outlet+ attribute.
|
|
6
|
+
#
|
|
7
|
+
# @example Existence check
|
|
8
|
+
# expect(response).to have_stimulus_outlet("search", "results")
|
|
9
|
+
# @example Selector check
|
|
10
|
+
# expect(response).to have_stimulus_outlet("search", "results", "#results-list")
|
|
5
11
|
class HaveStimulusOutlet
|
|
12
|
+
# @param controller [String] controller name
|
|
13
|
+
# @param outlet [String] outlet name
|
|
14
|
+
# @param selector [String, nil] expected CSS selector value (omit for existence check)
|
|
6
15
|
def initialize(controller, outlet, selector = nil)
|
|
7
16
|
@controller = controller.to_s
|
|
8
17
|
@outlet = outlet.to_s
|
|
@@ -10,11 +19,15 @@ module StimulusSpec
|
|
|
10
19
|
@attr = "data-#{@controller}-#{@outlet}-outlet"
|
|
11
20
|
end
|
|
12
21
|
|
|
22
|
+
# @param selector [String] CSS selector for the scope element
|
|
23
|
+
# @return [self]
|
|
13
24
|
def within(selector)
|
|
14
25
|
@scope = selector
|
|
15
26
|
self
|
|
16
27
|
end
|
|
17
28
|
|
|
29
|
+
# @param subject [#body, String] response object or HTML string
|
|
30
|
+
# @return [Boolean]
|
|
18
31
|
def matches?(subject)
|
|
19
32
|
@body = extract_body(subject)
|
|
20
33
|
@doc = Nokogiri::HTML5.fragment(@body)
|
|
@@ -72,6 +85,10 @@ module StimulusSpec
|
|
|
72
85
|
end
|
|
73
86
|
end
|
|
74
87
|
|
|
88
|
+
# @param controller [String] controller name
|
|
89
|
+
# @param outlet [String] outlet name
|
|
90
|
+
# @param selector [String, nil] expected CSS selector value
|
|
91
|
+
# @return [HaveStimulusOutlet]
|
|
75
92
|
def have_stimulus_outlet(controller, outlet, selector = nil)
|
|
76
93
|
HaveStimulusOutlet.new(controller, outlet, selector)
|
|
77
94
|
end
|
|
@@ -2,18 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
module StimulusSpec
|
|
4
4
|
module Matchers
|
|
5
|
+
# Asserts that rendered HTML contains a +data-{controller}-target+ attribute with the given target name.
|
|
6
|
+
#
|
|
7
|
+
# @example
|
|
8
|
+
# expect(response).to have_stimulus_target("hello", "name")
|
|
5
9
|
class HaveStimulusTarget
|
|
10
|
+
# @param controller [String] controller name
|
|
11
|
+
# @param target [String] target name
|
|
6
12
|
def initialize(controller, target)
|
|
7
13
|
@controller = controller.to_s
|
|
8
14
|
@target = target.to_s
|
|
9
15
|
@attr = "data-#{@controller}-target"
|
|
10
16
|
end
|
|
11
17
|
|
|
18
|
+
# @param selector [String] CSS selector for the scope element
|
|
19
|
+
# @return [self]
|
|
12
20
|
def within(selector)
|
|
13
21
|
@scope = selector
|
|
14
22
|
self
|
|
15
23
|
end
|
|
16
24
|
|
|
25
|
+
# @param subject [#body, String] response object or HTML string
|
|
26
|
+
# @return [Boolean]
|
|
17
27
|
def matches?(subject)
|
|
18
28
|
@body = extract_body(subject)
|
|
19
29
|
@doc = Nokogiri::HTML5.fragment(@body)
|
|
@@ -64,6 +74,9 @@ module StimulusSpec
|
|
|
64
74
|
end
|
|
65
75
|
end
|
|
66
76
|
|
|
77
|
+
# @param controller [String] controller name
|
|
78
|
+
# @param target [String] target name
|
|
79
|
+
# @return [HaveStimulusTarget]
|
|
67
80
|
def have_stimulus_target(controller, target)
|
|
68
81
|
HaveStimulusTarget.new(controller, target)
|
|
69
82
|
end
|
|
@@ -2,7 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
module StimulusSpec
|
|
4
4
|
module Matchers
|
|
5
|
+
# Asserts that rendered HTML contains a +data-{controller}-{name}-value+ attribute.
|
|
6
|
+
#
|
|
7
|
+
# @example Existence check
|
|
8
|
+
# expect(response).to have_stimulus_value("search", "url")
|
|
9
|
+
# @example Equality check
|
|
10
|
+
# expect(response).to have_stimulus_value("search", "url", "/results")
|
|
5
11
|
class HaveStimulusValue
|
|
12
|
+
# @param controller [String] controller name
|
|
13
|
+
# @param name [String] value name
|
|
14
|
+
# @param expected [String, nil] expected attribute value (omit for existence check)
|
|
6
15
|
def initialize(controller, name, expected = nil)
|
|
7
16
|
@controller = controller.to_s
|
|
8
17
|
@name = name.to_s
|
|
@@ -10,11 +19,15 @@ module StimulusSpec
|
|
|
10
19
|
@attr = "data-#{@controller}-#{@name}-value"
|
|
11
20
|
end
|
|
12
21
|
|
|
22
|
+
# @param selector [String] CSS selector for the scope element
|
|
23
|
+
# @return [self]
|
|
13
24
|
def within(selector)
|
|
14
25
|
@scope = selector
|
|
15
26
|
self
|
|
16
27
|
end
|
|
17
28
|
|
|
29
|
+
# @param subject [#body, String] response object or HTML string
|
|
30
|
+
# @return [Boolean]
|
|
18
31
|
def matches?(subject)
|
|
19
32
|
@body = extract_body(subject)
|
|
20
33
|
@doc = Nokogiri::HTML5.fragment(@body)
|
|
@@ -72,6 +85,10 @@ module StimulusSpec
|
|
|
72
85
|
end
|
|
73
86
|
end
|
|
74
87
|
|
|
88
|
+
# @param controller [String] controller name
|
|
89
|
+
# @param name [String] value name
|
|
90
|
+
# @param expected [String, nil] expected value
|
|
91
|
+
# @return [HaveStimulusValue]
|
|
75
92
|
def have_stimulus_value(controller, name, expected = nil)
|
|
76
93
|
HaveStimulusValue.new(controller, name, expected)
|
|
77
94
|
end
|
data/lib/stimulus_spec.rb
CHANGED
|
@@ -5,21 +5,46 @@ require_relative "stimulus_spec/configuration"
|
|
|
5
5
|
require_relative "stimulus_spec/matchers"
|
|
6
6
|
require_relative "stimulus_spec/capybara/matchers"
|
|
7
7
|
|
|
8
|
+
# RSpec matchers for testing Stimulus controller wiring in Rails applications.
|
|
9
|
+
#
|
|
10
|
+
# Provides matchers for asserting +data-controller+, +data-action+,
|
|
11
|
+
# +data-*-target+, +data-*-*-value+, +data-*-*-class+, and
|
|
12
|
+
# +data-*-*-outlet+ attributes in rendered HTML and Capybara pages.
|
|
13
|
+
#
|
|
14
|
+
# @example Auto-included in Rails with stimulus-rails
|
|
15
|
+
# RSpec.describe "Search", type: :request do
|
|
16
|
+
# it "wires up the controller" do
|
|
17
|
+
# get search_path
|
|
18
|
+
# expect(response).to have_stimulus_controller("search")
|
|
19
|
+
# end
|
|
20
|
+
# end
|
|
8
21
|
module StimulusSpec
|
|
9
22
|
class Error < StandardError; end
|
|
10
23
|
|
|
24
|
+
# @return [Configuration] the current configuration instance
|
|
11
25
|
def self.configuration
|
|
12
26
|
@configuration ||= Configuration.new
|
|
13
27
|
end
|
|
14
28
|
|
|
29
|
+
# Yields the configuration for modification.
|
|
30
|
+
#
|
|
31
|
+
# @yieldparam config [Configuration]
|
|
32
|
+
# @return [void]
|
|
15
33
|
def self.configure
|
|
16
34
|
yield configuration
|
|
17
35
|
end
|
|
18
36
|
|
|
37
|
+
# Replaces the current configuration with a fresh instance.
|
|
38
|
+
#
|
|
39
|
+
# @return [Configuration] the new configuration
|
|
19
40
|
def self.reset_configuration!
|
|
20
41
|
@configuration = Configuration.new
|
|
21
42
|
end
|
|
22
43
|
|
|
44
|
+
# Includes matchers into RSpec example groups when stimulus-rails is present.
|
|
45
|
+
#
|
|
46
|
+
# @param config [RSpec::Core::Configuration]
|
|
47
|
+
# @return [void]
|
|
23
48
|
def self.install_rspec_integration(config)
|
|
24
49
|
return unless Gem.loaded_specs.key?("stimulus-rails")
|
|
25
50
|
return unless configuration.auto_include
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: stimulus_spec
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.8.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Chuck Smith
|
|
@@ -36,6 +36,7 @@ files:
|
|
|
36
36
|
- ".github/FUNDING.yml"
|
|
37
37
|
- ".github/workflows/main.yml"
|
|
38
38
|
- ".github/workflows/publish.yml"
|
|
39
|
+
- ".yardopts"
|
|
39
40
|
- CHANGELOG.md
|
|
40
41
|
- CONTRIBUTING.md
|
|
41
42
|
- LICENSE.txt
|
|
@@ -43,6 +44,8 @@ files:
|
|
|
43
44
|
- ROADMAP.md
|
|
44
45
|
- Rakefile
|
|
45
46
|
- codecov.yml
|
|
47
|
+
- docs/cookbook.md
|
|
48
|
+
- docs/migration_guide.md
|
|
46
49
|
- lib/stimulus_spec.rb
|
|
47
50
|
- lib/stimulus_spec/capybara/matchers.rb
|
|
48
51
|
- lib/stimulus_spec/capybara/matchers/have_stimulus_action.rb
|