js-routes 1.4.13 → 2.0.3

Sign up to get free protection for your applications and to get access to all the features.
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