stimulus_spec 0.5.0 → 0.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f9f2064cf807ad376e2e9098aa7a400986c40f2fff504d7e4f2db7450ef02154
4
- data.tar.gz: 0c221ae06953f2ce8e74663b2500ee452e30fee9acfbf08edf02a35c99ea4cb5
3
+ metadata.gz: 016bc15660c32251a12c1c9129fa88c86a3e2ac1059949535a67cdd5d64448ce
4
+ data.tar.gz: 76277d4b548369259e6ae9f28b8ad2b4d22637659f7c13a938e5cf2fd95127e5
5
5
  SHA512:
6
- metadata.gz: c06ffeb2e5a16290a59ee122a7dd40a7933a840dd1899e006755184c172a92ff472260976b0fc08f29522bd78c961d5315ab98471867785342099aef49503646
7
- data.tar.gz: a6d8f79f021f954e00c7c2aec8e5c14c972ced90b1e143324fc47b75bc8b5d6f641e9d33efdf95e348600573df5271a43586f4bdaed3145ac567ff0b24b24672
6
+ metadata.gz: 8502635e782f3c870ee6aa638e09cba1bbc054c731d1c4599e5b23a31551bd0fb5dce9fc71eaa3d2ca8d3713b2ab8ba26591749a59b9bcd51bb09d871d11a2cc
7
+ data.tar.gz: 300a7bc9351bb8d0dbcc3f70122094d03705fd876322f36187c587daa0bf44446477a57df6e2130252d3501577b1e410bd1510836e70c97729b430b7dd5a6f33
data/CHANGELOG.md CHANGED
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.6.0] - 2026-06-23
11
+
12
+ ### Added
13
+
14
+ - Multi-controller assertion: `have_stimulus_controller("hello", "clipboard")` asserts multiple controllers on a single element
15
+ - Scoped matching via `.within(selector)` on all matchers (request-spec and Capybara)
16
+
10
17
  ## [0.5.0] - 2026-06-23
11
18
 
12
19
  ### Added
@@ -46,7 +53,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
46
53
  - `have_stimulus_action(descriptor)` matcher — full descriptor (`~=`) and shorthand without event (`*=`)
47
54
  - `have_stimulus_target(controller, target)` matcher — asserts `[data-{controller}-target~="target"]`
48
55
 
49
- [Unreleased]: https://github.com/eclectic-coding/stimulus_spec/compare/v0.5.0...HEAD
56
+ [Unreleased]: https://github.com/eclectic-coding/stimulus_spec/compare/v0.6.0...HEAD
57
+ [0.6.0]: https://github.com/eclectic-coding/stimulus_spec/releases/tag/v0.6.0
50
58
  [0.5.0]: https://github.com/eclectic-coding/stimulus_spec/releases/tag/v0.5.0
51
59
  [0.4.0]: https://github.com/eclectic-coding/stimulus_spec/releases/tag/v0.4.0
52
60
  [0.3.0]: https://github.com/eclectic-coding/stimulus_spec/releases/tag/v0.3.0
data/README.md CHANGED
@@ -26,6 +26,7 @@ Companion gem to [turbo_rspec](https://github.com/eclectic-coding/turbo_rspec)
26
26
  - [have\_stimulus\_value](#have_stimulus_value)
27
27
  - [have\_stimulus\_class](#have_stimulus_class)
28
28
  - [have\_stimulus\_outlet](#have_stimulus_outlet)
29
+ - [Scoped matching with `.within`](#scoped-matching-with-within)
29
30
  - [Example](#example)
30
31
  - [Relationship to turbo\_rspec](#relationship-to-turbo_rspec)
31
32
  - [Contributing](#contributing)
@@ -84,8 +85,8 @@ Assert that rendered HTML contains a `data-controller` attribute with the given
84
85
  ```ruby
85
86
  expect(response).to have_stimulus_controller("hello")
86
87
 
87
- # Works with multiple controllers on a single element
88
- expect(response).to have_stimulus_controller("clipboard")
88
+ # Assert multiple controllers on a single element
89
+ expect(response).to have_stimulus_controller("hello", "clipboard")
89
90
 
90
91
  # Negation
91
92
  expect(response).not_to have_stimulus_controller("missing")
@@ -165,6 +166,20 @@ expect(response).to have_stimulus_outlet("search", "results", "#results-list")
165
166
  expect(response).not_to have_stimulus_outlet("search", "results")
166
167
  ```
167
168
 
169
+ ### Scoped matching with `.within`
170
+
171
+ All matchers support `.within(selector)` to restrict matching to a specific part of the page:
172
+
173
+ ```ruby
174
+ # Request/controller specs — search within a CSS selector
175
+ expect(response).to have_stimulus_controller("search").within(".search-form")
176
+ expect(response).to have_stimulus_action("click->search#query").within(".search-form")
177
+ expect(response).to have_stimulus_target("search", "input").within(".search-form")
178
+
179
+ # System/feature specs — same API
180
+ expect(page).to have_stimulus_controller("search").within(".search-form")
181
+ ```
182
+
168
183
  [Back to top](#stimulusspec)
169
184
 
170
185
  ## Example
data/ROADMAP.md CHANGED
@@ -11,13 +11,6 @@ RSpec matchers for [Stimulus](https://github.com/hotwired/stimulus-rails): contr
11
11
 
12
12
  ---
13
13
 
14
- ## 0.6.0 — Multi-Controller and Scoped Matching
15
-
16
- - `have_stimulus_controller("hello", "clipboard")` — assert multiple controllers on a single element
17
- - Scoped matching — assert Stimulus attributes within a specific CSS selector (e.g., within a form or component root)
18
-
19
- ---
20
-
21
14
  ## 0.7.0 — Documentation and Polish
22
15
 
23
16
  - Full YARD documentation on all public methods and classes
@@ -8,13 +8,18 @@ module StimulusSpec
8
8
  @descriptor = descriptor.to_s
9
9
  end
10
10
 
11
+ def within(selector)
12
+ @scope = selector
13
+ self
14
+ end
15
+
11
16
  def matches?(page)
12
17
  @page = page
13
- page.has_css?(css_selector, wait: 0)
18
+ page.has_css?(scoped_selector, wait: 0)
14
19
  end
15
20
 
16
21
  def does_not_match?(page)
17
- page.has_no_css?(css_selector, wait: 0)
22
+ page.has_no_css?(scoped_selector, wait: 0)
18
23
  end
19
24
 
20
25
  def failure_message
@@ -31,12 +36,13 @@ module StimulusSpec
31
36
 
32
37
  private
33
38
 
34
- def css_selector
35
- if @descriptor.include?("->")
36
- "[data-action~='#{@descriptor}']"
37
- else
38
- "[data-action*='#{@descriptor}']"
39
- end
39
+ def scoped_selector
40
+ base = if @descriptor.include?("->")
41
+ "[data-action~='#{@descriptor}']"
42
+ else
43
+ "[data-action*='#{@descriptor}']"
44
+ end
45
+ @scope ? "#{@scope} #{base}" : base
40
46
  end
41
47
  end
42
48
 
@@ -11,9 +11,14 @@ module StimulusSpec
11
11
  @attr = "data-#{@controller}-#{@name}-class"
12
12
  end
13
13
 
14
+ def within(selector)
15
+ @scope = selector
16
+ self
17
+ end
18
+
14
19
  def matches?(page)
15
20
  @page = page
16
- element = page.first("[#{@attr}]", minimum: 0, wait: 0)
21
+ element = page.first(scoped_selector, minimum: 0, wait: 0)
17
22
  return false unless element
18
23
 
19
24
  if @expected
@@ -47,6 +52,13 @@ module StimulusSpec
47
52
  "have Stimulus class \"#{@name}\" for controller \"#{@controller}\""
48
53
  end
49
54
  end
55
+
56
+ private
57
+
58
+ def scoped_selector
59
+ base = "[#{@attr}]"
60
+ @scope ? "#{@scope} #{base}" : base
61
+ end
50
62
  end
51
63
 
52
64
  def have_stimulus_class(controller, name, expected = nil)
@@ -4,34 +4,50 @@ module StimulusSpec
4
4
  module Capybara
5
5
  module Matchers
6
6
  class HaveStimulusController
7
- def initialize(name)
8
- @name = name.to_s
7
+ def initialize(*names)
8
+ @names = names.map(&:to_s)
9
+ end
10
+
11
+ def within(selector)
12
+ @scope = selector
13
+ self
9
14
  end
10
15
 
11
16
  def matches?(page)
12
17
  @page = page
13
- page.has_css?("[data-controller~='#{@name}']", wait: 0)
18
+ page.has_css?(scoped_selector, wait: 0)
14
19
  end
15
20
 
16
21
  def does_not_match?(page)
17
- page.has_no_css?("[data-controller~='#{@name}']", wait: 0)
22
+ page.has_no_css?(scoped_selector, wait: 0)
18
23
  end
19
24
 
20
25
  def failure_message
21
- "expected to find an element with data-controller=\"#{@name}\" on the page"
26
+ "expected to find an element with data-controller=#{label} on the page"
22
27
  end
23
28
 
24
29
  def failure_message_when_negated
25
- "expected not to find an element with data-controller=\"#{@name}\" on the page"
30
+ "expected not to find an element with data-controller=#{label} on the page"
26
31
  end
27
32
 
28
33
  def description
29
- "have Stimulus controller \"#{@name}\""
34
+ "have Stimulus controller #{label}"
35
+ end
36
+
37
+ private
38
+
39
+ def label
40
+ @names.map { |n| "\"#{n}\"" }.join(", ")
41
+ end
42
+
43
+ def scoped_selector
44
+ selector = @names.map { |n| "[data-controller~='#{n}']" }.join
45
+ @scope ? "#{@scope} #{selector}" : selector
30
46
  end
31
47
  end
32
48
 
33
- def have_stimulus_controller(name)
34
- HaveStimulusController.new(name)
49
+ def have_stimulus_controller(*names)
50
+ HaveStimulusController.new(*names)
35
51
  end
36
52
  end
37
53
  end
@@ -11,9 +11,14 @@ module StimulusSpec
11
11
  @attr = "data-#{@controller}-#{@outlet}-outlet"
12
12
  end
13
13
 
14
+ def within(selector)
15
+ @scope = selector
16
+ self
17
+ end
18
+
14
19
  def matches?(page)
15
20
  @page = page
16
- element = page.first("[#{@attr}]", minimum: 0, wait: 0)
21
+ element = page.first(scoped_selector, minimum: 0, wait: 0)
17
22
  return false unless element
18
23
 
19
24
  if @selector
@@ -47,6 +52,13 @@ module StimulusSpec
47
52
  "have Stimulus outlet \"#{@outlet}\" for controller \"#{@controller}\""
48
53
  end
49
54
  end
55
+
56
+ private
57
+
58
+ def scoped_selector
59
+ base = "[#{@attr}]"
60
+ @scope ? "#{@scope} #{base}" : base
61
+ end
50
62
  end
51
63
 
52
64
  def have_stimulus_outlet(controller, outlet, selector = nil)
@@ -9,13 +9,18 @@ module StimulusSpec
9
9
  @target = target.to_s
10
10
  end
11
11
 
12
+ def within(selector)
13
+ @scope = selector
14
+ self
15
+ end
16
+
12
17
  def matches?(page)
13
18
  @page = page
14
- page.has_css?("[data-#{@controller}-target~='#{@target}']", wait: 0)
19
+ page.has_css?(scoped_selector, wait: 0)
15
20
  end
16
21
 
17
22
  def does_not_match?(page)
18
- page.has_no_css?("[data-#{@controller}-target~='#{@target}']", wait: 0)
23
+ page.has_no_css?(scoped_selector, wait: 0)
19
24
  end
20
25
 
21
26
  def failure_message
@@ -29,6 +34,13 @@ module StimulusSpec
29
34
  def description
30
35
  "have Stimulus target \"#{@target}\" for controller \"#{@controller}\""
31
36
  end
37
+
38
+ private
39
+
40
+ def scoped_selector
41
+ base = "[data-#{@controller}-target~='#{@target}']"
42
+ @scope ? "#{@scope} #{base}" : base
43
+ end
32
44
  end
33
45
 
34
46
  def have_stimulus_target(controller, target)
@@ -11,9 +11,14 @@ module StimulusSpec
11
11
  @attr = "data-#{@controller}-#{@name}-value"
12
12
  end
13
13
 
14
+ def within(selector)
15
+ @scope = selector
16
+ self
17
+ end
18
+
14
19
  def matches?(page)
15
20
  @page = page
16
- element = page.first("[#{@attr}]", minimum: 0, wait: 0)
21
+ element = page.first(scoped_selector, minimum: 0, wait: 0)
17
22
  return false unless element
18
23
 
19
24
  if @expected
@@ -47,6 +52,13 @@ module StimulusSpec
47
52
  "have Stimulus value \"#{@name}\" for controller \"#{@controller}\""
48
53
  end
49
54
  end
55
+
56
+ private
57
+
58
+ def scoped_selector
59
+ base = "[#{@attr}]"
60
+ @scope ? "#{@scope} #{base}" : base
61
+ end
50
62
  end
51
63
 
52
64
  def have_stimulus_value(controller, name, expected = nil)
@@ -7,13 +7,21 @@ module StimulusSpec
7
7
  @descriptor = descriptor.to_s
8
8
  end
9
9
 
10
+ def within(selector)
11
+ @scope = selector
12
+ self
13
+ end
14
+
10
15
  def matches?(subject)
11
16
  @body = extract_body(subject)
12
17
  @doc = Nokogiri::HTML5.fragment(@body)
18
+ root = search_root
19
+ return false unless root
20
+
13
21
  if @descriptor.include?("->")
14
- !@doc.at_css("[data-action~='#{@descriptor}']").nil?
22
+ !root.at_css("[data-action~='#{@descriptor}']").nil?
15
23
  else
16
- !@doc.at_css("[data-action*='#{@descriptor}']").nil?
24
+ !root.at_css("[data-action*='#{@descriptor}']").nil?
17
25
  end
18
26
  end
19
27
 
@@ -43,8 +51,15 @@ module StimulusSpec
43
51
  subject.respond_to?(:body) ? subject.body : subject.to_s
44
52
  end
45
53
 
54
+ def search_root
55
+ return @doc unless @scope
56
+
57
+ @doc.at_css(@scope)
58
+ end
59
+
46
60
  def snippet
47
- elements = @doc.css("[data-action]")
61
+ root = search_root || @doc
62
+ elements = root.css("[data-action]")
48
63
  return @body if elements.empty?
49
64
 
50
65
  elements.map(&:to_html).join("\n")
@@ -10,18 +10,21 @@ module StimulusSpec
10
10
  @attr = "data-#{@controller}-#{@name}-class"
11
11
  end
12
12
 
13
+ def within(selector)
14
+ @scope = selector
15
+ self
16
+ end
17
+
13
18
  def matches?(subject)
14
19
  @body = extract_body(subject)
15
20
  @doc = Nokogiri::HTML5.fragment(@body)
16
- @element = @doc.at_css("[#{@attr}]")
21
+ @element = search_root&.at_css("[#{@attr}]")
17
22
  return false unless @element
18
23
 
19
- if @expected
20
- @actual = @element[@attr]
21
- @actual == @expected.to_s
22
- else
23
- true
24
- end
24
+ return true unless @expected
25
+
26
+ @actual = @element[@attr]
27
+ @actual == @expected.to_s
25
28
  end
26
29
 
27
30
  def does_not_match?(subject)
@@ -54,8 +57,15 @@ module StimulusSpec
54
57
  subject.respond_to?(:body) ? subject.body : subject.to_s
55
58
  end
56
59
 
60
+ def search_root
61
+ return @doc unless @scope
62
+
63
+ @doc.at_css(@scope)
64
+ end
65
+
57
66
  def snippet
58
- elements = @doc.css("[data-controller]")
67
+ root = search_root || @doc
68
+ elements = root.css("[data-controller]")
59
69
  return @body if elements.empty?
60
70
 
61
71
  elements.map(&:to_html).join("\n")
@@ -3,15 +3,24 @@
3
3
  module StimulusSpec
4
4
  module Matchers
5
5
  class HaveStimulusController
6
- def initialize(name)
7
- @name = name.to_s
6
+ def initialize(*names)
7
+ @names = names.map(&:to_s)
8
+ end
9
+
10
+ def within(selector)
11
+ @scope = selector
12
+ self
8
13
  end
9
14
 
10
15
  def matches?(subject)
11
16
  @body = extract_body(subject)
12
17
  @doc = Nokogiri::HTML5.fragment(@body)
13
- @found_controllers = @doc.css("[data-controller]").flat_map { |el| el["data-controller"].split }
14
- !@doc.at_css("[data-controller~='#{@name}']").nil?
18
+ root = search_root
19
+ return false unless root
20
+
21
+ @found_controllers = root.css("[data-controller]").flat_map { |el| el["data-controller"].split }
22
+ selector = @names.map { |n| "[data-controller~='#{n}']" }.join
23
+ !root.at_css(selector).nil?
15
24
  end
16
25
 
17
26
  def does_not_match?(subject)
@@ -19,8 +28,9 @@ module StimulusSpec
19
28
  end
20
29
 
21
30
  def failure_message
22
- msg = "expected to find an element with data-controller=\"#{@name}\""
23
- if @found_controllers.any?
31
+ label = @names.map { |n| "\"#{n}\"" }.join(", ")
32
+ msg = "expected to find an element with data-controller=#{label}"
33
+ if @found_controllers&.any?
24
34
  msg += "\n found controllers: #{@found_controllers.uniq.map { |c| "\"#{c}\"" }.join(", ")}"
25
35
  end
26
36
  msg += "\n in:\n#{snippet}"
@@ -28,11 +38,13 @@ module StimulusSpec
28
38
  end
29
39
 
30
40
  def failure_message_when_negated
31
- "expected not to find an element with data-controller=\"#{@name}\" but found one"
41
+ label = @names.map { |n| "\"#{n}\"" }.join(", ")
42
+ "expected not to find an element with data-controller=#{label} but found one"
32
43
  end
33
44
 
34
45
  def description
35
- "have Stimulus controller \"#{@name}\""
46
+ label = @names.map { |n| "\"#{n}\"" }.join(", ")
47
+ "have Stimulus controller #{label}"
36
48
  end
37
49
 
38
50
  private
@@ -41,16 +53,23 @@ module StimulusSpec
41
53
  subject.respond_to?(:body) ? subject.body : subject.to_s
42
54
  end
43
55
 
56
+ def search_root
57
+ return @doc unless @scope
58
+
59
+ @doc.at_css(@scope)
60
+ end
61
+
44
62
  def snippet
45
- elements = @doc.css("[data-controller]")
63
+ root = search_root || @doc
64
+ elements = root.css("[data-controller]")
46
65
  return @body if elements.empty?
47
66
 
48
67
  elements.map(&:to_html).join("\n")
49
68
  end
50
69
  end
51
70
 
52
- def have_stimulus_controller(name)
53
- HaveStimulusController.new(name)
71
+ def have_stimulus_controller(*names)
72
+ HaveStimulusController.new(*names)
54
73
  end
55
74
  end
56
75
  end
@@ -10,18 +10,21 @@ module StimulusSpec
10
10
  @attr = "data-#{@controller}-#{@outlet}-outlet"
11
11
  end
12
12
 
13
+ def within(selector)
14
+ @scope = selector
15
+ self
16
+ end
17
+
13
18
  def matches?(subject)
14
19
  @body = extract_body(subject)
15
20
  @doc = Nokogiri::HTML5.fragment(@body)
16
- @element = @doc.at_css("[#{@attr}]")
21
+ @element = search_root&.at_css("[#{@attr}]")
17
22
  return false unless @element
18
23
 
19
- if @selector
20
- @actual = @element[@attr]
21
- @actual == @selector.to_s
22
- else
23
- true
24
- end
24
+ return true unless @selector
25
+
26
+ @actual = @element[@attr]
27
+ @actual == @selector.to_s
25
28
  end
26
29
 
27
30
  def does_not_match?(subject)
@@ -54,8 +57,15 @@ module StimulusSpec
54
57
  subject.respond_to?(:body) ? subject.body : subject.to_s
55
58
  end
56
59
 
60
+ def search_root
61
+ return @doc unless @scope
62
+
63
+ @doc.at_css(@scope)
64
+ end
65
+
57
66
  def snippet
58
- elements = @doc.css("[data-controller]")
67
+ root = search_root || @doc
68
+ elements = root.css("[data-controller]")
59
69
  return @body if elements.empty?
60
70
 
61
71
  elements.map(&:to_html).join("\n")
@@ -9,10 +9,18 @@ module StimulusSpec
9
9
  @attr = "data-#{@controller}-target"
10
10
  end
11
11
 
12
+ def within(selector)
13
+ @scope = selector
14
+ self
15
+ end
16
+
12
17
  def matches?(subject)
13
18
  @body = extract_body(subject)
14
19
  @doc = Nokogiri::HTML5.fragment(@body)
15
- !@doc.at_css("[#{@attr}~='#{@target}']").nil?
20
+ root = search_root
21
+ return false unless root
22
+
23
+ !root.at_css("[#{@attr}~='#{@target}']").nil?
16
24
  end
17
25
 
18
26
  def does_not_match?(subject)
@@ -41,8 +49,15 @@ module StimulusSpec
41
49
  subject.respond_to?(:body) ? subject.body : subject.to_s
42
50
  end
43
51
 
52
+ def search_root
53
+ return @doc unless @scope
54
+
55
+ @doc.at_css(@scope)
56
+ end
57
+
44
58
  def snippet
45
- elements = @doc.css("[#{@attr}]")
59
+ root = search_root || @doc
60
+ elements = root.css("[#{@attr}]")
46
61
  return @body if elements.empty?
47
62
 
48
63
  elements.map(&:to_html).join("\n")
@@ -10,18 +10,21 @@ module StimulusSpec
10
10
  @attr = "data-#{@controller}-#{@name}-value"
11
11
  end
12
12
 
13
+ def within(selector)
14
+ @scope = selector
15
+ self
16
+ end
17
+
13
18
  def matches?(subject)
14
19
  @body = extract_body(subject)
15
20
  @doc = Nokogiri::HTML5.fragment(@body)
16
- @element = @doc.at_css("[#{@attr}]")
21
+ @element = search_root&.at_css("[#{@attr}]")
17
22
  return false unless @element
18
23
 
19
- if @expected
20
- @actual = @element[@attr]
21
- @actual == @expected.to_s
22
- else
23
- true
24
- end
24
+ return true unless @expected
25
+
26
+ @actual = @element[@attr]
27
+ @actual == @expected.to_s
25
28
  end
26
29
 
27
30
  def does_not_match?(subject)
@@ -54,8 +57,15 @@ module StimulusSpec
54
57
  subject.respond_to?(:body) ? subject.body : subject.to_s
55
58
  end
56
59
 
60
+ def search_root
61
+ return @doc unless @scope
62
+
63
+ @doc.at_css(@scope)
64
+ end
65
+
57
66
  def snippet
58
- elements = @doc.css("[data-controller]")
67
+ root = search_root || @doc
68
+ elements = root.css("[data-controller]")
59
69
  return @body if elements.empty?
60
70
 
61
71
  elements.map(&:to_html).join("\n")
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module StimulusSpec
4
- VERSION = "0.5.0"
4
+ VERSION = "0.6.0"
5
5
  end
@@ -13,7 +13,7 @@ module StimulusSpec
13
13
  end
14
14
 
15
15
  module Matchers
16
- def have_stimulus_controller: (String name) -> HaveStimulusController
16
+ def have_stimulus_controller: (*String names) -> HaveStimulusController
17
17
  def have_stimulus_action: (String descriptor) -> HaveStimulusAction
18
18
  def have_stimulus_target: (String controller, String target) -> HaveStimulusTarget
19
19
  def have_stimulus_value: (String controller, String name, ?String? expected) -> HaveStimulusValue
@@ -21,7 +21,8 @@ module StimulusSpec
21
21
  def have_stimulus_outlet: (String controller, String outlet, ?String? selector) -> HaveStimulusOutlet
22
22
 
23
23
  class HaveStimulusController
24
- def initialize: (String name) -> void
24
+ def initialize: (*String names) -> void
25
+ def within: (String selector) -> self
25
26
  def matches?: (untyped subject) -> bool
26
27
  def does_not_match?: (untyped subject) -> bool
27
28
  def failure_message: () -> String
@@ -31,6 +32,7 @@ module StimulusSpec
31
32
 
32
33
  class HaveStimulusAction
33
34
  def initialize: (String descriptor) -> void
35
+ def within: (String selector) -> self
34
36
  def matches?: (untyped subject) -> bool
35
37
  def does_not_match?: (untyped subject) -> bool
36
38
  def failure_message: () -> String
@@ -40,6 +42,7 @@ module StimulusSpec
40
42
 
41
43
  class HaveStimulusTarget
42
44
  def initialize: (String controller, String target) -> void
45
+ def within: (String selector) -> self
43
46
  def matches?: (untyped subject) -> bool
44
47
  def does_not_match?: (untyped subject) -> bool
45
48
  def failure_message: () -> String
@@ -49,6 +52,7 @@ module StimulusSpec
49
52
 
50
53
  class HaveStimulusValue
51
54
  def initialize: (String controller, String name, ?String? expected) -> void
55
+ def within: (String selector) -> self
52
56
  def matches?: (untyped subject) -> bool
53
57
  def does_not_match?: (untyped subject) -> bool
54
58
  def failure_message: () -> String
@@ -58,6 +62,7 @@ module StimulusSpec
58
62
 
59
63
  class HaveStimulusClass
60
64
  def initialize: (String controller, String name, ?String? expected) -> void
65
+ def within: (String selector) -> self
61
66
  def matches?: (untyped subject) -> bool
62
67
  def does_not_match?: (untyped subject) -> bool
63
68
  def failure_message: () -> String
@@ -67,6 +72,7 @@ module StimulusSpec
67
72
 
68
73
  class HaveStimulusOutlet
69
74
  def initialize: (String controller, String outlet, ?String? selector) -> void
75
+ def within: (String selector) -> self
70
76
  def matches?: (untyped subject) -> bool
71
77
  def does_not_match?: (untyped subject) -> bool
72
78
  def failure_message: () -> String
@@ -77,7 +83,7 @@ module StimulusSpec
77
83
 
78
84
  module Capybara
79
85
  module Matchers
80
- def have_stimulus_controller: (String name) -> HaveStimulusController
86
+ def have_stimulus_controller: (*String names) -> HaveStimulusController
81
87
  def have_stimulus_action: (String descriptor) -> HaveStimulusAction
82
88
  def have_stimulus_target: (String controller, String target) -> HaveStimulusTarget
83
89
  def have_stimulus_value: (String controller, String name, ?String? expected) -> HaveStimulusValue
@@ -85,7 +91,8 @@ module StimulusSpec
85
91
  def have_stimulus_outlet: (String controller, String outlet, ?String? selector) -> HaveStimulusOutlet
86
92
 
87
93
  class HaveStimulusController
88
- def initialize: (String name) -> void
94
+ def initialize: (*String names) -> void
95
+ def within: (String selector) -> self
89
96
  def matches?: (untyped page) -> bool
90
97
  def does_not_match?: (untyped page) -> bool
91
98
  def failure_message: () -> String
@@ -95,6 +102,7 @@ module StimulusSpec
95
102
 
96
103
  class HaveStimulusAction
97
104
  def initialize: (String descriptor) -> void
105
+ def within: (String selector) -> self
98
106
  def matches?: (untyped page) -> bool
99
107
  def does_not_match?: (untyped page) -> bool
100
108
  def failure_message: () -> String
@@ -104,6 +112,7 @@ module StimulusSpec
104
112
 
105
113
  class HaveStimulusTarget
106
114
  def initialize: (String controller, String target) -> void
115
+ def within: (String selector) -> self
107
116
  def matches?: (untyped page) -> bool
108
117
  def does_not_match?: (untyped page) -> bool
109
118
  def failure_message: () -> String
@@ -113,6 +122,7 @@ module StimulusSpec
113
122
 
114
123
  class HaveStimulusValue
115
124
  def initialize: (String controller, String name, ?String? expected) -> void
125
+ def within: (String selector) -> self
116
126
  def matches?: (untyped page) -> bool
117
127
  def does_not_match?: (untyped page) -> bool
118
128
  def failure_message: () -> String
@@ -122,6 +132,7 @@ module StimulusSpec
122
132
 
123
133
  class HaveStimulusClass
124
134
  def initialize: (String controller, String name, ?String? expected) -> void
135
+ def within: (String selector) -> self
125
136
  def matches?: (untyped page) -> bool
126
137
  def does_not_match?: (untyped page) -> bool
127
138
  def failure_message: () -> String
@@ -131,6 +142,7 @@ module StimulusSpec
131
142
 
132
143
  class HaveStimulusOutlet
133
144
  def initialize: (String controller, String outlet, ?String? selector) -> void
145
+ def within: (String selector) -> self
134
146
  def matches?: (untyped page) -> bool
135
147
  def does_not_match?: (untyped page) -> bool
136
148
  def failure_message: () -> String
@@ -139,4 +151,4 @@ module StimulusSpec
139
151
  end
140
152
  end
141
153
  end
142
- end
154
+ end
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.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chuck Smith