turbo_rspec 0.4.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 +4 -4
- data/.github/workflows/ci.yml +5 -2
- data/CHANGELOG.md +18 -0
- data/README.md +61 -0
- data/ROADMAP.md +0 -27
- data/lib/turbo_rspec/assertions.rb +55 -0
- data/lib/turbo_rspec/helpers.rb +17 -0
- data/lib/turbo_rspec/shared_examples.rb +27 -0
- data/lib/turbo_rspec/version.rb +1 -1
- data/lib/turbo_rspec.rb +6 -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: 7e6568858c6d2ba4487a184d5161e3a254368447704c86437f7f5753003af0bb
|
|
4
|
+
data.tar.gz: c3b05381ef257037eb0112e3bc925d4db1973780e16d6d56a9cd842db9f4d994
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 710e2a679f38e346a19031c81441b2ce56e0317b5b770275a1d69d1117fb7eb48af0551e1c5c6a62cd4651cdee9cc6976c32ec038472b3dd5beea2d5d978e662
|
|
7
|
+
data.tar.gz: 557f56e9807599846b81204772ec47919daf2621ef090253971f1f9f9390bc5f22a63e438a9c4715dedbb939c44c4c517654852ac41fc87392bee88b4f8ff83d
|
data/.github/workflows/ci.yml
CHANGED
|
@@ -39,12 +39,13 @@ jobs:
|
|
|
39
39
|
- run: bundle exec bundle-audit check
|
|
40
40
|
|
|
41
41
|
test:
|
|
42
|
-
name: Ruby ${{ matrix.ruby }}
|
|
42
|
+
name: Ruby ${{ matrix.ruby }} / Rails ${{ matrix.rails }}
|
|
43
43
|
runs-on: ubuntu-latest
|
|
44
44
|
strategy:
|
|
45
45
|
fail-fast: false
|
|
46
46
|
matrix:
|
|
47
47
|
ruby: ["3.3", "3.4", "4.0"]
|
|
48
|
+
rails: ["7.2", "8.0", "8.1"]
|
|
48
49
|
|
|
49
50
|
steps:
|
|
50
51
|
- uses: actions/checkout@v6
|
|
@@ -54,4 +55,6 @@ jobs:
|
|
|
54
55
|
ruby-version: ${{ matrix.ruby }}
|
|
55
56
|
bundler-cache: true
|
|
56
57
|
|
|
57
|
-
- run: bundle exec rspec
|
|
58
|
+
- run: bundle exec rspec
|
|
59
|
+
env:
|
|
60
|
+
RAILS_VERSION: ${{ matrix.rails }}
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.6.0] - 2026-05-28
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- `TurboRspec::Helpers` module with `turbo_stream_html` and `turbo_frame_html` factory helpers for building test HTML inline
|
|
8
|
+
- Shared examples: `it_behaves_like "a turbo stream response"` and `it_behaves_like "a turbo frame response"` for common assertions
|
|
9
|
+
- `have_turbo_stream`, `have_turbo_frame`, and `TurboRspec::Helpers` auto-included into `type: :controller` example groups alongside `type: :request`
|
|
10
|
+
|
|
11
|
+
## [0.5.0] - 2026-05-28
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- `TurboRspec::Assertions` — opt-in minitest companion module with `assert_turbo_stream`, `refute_turbo_stream`, `assert_turbo_frame`, `refute_turbo_frame`; no RSpec dependency required
|
|
16
|
+
- `refresh` and `morph` action support confirmed working via compatibility specs
|
|
17
|
+
- Multi-stream response body parsing confirmed — a single response body with multiple `<turbo-stream>` tags works with all matchers
|
|
18
|
+
- Graceful no-op when `turbo-rails` is not in the Gemfile — no `LoadError`
|
|
19
|
+
- CI Rails matrix: Ruby 3.3/3.4/4.0 × Rails 7.2/8.0/8.1
|
|
20
|
+
|
|
3
21
|
## [0.4.0] - 2026-05-28
|
|
4
22
|
|
|
5
23
|
### Added
|
data/README.md
CHANGED
|
@@ -201,6 +201,38 @@ expect(page).to have_turbo_stream_tag("signed_stream_name")
|
|
|
201
201
|
expect(page).not_to have_turbo_stream_tag
|
|
202
202
|
```
|
|
203
203
|
|
|
204
|
+
## Test helpers
|
|
205
|
+
|
|
206
|
+
`TurboRspec::Helpers` provides factory methods for building Turbo HTML inline in tests. Auto-included in `type: :request` and `type: :controller` example groups.
|
|
207
|
+
|
|
208
|
+
```ruby
|
|
209
|
+
# Build a <turbo-stream> element
|
|
210
|
+
turbo_stream_html(action: :append, target: "messages", content: "Hello")
|
|
211
|
+
turbo_stream_html(action: :remove, targets: ".item")
|
|
212
|
+
|
|
213
|
+
# Build a <turbo-frame> element
|
|
214
|
+
turbo_frame_html(id: "messages", content: "Hello")
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## Shared examples
|
|
218
|
+
|
|
219
|
+
```ruby
|
|
220
|
+
RSpec.describe "Messages", type: :request do
|
|
221
|
+
describe "POST /messages" do
|
|
222
|
+
before { post messages_path, params: { body: "Hello" }, as: :turbo_stream }
|
|
223
|
+
|
|
224
|
+
# Assert any turbo stream is present
|
|
225
|
+
it_behaves_like "a turbo stream response"
|
|
226
|
+
|
|
227
|
+
# Assert a specific stream
|
|
228
|
+
it_behaves_like "a turbo stream response", action: :append, target: "messages", content: "Hello"
|
|
229
|
+
|
|
230
|
+
# Assert a turbo frame
|
|
231
|
+
it_behaves_like "a turbo frame response", id: "messages"
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
```
|
|
235
|
+
|
|
204
236
|
## Example: request spec
|
|
205
237
|
|
|
206
238
|
```ruby
|
|
@@ -250,6 +282,35 @@ RSpec.describe "Messages", type: :system do
|
|
|
250
282
|
end
|
|
251
283
|
```
|
|
252
284
|
|
|
285
|
+
## Minitest support
|
|
286
|
+
|
|
287
|
+
`TurboRspec::Assertions` is an opt-in companion module with no RSpec dependency. Include it in any Minitest test class:
|
|
288
|
+
|
|
289
|
+
```ruby
|
|
290
|
+
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
|
|
291
|
+
include TurboRspec::Assertions
|
|
292
|
+
end
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### Available assertions
|
|
296
|
+
|
|
297
|
+
```ruby
|
|
298
|
+
# Stream assertions
|
|
299
|
+
assert_turbo_stream(response, action: :append, target: "messages")
|
|
300
|
+
assert_turbo_stream(response, action: :append, target: "messages", content: "Hello")
|
|
301
|
+
assert_turbo_stream(response, targets: ".items")
|
|
302
|
+
assert_turbo_stream(response, partial: "messages/_message")
|
|
303
|
+
refute_turbo_stream(response, action: :replace)
|
|
304
|
+
|
|
305
|
+
# Frame assertions
|
|
306
|
+
assert_turbo_frame(response, id: "messages")
|
|
307
|
+
assert_turbo_frame(response, id: "messages", content: "Hello")
|
|
308
|
+
refute_turbo_frame(response, id: "notifications")
|
|
309
|
+
|
|
310
|
+
# Custom failure message
|
|
311
|
+
assert_turbo_stream(response, action: :append, message: "expected append stream")
|
|
312
|
+
```
|
|
313
|
+
|
|
253
314
|
## Contributing
|
|
254
315
|
|
|
255
316
|
Bug reports and pull requests are welcome on [GitHub](https://github.com/eclectic-coding/turbo_rspec).
|
data/ROADMAP.md
CHANGED
|
@@ -4,33 +4,6 @@ RSpec matchers for [Turbo](https://github.com/hotwired/turbo-rails): Turbo Strea
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
## v0.5.0 — Compatibility and edge cases
|
|
11
|
-
|
|
12
|
-
**Goal:** harden the gem against real-world app variations.
|
|
13
|
-
|
|
14
|
-
- Rails 7.2/8.0/8.1 and Turbo 1.x/2.x compatibility matrix in CI (7.1 is EOL)
|
|
15
|
-
- Multi-stream response body parsing (a single response can contain multiple `<turbo-stream>` tags)
|
|
16
|
-
- `refresh` action support (Turbo 8 page refresh streams)
|
|
17
|
-
- `morph` action support (Turbo Morphing)
|
|
18
|
-
- Graceful no-op when `turbo-rails` is not in the Gemfile (no `LoadError`)
|
|
19
|
-
- Minitest module (`TurboRspec::Assertions`) as opt-in companion (no RSpec dependency for that module)
|
|
20
|
-
|
|
21
|
-
---
|
|
22
|
-
|
|
23
|
-
## v0.6.0 — Testing utilities
|
|
24
|
-
|
|
25
|
-
**Goal:** reduce boilerplate in real test suites and close the controller spec gap.
|
|
26
|
-
|
|
27
|
-
- `turbo_stream_html(action:, target:, content: nil)` — factory helper for building `<turbo-stream>` HTML inline in tests
|
|
28
|
-
- Shared examples: `it_behaves_like "a turbo stream response"` and `"a turbo frame response"` for common assertions
|
|
29
|
-
- Controller spec support — `have_turbo_stream` and `have_turbo_frame` working against `response` in `type: :controller`
|
|
30
|
-
- Auto-include `TurboRspec::Matchers` into `type: :controller` when `turbo-rails` is present
|
|
31
|
-
|
|
32
|
-
---
|
|
33
|
-
|
|
34
7
|
## v0.7.0 — Documentation
|
|
35
8
|
|
|
36
9
|
**Goal:** full docs before freezing the API.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "matchers/have_turbo_frame"
|
|
4
|
+
require_relative "matchers/have_turbo_stream"
|
|
5
|
+
|
|
6
|
+
module TurboRspec
|
|
7
|
+
# Minitest-compatible assertions. Include in your test class:
|
|
8
|
+
#
|
|
9
|
+
# class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
|
|
10
|
+
# include TurboRspec::Assertions
|
|
11
|
+
# end
|
|
12
|
+
#
|
|
13
|
+
# No RSpec dependency required.
|
|
14
|
+
module Assertions
|
|
15
|
+
def assert_turbo_stream(response_or_body, action: nil, target: nil, targets: nil, content: nil, partial: nil, message: nil)
|
|
16
|
+
matcher = build_stream_matcher(action: action, target: target, targets: targets, content: content, partial: partial)
|
|
17
|
+
assert matcher.matches?(response_or_body), message || matcher.failure_message
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def refute_turbo_stream(response_or_body, action: nil, target: nil, targets: nil, content: nil, partial: nil, message: nil)
|
|
21
|
+
matcher = build_stream_matcher(action: action, target: target, targets: targets, content: content, partial: partial)
|
|
22
|
+
assert matcher.does_not_match?(response_or_body), message || matcher.failure_message_when_negated
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def assert_turbo_frame(response_or_body, id: nil, content: nil, partial: nil, message: nil)
|
|
26
|
+
matcher = build_frame_matcher(id: id, content: content, partial: partial)
|
|
27
|
+
assert matcher.matches?(response_or_body), message || matcher.failure_message
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def refute_turbo_frame(response_or_body, id: nil, content: nil, partial: nil, message: nil)
|
|
31
|
+
matcher = build_frame_matcher(id: id, content: content, partial: partial)
|
|
32
|
+
assert matcher.does_not_match?(response_or_body), message || matcher.failure_message_when_negated
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def build_stream_matcher(action:, target:, targets:, content:, partial:)
|
|
38
|
+
matcher = Matchers::HaveTurboStream.new
|
|
39
|
+
matcher.with_action(action) if action
|
|
40
|
+
matcher.targeting(target) if target
|
|
41
|
+
matcher.targeting_all(targets) if targets
|
|
42
|
+
matcher.with_content(content) if content
|
|
43
|
+
matcher.rendering(partial) if partial
|
|
44
|
+
matcher
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def build_frame_matcher(id:, content:, partial:)
|
|
48
|
+
matcher = Matchers::HaveTurboFrame.new
|
|
49
|
+
matcher.with_id(id) if id
|
|
50
|
+
matcher.with_content(content) if content
|
|
51
|
+
matcher.rendering(partial) if partial
|
|
52
|
+
matcher
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module TurboRspec
|
|
4
|
+
module Helpers
|
|
5
|
+
def turbo_stream_html(action:, target: nil, targets: nil, content: nil)
|
|
6
|
+
attrs = "action=\"#{action}\""
|
|
7
|
+
attrs += " target=\"#{target}\"" if target
|
|
8
|
+
attrs += " targets=\"#{targets}\"" if targets
|
|
9
|
+
inner = content ? "<template>#{content}</template>" : "<template></template>"
|
|
10
|
+
"<turbo-stream #{attrs}>#{inner}</turbo-stream>"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def turbo_frame_html(id:, content: nil)
|
|
14
|
+
"<turbo-frame id=\"#{id}\">#{content}</turbo-frame>"
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# :nocov:
|
|
4
|
+
if defined?(RSpec)
|
|
5
|
+
# :nocov:
|
|
6
|
+
RSpec.shared_examples "a turbo stream response" do |action: nil, target: nil, targets: nil, content: nil, partial: nil|
|
|
7
|
+
it "responds with a turbo stream" do
|
|
8
|
+
matcher = have_turbo_stream
|
|
9
|
+
matcher.with_action(action) if action
|
|
10
|
+
matcher.targeting(target) if target
|
|
11
|
+
matcher.targeting_all(targets) if targets
|
|
12
|
+
matcher.with_content(content) if content
|
|
13
|
+
matcher.rendering(partial) if partial
|
|
14
|
+
expect(response).to matcher
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
RSpec.shared_examples "a turbo frame response" do |id: nil, content: nil, partial: nil|
|
|
19
|
+
it "responds with a turbo frame" do
|
|
20
|
+
matcher = have_turbo_frame
|
|
21
|
+
matcher.with_id(id) if id
|
|
22
|
+
matcher.with_content(content) if content
|
|
23
|
+
matcher.rendering(partial) if partial
|
|
24
|
+
expect(response).to matcher
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
data/lib/turbo_rspec/version.rb
CHANGED
data/lib/turbo_rspec.rb
CHANGED
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
require_relative "turbo_rspec/version"
|
|
4
4
|
require_relative "turbo_rspec/configuration"
|
|
5
5
|
require_relative "turbo_rspec/matchers"
|
|
6
|
+
require_relative "turbo_rspec/helpers"
|
|
7
|
+
require_relative "turbo_rspec/assertions"
|
|
8
|
+
require_relative "turbo_rspec/shared_examples"
|
|
6
9
|
require_relative "turbo_rspec/capybara/matchers"
|
|
7
10
|
|
|
8
11
|
module TurboRspec
|
|
@@ -24,6 +27,9 @@ module TurboRspec
|
|
|
24
27
|
def install_rspec_integration(config)
|
|
25
28
|
return unless configuration.auto_include && Gem.loaded_specs.key?("turbo-rails")
|
|
26
29
|
config.include Matchers, type: :request
|
|
30
|
+
config.include Matchers, type: :controller
|
|
31
|
+
config.include Helpers, type: :request
|
|
32
|
+
config.include Helpers, type: :controller
|
|
27
33
|
if Gem.loaded_specs.key?("capybara")
|
|
28
34
|
config.include Capybara::Matchers, type: :system
|
|
29
35
|
config.include Capybara::Matchers, type: :feature
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: turbo_rspec
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Chuck Smith
|
|
@@ -43,15 +43,18 @@ files:
|
|
|
43
43
|
- Rakefile
|
|
44
44
|
- codecov.yml
|
|
45
45
|
- lib/turbo_rspec.rb
|
|
46
|
+
- lib/turbo_rspec/assertions.rb
|
|
46
47
|
- lib/turbo_rspec/capybara/matchers.rb
|
|
47
48
|
- lib/turbo_rspec/capybara/matchers/have_turbo_frame.rb
|
|
48
49
|
- lib/turbo_rspec/capybara/matchers/have_turbo_stream_tag.rb
|
|
49
50
|
- lib/turbo_rspec/configuration.rb
|
|
51
|
+
- lib/turbo_rspec/helpers.rb
|
|
50
52
|
- lib/turbo_rspec/matchers.rb
|
|
51
53
|
- lib/turbo_rspec/matchers/have_broadcasted_turbo_stream_to.rb
|
|
52
54
|
- lib/turbo_rspec/matchers/have_turbo_frame.rb
|
|
53
55
|
- lib/turbo_rspec/matchers/have_turbo_stream.rb
|
|
54
56
|
- lib/turbo_rspec/matchers/have_turbo_streams.rb
|
|
57
|
+
- lib/turbo_rspec/shared_examples.rb
|
|
55
58
|
- lib/turbo_rspec/version.rb
|
|
56
59
|
- sig/turbo_rspec.rbs
|
|
57
60
|
homepage: https://github.com/eclectic-coding/turbo_rspec
|