js-routes 1.4.11 → 2.0.1

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,22 +24,11 @@ describe JsRoutes, "compatibility with AMD/require.js" do
24
24
  };
25
25
  EOF
26
26
  evaljs(strRequire)
27
- evaljs(JsRoutes.generate({}))
28
- end
29
-
30
- it "should working from global scope" do
31
- expect(evaljs("Routes.inboxes_path()")).to eq(test_routes.inboxes_path())
32
- end
33
-
34
- it "should working from define function" do
35
- expect(evaljs("Routes.inboxes_path()")).to eq(evaljs("GlobalCheck['js-routes'].inboxes_path()"))
27
+ evaljs(JsRoutes.generate({module_type: 'AMD'}))
36
28
  end
37
29
 
38
30
  it "should working from require" do
39
31
  expect(evaljs("require(['js-routes'], function(r){ return r.inboxes_path(); })")).to eq(test_routes.inboxes_path())
40
32
  end
41
33
 
42
- it "should define default export for es6 modules" do
43
- expect(evaljs("require(['js-routes'], function(r){ return r.default.inboxes_path(); })")).to eq(test_routes.inboxes_path())
44
- end
45
34
  end
@@ -0,0 +1,15 @@
1
+ require "spec_helper"
2
+
3
+ describe JsRoutes, "compatibility with CJS" do
4
+ before(:each) do
5
+ evaljs("module = { exports: null }")
6
+ evaljs(JsRoutes.generate(
7
+ module_type: 'CJS',
8
+ include: /^inboxes/
9
+ ))
10
+ end
11
+
12
+ it "should define module exports" do
13
+ expect(evaljs("module.exports.inboxes_path()")).to eq(test_routes.inboxes_path())
14
+ end
15
+ end
@@ -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
 
@@ -149,7 +153,7 @@ describe JsRoutes, "compatibility with Rails" do
149
153
  expect(evaljs("Routes.root_path()")).to eq(test_routes.root_path)
150
154
  end
151
155
 
152
- describe "get paramters" do
156
+ describe "get parameters" do
153
157
  it "should support simple get parameters" do
154
158
  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
159
  end
@@ -158,6 +162,18 @@ describe JsRoutes, "compatibility with Rails" do
158
162
  expect(evaljs("Routes.inbox_path(1, {hello: ['world', 'mars']})")).to eq(test_routes.inbox_path(1, :hello => [:world, :mars]))
159
163
  end
160
164
 
165
+ context "object without prototype" do
166
+ before(:each) do
167
+ evaljs("let params = Object.create(null); params.q = 'hello'")
168
+ end
169
+
170
+ it "should still work correctly" do
171
+ expect(evaljs("Routes.inbox_path(1, params)")).to eq(
172
+ test_routes.inbox_path(1, :q => "hello")
173
+ )
174
+ end
175
+ end
176
+
161
177
  it "should support nested get parameters" do
162
178
  expect(evaljs("Routes.inbox_path(1, {format: 'json', env: 'test', search: { category_ids: [2,5], q: 'hello'}})")).to eq(
163
179
  test_routes.inbox_path(1, :env => 'test', :search => {:category_ids => [2,5], :q => "hello"}, :format => "json")
@@ -235,7 +251,7 @@ describe JsRoutes, "compatibility with Rails" do
235
251
 
236
252
  it "should raise error when passing non-full list of arguments and some query params" do
237
253
  expect { evaljs("Routes.thing_path(5, {q: 'hello'})") }
238
- .to raise_error(/Route parameter missing: id/)
254
+ .to raise_error(/Route missing required keys: id/)
239
255
  end
240
256
 
241
257
  it "should treat null as non-given optional part" do
@@ -253,7 +269,7 @@ describe JsRoutes, "compatibility with Rails" do
253
269
 
254
270
  context "and including them" do
255
271
  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/)
272
+ expect { evaljs("Routes.thing_deep_path(2)") }.to raise_error(/Route missing required keys: third_required/)
257
273
  end
258
274
 
259
275
  it "should include the optional parts" do
@@ -302,27 +318,22 @@ describe JsRoutes, "compatibility with Rails" do
302
318
  evaljs("Routes.inbox_path()")
303
319
  }.to raise_error(js_error_class)
304
320
  end
321
+
305
322
  it "should throw Exception if required parameter is not defined" do
306
323
  expect {
307
324
  evaljs("Routes.inbox_path(null)")
308
325
  }.to raise_error(js_error_class)
309
326
  end
310
327
 
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
328
+ it "should throw Exception if required parameter is not defined" do
318
329
  expect {
319
- evaljs("Routes.inbox_path({id: null})")
330
+ evaljs("Routes.inbox_path(undefined)")
320
331
  }.to raise_error(js_error_class)
321
332
  end
322
333
 
323
- it "should throw Exceptions if when pass to_param with null" do
334
+ it "should throw Exceptions if when there is too many parameters" do
324
335
  expect {
325
- evaljs("Routes.inbox_path({to_param: null})")
336
+ evaljs("Routes.inbox_path(1,2,3)")
326
337
  }.to raise_error(js_error_class)
327
338
  end
328
339
  end
@@ -341,8 +352,19 @@ describe JsRoutes, "compatibility with Rails" do
341
352
  let(:klass) { Struct.new(:id, :to_param) }
342
353
  let(:inbox) { klass.new(1,"my") }
343
354
 
355
+ it "should throw Exceptions if when pass id with null" do
356
+ expect {
357
+ evaljs("Routes.inbox_path({id: null})")
358
+ }.to raise_error(js_error_class)
359
+ end
360
+
361
+ it "should throw Exceptions if when pass to_param with null" do
362
+ expect {
363
+ evaljs("Routes.inbox_path({to_param: null})")
364
+ }.to raise_error(js_error_class)
365
+ end
344
366
  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))
367
+ expect(evaljs("Routes.inbox_path({to_param: 0})")).to eq(test_routes.inbox_path(Struct.new(:to_param).new('0')))
346
368
  end
347
369
 
348
370
  it "should check for options special key" do
@@ -379,6 +401,14 @@ describe JsRoutes, "compatibility with Rails" do
379
401
  )).to eq(test_routes.inbox_message_path(inbox, 2, :custom => true, :format => "json"))
380
402
  end
381
403
 
404
+ it "supports camel case property name" do
405
+ expect(evaljs("Routes.inbox_path({id: 1, toParam: 'my'})")).to eq(test_routes.inbox_path(inbox))
406
+ end
407
+
408
+ it "supports camel case method name" do
409
+ expect(evaljs("Routes.inbox_path({id: 1, toParam: function(){ return 'my';}})")).to eq(test_routes.inbox_path(inbox))
410
+ end
411
+
382
412
  context "when globbing" do
383
413
  it "should prefer to_param property over id property" do
384
414
  expect(evaljs("Routes.book_path({id: 1, to_param: 'my'}, 1)")).to eq(test_routes.book_path(inbox, 1))
@@ -398,6 +428,7 @@ describe JsRoutes, "compatibility with Rails" do
398
428
  )).to eq(test_routes.book_path(inbox, 2, :custom => true, :format => "json"))
399
429
  end
400
430
  end
431
+
401
432
  end
402
433
 
403
434
  context "when specs" do
@@ -418,15 +449,13 @@ describe JsRoutes, "compatibility with Rails" do
418
449
  end
419
450
  end
420
451
 
421
- describe "required_params" do
452
+ describe "requiredParams" do
422
453
  it "should show inbox spec" do
423
- expect(evaljs("Routes.inbox_path.required_params").to_a).to eq(["id"])
454
+ expect(evaljs("Routes.inbox_path.requiredParams()").to_a).to eq(["id"])
424
455
  end
425
456
 
426
457
  it "should show inbox message spec" do
427
- expect(evaljs("Routes.inbox_message_path.required_params").to_a).to eq(["inbox_id", "id"])
458
+ expect(evaljs("Routes.inbox_message_path.requiredParams()").to_a).to eq(["inbox_id", "id"])
428
459
  end
429
460
  end
430
-
431
-
432
461
  end