render_turbo_stream 0.1.41 → 0.1.42
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/README.md +43 -34
- data/lib/render_turbo_stream/test/request_helpers.rb +52 -0
- data/lib/render_turbo_stream/version.rb +1 -1
- data/lib/render_turbo_stream.rb +66 -1
- metadata +2 -2
- data/lib/render_turbo_stream/request_test_helpers.rb +0 -107
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 262075083599385cfe9bf300a909ae3dd0feee5f7ba32691a3024260307301c5
|
4
|
+
data.tar.gz: 71629066a9d7dfd6a2fab896e63011d23a8b735539cda0afb21eec2a4807d571
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ae1caa61d33da5504bc562eabd139d1c0566b4ac7a23989603e4225464b7e41a6e423e67e2141255f0488698ca08ac65533cf1e87013a734362b0404f48e0705
|
7
|
+
data.tar.gz: e95004ea0010b2c4ee433208b36250ad47fd4dd48646f962bfa4a0cd966deb5421fc95dbb82d6ff8759ed09b5da14dab3808976895bf64270203f6902755a29e
|
data/README.md
CHANGED
@@ -58,19 +58,15 @@ look like this:
|
|
58
58
|
|
59
59
|
```ruby
|
60
60
|
|
61
|
-
def
|
62
|
-
@customer = Customer.new(customer_params)
|
63
|
-
|
61
|
+
def update
|
64
62
|
turbo_stream_save(
|
65
|
-
@customer.
|
63
|
+
@customer.update(customer_params),
|
66
64
|
redirect_on_success_to: edit_customer_path(@customer)
|
67
65
|
)
|
68
|
-
|
69
66
|
end
|
70
67
|
```
|
71
68
|
|
72
|
-
This will set a status, generate a flash message and perform `stream_partials`, which could result in something like
|
73
|
-
this:
|
69
|
+
This will set a status, generate a flash message and perform `stream_partials`, which could result in something like this:
|
74
70
|
|
75
71
|
```ruby
|
76
72
|
stream_partials(
|
@@ -101,7 +97,7 @@ stream_partial(
|
|
101
97
|
|
102
98
|
## Testing
|
103
99
|
|
104
|
-
For system testing
|
100
|
+
For system testing there is Capybara. This works great and is necessary for javascript and backend combined apps, but it
|
105
101
|
is good practice to break tests into smaller pieces.
|
106
102
|
|
107
103
|
For the much faster request-level tests, there are some helpers:
|
@@ -126,11 +122,20 @@ RSpec.describe "Articles", type: :request do
|
|
126
122
|
expect(partials_log.join('')).to include('Article could not be created')
|
127
123
|
expect(partials_log.join('')).to include('layouts/flash')
|
128
124
|
|
129
|
-
expect(partials_count).to eq(2)
|
130
|
-
|
131
|
-
expect(assert_partials('articles/form', id: 'form')).to be_truthy #=> expect flash to render exact one time to html-id 'form' by turbo-stream
|
125
|
+
expect(partials_count).to eq(2)
|
126
|
+
#=> 2 partials in total: form, flash, no matter how many times each is rendered (example «flash»: a flash partial can be rendered several times)
|
132
127
|
|
128
|
+
expect(partial_response('form')).to eq(true)
|
129
|
+
expect(partial_response('layouts/flash')).to eq(true)
|
130
|
+
expect(partial_response('flash', id: 'flash-wrapper', count: 1)).to eq(true)
|
131
|
+
#=> id is the ID that turbo-stream pointed to (for replace/append/... an item)
|
132
|
+
|
133
|
+
expect(partial_response('flash'){|r|r.inner_html.include?('Article could not be created')}).to eq(true)
|
134
|
+
expect(partial_response('flash'){|r|r.css('div').inner_html.include?('Article could not be created')}).to eq(true)
|
135
|
+
#=> you can use the validators of nokogiri, check: https://nokogiri.org/tutorials/parsing_an_html_xml_document.html
|
136
|
+
#=> if a partial was rendered more than once: at least one response must match
|
133
137
|
end
|
138
|
+
|
134
139
|
end
|
135
140
|
```
|
136
141
|
|
@@ -151,29 +156,33 @@ includes the plugin and has tests done by rspec/request and capybara.
|
|
151
156
|
|
152
157
|
## Parameters for turbo_stream_save
|
153
158
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
159
|
+
save_action,
|
160
|
+
redirect_on_success_to: nil,
|
161
|
+
object: nil, # object used in save_action, example: @customer
|
162
|
+
id: 'form', # if nil: no partial is rendered
|
163
|
+
partial: nil, # example: 'customers/form' default: "#{controller_path}/#{id}"
|
164
|
+
action: 'replace', # options: append, prepend
|
165
|
+
locals: {}, # locals used by the partial
|
166
|
+
streams_on_success: [
|
167
|
+
{
|
168
|
+
id: nil,
|
169
|
+
partial: 'form',
|
170
|
+
locals: {},
|
171
|
+
action: 'replace'
|
172
|
+
}
|
173
|
+
], # additional partials that should be rendered if save_action succeeded
|
174
|
+
streams_on_error: [
|
175
|
+
{
|
176
|
+
id: nil,
|
177
|
+
partial: 'form',
|
178
|
+
locals: {},
|
179
|
+
action: 'replace'
|
180
|
+
}
|
181
|
+
], # additional partials that should be rendered if save_action failed
|
182
|
+
add_flash_alerts: [], #=> array of strings
|
183
|
+
add_flash_notices: [], #=> array of strings
|
184
|
+
flashes_on_success: [], #=> array of strings
|
185
|
+
flashes_on_error: [] #=> array of strings
|
177
186
|
|
178
187
|
## Requirements
|
179
188
|
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module RenderTurboStream
|
2
|
+
module Test
|
3
|
+
module RequestHelpers
|
4
|
+
|
5
|
+
# count of rendered partials
|
6
|
+
# count rendering different partials (example: «customer/form»)
|
7
|
+
# doesnt check how often a specific partial is rendered
|
8
|
+
|
9
|
+
def partials_count
|
10
|
+
RenderTurboStream::Libs.partials_count(response)
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
|
15
|
+
# log as helper for the developer to see which flash is set and which partials are rendered to wich ids
|
16
|
+
def partials_log
|
17
|
+
all_responses = RenderTurboStream::Libs.all_responses(response)
|
18
|
+
r = []
|
19
|
+
if response.status == 302
|
20
|
+
r.push("redirect to #{turbo_redirect_to}")
|
21
|
+
else
|
22
|
+
all_responses.map do |a|
|
23
|
+
str = [
|
24
|
+
a['action'],
|
25
|
+
'id',
|
26
|
+
"«#{a['id']}»",
|
27
|
+
'by partial',
|
28
|
+
"«#{a['partial']}»",
|
29
|
+
(a['locals'].present? ? "locals: «#{a['locals']}»" : nil)
|
30
|
+
].compact.join(' ')
|
31
|
+
r.push(str)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
r
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
# Returns the path to which turbo_stream.redirect_to would be applied.
|
39
|
+
def turbo_redirect_to
|
40
|
+
expect(response.status).to eq(302)
|
41
|
+
r = JSON.parse(response.body)
|
42
|
+
r['redirected_to']
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
def partial_response(partial, id: nil, count: 1, &block)
|
47
|
+
RenderTurboStream::Libs.partial_response(response, partial, id, count, &block )
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/render_turbo_stream.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require "render_turbo_stream/version"
|
2
2
|
require "render_turbo_stream/railtie"
|
3
3
|
require 'render_turbo_stream/engine'
|
4
|
-
require 'render_turbo_stream/
|
4
|
+
require 'render_turbo_stream/test/request_helpers'
|
5
5
|
|
6
6
|
module RenderTurboStream
|
7
7
|
|
@@ -191,4 +191,69 @@ module RenderTurboStream
|
|
191
191
|
]
|
192
192
|
)
|
193
193
|
end
|
194
|
+
|
195
|
+
class Libs
|
196
|
+
def self.all_responses(response)
|
197
|
+
e = Nokogiri::HTML(response.body).search('#rendered-partials').first
|
198
|
+
JSON.parse(e.inner_html)
|
199
|
+
end
|
200
|
+
|
201
|
+
# if partial is one word, its checked against the last behind the slash, example: 'articles/form' matches 'form'
|
202
|
+
|
203
|
+
def self.select_responses(response, partial, id)
|
204
|
+
all = all_responses(response)
|
205
|
+
|
206
|
+
all.select do |a|
|
207
|
+
partial_matched = if !partial.present?
|
208
|
+
false
|
209
|
+
elsif partial.include?('/')
|
210
|
+
a['partial'] == partial
|
211
|
+
else
|
212
|
+
a['partial'].split('/').last == partial
|
213
|
+
end
|
214
|
+
id_matched = if !id.present?
|
215
|
+
false
|
216
|
+
else
|
217
|
+
a['id'] == id
|
218
|
+
end
|
219
|
+
partial_matched || id_matched
|
220
|
+
end
|
221
|
+
|
222
|
+
end
|
223
|
+
|
224
|
+
def self.partials_count(response)
|
225
|
+
all = all_responses(response)
|
226
|
+
part = []
|
227
|
+
all.each do |p|
|
228
|
+
_p = p['partial']
|
229
|
+
unless part.include?(_p)
|
230
|
+
part.push(_p)
|
231
|
+
end
|
232
|
+
end
|
233
|
+
part.length
|
234
|
+
end
|
235
|
+
|
236
|
+
def self.partial_response(response, partial, id, count, &block)
|
237
|
+
responses = select_responses(response, partial, id)
|
238
|
+
if block_given?
|
239
|
+
|
240
|
+
success = false
|
241
|
+
|
242
|
+
responses.each do |r|
|
243
|
+
parsed = Nokogiri::HTML(r['html_response'])
|
244
|
+
r = yield parsed
|
245
|
+
success = true if r.present?
|
246
|
+
end
|
247
|
+
success
|
248
|
+
|
249
|
+
else
|
250
|
+
if count
|
251
|
+
responses.length == count
|
252
|
+
else
|
253
|
+
nil
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
end
|
194
259
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: render_turbo_stream
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.42
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- christian
|
@@ -43,7 +43,7 @@ files:
|
|
43
43
|
- lib/render_turbo_stream.rb
|
44
44
|
- lib/render_turbo_stream/engine.rb
|
45
45
|
- lib/render_turbo_stream/railtie.rb
|
46
|
-
- lib/render_turbo_stream/
|
46
|
+
- lib/render_turbo_stream/test/request_helpers.rb
|
47
47
|
- lib/render_turbo_stream/version.rb
|
48
48
|
- lib/tasks/render_turbo_stream_tasks.rake
|
49
49
|
homepage: https://gitlab.com/sedl/renderturbostream
|
@@ -1,107 +0,0 @@
|
|
1
|
-
module RenderTurboStream
|
2
|
-
module RequestTestHelpers
|
3
|
-
|
4
|
-
# returns false if partial is rendered cero or multiple times
|
5
|
-
# response can be searched by nokogiri https://nokogiri.org/tutorials/searching_a_xml_html_document.html#basic-searching
|
6
|
-
def partial_response(id: nil, partial: nil)
|
7
|
-
res = partials_responses(id: id, partial: partial)
|
8
|
-
if res.length != 1
|
9
|
-
false
|
10
|
-
else
|
11
|
-
res.first
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
# like partial_response, but returns an array with length of how many times partial was rendered
|
16
|
-
#
|
17
|
-
|
18
|
-
# def partials_responses(id: nil, partial: nil)
|
19
|
-
# ary = partials_attributes
|
20
|
-
# if id && partial
|
21
|
-
# res = ary.select { |a| a['partial'] == partial && a['id'] == id }
|
22
|
-
# elsif id
|
23
|
-
# res = ary.select { |a| a['id'] == id }
|
24
|
-
# elsif partial
|
25
|
-
# res = ary.select { |a| a['partial'] == partial }
|
26
|
-
# else
|
27
|
-
# raise 'missing parameter'
|
28
|
-
# end
|
29
|
-
# res.map { |r| Nokogiri::HTML(r['html_response']) }
|
30
|
-
# end
|
31
|
-
|
32
|
-
# if no count given: expects exactly one match
|
33
|
-
|
34
|
-
def assert_partials(partial, id: nil, count: 1, &block)
|
35
|
-
partials = partials_attributes
|
36
|
-
if id && partial
|
37
|
-
part = partials.select { |a| a['partial'] == partial && a['id'] == id }
|
38
|
-
elsif id
|
39
|
-
part = partials.select { |a| a['id'] == id }
|
40
|
-
elsif partial
|
41
|
-
part = partials.select { |a| a['partial'] == partial }
|
42
|
-
else
|
43
|
-
raise 'missing parameter'
|
44
|
-
end
|
45
|
-
if block_given?
|
46
|
-
part.each do |r|
|
47
|
-
noko = Nokogiri::HTML(r['html_response'])
|
48
|
-
end
|
49
|
-
else
|
50
|
-
if count
|
51
|
-
part.length == count
|
52
|
-
else
|
53
|
-
part.length
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
# count of rendered partials
|
59
|
-
# count rendering different partials (example: «customer/form»)
|
60
|
-
# doesnt check how often a specific partial is rendered
|
61
|
-
|
62
|
-
def partials_count
|
63
|
-
part = []
|
64
|
-
partials_attributes.each do |p|
|
65
|
-
_p = p['partial']
|
66
|
-
unless part.include?(_p)
|
67
|
-
part.push(_p)
|
68
|
-
end
|
69
|
-
end
|
70
|
-
part.length
|
71
|
-
end
|
72
|
-
|
73
|
-
# returns an array of hashes with the attributes used to call partials and the response (html as string) from the partial.
|
74
|
-
def partials_attributes
|
75
|
-
e = Nokogiri::HTML(response.body).search('#rendered-partials').first
|
76
|
-
JSON.parse(e.inner_html)
|
77
|
-
end
|
78
|
-
|
79
|
-
# Returns the path to which turbo_stream.redirect_to would be applied.
|
80
|
-
def turbo_redirect_to
|
81
|
-
expect(response.status).to eq(302)
|
82
|
-
r = JSON.parse(response.body)
|
83
|
-
r['redirected_to']
|
84
|
-
end
|
85
|
-
|
86
|
-
# log as helper for the developer to see which flash is set and which partials are rendered to wich ids
|
87
|
-
def partials_log
|
88
|
-
r = []
|
89
|
-
if response.status == 302
|
90
|
-
r.push("redirect to #{turbo_redirect_to}")
|
91
|
-
else
|
92
|
-
partials_attributes.map do |a|
|
93
|
-
str = [
|
94
|
-
a['action'],
|
95
|
-
'id',
|
96
|
-
"«#{a['id']}»",
|
97
|
-
'by partial',
|
98
|
-
"«#{a['partial']}»",
|
99
|
-
(a['locals'].present? ? "locals: «#{a['locals']}»" : nil)
|
100
|
-
].compact.join(' ')
|
101
|
-
r.push(str)
|
102
|
-
end
|
103
|
-
end
|
104
|
-
r
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|