js-routes 1.4.13 → 2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "js-routes",
3
+ "version": "1.0.0",
4
+ "main": "index.js",
5
+ "repository": "git@github.com:railsware/js-routes.git",
6
+ "author": "Bogdan Gusiev <agresso@gmail.com>, Alexey Vasiliev <https://leopard.in.ua> ",
7
+ "license": "MIT",
8
+ "private": false,
9
+ "devDependencies": {
10
+ "typescript": "^4.1.2"
11
+ },
12
+ "dependencies": {
13
+ "@typescript-eslint/eslint-plugin": "^4.9.0",
14
+ "@typescript-eslint/parser": "^4.9.0",
15
+ "eslint": "^7.14.0",
16
+ "eslint-config-prettier": "^6.15.0",
17
+ "eslint-plugin-import": "^2.22.1",
18
+ "husky": "^4.3.0",
19
+ "lint-staged": "^10.5.2",
20
+ "pinst": "^2.1.1",
21
+ "prettier": "^2.2.1"
22
+ },
23
+ "scripts": {
24
+ "lint:fix": "yarn eslint --fix && yarn prettier --write lib/routes.ts",
25
+ "postinstall": "yarn husky-upgrade"
26
+ },
27
+ "husky": {
28
+ "hooks": {
29
+ "pre-commit": "yarn lint:fix"
30
+ }
31
+ },
32
+ "lint-staged": {
33
+ "*.ts": ["yarn lint:fix" ]
34
+ }
35
+
36
+ }
@@ -1,15 +1,31 @@
1
1
  require "spec_helper"
2
2
 
3
- describe JsRoutes, "#default_serializer" do
3
+ describe JsRoutes, "#serialize" do
4
4
 
5
5
  before(:each) do
6
- evaljs(JsRoutes.generate({}))
6
+ evaljs(JsRoutes.generate({module_type: nil}))
7
7
  end
8
8
 
9
9
  it "should provide this method" do
10
- expect(evaljs("Routes.default_serializer({a: 1, b: [2,3], c: {d: 4, e: 5}, f: ''})")).to eq(
10
+ expect(evaljs("Routes.serialize({a: 1, b: [2,3], c: {d: 4, e: 5}, f: ''})")).to eq(
11
11
  "a=1&b%5B%5D=2&b%5B%5D=3&c%5Bd%5D=4&c%5Be%5D=5&f="
12
12
  )
13
13
  end
14
14
 
15
+ it "should provide this method" do
16
+ expect(evaljs("Routes.serialize({a: 1, b: [2,3], c: {d: 4, e: 5}, f: ''})")).to eq(
17
+ "a=1&b%5B%5D=2&b%5B%5D=3&c%5Bd%5D=4&c%5Be%5D=5&f="
18
+ )
19
+ end
20
+
21
+ it "works with JS suckiness" do
22
+ expect(evaljs(
23
+ [
24
+ "const query = Object.create(null);",
25
+ "query.a = 1;",
26
+ "query.b = 2;",
27
+ "Routes.serialize(query);",
28
+ ].join("\n")
29
+ )).to eq("a=1&b=2")
30
+ end
15
31
  end
@@ -24,14 +24,11 @@ describe JsRoutes, "compatibility with AMD/require.js" do
24
24
  };
25
25
  EOF
26
26
  evaljs(strRequire)
27
- evaljs(JsRoutes.generate({}))
27
+ evaljs(JsRoutes.generate({module_type: 'AMD'}))
28
28
  end
29
29
 
30
30
  it "should working from require" do
31
31
  expect(evaljs("require(['js-routes'], function(r){ return r.inboxes_path(); })")).to eq(test_routes.inboxes_path())
32
32
  end
33
33
 
34
- it "should define default export for es6 modules" do
35
- expect(evaljs("require(['js-routes'], function(r){ return r.default.inboxes_path(); })")).to eq(test_routes.inboxes_path())
36
- end
37
34
  end
@@ -1,9 +1,12 @@
1
1
  require "spec_helper"
2
2
 
3
- describe JsRoutes, "compatibility with CommonJS (node)" do
3
+ describe JsRoutes, "compatibility with CJS" do
4
4
  before(:each) do
5
5
  evaljs("module = { exports: null }")
6
- evaljs(JsRoutes.generate({}))
6
+ evaljs(JsRoutes.generate(
7
+ module_type: 'CJS',
8
+ include: /^inboxes/
9
+ ))
7
10
  end
8
11
 
9
12
  it "should define module exports" do
@@ -0,0 +1,45 @@
1
+ require "active_support/core_ext/string/strip"
2
+ require "spec_helper"
3
+
4
+ describe JsRoutes, "compatibility with ESM" do
5
+
6
+ let(:generated_js) {
7
+ JsRoutes.generate(module_type: 'ESM')
8
+ }
9
+
10
+ before(:each) do
11
+ # export keyword is not supported by a simulated js environment
12
+ evaljs(generated_js.gsub("export const ", "const "))
13
+ end
14
+
15
+ it "defines route helpers" do
16
+ expect(evaljs("inboxes_path()")).to eq(test_routes.inboxes_path())
17
+ end
18
+
19
+ it "exports route helpers" do
20
+ expect(generated_js).to include(<<-DOC.rstrip)
21
+ /**
22
+ * Generates rails route to
23
+ * /inboxes(.:format)
24
+ * @param {object | undefined} options
25
+ * @returns {string} route path
26
+ */
27
+ export const inboxes_path = __jsr.r
28
+ DOC
29
+ end
30
+
31
+ it "exports utility methods" do
32
+ expect(generated_js).to include("export const serialize = ")
33
+ end
34
+
35
+ it "defines utility methods" do
36
+ expect(evaljs("serialize({a: 1, b: 2})")).to eq({a: 1, b: 2}.to_param)
37
+ end
38
+
39
+ describe "compiled javascript asset" do
40
+ subject { ERB.new(File.read("app/assets/javascripts/js-routes.js.erb")).result(binding) }
41
+ it "should have js routes code" do
42
+ is_expected.to include("export const inbox_message_path = __jsr.r(")
43
+ end
44
+ end
45
+ end
@@ -1,14 +1,15 @@
1
- require 'spec_helper'
1
+ require "active_support/core_ext/string/strip"
2
2
  require "fileutils"
3
-
3
+ require 'spec_helper'
4
4
 
5
5
  describe JsRoutes do
6
- before(:each) do
7
- evaljs(JsRoutes.generate)
8
- end
9
-
10
6
  describe "generated js" do
11
- subject { JsRoutes.generate }
7
+ subject do
8
+ JsRoutes.generate(
9
+ module_type: 'UMD',
10
+ include: /book|inboxes|inbox_message/,
11
+ )
12
+ end
12
13
 
13
14
  it "should include a comment in the header" do
14
15
  app_class = "App"
@@ -18,23 +19,41 @@ describe JsRoutes do
18
19
  end
19
20
 
20
21
  it "should call route function for each route" do
21
- is_expected.to include("inboxes_path: Utils.route(")
22
+ is_expected.to include("inboxes_path: __jsr.r(")
22
23
  end
23
24
  it "should have correct function without arguments signature" do
24
- is_expected.to include("inboxes_path: Utils.route([[\"format\",false]]")
25
+ is_expected.to include('inboxes_path: __jsr.r({"format":{}}')
25
26
  end
26
27
  it "should have correct function with arguments signature" do
27
- is_expected.to include("inbox_message_path: Utils.route([[\"inbox_id\",true],[\"id\",true],[\"format\",false]]")
28
+ is_expected.to include('inbox_message_path: __jsr.r({"inbox_id":{"r":true},"id":{"r":true},"format":{}}')
28
29
  end
29
30
  it "should have correct function signature with unordered hash" do
30
- is_expected.to include("inbox_message_attachment_path: Utils.route([[\"inbox_id\",true],[\"message_id\",true],[\"id\",true],[\"format\",false]]")
31
+ is_expected.to include('inbox_message_attachment_path: __jsr.r({"inbox_id":{"r":true},"message_id":{"r":true},"id":{"r":true},"format":{}}')
31
32
  end
32
33
 
33
34
  it "should have correct function comment with options argument" do
34
- is_expected.to include("// function(options)\n inboxes_path: Utils.route")
35
+ is_expected.to include(<<-DOC.rstrip)
36
+ /**
37
+ * Generates rails route to
38
+ * /inboxes(.:format)
39
+ * @param {object | undefined} options
40
+ * @returns {string} route path
41
+ */
42
+ inboxes_path: __jsr.r
43
+ DOC
35
44
  end
36
45
  it "should have correct function comment with arguments" do
37
- is_expected.to include("// function(inbox_id, message_id, options)\n new_inbox_message_attachment_path: Utils.route")
46
+ is_expected.to include(<<-DOC.rstrip)
47
+ /**
48
+ * Generates rails route to
49
+ * /inboxes/:inbox_id/messages/:message_id/attachments/new(.:format)
50
+ * @param {any} inbox_id
51
+ * @param {any} message_id
52
+ * @param {object | undefined} options
53
+ * @returns {string} route path
54
+ */
55
+ new_inbox_message_attachment_path: __jsr.r
56
+ DOC
38
57
  end
39
58
 
40
59
  it "routes should be sorted in alphabetical order" do
@@ -62,13 +81,5 @@ describe JsRoutes do
62
81
  it "should not generate file before initialization" do
63
82
  expect(File.exists?(name)).to be_falsey
64
83
  end
65
-
66
- end
67
-
68
- describe "compiled javascript asset" do
69
- subject { ERB.new(File.read("app/assets/javascripts/js-routes.js.erb")).result(binding) }
70
- it "should have js routes code" do
71
- is_expected.to include("inbox_message_path: Utils.route([[\"inbox_id\",true],[\"id\",true],[\"format\",false]]")
72
- end
73
84
  end
74
85
  end
@@ -2,10 +2,14 @@ require 'spec_helper'
2
2
 
3
3
  describe JsRoutes, "options" do
4
4
 
5
+ let(:generated_js) do
6
+ JsRoutes.generate({module_type: nil, **_options})
7
+ end
8
+
5
9
  before(:each) do
6
10
  evaljs(_presetup) if _presetup
7
11
  with_warnings(_warnings) do
8
- evaljs(JsRoutes.generate(_options))
12
+ evaljs(generated_js)
9
13
  App.routes.default_url_options = _options[:default_url_options] || {}
10
14
  end
11
15
  end
@@ -37,9 +41,10 @@ describe JsRoutes, "options" do
37
41
  let(:_presetup){ %q(var myCustomSerializer = 1) }
38
42
  let(:_options) { {:serializer => "myCustomSerializer"} }
39
43
 
40
- it "should set configurable serializer" do
41
- # expect to use default
42
- expect(evaljs(%q(Routes.inboxes_path({a: 1})))).to eql("/inboxes?a=1")
44
+ it "should throw error" do
45
+ expect {
46
+ evaljs(%q(Routes.inboxes_path({a: 1})))
47
+ }.to raise_error(js_error_class)
43
48
  end
44
49
  end
45
50
 
@@ -177,8 +182,7 @@ describe JsRoutes, "options" do
177
182
  context "is nil" do
178
183
  let(:_options) { {:namespace => nil} }
179
184
  it "should use this namespace for routing" do
180
- evaljs("window.zz = #{JsRoutes.generate(namespace: nil)}")
181
- expect(evaljs("window.Routes")).to be_nil
185
+ evaljs("window.zz = #{JsRoutes.generate(module_type: nil, namespace: nil)}")
182
186
  expect(evaljs("window.zz.inbox_path")).not_to be_nil
183
187
  end
184
188
 
@@ -491,4 +495,13 @@ describe JsRoutes, "options" do
491
495
  expect(evaljs("Routes.posts_path()")).not_to be_nil
492
496
  end
493
497
  end
498
+
499
+ describe "documentation option" do
500
+ let(:_options) { {documentation: false} }
501
+
502
+ it "disables documentation generation" do
503
+ expect(generated_js).not_to include("@param")
504
+ expect(generated_js).not_to include("@returns")
505
+ end
506
+ end
494
507
  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}))
7
7
  end
8
8
 
9
9
  it "should generate collection routing" do
@@ -16,13 +16,16 @@ describe JsRoutes, "compatibility with Rails" do
16
16
 
17
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'])
26
29
  end
27
30
 
28
31
  it "should produce error stacktraces including function names" do
@@ -70,7 +73,7 @@ describe JsRoutes, "compatibility with Rails" do
70
73
  expect(evaljs("Routes.inbox_path(1, {expanded: true, anchor: 'hello'})")).to eq(test_routes.inbox_path(1, :expanded => true, :anchor => "hello"))
71
74
  end
72
75
 
73
- it "should support required paramters given as options hash" do
76
+ it "should support required parameters given as options hash" do
74
77
  expect(evaljs("Routes.search_path({q: 'hello'})")).to eq(test_routes.search_path(:q => 'hello'))
75
78
  end
76
79
 
@@ -110,6 +113,7 @@ describe JsRoutes, "compatibility with Rails" do
110
113
 
111
114
  it "doesn't apply defaults to path" do
112
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'))
113
117
  end
114
118
  end
115
119
 
@@ -131,6 +135,10 @@ describe JsRoutes, "compatibility with Rails" do
131
135
  it "should support single route mapping" do
132
136
  expect(evaljs("Routes.support_path({page: 3})")).to eq(test_routes.support_path(:page => 3))
133
137
  end
138
+
139
+ it 'works' do
140
+ expect(evaljs("Routes.planner_manage_path()")).to eq(planner_routes.manage_path)
141
+ end
134
142
  end
135
143
 
136
144
  it "shouldn't require the format" do
@@ -149,7 +157,7 @@ describe JsRoutes, "compatibility with Rails" do
149
157
  expect(evaljs("Routes.root_path()")).to eq(test_routes.root_path)
150
158
  end
151
159
 
152
- describe "get paramters" do
160
+ describe "get parameters" do
153
161
  it "should support simple get parameters" do
154
162
  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"))
155
163
  end
@@ -158,6 +166,19 @@ describe JsRoutes, "compatibility with Rails" do
158
166
  expect(evaljs("Routes.inbox_path(1, {hello: ['world', 'mars']})")).to eq(test_routes.inbox_path(1, :hello => [:world, :mars]))
159
167
  end
160
168
 
169
+ context "object without prototype" do
170
+ before(:each) do
171
+ evaljs("let params = Object.create(null); params.q = 'hello';")
172
+ evaljs("let inbox = Object.create(null); inbox.to_param = 1;")
173
+ end
174
+
175
+ it "should still work correctly" do
176
+ expect(evaljs("Routes.inbox_path(inbox, params)")).to eq(
177
+ test_routes.inbox_path(1, q: "hello")
178
+ )
179
+ end
180
+ end
181
+
161
182
  it "should support nested get parameters" do
162
183
  expect(evaljs("Routes.inbox_path(1, {format: 'json', env: 'test', search: { category_ids: [2,5], q: 'hello'}})")).to eq(
163
184
  test_routes.inbox_path(1, :env => 'test', :search => {:category_ids => [2,5], :q => "hello"}, :format => "json")
@@ -225,6 +246,15 @@ describe JsRoutes, "compatibility with Rails" do
225
246
  expect(evaljs("Routes.things_path({ q: 'hello' })")).to eq(test_routes.things_path(q: 'hello'))
226
247
  end
227
248
 
249
+ it "treats false as absent optional part" do
250
+ pending("https://github.com/rails/rails/issues/42280")
251
+ expect(evaljs("Routes.things_path(false)")).to eq(test_routes.things_path(false))
252
+ end
253
+
254
+ it "treats false as absent optional part when default is specified" do
255
+ expect(evaljs("Routes.campaigns_path(false)")).to eq(test_routes.campaigns_path(false))
256
+ end
257
+
228
258
  it "should not require the optional parts as arguments" do
229
259
  expect(evaljs("Routes.thing_path(null, 5)")).to eq(test_routes.thing_path(nil, 5))
230
260
  end
@@ -235,7 +265,7 @@ describe JsRoutes, "compatibility with Rails" do
235
265
 
236
266
  it "should raise error when passing non-full list of arguments and some query params" do
237
267
  expect { evaljs("Routes.thing_path(5, {q: 'hello'})") }
238
- .to raise_error(/Route parameter missing: id/)
268
+ .to raise_error(/Route missing required keys: id/)
239
269
  end
240
270
 
241
271
  it "should treat null as non-given optional part" do
@@ -253,7 +283,7 @@ describe JsRoutes, "compatibility with Rails" do
253
283
 
254
284
  context "and including them" do
255
285
  it "should fail when insufficient arguments are given" do
256
- expect { evaljs("Routes.thing_deep_path(2)") }.to raise_error(/Route parameter missing: third_required/)
286
+ expect { evaljs("Routes.thing_deep_path(2)") }.to raise_error(/Route missing required keys: third_required/)
257
287
  end
258
288
 
259
289
  it "should include the optional parts" do
@@ -302,27 +332,22 @@ describe JsRoutes, "compatibility with Rails" do
302
332
  evaljs("Routes.inbox_path()")
303
333
  }.to raise_error(js_error_class)
304
334
  end
335
+
305
336
  it "should throw Exception if required parameter is not defined" do
306
337
  expect {
307
338
  evaljs("Routes.inbox_path(null)")
308
339
  }.to raise_error(js_error_class)
309
340
  end
310
341
 
311
- it "should throw Exceptions if when there is too many parameters" do
312
- expect {
313
- evaljs("Routes.inbox_path(1,2,3)")
314
- }.to raise_error(js_error_class)
315
- end
316
-
317
- it "should throw Exceptions if when pass id with null" do
342
+ it "should throw Exception if required parameter is not defined" do
318
343
  expect {
319
- evaljs("Routes.inbox_path({id: null})")
344
+ evaljs("Routes.inbox_path(undefined)")
320
345
  }.to raise_error(js_error_class)
321
346
  end
322
347
 
323
- it "should throw Exceptions if when pass to_param with null" do
348
+ it "should throw Exceptions if when there is too many parameters" do
324
349
  expect {
325
- evaljs("Routes.inbox_path({to_param: null})")
350
+ evaljs("Routes.inbox_path(1,2,3)")
326
351
  }.to raise_error(js_error_class)
327
352
  end
328
353
  end
@@ -341,8 +366,19 @@ describe JsRoutes, "compatibility with Rails" do
341
366
  let(:klass) { Struct.new(:id, :to_param) }
342
367
  let(:inbox) { klass.new(1,"my") }
343
368
 
369
+ it "should throw Exceptions if when pass id with null" do
370
+ expect {
371
+ evaljs("Routes.inbox_path({id: null})")
372
+ }.to raise_error(js_error_class)
373
+ end
374
+
375
+ it "should throw Exceptions if when pass to_param with null" do
376
+ expect {
377
+ evaljs("Routes.inbox_path({to_param: null})")
378
+ }.to raise_error(js_error_class)
379
+ end
344
380
  it "should support 0 as a to_param option" do
345
- expect(evaljs("Routes.inbox_path({to_param: 0})")).to eq(test_routes.inbox_path(0))
381
+ expect(evaljs("Routes.inbox_path({to_param: 0})")).to eq(test_routes.inbox_path(Struct.new(:to_param).new('0')))
346
382
  end
347
383
 
348
384
  it "should check for options special key" do
@@ -379,6 +415,14 @@ describe JsRoutes, "compatibility with Rails" do
379
415
  )).to eq(test_routes.inbox_message_path(inbox, 2, :custom => true, :format => "json"))
380
416
  end
381
417
 
418
+ it "supports camel case property name" do
419
+ expect(evaljs("Routes.inbox_path({id: 1, toParam: 'my'})")).to eq(test_routes.inbox_path(inbox))
420
+ end
421
+
422
+ it "supports camel case method name" do
423
+ expect(evaljs("Routes.inbox_path({id: 1, toParam: function(){ return 'my';}})")).to eq(test_routes.inbox_path(inbox))
424
+ end
425
+
382
426
  context "when globbing" do
383
427
  it "should prefer to_param property over id property" do
384
428
  expect(evaljs("Routes.book_path({id: 1, to_param: 'my'}, 1)")).to eq(test_routes.book_path(inbox, 1))
@@ -398,6 +442,7 @@ describe JsRoutes, "compatibility with Rails" do
398
442
  )).to eq(test_routes.book_path(inbox, 2, :custom => true, :format => "json"))
399
443
  end
400
444
  end
445
+
401
446
  end
402
447
 
403
448
  context "when specs" do
@@ -418,15 +463,13 @@ describe JsRoutes, "compatibility with Rails" do
418
463
  end
419
464
  end
420
465
 
421
- describe "required_params" do
466
+ describe "requiredParams" do
422
467
  it "should show inbox spec" do
423
- expect(evaljs("Routes.inbox_path.required_params").to_a).to eq(["id"])
468
+ expect(evaljs("Routes.inbox_path.requiredParams()").to_a).to eq(["id"])
424
469
  end
425
470
 
426
471
  it "should show inbox message spec" do
427
- expect(evaljs("Routes.inbox_message_path.required_params").to_a).to eq(["inbox_id", "id"])
472
+ expect(evaljs("Routes.inbox_message_path.requiredParams()").to_a).to eq(["inbox_id", "id"])
428
473
  end
429
474
  end
430
-
431
-
432
475
  end