js-routes-zigexn 1.3.3
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 +7 -0
- data/.document +5 -0
- data/.gitignore +60 -0
- data/.rspec +1 -0
- data/.travis.yml +60 -0
- data/Appraisals +16 -0
- data/CHANGELOG.md +112 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +20 -0
- data/Rakefile +33 -0
- data/Readme.md +234 -0
- data/app/assets/javascripts/js-routes.js.erb +2 -0
- data/gemfiles/rails32.gemfile +8 -0
- data/gemfiles/rails40.gemfile +8 -0
- data/gemfiles/rails40_sprockets3.gemfile +8 -0
- data/gemfiles/rails41.gemfile +8 -0
- data/gemfiles/rails41_sprockets3.gemfile +8 -0
- data/gemfiles/rails42.gemfile +8 -0
- data/gemfiles/rails42_sprockets3.gemfile +8 -0
- data/gemfiles/rails50.gemfile +8 -0
- data/gemfiles/rails50_sprockets3.gemfile +8 -0
- data/js-routes-zigexn.gemspec +36 -0
- data/lib/js-routes.rb +1 -0
- data/lib/js_routes/engine.rb +73 -0
- data/lib/js_routes/version.rb +3 -0
- data/lib/js_routes.rb +293 -0
- data/lib/routes.js +470 -0
- data/lib/routes.js.coffee +368 -0
- data/lib/tasks/js_routes.rake +8 -0
- data/spec/dummy/app/assets/javascripts/.gitkeep +0 -0
- data/spec/dummy/config/routes.rb +55 -0
- data/spec/js_routes/amd_compatibility_spec.rb +42 -0
- data/spec/js_routes/default_serializer_spec.rb +15 -0
- data/spec/js_routes/generated_javascript_spec.rb +83 -0
- data/spec/js_routes/options_spec.rb +450 -0
- data/spec/js_routes/rails_routes_compatibility_spec.rb +414 -0
- data/spec/js_routes/zzz_last_post_rails_init_spec.rb +135 -0
- data/spec/spec_helper.rb +121 -0
- data/spec/support/routes.rb +76 -0
- metadata +209 -0
@@ -0,0 +1,414 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe JsRoutes, "compatibility with Rails" do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
evaljs(JsRoutes.generate({}))
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should generate collection routing" do
|
10
|
+
expect(evaljs("Routes.inboxes_path()")).to eq(routes.inboxes_path())
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should generate member routing" do
|
14
|
+
expect(evaljs("Routes.inbox_path(1)")).to eq(routes.inbox_path(1))
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should raise error if required argument is not passed" do
|
18
|
+
expect { evaljs("Routes.thing_path()") }
|
19
|
+
.to raise_error('Route parameter missing: id')
|
20
|
+
expect { evaljs("Routes.search_path()") }
|
21
|
+
.to raise_error('Route parameter missing: q')
|
22
|
+
expect { evaljs("Routes.book_path()") }
|
23
|
+
.to raise_error('Route parameter missing: title')
|
24
|
+
expect { evaljs("Routes.book_title_path()") }
|
25
|
+
.to raise_error('Route parameter missing: title')
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should support 0 as a member parameter" do
|
29
|
+
expect(evaljs("Routes.inbox_path(0)")).to eq(routes.inbox_path(0))
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should generate nested routing with one parameter" do
|
33
|
+
expect(evaljs("Routes.inbox_messages_path(1)")).to eq(routes.inbox_messages_path(1))
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should generate nested routing" do
|
37
|
+
expect(evaljs("Routes.inbox_message_path(1,2)")).to eq(routes.inbox_message_path(1, 2))
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should generate routing with format" do
|
41
|
+
expect(evaljs("Routes.inbox_path(1, {format: 'json'})")).to eq(routes.inbox_path(1, :format => "json"))
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should support routes with reserved javascript words as parameters" do
|
45
|
+
expect(evaljs("Routes.object_path(1, 2)")).to eq(routes.object_path(1,2))
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should support routes with trailing_slash" do
|
49
|
+
expect(evaljs("Routes.inbox_path(1, {trailing_slash: true})")).to eq(routes.inbox_path(1, trailing_slash: true))
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should support url anchor given as parameter" do
|
53
|
+
expect(evaljs("Routes.inbox_path(1, {anchor: 'hello'})")).to eq(routes.inbox_path(1, :anchor => "hello"))
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should support url anchor and get parameters" do
|
57
|
+
expect(evaljs("Routes.inbox_path(1, {expanded: true, anchor: 'hello'})")).to eq(routes.inbox_path(1, :expanded => true, :anchor => "hello"))
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should use irregular ActiveSupport pluralizations" do
|
61
|
+
expect(evaljs("Routes.budgies_path()")).to eq(routes.budgies_path)
|
62
|
+
expect(evaljs("Routes.budgie_path(1)")).to eq(routes.budgie_path(1))
|
63
|
+
expect(evaljs("Routes.budgy_path")).to eq(nil)
|
64
|
+
expect(evaljs("Routes.budgie_descendents_path(1)")).to eq(routes.budgie_descendents_path(1))
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "when route has defaults" do
|
68
|
+
it "should support route default format" do
|
69
|
+
expect(evaljs("Routes.api_purchases_path()")).to eq(routes.api_purchases_path)
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should support route default subdomain' do
|
73
|
+
expect(evaljs("Routes.backend_root_path()")).to eq(routes.backend_root_path)
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should support default format override" do
|
77
|
+
expect(evaljs("Routes.api_purchases_path({format: 'xml'})")).to eq(routes.api_purchases_path(format: 'xml'))
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should support default format override by passing it in args" do
|
81
|
+
expect(evaljs("Routes.api_purchases_path('xml')")).to eq(routes.api_purchases_path('xml'))
|
82
|
+
end
|
83
|
+
|
84
|
+
it "doesn't apply defaults to path" do
|
85
|
+
expect(evaljs("Routes.with_defaults_path()")).to eq(routes.with_defaults_path)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context "with rails engines" do
|
90
|
+
it "should support simple route" do
|
91
|
+
expect(evaljs("Routes.blog_app_posts_path()")).to eq(blog_routes.posts_path())
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should support root route" do
|
95
|
+
expect(evaljs("Routes.blog_app_path()")).to eq(routes.blog_app_path())
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should support route with parameters" do
|
99
|
+
expect(evaljs("Routes.blog_app_post_path(1)")).to eq(blog_routes.post_path(1))
|
100
|
+
end
|
101
|
+
it "should support root path" do
|
102
|
+
expect(evaljs("Routes.blog_app_root_path()")).to eq(blog_routes.root_path)
|
103
|
+
end
|
104
|
+
it "should support single route mapping" do
|
105
|
+
expect(evaljs("Routes.support_path({page: 3})")).to eq(routes.support_path(:page => 3))
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
it "shouldn't require the format" do
|
110
|
+
expect(evaljs("Routes.json_only_path({format: 'json'})")).to eq(routes.json_only_path(:format => 'json'))
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should serialize object with empty string value" do
|
114
|
+
expect(evaljs("Routes.inboxes_path({a: '', b: 1})")).to eq(routes.inboxes_path(:a => '', :b => 1))
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should support utf-8 route" do
|
118
|
+
expect(evaljs("Routes.hello_path()")).to eq(routes.hello_path)
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should support root_path" do
|
122
|
+
expect(evaljs("Routes.root_path()")).to eq(routes.root_path)
|
123
|
+
end
|
124
|
+
|
125
|
+
describe "get paramters" do
|
126
|
+
it "should support simple get parameters" do
|
127
|
+
expect(evaljs("Routes.inbox_path(1, {format: 'json', lang: 'ua', q: 'hello'})")).to eq(routes.inbox_path(1, :lang => "ua", :q => "hello", :format => "json"))
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should support array get parameters" do
|
131
|
+
expect(evaljs("Routes.inbox_path(1, {hello: ['world', 'mars']})")).to eq(routes.inbox_path(1, :hello => [:world, :mars]))
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should support nested get parameters" do
|
135
|
+
expect(evaljs("Routes.inbox_path(1, {format: 'json', env: 'test', search: { category_ids: [2,5], q: 'hello'}})")).to eq(
|
136
|
+
routes.inbox_path(1, :env => 'test', :search => {:category_ids => [2,5], :q => "hello"}, :format => "json")
|
137
|
+
)
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should support null and undefined parameters" do
|
141
|
+
expect(evaljs("Routes.inboxes_path({uri: null, key: undefined})")).to eq(routes.inboxes_path(:uri => nil, :key => nil))
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should escape get parameters" do
|
145
|
+
expect(evaljs("Routes.inboxes_path({uri: 'http://example.com'})")).to eq(routes.inboxes_path(:uri => 'http://example.com'))
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
|
151
|
+
context "routes globbing" do
|
152
|
+
it "should be supported as parameters" do
|
153
|
+
expect(evaljs("Routes.book_path('thrillers', 1)")).to eq(routes.book_path('thrillers', 1))
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should support routes globbing as array" do
|
157
|
+
expect(evaljs("Routes.book_path(['thrillers'], 1)")).to eq(routes.book_path(['thrillers'], 1))
|
158
|
+
end
|
159
|
+
|
160
|
+
it "should bee support routes globbing as array" do
|
161
|
+
expect(evaljs("Routes.book_path([1, 2, 3], 1)")).to eq(routes.book_path([1, 2, 3], 1))
|
162
|
+
end
|
163
|
+
|
164
|
+
it "should bee support routes globbing as hash" do
|
165
|
+
expect(evaljs("Routes.book_path('a_test/b_test/c_test', 1)")).to eq(routes.book_path('a_test/b_test/c_test', 1))
|
166
|
+
end
|
167
|
+
|
168
|
+
it "should support routes globbing as array with optional params" do
|
169
|
+
expect(evaljs("Routes.book_path([1, 2, 3, 5], 1, {c: '1'})")).to eq(routes.book_path([1, 2, 3, 5], 1, { :c => "1" }))
|
170
|
+
end
|
171
|
+
|
172
|
+
it "should support routes globbing in book_title route as array" do
|
173
|
+
expect(evaljs("Routes.book_title_path('john', ['thrillers', 'comedian'])")).to eq(routes.book_title_path('john', ['thrillers', 'comedian']))
|
174
|
+
end
|
175
|
+
|
176
|
+
it "should support routes globbing in book_title route as array with optional params" do
|
177
|
+
expect(evaljs("Routes.book_title_path('john', ['thrillers', 'comedian'], {some_key: 'some_value'})")).to eq(routes.book_title_path('john', ['thrillers', 'comedian'], {:some_key => 'some_value'}))
|
178
|
+
end
|
179
|
+
|
180
|
+
it "should support required paramters given as options hash" do
|
181
|
+
expect(evaljs("Routes.search_path({q: 'hello'})")).to eq(routes.search_path(:q => 'hello'))
|
182
|
+
end
|
183
|
+
|
184
|
+
it "should support nested object null parameters" do
|
185
|
+
expect(evaljs("Routes.inboxes_path({hello: {world: null}})")).to eq(routes.inboxes_path(:hello => {:world => nil}))
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
context "using optional path fragments" do
|
190
|
+
context "including not optional parts" do
|
191
|
+
it "should include everything that is not optional" do
|
192
|
+
expect(evaljs("Routes.foo_path()")).to eq(routes.foo_path)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
context "but not including them" do
|
197
|
+
it "should not include the optional parts" do
|
198
|
+
expect(evaljs("Routes.things_path()")).to eq(routes.things_path)
|
199
|
+
expect(evaljs("Routes.things_path({ q: 'hello' })")).to eq(routes.things_path(q: 'hello'))
|
200
|
+
end
|
201
|
+
|
202
|
+
it "should not require the optional parts as arguments" do
|
203
|
+
expect(evaljs("Routes.thing_path(null, 5)")).to eq(routes.thing_path(nil, 5))
|
204
|
+
end
|
205
|
+
|
206
|
+
it "should treat undefined as non-given optional part" do
|
207
|
+
expect(evaljs("Routes.thing_path(5, {optional_id: undefined})")).to eq(routes.thing_path(5, :optional_id => nil))
|
208
|
+
end
|
209
|
+
|
210
|
+
it "should raise error when passing non-full list of arguments and some query params" do
|
211
|
+
expect { evaljs("Routes.thing_path(5, {q: 'hello'})") }
|
212
|
+
.to raise_error('Route parameter missing: id')
|
213
|
+
end
|
214
|
+
|
215
|
+
it "should treat null as non-given optional part" do
|
216
|
+
expect(evaljs("Routes.thing_path(5, {optional_id: null})")).to eq(routes.thing_path(5, :optional_id => nil))
|
217
|
+
end
|
218
|
+
|
219
|
+
it "should work when passing required params in options" do
|
220
|
+
expect(evaljs("Routes.thing_deep_path({second_required: 1, third_required: 2})")).to eq(routes.thing_deep_path(second_required: 1, third_required: 2))
|
221
|
+
end
|
222
|
+
|
223
|
+
it "should skip leading and trailing optional parts" do
|
224
|
+
skip if Rails.version < '4'
|
225
|
+
expect(evaljs("Routes.thing_deep_path(1, 2)")).to eq(routes.thing_deep_path(1, 2))
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
context "and including them" do
|
230
|
+
if Rails.version < '4'
|
231
|
+
it "should fail when insufficient arguments are given" do
|
232
|
+
expect { evaljs("Routes.thing_deep_path(1)")}
|
233
|
+
.to raise_error('Route parameter missing: second_required')
|
234
|
+
expect { evaljs("Routes.thing_deep_path(1,2)")}
|
235
|
+
.to raise_error('Route parameter missing: third_required')
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
it "should include the optional parts" do
|
240
|
+
expect(evaljs("Routes.things_path({optional_id: 5})")).to eq(routes.things_path(:optional_id => 5))
|
241
|
+
expect(evaljs("Routes.things_path(5)")).to eq(routes.things_path(5))
|
242
|
+
expect(evaljs("Routes.thing_deep_path(1, { third_required: 3, second_required: 2 })")).to eq(routes.thing_deep_path(1, third_required: 3, second_required: 2))
|
243
|
+
expect(evaljs("Routes.thing_deep_path(1, { third_required: 3, second_required: 2, forth_optional: 4 })")).to eq(routes.thing_deep_path(1, third_required: 3, second_required: 2, forth_optional: 4))
|
244
|
+
expect(evaljs("Routes.thing_deep_path(2, { third_required: 3, first_optional: 1 })")).to eq(routes.thing_deep_path(2, third_required: 3, first_optional: 1))
|
245
|
+
expect(evaljs("Routes.thing_deep_path(3, { first_optional: 1, second_required: 2 })")).to eq(routes.thing_deep_path(3, first_optional: 1, second_required: 2))
|
246
|
+
expect(evaljs("Routes.thing_deep_path(3, { first_optional: 1, second_required: 2, forth_optional: 4 })")).to eq(routes.thing_deep_path(3, first_optional: 1, second_required: 2, forth_optional: 4))
|
247
|
+
expect(evaljs("Routes.thing_deep_path(4, { first_optional: 1, second_required: 2, third_required: 3 })")).to eq(routes.thing_deep_path(4, first_optional: 1, second_required: 2, third_required: 3))
|
248
|
+
expect(evaljs("Routes.thing_deep_path(1, 2, { third_required: 3 })")).to eq(routes.thing_deep_path(1, 2, third_required: 3))
|
249
|
+
expect(evaljs("Routes.thing_deep_path(1,2, {third_required: 3, q: 'bogdan'})")).to eq(routes.thing_deep_path(1,2, {third_required: 3, q: 'bogdan'}))
|
250
|
+
expect(evaljs("Routes.thing_deep_path(1, 2, { forth_optional: 4, third_required: 3 })")).to eq(routes.thing_deep_path(1, 2, forth_optional: 4, third_required: 3))
|
251
|
+
expect(evaljs("Routes.thing_deep_path(1, 3, { second_required: 2 })")).to eq(routes.thing_deep_path(1, 3, second_required: 2))
|
252
|
+
expect(evaljs("Routes.thing_deep_path(1, 4, { second_required: 2, third_required: 3 })")).to eq(routes.thing_deep_path(1, 4, second_required: 2, third_required: 3))
|
253
|
+
expect(evaljs("Routes.thing_deep_path(2, 3, { first_optional: 1 })")).to eq(routes.thing_deep_path(2, 3, first_optional: 1))
|
254
|
+
expect(evaljs("Routes.thing_deep_path(2, 3, { first_optional: 1, forth_optional: 4 })")).to eq(routes.thing_deep_path(2, 3, first_optional: 1, forth_optional: 4))
|
255
|
+
expect(evaljs("Routes.thing_deep_path(2, 4, { first_optional: 1, third_required: 3 })")).to eq(routes.thing_deep_path(2, 4, first_optional: 1, third_required: 3))
|
256
|
+
expect(evaljs("Routes.thing_deep_path(3, 4, { first_optional: 1, second_required: 2 })")).to eq(routes.thing_deep_path(3, 4, first_optional: 1, second_required: 2))
|
257
|
+
expect(evaljs("Routes.thing_deep_path(1, 2, 3)")).to eq(routes.thing_deep_path(1, 2, 3))
|
258
|
+
expect(evaljs("Routes.thing_deep_path(1, 2, 3, { forth_optional: 4 })")).to eq(routes.thing_deep_path(1, 2, 3, forth_optional: 4))
|
259
|
+
expect(evaljs("Routes.thing_deep_path(1, 2, 4, { third_required: 3 })")).to eq(routes.thing_deep_path(1, 2, 4, third_required: 3))
|
260
|
+
expect(evaljs("Routes.thing_deep_path(1, 3, 4, { second_required: 2 })")).to eq(routes.thing_deep_path(1, 3, 4, second_required: 2))
|
261
|
+
expect(evaljs("Routes.thing_deep_path(2, 3, 4, { first_optional: 1 })")).to eq(routes.thing_deep_path(2, 3, 4, first_optional: 1))
|
262
|
+
expect(evaljs("Routes.thing_deep_path(1, 2, 3, 4)")).to eq(routes.thing_deep_path(1, 2, 3, 4))
|
263
|
+
|
264
|
+
end
|
265
|
+
|
266
|
+
context "on nested optional parts" do
|
267
|
+
if Rails.version <= "5.0.0"
|
268
|
+
# this type of routing is deprecated
|
269
|
+
it "should include everything that is not optional" do
|
270
|
+
expect(evaljs("Routes.classic_path({controller: 'classic', action: 'edit'})")).to eq(routes.classic_path(controller: :classic, action: :edit))
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
context "when wrong parameters given" do
|
278
|
+
|
279
|
+
it "should throw Exception if not enough parameters" do
|
280
|
+
expect {
|
281
|
+
evaljs("Routes.inbox_path()")
|
282
|
+
}.to raise_error(js_error_class)
|
283
|
+
end
|
284
|
+
it "should throw Exception if required parameter is not defined" do
|
285
|
+
expect {
|
286
|
+
evaljs("Routes.inbox_path(null)")
|
287
|
+
}.to raise_error(js_error_class)
|
288
|
+
end
|
289
|
+
|
290
|
+
it "should throw Exceptions if when there is too many parameters" do
|
291
|
+
expect {
|
292
|
+
evaljs("Routes.inbox_path(1,2,3)")
|
293
|
+
}.to raise_error(js_error_class)
|
294
|
+
end
|
295
|
+
|
296
|
+
it "should throw Exceptions if when pass id with null" do
|
297
|
+
expect {
|
298
|
+
evaljs("Routes.inbox_path({id: null})")
|
299
|
+
}.to raise_error(js_error_class)
|
300
|
+
end
|
301
|
+
|
302
|
+
it "should throw Exceptions if when pass to_param with null" do
|
303
|
+
expect {
|
304
|
+
evaljs("Routes.inbox_path({to_param: null})")
|
305
|
+
}.to raise_error(js_error_class)
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
context "when javascript engine without Array#indexOf is used" do
|
310
|
+
before(:each) do
|
311
|
+
evaljs("Array.prototype.indexOf = null")
|
312
|
+
end
|
313
|
+
it "should still work correctly" do
|
314
|
+
expect(evaljs("Routes.inboxes_path()")).to eq(routes.inboxes_path())
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
context "when arguments are objects" do
|
319
|
+
|
320
|
+
let(:klass) { Struct.new(:id, :to_param) }
|
321
|
+
let(:inbox) { klass.new(1,"my") }
|
322
|
+
|
323
|
+
it "should support 0 as a to_param option" do
|
324
|
+
expect(evaljs("Routes.inbox_path({to_param: 0})")).to eq(routes.inbox_path(0))
|
325
|
+
end
|
326
|
+
|
327
|
+
it "should check for options special key" do
|
328
|
+
expect(evaljs("Routes.inbox_path({id: 7, q: 'hello', _options: true})")).to eq(routes.inbox_path(id: 7, q: 'hello'))
|
329
|
+
expect {
|
330
|
+
evaljs("Routes.inbox_path({to_param: 7, _options: true})")
|
331
|
+
}.to raise_error(js_error_class)
|
332
|
+
expect(evaljs("Routes.inbox_message_path(5, {id: 7, q: 'hello', _options: true})")).to eq(routes.inbox_message_path(5, id: 7, q: 'hello'))
|
333
|
+
end
|
334
|
+
|
335
|
+
it "should check for options special key" do
|
336
|
+
end
|
337
|
+
|
338
|
+
it "should support 0 as an id option" do
|
339
|
+
expect(evaljs("Routes.inbox_path({id: 0})")).to eq(routes.inbox_path(0))
|
340
|
+
end
|
341
|
+
|
342
|
+
it "should use id property of the object in path" do
|
343
|
+
expect(evaljs("Routes.inbox_path({id: 1})")).to eq(routes.inbox_path(1))
|
344
|
+
end
|
345
|
+
|
346
|
+
it "should prefer to_param property over id property" do
|
347
|
+
expect(evaljs("Routes.inbox_path({id: 1, to_param: 'my'})")).to eq(routes.inbox_path(inbox))
|
348
|
+
end
|
349
|
+
|
350
|
+
it "should call to_param if it is a function" do
|
351
|
+
expect(evaljs("Routes.inbox_path({id: 1, to_param: function(){ return 'my';}})")).to eq(routes.inbox_path(inbox))
|
352
|
+
end
|
353
|
+
|
354
|
+
it "should call id if it is a function" do
|
355
|
+
expect(evaljs("Routes.inbox_path({id: function() { return 1;}})")).to eq(routes.inbox_path(1))
|
356
|
+
end
|
357
|
+
|
358
|
+
it "should support options argument" do
|
359
|
+
expect(evaljs(
|
360
|
+
"Routes.inbox_message_path({id:1, to_param: 'my'}, {id:2}, {custom: true, format: 'json'})"
|
361
|
+
)).to eq(routes.inbox_message_path(inbox, 2, :custom => true, :format => "json"))
|
362
|
+
end
|
363
|
+
|
364
|
+
context "when globbing" do
|
365
|
+
it "should prefer to_param property over id property" do
|
366
|
+
expect(evaljs("Routes.book_path({id: 1, to_param: 'my'}, 1)")).to eq(routes.book_path(inbox, 1))
|
367
|
+
end
|
368
|
+
|
369
|
+
it "should call to_param if it is a function" do
|
370
|
+
expect(evaljs("Routes.book_path({id: 1, to_param: function(){ return 'my';}}, 1)")).to eq(routes.book_path(inbox, 1))
|
371
|
+
end
|
372
|
+
|
373
|
+
it "should call id if it is a function" do
|
374
|
+
expect(evaljs("Routes.book_path({id: function() { return 'technical';}}, 1)")).to eq(routes.book_path('technical', 1))
|
375
|
+
end
|
376
|
+
|
377
|
+
it "should support options argument" do
|
378
|
+
expect(evaljs(
|
379
|
+
"Routes.book_path({id:1, to_param: 'my'}, {id:2}, {custom: true, format: 'json'})"
|
380
|
+
)).to eq(routes.book_path(inbox, 2, :custom => true, :format => "json"))
|
381
|
+
end
|
382
|
+
end
|
383
|
+
end
|
384
|
+
|
385
|
+
context "when specs" do
|
386
|
+
it "should show inbox spec" do
|
387
|
+
expect(evaljs("Routes.inbox_path.toString()")).to eq('/inboxes/:id(.:format)')
|
388
|
+
end
|
389
|
+
|
390
|
+
it "should show inbox spec convert to string" do
|
391
|
+
expect(evaljs("'' + Routes.inbox_path")).to eq('/inboxes/:id(.:format)')
|
392
|
+
end
|
393
|
+
|
394
|
+
it "should show inbox message spec" do
|
395
|
+
expect(evaljs("Routes.inbox_message_path.toString()")).to eq('/inboxes/:inbox_id/messages/:id(.:format)')
|
396
|
+
end
|
397
|
+
|
398
|
+
it "should show inbox message spec convert to string" do
|
399
|
+
expect(evaljs("'' + Routes.inbox_message_path")).to eq('/inboxes/:inbox_id/messages/:id(.:format)')
|
400
|
+
end
|
401
|
+
end
|
402
|
+
|
403
|
+
describe "required_params" do
|
404
|
+
it "should show inbox spec" do
|
405
|
+
expect(evaljs("Routes.inbox_path.required_params").to_a).to eq(["id"])
|
406
|
+
end
|
407
|
+
|
408
|
+
it "should show inbox message spec" do
|
409
|
+
expect(evaljs("Routes.inbox_message_path.required_params").to_a).to eq(["inbox_id", "id"])
|
410
|
+
end
|
411
|
+
end
|
412
|
+
|
413
|
+
|
414
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
# we need to run post_rails_init_spec as the latest
|
2
|
+
# because it cause unrevertable changes to runtime
|
3
|
+
# what is why I added "zzz_last" in the beginning
|
4
|
+
|
5
|
+
require 'spec_helper'
|
6
|
+
require "fileutils"
|
7
|
+
|
8
|
+
describe "after Rails initialization" do
|
9
|
+
NAME = Rails.root.join('app', 'assets', 'javascripts', 'routes.js').to_s
|
10
|
+
|
11
|
+
def sprockets_v3?
|
12
|
+
Sprockets::VERSION.to_i >= 3
|
13
|
+
end
|
14
|
+
|
15
|
+
def sprockets_context(environment, name, filename)
|
16
|
+
if sprockets_v3?
|
17
|
+
Sprockets::Context.new(environment: environment, name: name, filename: filename.to_s, metadata: {})
|
18
|
+
else
|
19
|
+
Sprockets::Context.new(environment, name, filename)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def evaluate(ctx, file)
|
24
|
+
if sprockets_v3?
|
25
|
+
ctx.load(ctx.environment.find_asset(file, pipeline: :default).uri).to_s
|
26
|
+
else
|
27
|
+
ctx.evaluate(file)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
before(:each) do
|
32
|
+
FileUtils.rm_rf Rails.root.join('tmp/cache')
|
33
|
+
FileUtils.rm_f NAME
|
34
|
+
JsRoutes.generate!(NAME)
|
35
|
+
end
|
36
|
+
|
37
|
+
before(:all) do
|
38
|
+
Rails.configuration.eager_load = false
|
39
|
+
Rails.application.initialize!
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should generate routes file" do
|
43
|
+
expect(File.exists?(NAME)).to be_truthy
|
44
|
+
end
|
45
|
+
|
46
|
+
context "JsRoutes::Engine" do
|
47
|
+
TEST_ASSET_PATH = Rails.root.join('app','assets','javascripts','test.js')
|
48
|
+
|
49
|
+
before(:all) do
|
50
|
+
File.open(TEST_ASSET_PATH,'w') do |f|
|
51
|
+
f.puts "function() {}"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
after(:all) do
|
55
|
+
FileUtils.rm_f(TEST_ASSET_PATH)
|
56
|
+
end
|
57
|
+
|
58
|
+
context "the preprocessor" do
|
59
|
+
before(:each) do
|
60
|
+
path = Rails.root.join('config','routes.rb').to_s
|
61
|
+
if sprockets_v3?
|
62
|
+
expect_any_instance_of(Sprockets::Context).to receive(:depend_on).with(path)
|
63
|
+
else
|
64
|
+
expect(ctx).to receive(:depend_on).with(path)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
let!(:ctx) do
|
68
|
+
sprockets_context(Rails.application.assets,
|
69
|
+
'js-routes.js',
|
70
|
+
Pathname.new('js-routes.js'))
|
71
|
+
end
|
72
|
+
|
73
|
+
context "when dealing with js-routes.js" do
|
74
|
+
|
75
|
+
context "with Rails" do
|
76
|
+
context "and initialize on precompile" do
|
77
|
+
before(:each) do
|
78
|
+
Rails.application.config.assets.initialize_on_precompile = true
|
79
|
+
end
|
80
|
+
it "should render some javascript" do
|
81
|
+
expect(evaluate(ctx, 'js-routes.js')).to match(/routes = /)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
context "and not initialize on precompile" do
|
85
|
+
before(:each) do
|
86
|
+
Rails.application.config.assets.initialize_on_precompile = false
|
87
|
+
end
|
88
|
+
it "should raise an exception if 3 version" do
|
89
|
+
if 3 == Rails::VERSION::MAJOR
|
90
|
+
expect { evaluate(ctx, 'js-routes.js') }.to raise_error(/Cannot precompile/)
|
91
|
+
else
|
92
|
+
expect(evaluate(ctx, 'js-routes.js')).to match(/routes = /)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
end
|
102
|
+
context "when not dealing with js-routes.js" do
|
103
|
+
it "should not depend on routes.rb" do
|
104
|
+
ctx = sprockets_context(Rails.application.assets,
|
105
|
+
'test.js',
|
106
|
+
TEST_ASSET_PATH)
|
107
|
+
expect(ctx).not_to receive(:depend_on)
|
108
|
+
evaluate(ctx, 'test.js')
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe "JSRoutes thread safety" do
|
115
|
+
before do
|
116
|
+
begin
|
117
|
+
Rails.application.initialize!
|
118
|
+
rescue
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
it "can produce the routes from multiple threads" do
|
123
|
+
threads = 2.times.map do
|
124
|
+
Thread.start do
|
125
|
+
10.times {
|
126
|
+
expect { JsRoutes.generate }.to_not raise_error
|
127
|
+
}
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
threads.each do |thread|
|
132
|
+
thread.join
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|