js-routes 1.4.1 → 2.1.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 +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!
|