js-routes 1.4.1 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.eslintrc.js +15 -0
- data/.gitignore +5 -0
- data/.nvmrc +1 -0
- data/.travis.yml +37 -30
- data/Appraisals +16 -13
- data/CHANGELOG.md +95 -0
- data/Rakefile +6 -2
- data/Readme.md +220 -88
- data/VERSION_2_UPGRADE.md +66 -0
- data/app/assets/javascripts/js-routes.js.erb +1 -1
- data/gemfiles/{rails40.gemfile → rails40_sprockets_2.gemfile} +1 -1
- data/gemfiles/{rails40_sprockets3.gemfile → rails40_sprockets_3.gemfile} +0 -0
- data/gemfiles/{rails41.gemfile → rails41_sprockets_2.gemfile} +1 -1
- data/gemfiles/{rails41_sprockets3.gemfile → rails41_sprockets_3.gemfile} +0 -0
- data/gemfiles/{rails32.gemfile → rails42_sprockets_2.gemfile} +2 -2
- data/gemfiles/{rails42_sprockets3.gemfile → rails42_sprockets_3.gemfile} +1 -1
- data/gemfiles/{rails50_sprockets3.gemfile → rails50_sprockets_3.gemfile} +1 -1
- data/gemfiles/rails51_sprockets_3.gemfile +8 -0
- data/gemfiles/rails52_sprockets_3.gemfile +8 -0
- data/js-routes.gemspec +9 -6
- data/lib/js_routes/engine.rb +6 -18
- data/lib/js_routes/version.rb +1 -1
- data/lib/js_routes.rb +329 -171
- data/lib/routes.d.ts +79 -0
- data/lib/routes.js +499 -485
- data/lib/routes.ts +732 -0
- data/lib/tasks/js_routes.rake +8 -2
- data/package.json +37 -0
- data/spec/dummy/app/assets/config/manifest.js +2 -0
- data/spec/js_routes/default_serializer_spec.rb +19 -3
- data/spec/js_routes/{amd_compatibility_spec.rb → module_types/amd_spec.rb} +1 -9
- data/spec/js_routes/module_types/cjs_spec.rb +15 -0
- data/spec/js_routes/module_types/dts/routes.spec.d.ts +114 -0
- data/spec/js_routes/module_types/dts/test.spec.ts +56 -0
- data/spec/js_routes/module_types/dts_spec.rb +111 -0
- data/spec/js_routes/module_types/esm_spec.rb +45 -0
- data/spec/js_routes/{generated_javascript_spec.rb → module_types/umd_spec.rb} +33 -27
- data/spec/js_routes/options_spec.rb +92 -50
- data/spec/js_routes/rails_routes_compatibility_spec.rb +107 -45
- data/spec/js_routes/zzz_last_post_rails_init_spec.rb +19 -8
- data/spec/spec_helper.rb +45 -42
- data/spec/support/routes.rb +19 -14
- data/spec/tsconfig.json +4 -0
- data/tsconfig.json +28 -0
- data/yarn.lock +2145 -0
- metadata +47 -34
- data/gemfiles/rails42.gemfile +0 -8
- data/gemfiles/rails50.gemfile +0 -8
- data/lib/routes.js.coffee +0 -386
@@ -2,13 +2,26 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe JsRoutes, "options" do
|
4
4
|
|
5
|
+
let(:generated_js) do
|
6
|
+
JsRoutes.generate({
|
7
|
+
module_type: nil,
|
8
|
+
namespace: 'Routes',
|
9
|
+
**_options
|
10
|
+
})
|
11
|
+
end
|
12
|
+
|
5
13
|
before(:each) do
|
6
14
|
evaljs(_presetup) if _presetup
|
7
15
|
with_warnings(_warnings) do
|
8
|
-
evaljs(
|
16
|
+
evaljs(generated_js)
|
17
|
+
App.routes.default_url_options = _options[:default_url_options] || {}
|
9
18
|
end
|
10
19
|
end
|
11
20
|
|
21
|
+
after(:each) do
|
22
|
+
App.routes.default_url_options = {}
|
23
|
+
end
|
24
|
+
|
12
25
|
let(:_presetup) { nil }
|
13
26
|
let(:_options) { {} }
|
14
27
|
let(:_warnings) { true }
|
@@ -32,9 +45,10 @@ describe JsRoutes, "options" do
|
|
32
45
|
let(:_presetup){ %q(var myCustomSerializer = 1) }
|
33
46
|
let(:_options) { {:serializer => "myCustomSerializer"} }
|
34
47
|
|
35
|
-
it "should
|
36
|
-
|
37
|
-
|
48
|
+
it "should throw error" do
|
49
|
+
expect {
|
50
|
+
evaljs(%q(Routes.inboxes_path({a: 1})))
|
51
|
+
}.to raise_error(js_error_class)
|
38
52
|
end
|
39
53
|
end
|
40
54
|
|
@@ -81,6 +95,18 @@ describe JsRoutes, "options" do
|
|
81
95
|
expect(evaljs("Routes.inboxes_path")).to be_nil
|
82
96
|
end
|
83
97
|
|
98
|
+
context "with camel_case option" do
|
99
|
+
let(:_options) { {include: /^admin_/, camel_case: true} }
|
100
|
+
|
101
|
+
it "should exclude specified routes from file" do
|
102
|
+
expect(evaljs("Routes.adminUsersPath()")).not_to be_nil
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should not exclude routes not under specified pattern" do
|
106
|
+
expect(evaljs("Routes.inboxesPath")).to be_nil
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
84
110
|
context "for rails engine" do
|
85
111
|
let(:_options) { {:include => /^blog_app_posts/} }
|
86
112
|
|
@@ -134,12 +160,14 @@ describe JsRoutes, "options" do
|
|
134
160
|
let(:_options) { {:default_url_options => {format: "json"}} }
|
135
161
|
let(:_warnings) { nil }
|
136
162
|
|
137
|
-
|
138
|
-
|
139
|
-
|
163
|
+
if Rails.version >= "5"
|
164
|
+
it "should render routing with default_format" do
|
165
|
+
expect(evaljs("Routes.inbox_path(1)")).to eq(test_routes.inbox_path(1))
|
166
|
+
end
|
140
167
|
|
141
|
-
|
142
|
-
|
168
|
+
it "should render routing with default_format and zero object" do
|
169
|
+
expect(evaljs("Routes.inbox_path(0)")).to eq(test_routes.inbox_path(0))
|
170
|
+
end
|
143
171
|
end
|
144
172
|
|
145
173
|
it "should override default_format when spefified implicitly" do
|
@@ -147,13 +175,11 @@ describe JsRoutes, "options" do
|
|
147
175
|
end
|
148
176
|
|
149
177
|
it "should override nullify implicitly when specified implicitly" do
|
150
|
-
expect(evaljs("Routes.inbox_path(1, {format: null})")).to eq(test_routes.inbox_path(1))
|
178
|
+
expect(evaljs("Routes.inbox_path(1, {format: null})")).to eq(test_routes.inbox_path(1, format: nil))
|
151
179
|
end
|
152
180
|
|
153
|
-
|
154
181
|
it "shouldn't require the format" do
|
155
|
-
|
156
|
-
expect(evaljs("Routes.json_only_path()")).to eq(test_routes.json_only_path(:format => 'json'))
|
182
|
+
expect(evaljs("Routes.json_only_path()")).to eq(test_routes.json_only_path)
|
157
183
|
end
|
158
184
|
end
|
159
185
|
|
@@ -162,36 +188,45 @@ describe JsRoutes, "options" do
|
|
162
188
|
expect(evaljs("Routes.no_format_path({format: 'json'})")).to eq(test_routes.no_format_path(format: 'json'))
|
163
189
|
end
|
164
190
|
|
165
|
-
describe "
|
191
|
+
describe "namespace option" do
|
166
192
|
let(:_options) { {:namespace => "PHM"} }
|
167
193
|
it "should use this namespace for routing" do
|
168
194
|
expect(evaljs("window.Routes")).to be_nil
|
169
195
|
expect(evaljs("PHM.inbox_path")).not_to be_nil
|
170
196
|
end
|
171
|
-
end
|
172
197
|
|
173
|
-
|
174
|
-
|
175
|
-
let(:_presetup) { "window.PHM = {}" }
|
176
|
-
let(:_options) { {:namespace => "PHM.Routes"} }
|
198
|
+
context "is nil" do
|
199
|
+
let(:_options) { {:namespace => nil, include: /^inbox$/} }
|
177
200
|
it "should use this namespace for routing" do
|
178
|
-
|
201
|
+
evaljs("window.zz = #{generated_js}")
|
202
|
+
expect(evaljs("window.zz.inbox_path")).not_to be_nil
|
179
203
|
end
|
204
|
+
|
180
205
|
end
|
181
206
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
207
|
+
describe "is nested" do
|
208
|
+
context "and defined on client" do
|
209
|
+
let(:_presetup) { "window.PHM = {}" }
|
210
|
+
let(:_options) { {:namespace => "PHM.Routes"} }
|
211
|
+
it "should use this namespace for routing" do
|
212
|
+
expect(evaljs("PHM.Routes.inbox_path")).not_to be_nil
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
context "but undefined on client" do
|
217
|
+
let(:_options) { {:namespace => "PHM.Routes"} }
|
218
|
+
it "should initialize namespace" do
|
219
|
+
expect(evaljs("window.PHM.Routes.inbox_path")).not_to be_nil
|
220
|
+
end
|
186
221
|
end
|
187
|
-
end
|
188
222
|
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
223
|
+
context "and some parts are defined" do
|
224
|
+
let(:_presetup) { "window.PHM = { Utils: {} };" }
|
225
|
+
let(:_options) { {:namespace => "PHM.Routes"} }
|
226
|
+
it "should not overwrite existing parts" do
|
227
|
+
expect(evaljs("window.PHM.Utils")).not_to be_nil
|
228
|
+
expect(evaljs("window.PHM.Routes.inbox_path")).not_to be_nil
|
229
|
+
end
|
195
230
|
end
|
196
231
|
end
|
197
232
|
end
|
@@ -201,14 +236,14 @@ describe JsRoutes, "options" do
|
|
201
236
|
context "provided" do
|
202
237
|
let(:_options) { { :default_url_options => { :optional_id => "12", :format => "json" } } }
|
203
238
|
it "should use this opions to fill optional parameters" do
|
204
|
-
expect(evaljs("Routes.things_path()")).to eq(test_routes.things_path
|
239
|
+
expect(evaljs("Routes.things_path()")).to eq(test_routes.things_path)
|
205
240
|
end
|
206
241
|
end
|
207
242
|
|
208
243
|
context "not provided" do
|
209
244
|
let(:_options) { { :default_url_options => { :format => "json" } } }
|
210
245
|
it "breaks" do
|
211
|
-
expect(evaljs("Routes.foo_all_path()")).to eq(test_routes.foo_all_path
|
246
|
+
expect(evaljs("Routes.foo_all_path()")).to eq(test_routes.foo_all_path)
|
212
247
|
end
|
213
248
|
end
|
214
249
|
end
|
@@ -216,7 +251,7 @@ describe JsRoutes, "options" do
|
|
216
251
|
context "with required route parts" do
|
217
252
|
let(:_options) { {:default_url_options => {:inbox_id => "12"}} }
|
218
253
|
it "should use this opions to fill optional parameters" do
|
219
|
-
expect(evaljs("Routes.inbox_messages_path()")).to eq(test_routes.inbox_messages_path
|
254
|
+
expect(evaljs("Routes.inbox_messages_path()")).to eq(test_routes.inbox_messages_path)
|
220
255
|
end
|
221
256
|
end
|
222
257
|
|
@@ -248,7 +283,7 @@ describe JsRoutes, "options" do
|
|
248
283
|
end
|
249
284
|
|
250
285
|
it "should remove it by params" do
|
251
|
-
expect(evaljs("Routes.inbox_path(1, {trailing_slash: false})")).to eq(test_routes.inbox_path(1))
|
286
|
+
expect(evaljs("Routes.inbox_path(1, {trailing_slash: false})")).to eq(test_routes.inbox_path(1, trailing_slash: false))
|
252
287
|
end
|
253
288
|
end
|
254
289
|
|
@@ -349,8 +384,8 @@ describe JsRoutes, "options" do
|
|
349
384
|
expect(evaljs("Routes.sso_url()")).to eq("http://sso.example.com:3000" + test_routes.sso_path)
|
350
385
|
end
|
351
386
|
|
352
|
-
it "does not override
|
353
|
-
expect(evaljs("Routes.
|
387
|
+
it "does not override parts when specified in route" do
|
388
|
+
expect(evaljs("Routes.secret_root_url()")).to eq(test_routes.secret_root_url)
|
354
389
|
end
|
355
390
|
end
|
356
391
|
|
@@ -358,9 +393,6 @@ describe JsRoutes, "options" do
|
|
358
393
|
let(:_options) { { :camel_case => true, :url_links => true, :default_url_options => {:host => "example.com"} } }
|
359
394
|
it "should generate path and url links" do
|
360
395
|
expect(evaljs("Routes.inboxUrl(1)")).to eq("http://example.com#{test_routes.inbox_path(1)}")
|
361
|
-
expect(evaljs("Routes.newSessionUrl()")).to eq("https://example.com#{test_routes.new_session_path}")
|
362
|
-
expect(evaljs("Routes.ssoUrl()")).to eq(test_routes.sso_url)
|
363
|
-
expect(evaljs("Routes.portalsUrl()")).to eq("http://example.com:8080#{test_routes.portals_path}")
|
364
396
|
end
|
365
397
|
end
|
366
398
|
|
@@ -368,9 +400,6 @@ describe JsRoutes, "options" do
|
|
368
400
|
let(:_options) { { :prefix => "/api", :url_links => true, :default_url_options => {:host => 'example.com'} } }
|
369
401
|
it "should generate path and url links" do
|
370
402
|
expect(evaljs("Routes.inbox_url(1)")).to eq("http://example.com/api#{test_routes.inbox_path(1)}")
|
371
|
-
expect(evaljs("Routes.new_session_url()")).to eq("https://example.com/api#{test_routes.new_session_path}")
|
372
|
-
expect(evaljs("Routes.sso_url()")).to eq("http://sso.example.com/api#{test_routes.sso_path}")
|
373
|
-
expect(evaljs("Routes.portals_url()")).to eq("http://example.com:8080/api#{test_routes.portals_path}")
|
374
403
|
end
|
375
404
|
end
|
376
405
|
|
@@ -378,9 +407,6 @@ describe JsRoutes, "options" do
|
|
378
407
|
let(:_options) { { :compact => true, :url_links => true, :default_url_options => {:host => 'example.com'} } }
|
379
408
|
it "does not affect url helpers" do
|
380
409
|
expect(evaljs("Routes.inbox_url(1)")).to eq("http://example.com#{test_routes.inbox_path(1)}")
|
381
|
-
expect(evaljs("Routes.new_session_url()")).to eq("https://example.com#{test_routes.new_session_path}")
|
382
|
-
expect(evaljs("Routes.sso_url()")).to eq(test_routes.sso_url)
|
383
|
-
expect(evaljs("Routes.portals_url()")).to eq("http://example.com:8080#{test_routes.portals_path}")
|
384
410
|
end
|
385
411
|
end
|
386
412
|
end
|
@@ -408,20 +434,27 @@ describe JsRoutes, "options" do
|
|
408
434
|
expect(evaljs("Routes.inbox_url(1)")).to eq("http://current.example.com#{test_routes.inbox_path(1)}")
|
409
435
|
expect(evaljs("Routes.inbox_url(1, { test_key: \"test_val\" })")).to eq("http://current.example.com#{test_routes.inbox_path(1, :test_key => "test_val")}")
|
410
436
|
expect(evaljs("Routes.new_session_url()")).to eq("https://current.example.com#{test_routes.new_session_path}")
|
411
|
-
expect(evaljs("Routes.sso_url()")).to eq("http://sso.example.com#{test_routes.sso_path}")
|
412
437
|
|
413
438
|
end
|
414
439
|
|
440
|
+
it "doesn't use current when specified in the route" do
|
441
|
+
expect(evaljs("Routes.sso_url()")).to eq(test_routes.sso_url)
|
442
|
+
end
|
443
|
+
|
415
444
|
it "uses host option as an argument" do
|
416
|
-
expect(evaljs("Routes.
|
445
|
+
expect(evaljs("Routes.secret_root_url({host: 'another.com'})")).to eq(test_routes.secret_root_url(host: 'another.com'))
|
417
446
|
end
|
418
447
|
|
419
448
|
it "uses port option as an argument" do
|
420
|
-
expect(evaljs("Routes.
|
449
|
+
expect(evaljs("Routes.secret_root_url({host: 'localhost', port: 8080})")).to eq(test_routes.secret_root_url(host: 'localhost', port: 8080))
|
421
450
|
end
|
422
451
|
|
423
452
|
it "uses protocol option as an argument" do
|
424
|
-
expect(evaljs("Routes.
|
453
|
+
expect(evaljs("Routes.secret_root_url({host: 'localhost', protocol: 'https'})")).to eq(test_routes.secret_root_url(protocol: 'https', host: 'localhost'))
|
454
|
+
end
|
455
|
+
|
456
|
+
it "uses subdomain option as an argument" do
|
457
|
+
expect(evaljs("Routes.secret_root_url({subdomain: 'custom'})")).to eq(test_routes.secret_root_url(subdomain: 'custom'))
|
425
458
|
end
|
426
459
|
end
|
427
460
|
end
|
@@ -478,4 +511,13 @@ describe JsRoutes, "options" do
|
|
478
511
|
expect(evaljs("Routes.posts_path()")).not_to be_nil
|
479
512
|
end
|
480
513
|
end
|
514
|
+
|
515
|
+
describe "documentation option" do
|
516
|
+
let(:_options) { {documentation: false} }
|
517
|
+
|
518
|
+
it "disables documentation generation" do
|
519
|
+
expect(generated_js).not_to include("@param")
|
520
|
+
expect(generated_js).not_to include("@returns")
|
521
|
+
end
|
522
|
+
end
|
481
523
|
end
|
@@ -3,7 +3,7 @@ require "spec_helper"
|
|
3
3
|
describe JsRoutes, "compatibility with Rails" do
|
4
4
|
|
5
5
|
before(:each) do
|
6
|
-
evaljs(JsRoutes.generate({}))
|
6
|
+
evaljs(JsRoutes.generate({module_type: nil, namespace: 'Routes'}))
|
7
7
|
end
|
8
8
|
|
9
9
|
it "should generate collection routing" do
|
@@ -14,15 +14,31 @@ describe JsRoutes, "compatibility with Rails" do
|
|
14
14
|
expect(evaljs("Routes.inbox_path(1)")).to eq(test_routes.inbox_path(1))
|
15
15
|
end
|
16
16
|
|
17
|
-
it "should raise error if required argument is not passed" do
|
17
|
+
it "should raise error if required argument is not passed", :aggregate_failures do
|
18
18
|
expect { evaljs("Routes.thing_path()") }
|
19
|
-
.to raise_error(
|
19
|
+
.to raise_error(/Route missing required keys: id/)
|
20
20
|
expect { evaljs("Routes.search_path()") }
|
21
|
-
.to raise_error(
|
21
|
+
.to raise_error(/Route missing required keys: q/)
|
22
22
|
expect { evaljs("Routes.book_path()") }
|
23
|
-
.to raise_error(
|
23
|
+
.to raise_error(/Route missing required keys: section, title/)
|
24
24
|
expect { evaljs("Routes.book_title_path()") }
|
25
|
-
.to raise_error(
|
25
|
+
.to raise_error(/Route missing required keys: title/)
|
26
|
+
|
27
|
+
expect( evaljs("try {Routes.thing_path()} catch (e) { e.name }") ).to eq('ParametersMissing')
|
28
|
+
expect( evaljs("try {Routes.thing_path()} catch (e) { e.keys }") ).to eq(['id'])
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should produce error stacktraces including function names" do
|
32
|
+
stacktrace = evaljs("
|
33
|
+
(function(){
|
34
|
+
try {
|
35
|
+
Routes.thing_path()
|
36
|
+
} catch(e) {
|
37
|
+
return e.stack;
|
38
|
+
}
|
39
|
+
})()
|
40
|
+
")
|
41
|
+
expect(stacktrace).to include "thing_path"
|
26
42
|
end
|
27
43
|
|
28
44
|
it "should support 0 as a member parameter" do
|
@@ -57,6 +73,10 @@ describe JsRoutes, "compatibility with Rails" do
|
|
57
73
|
expect(evaljs("Routes.inbox_path(1, {expanded: true, anchor: 'hello'})")).to eq(test_routes.inbox_path(1, :expanded => true, :anchor => "hello"))
|
58
74
|
end
|
59
75
|
|
76
|
+
it "should support required parameters given as options hash" do
|
77
|
+
expect(evaljs("Routes.search_path({q: 'hello'})")).to eq(test_routes.search_path(:q => 'hello'))
|
78
|
+
end
|
79
|
+
|
60
80
|
it "should use irregular ActiveSupport pluralizations" do
|
61
81
|
expect(evaljs("Routes.budgies_path()")).to eq(test_routes.budgies_path)
|
62
82
|
expect(evaljs("Routes.budgie_path(1)")).to eq(test_routes.budgie_path(1))
|
@@ -64,6 +84,16 @@ describe JsRoutes, "compatibility with Rails" do
|
|
64
84
|
expect(evaljs("Routes.budgie_descendents_path(1)")).to eq(test_routes.budgie_descendents_path(1))
|
65
85
|
end
|
66
86
|
|
87
|
+
it "should support route with parameters containing symbols that need URI-encoding", :aggregate_failures do
|
88
|
+
expect(evaljs("Routes.inbox_path('#hello')")).to eq(test_routes.inbox_path('#hello'))
|
89
|
+
expect(evaljs("Routes.inbox_path('some param')")).to eq(test_routes.inbox_path('some param'))
|
90
|
+
expect(evaljs("Routes.inbox_path('some param with more & more encode symbols')")).to eq(test_routes.inbox_path('some param with more & more encode symbols'))
|
91
|
+
end
|
92
|
+
it "should support route with parameters containing symbols not need URI-encoding", :aggregate_failures do
|
93
|
+
expect(evaljs("Routes.inbox_path(':some_id')")).to eq(test_routes.inbox_path(':some_id'))
|
94
|
+
expect(evaljs("Routes.inbox_path('.+')")).to eq(test_routes.inbox_path('.+'))
|
95
|
+
end
|
96
|
+
|
67
97
|
describe "when route has defaults" do
|
68
98
|
it "should support route default format" do
|
69
99
|
expect(evaljs("Routes.api_purchases_path()")).to eq(test_routes.api_purchases_path)
|
@@ -83,6 +113,7 @@ describe JsRoutes, "compatibility with Rails" do
|
|
83
113
|
|
84
114
|
it "doesn't apply defaults to path" do
|
85
115
|
expect(evaljs("Routes.with_defaults_path()")).to eq(test_routes.with_defaults_path)
|
116
|
+
expect(evaljs("Routes.with_defaults_path({format: 'json'})")).to eq(test_routes.with_defaults_path(format: 'json'))
|
86
117
|
end
|
87
118
|
end
|
88
119
|
|
@@ -104,6 +135,11 @@ describe JsRoutes, "compatibility with Rails" do
|
|
104
135
|
it "should support single route mapping" do
|
105
136
|
expect(evaljs("Routes.support_path({page: 3})")).to eq(test_routes.support_path(:page => 3))
|
106
137
|
end
|
138
|
+
|
139
|
+
it 'works' do
|
140
|
+
expect(evaljs("Routes.planner_manage_path({locale: 'ua'})")).to eq(planner_routes.manage_path(locale: 'ua'))
|
141
|
+
expect(evaljs("Routes.planner_manage_path()")).to eq(planner_routes.manage_path)
|
142
|
+
end
|
107
143
|
end
|
108
144
|
|
109
145
|
it "shouldn't require the format" do
|
@@ -122,7 +158,7 @@ describe JsRoutes, "compatibility with Rails" do
|
|
122
158
|
expect(evaljs("Routes.root_path()")).to eq(test_routes.root_path)
|
123
159
|
end
|
124
160
|
|
125
|
-
describe "get
|
161
|
+
describe "get parameters" do
|
126
162
|
it "should support simple get parameters" do
|
127
163
|
expect(evaljs("Routes.inbox_path(1, {format: 'json', lang: 'ua', q: 'hello'})")).to eq(test_routes.inbox_path(1, :lang => "ua", :q => "hello", :format => "json"))
|
128
164
|
end
|
@@ -131,6 +167,19 @@ describe JsRoutes, "compatibility with Rails" do
|
|
131
167
|
expect(evaljs("Routes.inbox_path(1, {hello: ['world', 'mars']})")).to eq(test_routes.inbox_path(1, :hello => [:world, :mars]))
|
132
168
|
end
|
133
169
|
|
170
|
+
context "object without prototype" do
|
171
|
+
before(:each) do
|
172
|
+
evaljs("let params = Object.create(null); params.q = 'hello';")
|
173
|
+
evaljs("let inbox = Object.create(null); inbox.to_param = 1;")
|
174
|
+
end
|
175
|
+
|
176
|
+
it "should still work correctly" do
|
177
|
+
expect(evaljs("Routes.inbox_path(inbox, params)")).to eq(
|
178
|
+
test_routes.inbox_path(1, q: "hello")
|
179
|
+
)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
134
183
|
it "should support nested get parameters" do
|
135
184
|
expect(evaljs("Routes.inbox_path(1, {format: 'json', env: 'test', search: { category_ids: [2,5], q: 'hello'}})")).to eq(
|
136
185
|
test_routes.inbox_path(1, :env => 'test', :search => {:category_ids => [2,5], :q => "hello"}, :format => "json")
|
@@ -145,6 +194,9 @@ describe JsRoutes, "compatibility with Rails" do
|
|
145
194
|
expect(evaljs("Routes.inboxes_path({uri: 'http://example.com'})")).to eq(test_routes.inboxes_path(:uri => 'http://example.com'))
|
146
195
|
end
|
147
196
|
|
197
|
+
it "should support nested object null parameters" do
|
198
|
+
expect(evaljs("Routes.inboxes_path({hello: {world: null}})")).to eq(test_routes.inboxes_path(:hello => {:world => nil}))
|
199
|
+
end
|
148
200
|
end
|
149
201
|
|
150
202
|
|
@@ -157,14 +209,18 @@ describe JsRoutes, "compatibility with Rails" do
|
|
157
209
|
expect(evaljs("Routes.book_path(['thrillers'], 1)")).to eq(test_routes.book_path(['thrillers'], 1))
|
158
210
|
end
|
159
211
|
|
160
|
-
it "should
|
212
|
+
it "should support routes globbing as array" do
|
161
213
|
expect(evaljs("Routes.book_path([1, 2, 3], 1)")).to eq(test_routes.book_path([1, 2, 3], 1))
|
162
214
|
end
|
163
215
|
|
164
|
-
it "should
|
216
|
+
it "should support routes globbing with slash" do
|
165
217
|
expect(evaljs("Routes.book_path('a_test/b_test/c_test', 1)")).to eq(test_routes.book_path('a_test/b_test/c_test', 1))
|
166
218
|
end
|
167
219
|
|
220
|
+
it "should support routes globbing as hash" do
|
221
|
+
expect(evaljs("Routes.book_path('a%b', 1)")).to eq(test_routes.book_path('a%b', 1))
|
222
|
+
end
|
223
|
+
|
168
224
|
it "should support routes globbing as array with optional params" do
|
169
225
|
expect(evaljs("Routes.book_path([1, 2, 3, 5], 1, {c: '1'})")).to eq(test_routes.book_path([1, 2, 3, 5], 1, { :c => "1" }))
|
170
226
|
end
|
@@ -176,14 +232,6 @@ describe JsRoutes, "compatibility with Rails" do
|
|
176
232
|
it "should support routes globbing in book_title route as array with optional params" do
|
177
233
|
expect(evaljs("Routes.book_title_path('john', ['thrillers', 'comedian'], {some_key: 'some_value'})")).to eq(test_routes.book_title_path('john', ['thrillers', 'comedian'], {:some_key => 'some_value'}))
|
178
234
|
end
|
179
|
-
|
180
|
-
it "should support required paramters given as options hash" do
|
181
|
-
expect(evaljs("Routes.search_path({q: 'hello'})")).to eq(test_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(test_routes.inboxes_path(:hello => {:world => nil}))
|
186
|
-
end
|
187
235
|
end
|
188
236
|
|
189
237
|
context "using optional path fragments" do
|
@@ -199,6 +247,15 @@ describe JsRoutes, "compatibility with Rails" do
|
|
199
247
|
expect(evaljs("Routes.things_path({ q: 'hello' })")).to eq(test_routes.things_path(q: 'hello'))
|
200
248
|
end
|
201
249
|
|
250
|
+
it "treats false as absent optional part" do
|
251
|
+
pending("https://github.com/rails/rails/issues/42280")
|
252
|
+
expect(evaljs("Routes.things_path(false)")).to eq(test_routes.things_path(false))
|
253
|
+
end
|
254
|
+
|
255
|
+
it "treats false as absent optional part when default is specified" do
|
256
|
+
expect(evaljs("Routes.campaigns_path(false)")).to eq(test_routes.campaigns_path(false))
|
257
|
+
end
|
258
|
+
|
202
259
|
it "should not require the optional parts as arguments" do
|
203
260
|
expect(evaljs("Routes.thing_path(null, 5)")).to eq(test_routes.thing_path(nil, 5))
|
204
261
|
end
|
@@ -209,7 +266,7 @@ describe JsRoutes, "compatibility with Rails" do
|
|
209
266
|
|
210
267
|
it "should raise error when passing non-full list of arguments and some query params" do
|
211
268
|
expect { evaljs("Routes.thing_path(5, {q: 'hello'})") }
|
212
|
-
.to raise_error(
|
269
|
+
.to raise_error(/Route missing required keys: id/)
|
213
270
|
end
|
214
271
|
|
215
272
|
it "should treat null as non-given optional part" do
|
@@ -221,19 +278,13 @@ describe JsRoutes, "compatibility with Rails" do
|
|
221
278
|
end
|
222
279
|
|
223
280
|
it "should skip leading and trailing optional parts" do
|
224
|
-
skip if Rails.version < '4'
|
225
281
|
expect(evaljs("Routes.thing_deep_path(1, 2)")).to eq(test_routes.thing_deep_path(1, 2))
|
226
282
|
end
|
227
283
|
end
|
228
284
|
|
229
285
|
context "and including them" do
|
230
|
-
|
231
|
-
|
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
|
286
|
+
it "should fail when insufficient arguments are given" do
|
287
|
+
expect { evaljs("Routes.thing_deep_path(2)") }.to raise_error(/Route missing required keys: third_required/)
|
237
288
|
end
|
238
289
|
|
239
290
|
it "should include the optional parts" do
|
@@ -245,6 +296,7 @@ describe JsRoutes, "compatibility with Rails" do
|
|
245
296
|
expect(evaljs("Routes.thing_deep_path(3, { first_optional: 1, second_required: 2 })")).to eq(test_routes.thing_deep_path(3, first_optional: 1, second_required: 2))
|
246
297
|
expect(evaljs("Routes.thing_deep_path(3, { first_optional: 1, second_required: 2, forth_optional: 4 })")).to eq(test_routes.thing_deep_path(3, first_optional: 1, second_required: 2, forth_optional: 4))
|
247
298
|
expect(evaljs("Routes.thing_deep_path(4, { first_optional: 1, second_required: 2, third_required: 3 })")).to eq(test_routes.thing_deep_path(4, first_optional: 1, second_required: 2, third_required: 3))
|
299
|
+
expect(evaljs("Routes.thing_deep_path(2, 3)")).to eq(test_routes.thing_deep_path(2, 3))
|
248
300
|
expect(evaljs("Routes.thing_deep_path(1, 2, { third_required: 3 })")).to eq(test_routes.thing_deep_path(1, 2, third_required: 3))
|
249
301
|
expect(evaljs("Routes.thing_deep_path(1,2, {third_required: 3, q: 'bogdan'})")).to eq(test_routes.thing_deep_path(1,2, {third_required: 3, q: 'bogdan'}))
|
250
302
|
expect(evaljs("Routes.thing_deep_path(1, 2, { forth_optional: 4, third_required: 3 })")).to eq(test_routes.thing_deep_path(1, 2, forth_optional: 4, third_required: 3))
|
@@ -281,27 +333,22 @@ describe JsRoutes, "compatibility with Rails" do
|
|
281
333
|
evaljs("Routes.inbox_path()")
|
282
334
|
}.to raise_error(js_error_class)
|
283
335
|
end
|
336
|
+
|
284
337
|
it "should throw Exception if required parameter is not defined" do
|
285
338
|
expect {
|
286
339
|
evaljs("Routes.inbox_path(null)")
|
287
340
|
}.to raise_error(js_error_class)
|
288
341
|
end
|
289
342
|
|
290
|
-
it "should throw
|
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
|
343
|
+
it "should throw Exception if required parameter is not defined" do
|
297
344
|
expect {
|
298
|
-
evaljs("Routes.inbox_path(
|
345
|
+
evaljs("Routes.inbox_path(undefined)")
|
299
346
|
}.to raise_error(js_error_class)
|
300
347
|
end
|
301
348
|
|
302
|
-
it "should throw Exceptions if when
|
349
|
+
it "should throw Exceptions if when there is too many parameters" do
|
303
350
|
expect {
|
304
|
-
evaljs("Routes.inbox_path(
|
351
|
+
evaljs("Routes.inbox_path(1,2,3)")
|
305
352
|
}.to raise_error(js_error_class)
|
306
353
|
end
|
307
354
|
end
|
@@ -320,8 +367,19 @@ describe JsRoutes, "compatibility with Rails" do
|
|
320
367
|
let(:klass) { Struct.new(:id, :to_param) }
|
321
368
|
let(:inbox) { klass.new(1,"my") }
|
322
369
|
|
370
|
+
it "should throw Exceptions if when pass id with null" do
|
371
|
+
expect {
|
372
|
+
evaljs("Routes.inbox_path({id: null})")
|
373
|
+
}.to raise_error(js_error_class)
|
374
|
+
end
|
375
|
+
|
376
|
+
it "should throw Exceptions if when pass to_param with null" do
|
377
|
+
expect {
|
378
|
+
evaljs("Routes.inbox_path({to_param: null})")
|
379
|
+
}.to raise_error(js_error_class)
|
380
|
+
end
|
323
381
|
it "should support 0 as a to_param option" do
|
324
|
-
expect(evaljs("Routes.inbox_path({to_param: 0})")).to eq(test_routes.inbox_path(0))
|
382
|
+
expect(evaljs("Routes.inbox_path({to_param: 0})")).to eq(test_routes.inbox_path(Struct.new(:to_param).new('0')))
|
325
383
|
end
|
326
384
|
|
327
385
|
it "should check for options special key" do
|
@@ -332,9 +390,6 @@ describe JsRoutes, "compatibility with Rails" do
|
|
332
390
|
expect(evaljs("Routes.inbox_message_path(5, {id: 7, q: 'hello', _options: true})")).to eq(test_routes.inbox_message_path(5, id: 7, q: 'hello'))
|
333
391
|
end
|
334
392
|
|
335
|
-
it "should check for options special key" do
|
336
|
-
end
|
337
|
-
|
338
393
|
it "should support 0 as an id option" do
|
339
394
|
expect(evaljs("Routes.inbox_path({id: 0})")).to eq(test_routes.inbox_path(0))
|
340
395
|
end
|
@@ -361,6 +416,14 @@ describe JsRoutes, "compatibility with Rails" do
|
|
361
416
|
)).to eq(test_routes.inbox_message_path(inbox, 2, :custom => true, :format => "json"))
|
362
417
|
end
|
363
418
|
|
419
|
+
it "supports camel case property name" do
|
420
|
+
expect(evaljs("Routes.inbox_path({id: 1, toParam: 'my'})")).to eq(test_routes.inbox_path(inbox))
|
421
|
+
end
|
422
|
+
|
423
|
+
it "supports camel case method name" do
|
424
|
+
expect(evaljs("Routes.inbox_path({id: 1, toParam: function(){ return 'my';}})")).to eq(test_routes.inbox_path(inbox))
|
425
|
+
end
|
426
|
+
|
364
427
|
context "when globbing" do
|
365
428
|
it "should prefer to_param property over id property" do
|
366
429
|
expect(evaljs("Routes.book_path({id: 1, to_param: 'my'}, 1)")).to eq(test_routes.book_path(inbox, 1))
|
@@ -380,6 +443,7 @@ describe JsRoutes, "compatibility with Rails" do
|
|
380
443
|
)).to eq(test_routes.book_path(inbox, 2, :custom => true, :format => "json"))
|
381
444
|
end
|
382
445
|
end
|
446
|
+
|
383
447
|
end
|
384
448
|
|
385
449
|
context "when specs" do
|
@@ -400,15 +464,13 @@ describe JsRoutes, "compatibility with Rails" do
|
|
400
464
|
end
|
401
465
|
end
|
402
466
|
|
403
|
-
describe "
|
467
|
+
describe "requiredParams" do
|
404
468
|
it "should show inbox spec" do
|
405
|
-
expect(evaljs("Routes.inbox_path.
|
469
|
+
expect(evaljs("Routes.inbox_path.requiredParams()").to_a).to eq(["id"])
|
406
470
|
end
|
407
471
|
|
408
472
|
it "should show inbox message spec" do
|
409
|
-
expect(evaljs("Routes.inbox_message_path.
|
473
|
+
expect(evaljs("Routes.inbox_message_path.requiredParams()").to_a).to eq(["inbox_id", "id"])
|
410
474
|
end
|
411
475
|
end
|
412
|
-
|
413
|
-
|
414
476
|
end
|
@@ -5,7 +5,7 @@
|
|
5
5
|
require 'spec_helper'
|
6
6
|
require "fileutils"
|
7
7
|
|
8
|
-
describe "after Rails initialization" do
|
8
|
+
describe "after Rails initialization", :slow do
|
9
9
|
NAME = Rails.root.join('app', 'assets', 'javascripts', 'routes.js').to_s
|
10
10
|
|
11
11
|
def sprockets_v3?
|
@@ -43,6 +43,21 @@ describe "after Rails initialization" do
|
|
43
43
|
expect(File.exists?(NAME)).to be_truthy
|
44
44
|
end
|
45
45
|
|
46
|
+
it "should not rewrite routes file if nothing changed" do
|
47
|
+
routes_file_mtime = File.mtime(NAME)
|
48
|
+
JsRoutes.generate!(NAME)
|
49
|
+
expect(File.mtime(NAME)).to eq(routes_file_mtime)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should rewrite routes file if file content changed" do
|
53
|
+
# Change content of existed routes file (add space to the end of file).
|
54
|
+
File.open(NAME, 'a') { |f| f << ' ' }
|
55
|
+
routes_file_mtime = File.mtime(NAME)
|
56
|
+
sleep(1)
|
57
|
+
JsRoutes.generate!(NAME)
|
58
|
+
expect(File.mtime(NAME)).not_to eq(routes_file_mtime)
|
59
|
+
end
|
60
|
+
|
46
61
|
context "JsRoutes::Engine" do
|
47
62
|
TEST_ASSET_PATH = Rails.root.join('app','assets','javascripts','test.js')
|
48
63
|
|
@@ -78,7 +93,7 @@ describe "after Rails initialization" do
|
|
78
93
|
Rails.application.config.assets.initialize_on_precompile = true
|
79
94
|
end
|
80
95
|
it "should render some javascript" do
|
81
|
-
expect(evaluate(ctx, 'js-routes.js')).to match(/
|
96
|
+
expect(evaluate(ctx, 'js-routes.js')).to match(/Utils\.define_module/)
|
82
97
|
end
|
83
98
|
end
|
84
99
|
context "and not initialize on precompile" do
|
@@ -86,11 +101,7 @@ describe "after Rails initialization" do
|
|
86
101
|
Rails.application.config.assets.initialize_on_precompile = false
|
87
102
|
end
|
88
103
|
it "should raise an exception if 3 version" do
|
89
|
-
|
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
|
104
|
+
expect(evaluate(ctx, 'js-routes.js')).to match(/Utils\.define_module/)
|
94
105
|
end
|
95
106
|
end
|
96
107
|
|
@@ -111,7 +122,7 @@ describe "after Rails initialization" do
|
|
111
122
|
end
|
112
123
|
end
|
113
124
|
|
114
|
-
describe "JSRoutes thread safety" do
|
125
|
+
describe "JSRoutes thread safety", :slow do
|
115
126
|
before do
|
116
127
|
begin
|
117
128
|
Rails.application.initialize!
|