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.
Files changed (50) hide show
  1. checksums.yaml +5 -5
  2. data/.eslintrc.js +15 -0
  3. data/.gitignore +5 -0
  4. data/.nvmrc +1 -0
  5. data/.travis.yml +37 -30
  6. data/Appraisals +16 -13
  7. data/CHANGELOG.md +95 -0
  8. data/Rakefile +6 -2
  9. data/Readme.md +220 -88
  10. data/VERSION_2_UPGRADE.md +66 -0
  11. data/app/assets/javascripts/js-routes.js.erb +1 -1
  12. data/gemfiles/{rails40.gemfile → rails40_sprockets_2.gemfile} +1 -1
  13. data/gemfiles/{rails40_sprockets3.gemfile → rails40_sprockets_3.gemfile} +0 -0
  14. data/gemfiles/{rails41.gemfile → rails41_sprockets_2.gemfile} +1 -1
  15. data/gemfiles/{rails41_sprockets3.gemfile → rails41_sprockets_3.gemfile} +0 -0
  16. data/gemfiles/{rails32.gemfile → rails42_sprockets_2.gemfile} +2 -2
  17. data/gemfiles/{rails42_sprockets3.gemfile → rails42_sprockets_3.gemfile} +1 -1
  18. data/gemfiles/{rails50_sprockets3.gemfile → rails50_sprockets_3.gemfile} +1 -1
  19. data/gemfiles/rails51_sprockets_3.gemfile +8 -0
  20. data/gemfiles/rails52_sprockets_3.gemfile +8 -0
  21. data/js-routes.gemspec +9 -6
  22. data/lib/js_routes/engine.rb +6 -18
  23. data/lib/js_routes/version.rb +1 -1
  24. data/lib/js_routes.rb +329 -171
  25. data/lib/routes.d.ts +79 -0
  26. data/lib/routes.js +499 -485
  27. data/lib/routes.ts +732 -0
  28. data/lib/tasks/js_routes.rake +8 -2
  29. data/package.json +37 -0
  30. data/spec/dummy/app/assets/config/manifest.js +2 -0
  31. data/spec/js_routes/default_serializer_spec.rb +19 -3
  32. data/spec/js_routes/{amd_compatibility_spec.rb → module_types/amd_spec.rb} +1 -9
  33. data/spec/js_routes/module_types/cjs_spec.rb +15 -0
  34. data/spec/js_routes/module_types/dts/routes.spec.d.ts +114 -0
  35. data/spec/js_routes/module_types/dts/test.spec.ts +56 -0
  36. data/spec/js_routes/module_types/dts_spec.rb +111 -0
  37. data/spec/js_routes/module_types/esm_spec.rb +45 -0
  38. data/spec/js_routes/{generated_javascript_spec.rb → module_types/umd_spec.rb} +33 -27
  39. data/spec/js_routes/options_spec.rb +92 -50
  40. data/spec/js_routes/rails_routes_compatibility_spec.rb +107 -45
  41. data/spec/js_routes/zzz_last_post_rails_init_spec.rb +19 -8
  42. data/spec/spec_helper.rb +45 -42
  43. data/spec/support/routes.rb +19 -14
  44. data/spec/tsconfig.json +4 -0
  45. data/tsconfig.json +28 -0
  46. data/yarn.lock +2145 -0
  47. metadata +47 -34
  48. data/gemfiles/rails42.gemfile +0 -8
  49. data/gemfiles/rails50.gemfile +0 -8
  50. 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(JsRoutes.generate(_options))
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 set configurable serializer" do
36
- # expect to use default
37
- expect(evaljs(%q(Routes.inboxes_path({a: 1})))).to eql("/inboxes?a=1")
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
- it "should render routing with default_format" do
138
- expect(evaljs("Routes.inbox_path(1)")).to eq(test_routes.inbox_path(1, :format => "json"))
139
- end
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
- it "should render routing with default_format and zero object" do
142
- expect(evaljs("Routes.inbox_path(0)")).to eq(test_routes.inbox_path(0, :format => "json"))
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
- pending if Rails.version < "4.0"
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 "when namespace option is specified" do
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
- describe "when nested namespace option is specified" do
174
- context "and defined on client" do
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
- expect(evaljs("PHM.Routes.inbox_path")).not_to be_nil
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
- context "but undefined on client" do
183
- let(:_options) { {:namespace => "PHM.Routes"} }
184
- it "should initialize namespace" do
185
- expect(evaljs("window.PHM.Routes.inbox_path")).not_to be_nil
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
- context "and some parts are defined" do
190
- let(:_presetup) { "window.PHM = { Utils: {} };" }
191
- let(:_options) { {:namespace => "PHM.Routes"} }
192
- it "should not overwrite existing parts" do
193
- expect(evaljs("window.PHM.Utils")).not_to be_nil
194
- expect(evaljs("window.PHM.Routes.inbox_path")).not_to be_nil
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(:optional_id => 12, :format => "json"))
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(:format => "json"))
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(:inbox_id => 12))
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 port when specified in route" do
353
- expect(evaljs("Routes.portals_url()")).to eq("http://example.com:8080#{test_routes.portals_path}")
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.portals_url({host: 'another.com'})")).to eq(test_routes.portals_url(host: 'another.com'))
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.portals_url({host: 'localhost', port: 8080})")).to eq(test_routes.portals_url(host: 'localhost', port: 8080))
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.portals_url({host: 'localhost', protocol: 'https'})")).to eq(test_routes.portals_url(protocol: 'https', host: 'localhost'))
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('Route parameter missing: id')
19
+ .to raise_error(/Route missing required keys: id/)
20
20
  expect { evaljs("Routes.search_path()") }
21
- .to raise_error('Route parameter missing: q')
21
+ .to raise_error(/Route missing required keys: q/)
22
22
  expect { evaljs("Routes.book_path()") }
23
- .to raise_error('Route parameter missing: title')
23
+ .to raise_error(/Route missing required keys: section, title/)
24
24
  expect { evaljs("Routes.book_title_path()") }
25
- .to raise_error('Route parameter missing: title')
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 paramters" do
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 bee support routes globbing as array" do
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 bee support routes globbing as hash" do
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('Route parameter missing: id')
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
- 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
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 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
343
+ it "should throw Exception if required parameter is not defined" do
297
344
  expect {
298
- evaljs("Routes.inbox_path({id: null})")
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 pass to_param with null" do
349
+ it "should throw Exceptions if when there is too many parameters" do
303
350
  expect {
304
- evaljs("Routes.inbox_path({to_param: null})")
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 "required_params" do
467
+ describe "requiredParams" do
404
468
  it "should show inbox spec" do
405
- expect(evaljs("Routes.inbox_path.required_params").to_a).to eq(["id"])
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.required_params").to_a).to eq(["inbox_id", "id"])
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(/routes = /)
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
- 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
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!