inertia_builder 0.1.1 → 0.2.1
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/lib/inertia_builder/version.rb +1 -1
- data/lib/inertia_builder.rb +56 -2
- data/test/inertia_builder_test.rb +134 -13
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c2db7cf7bc04f52285ccfb06231fcb67cca0038b80140b84ec314f2cf9f1196b
|
4
|
+
data.tar.gz: '02989fb26e14f25cbfe80ca52559813137c7cbf67c9983afed7f0cb23ad59451'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: faf2b72091c7fecc1c74f51b91e3a1e2237e8878d61777b8b6f5ed9505185c8a81c5cca058b0fcc470f42d98014783cd6b28a5494125a76df4525cbaac82b537
|
7
|
+
data.tar.gz: 359cfcca048b25bde18ac719f9a2a3dbccb02d1081d5c3886b424afcab8ef202d3d4997323640490ab3b63d1c48fa0806da861fa13dda60c7195442c3aa05d85
|
data/lib/inertia_builder.rb
CHANGED
@@ -4,18 +4,52 @@ require 'jbuilder/jbuilder_template'
|
|
4
4
|
require 'inertia_builder/handler'
|
5
5
|
require 'inertia_builder/controller'
|
6
6
|
require 'inertia_builder/renderer'
|
7
|
-
require 'inertia_builder/railtie'
|
7
|
+
require 'inertia_builder/railtie'
|
8
8
|
|
9
9
|
class JbuilderTemplate
|
10
|
-
self.template_lookup_options = { handlers: [
|
10
|
+
self.template_lookup_options = { handlers: %i[inertia jbuilder] }
|
11
11
|
end
|
12
12
|
|
13
13
|
module InertiaBuilder
|
14
14
|
class PropBuilder < JbuilderTemplate
|
15
15
|
alias props attributes!
|
16
16
|
|
17
|
+
def optional!(&block)
|
18
|
+
_call_inertia_block(:optional, &block)
|
19
|
+
end
|
20
|
+
|
21
|
+
def always!(&block)
|
22
|
+
_call_inertia_block(:always, &block)
|
23
|
+
end
|
24
|
+
|
25
|
+
def defer!(**opts, &block)
|
26
|
+
_call_inertia_block(:defer, **opts, &block)
|
27
|
+
end
|
28
|
+
|
29
|
+
def method_missing(name, *args, &block)
|
30
|
+
prop = self
|
31
|
+
|
32
|
+
if @inertia_block
|
33
|
+
method, opts = @inertia_block
|
34
|
+
_set_value(name, ::InertiaRails.send(method, **opts) { prop.set!(name, *args, &block) })
|
35
|
+
elsif !@in_scope
|
36
|
+
# Lazy evaluate outermost properties.
|
37
|
+
_set_value(name, -> { prop.set!(name, *args, &block); })
|
38
|
+
else
|
39
|
+
super
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
17
43
|
private
|
18
44
|
|
45
|
+
def _call_inertia_block(method, **opts)
|
46
|
+
::Kernel.raise "Nesting #{method}! in a #{@inertia_block[0]}! block is not allowed" if @inertia_block
|
47
|
+
|
48
|
+
@inertia_block = [method, opts]
|
49
|
+
yield
|
50
|
+
@inertia_block = nil
|
51
|
+
end
|
52
|
+
|
19
53
|
def _render_partial_with_options(options)
|
20
54
|
options[:locals] ||= options.except(:partial, :as, :collection, :cached)
|
21
55
|
options[:locals][:prop] = self
|
@@ -30,5 +64,25 @@ module InertiaBuilder
|
|
30
64
|
def _render_active_model_partial(object)
|
31
65
|
@context.render object, prop: self
|
32
66
|
end
|
67
|
+
|
68
|
+
def _scope
|
69
|
+
has_parent_scope = @in_scope
|
70
|
+
@in_scope = true
|
71
|
+
super
|
72
|
+
ensure
|
73
|
+
@in_scope = false unless has_parent_scope
|
74
|
+
end
|
75
|
+
|
76
|
+
def _merge_values(current_value, updates)
|
77
|
+
# Always override lazy evaluation procs. For the other special prop types, InertiaRails already handles merging.
|
78
|
+
if current_value.is_a?(::Proc) ||
|
79
|
+
current_value.is_a?(::InertiaRails::OptionalProp) ||
|
80
|
+
current_value.is_a?(::InertiaRails::AlwaysProp) ||
|
81
|
+
current_value.is_a?(::InertiaRails::DeferProp)
|
82
|
+
updates
|
83
|
+
else
|
84
|
+
super
|
85
|
+
end
|
86
|
+
end
|
33
87
|
end
|
34
88
|
end
|
@@ -8,6 +8,11 @@ class User < Struct.new(:id, :first_name, :last_name, :email)
|
|
8
8
|
include ActiveModel::Conversion
|
9
9
|
end
|
10
10
|
|
11
|
+
class Item < Struct.new(:id, :title)
|
12
|
+
extend ActiveModel::Naming
|
13
|
+
include ActiveModel::Conversion
|
14
|
+
end
|
15
|
+
|
11
16
|
class InertiaBuilderTest < Minitest::Test
|
12
17
|
USER_PARTIAL = <<~INERTIA
|
13
18
|
prop.id user.id
|
@@ -16,8 +21,14 @@ class InertiaBuilderTest < Minitest::Test
|
|
16
21
|
prop.email user.email
|
17
22
|
INERTIA
|
18
23
|
|
24
|
+
ITEM_PARTIAL = <<~INERTIA
|
25
|
+
prop.id item.id
|
26
|
+
prop.title item.title
|
27
|
+
INERTIA
|
28
|
+
|
19
29
|
PARTIALS = {
|
20
|
-
'users/_user.html.inertia' => USER_PARTIAL
|
30
|
+
'users/_user.html.inertia' => USER_PARTIAL,
|
31
|
+
'items/_item.html.inertia' => ITEM_PARTIAL
|
21
32
|
}
|
22
33
|
|
23
34
|
def test_basic_html_rendering
|
@@ -47,8 +58,8 @@ class InertiaBuilderTest < Minitest::Test
|
|
47
58
|
}
|
48
59
|
}
|
49
60
|
|
50
|
-
assert_equal inertia_html_with_props(expected_props), render_view(template)
|
51
61
|
assert_equal inertia_json_with_props(expected_props), render_view(template, json: true)
|
62
|
+
assert_equal inertia_html_with_props(expected_props), render_view(template)
|
52
63
|
end
|
53
64
|
|
54
65
|
def test_collection_prop
|
@@ -75,9 +86,9 @@ class InertiaBuilderTest < Minitest::Test
|
|
75
86
|
|
76
87
|
expected_props = { products: products }
|
77
88
|
|
78
|
-
assert_equal inertia_html_with_props(expected_props), render_view(template, assigns: { products: products })
|
79
89
|
assert_equal inertia_json_with_props(expected_props),
|
80
90
|
render_view(template, assigns: { products: products }, json: true)
|
91
|
+
assert_equal inertia_html_with_props(expected_props), render_view(template, assigns: { products: products })
|
81
92
|
end
|
82
93
|
|
83
94
|
def test_basic_partial_prop
|
@@ -91,8 +102,8 @@ class InertiaBuilderTest < Minitest::Test
|
|
91
102
|
|
92
103
|
expected_props = { user: user }
|
93
104
|
|
94
|
-
assert_equal inertia_html_with_props(expected_props), render_view(template, assigns: { user: user })
|
95
105
|
assert_equal inertia_json_with_props(expected_props), render_view(template, assigns: { user: user }, json: true)
|
106
|
+
assert_equal inertia_html_with_props(expected_props), render_view(template, assigns: { user: user })
|
96
107
|
end
|
97
108
|
|
98
109
|
def test_collection_partial_prop
|
@@ -119,12 +130,23 @@ class InertiaBuilderTest < Minitest::Test
|
|
119
130
|
User.new({ id: 43, first_name: 'Jane', last_name: 'Smith', email: 'jane@email.com' })
|
120
131
|
]
|
121
132
|
|
122
|
-
|
133
|
+
items = [
|
134
|
+
Item.new({ id: 1, title: 'Item 1' }),
|
135
|
+
Item.new({ id: 2, title: 'Item 2' })
|
136
|
+
]
|
123
137
|
|
124
|
-
|
138
|
+
template = <<~INERTIA
|
139
|
+
prop.data do
|
140
|
+
prop.users @users, partial: 'users/user', as: :user
|
141
|
+
prop.items @items, partial: 'items/item', as: :item
|
142
|
+
end
|
143
|
+
INERTIA
|
125
144
|
|
126
|
-
|
127
|
-
|
145
|
+
expected_props = { data: { users: users, items: items } }
|
146
|
+
|
147
|
+
assert_equal inertia_json_with_props(expected_props),
|
148
|
+
render_view(template, assigns: { users: users, items: items }, json: true)
|
149
|
+
assert_equal inertia_html_with_props(expected_props), render_view(template, assigns: { users: users, items: items })
|
128
150
|
end
|
129
151
|
|
130
152
|
def test_nil_prop_block
|
@@ -140,11 +162,110 @@ class InertiaBuilderTest < Minitest::Test
|
|
140
162
|
assert_equal inertia_json_with_props(expected_props), render_view(template, json: true)
|
141
163
|
end
|
142
164
|
|
165
|
+
def test_optional_block
|
166
|
+
template = <<~INERTIA
|
167
|
+
prop.id 1
|
168
|
+
prop.optional! do
|
169
|
+
prop.user do
|
170
|
+
prop.id 1
|
171
|
+
prop.email 'user@email.com'
|
172
|
+
end
|
173
|
+
prop.calculation 'Calculation'
|
174
|
+
end
|
175
|
+
INERTIA
|
176
|
+
|
177
|
+
partial_headers = {
|
178
|
+
'X-Inertia-Partial-Data' => 'user,calculation',
|
179
|
+
'X-Inertia-Partial-Component' => '/'
|
180
|
+
}
|
181
|
+
assert_equal inertia_json_with_props({ id: 1 }), render_view(template, json: true)
|
182
|
+
assert_equal inertia_json_with_props({ user: { id: 1, email: 'user@email.com' }, calculation: 'Calculation' }),
|
183
|
+
render_view(template, json: true, headers: partial_headers)
|
184
|
+
end
|
185
|
+
|
186
|
+
def test_always_block
|
187
|
+
template = <<~INERTIA
|
188
|
+
prop.id 1
|
189
|
+
prop.always! do
|
190
|
+
prop.user do
|
191
|
+
prop.id 1
|
192
|
+
prop.email 'user@email.com'
|
193
|
+
end
|
194
|
+
end
|
195
|
+
prop.optional! do
|
196
|
+
prop.calculation 'Calculation'
|
197
|
+
end
|
198
|
+
INERTIA
|
199
|
+
|
200
|
+
partial_headers = {
|
201
|
+
'X-Inertia-Partial-Data' => 'calculation',
|
202
|
+
'X-Inertia-Partial-Component' => '/'
|
203
|
+
}
|
204
|
+
assert_equal inertia_json_with_props({ id: 1, user: { id: 1, email: 'user@email.com' } }),
|
205
|
+
render_view(template, json: true)
|
206
|
+
assert_equal inertia_json_with_props({ user: { id: 1, email: 'user@email.com' }, calculation: 'Calculation' }),
|
207
|
+
render_view(template, json: true, headers: partial_headers)
|
208
|
+
end
|
209
|
+
|
210
|
+
def test_defer_block
|
211
|
+
template = <<~INERTIA
|
212
|
+
prop.id 1
|
213
|
+
prop.defer! do
|
214
|
+
prop.user do
|
215
|
+
prop.id 1
|
216
|
+
prop.email 'user@email.com'
|
217
|
+
end
|
218
|
+
prop.calculation 'Calculation'
|
219
|
+
end
|
220
|
+
INERTIA
|
221
|
+
|
222
|
+
assert_equal inertia_json_with_props({ id: 1 }, deferredProps: { default: %w[user calculation] }),
|
223
|
+
render_view(template, json: true)
|
224
|
+
end
|
225
|
+
|
226
|
+
def test_defer_block_grouping
|
227
|
+
template = <<~INERTIA
|
228
|
+
prop.id 1
|
229
|
+
prop.defer! group: 'group1' do
|
230
|
+
prop.user 'User'
|
231
|
+
end
|
232
|
+
prop.defer! group: 'group2' do
|
233
|
+
prop.calculation 'Calculation'
|
234
|
+
end
|
235
|
+
INERTIA
|
236
|
+
|
237
|
+
assert_equal inertia_json_with_props({ id: 1 }, deferredProps: { group1: ['user'], group2: ['calculation'] }),
|
238
|
+
render_view(template, json: true)
|
239
|
+
end
|
240
|
+
|
241
|
+
def test_defer_block_fetching
|
242
|
+
user = User.new({ id: 1, email: 'user@email.com' })
|
243
|
+
|
244
|
+
template = <<~INERTIA
|
245
|
+
prop.id 1
|
246
|
+
prop.defer! do
|
247
|
+
prop.user do
|
248
|
+
prop.partial! @user
|
249
|
+
end
|
250
|
+
prop.calculation 'Calculation'
|
251
|
+
end
|
252
|
+
INERTIA
|
253
|
+
|
254
|
+
partial_headers = {
|
255
|
+
'X-Inertia-Partial-Data' => 'user,calculation',
|
256
|
+
'X-Inertia-Partial-Component' => '/'
|
257
|
+
}
|
258
|
+
|
259
|
+
assert_equal inertia_json_with_props({ user: user, calculation: 'Calculation' }),
|
260
|
+
render_view(template, assigns: { user: user }, json: true, headers: partial_headers)
|
261
|
+
end
|
262
|
+
|
143
263
|
private
|
144
264
|
|
145
|
-
def render_view(source,
|
265
|
+
def render_view(source, **opts)
|
146
266
|
req = ActionDispatch::TestRequest.create
|
147
|
-
req.headers[
|
267
|
+
req.headers.merge!(opts[:headers] || {})
|
268
|
+
req.headers['X-Inertia'] = 'true' if opts[:json]
|
148
269
|
|
149
270
|
controller = ActionView::TestCase::TestController.new
|
150
271
|
controller.request = req
|
@@ -152,7 +273,7 @@ class InertiaBuilderTest < Minitest::Test
|
|
152
273
|
resolver = ActionView::FixtureResolver.new(PARTIALS.merge('source.html.inertia' => source))
|
153
274
|
lookup = ActionView::LookupContext.new([resolver], {}, [''])
|
154
275
|
|
155
|
-
view = ActionView::Base.with_empty_template_cache.new(lookup, assigns, controller)
|
276
|
+
view = ActionView::Base.with_empty_template_cache.new(lookup, opts[:assigns] || [], controller)
|
156
277
|
|
157
278
|
view.render(template: 'source')
|
158
279
|
end
|
@@ -163,7 +284,7 @@ class InertiaBuilderTest < Minitest::Test
|
|
163
284
|
HTML
|
164
285
|
end
|
165
286
|
|
166
|
-
def inertia_json_with_props(props)
|
287
|
+
def inertia_json_with_props(props, **extra_fields)
|
167
288
|
{
|
168
289
|
component: '/',
|
169
290
|
props: { errors: {} }.merge(props),
|
@@ -171,6 +292,6 @@ class InertiaBuilderTest < Minitest::Test
|
|
171
292
|
version: nil,
|
172
293
|
encryptHistory: false,
|
173
294
|
clearHistory: false
|
174
|
-
}.to_json
|
295
|
+
}.merge(extra_fields).to_json
|
175
296
|
end
|
176
297
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: inertia_builder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rodrigo Lima
|
@@ -70,8 +70,8 @@ licenses:
|
|
70
70
|
- MIT
|
71
71
|
metadata:
|
72
72
|
bug_tracker_uri: https://github.com/rodrigotavio91/inertia-builder/issues
|
73
|
-
changelog_uri: https://github.com/rodrigotavio91/inertia-builder/releases/tag/v0.
|
74
|
-
source_code_uri: https://github.com/rodrigotavio91/inertia-builder/tree/v0.
|
73
|
+
changelog_uri: https://github.com/rodrigotavio91/inertia-builder/releases/tag/v0.2.1
|
74
|
+
source_code_uri: https://github.com/rodrigotavio91/inertia-builder/tree/v0.2.1
|
75
75
|
rubygems_mfa_required: 'true'
|
76
76
|
rdoc_options: []
|
77
77
|
require_paths:
|