js-routes 1.4.14 → 2.0.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.
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,20 @@
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
15
20
  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
@@ -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
 
@@ -235,7 +239,7 @@ describe JsRoutes, "compatibility with Rails" do
235
239
 
236
240
  it "should raise error when passing non-full list of arguments and some query params" do
237
241
  expect { evaljs("Routes.thing_path(5, {q: 'hello'})") }
238
- .to raise_error(/Route parameter missing: id/)
242
+ .to raise_error(/Route missing required keys: id/)
239
243
  end
240
244
 
241
245
  it "should treat null as non-given optional part" do
@@ -253,7 +257,7 @@ describe JsRoutes, "compatibility with Rails" do
253
257
 
254
258
  context "and including them" do
255
259
  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/)
260
+ expect { evaljs("Routes.thing_deep_path(2)") }.to raise_error(/Route missing required keys: third_required/)
257
261
  end
258
262
 
259
263
  it "should include the optional parts" do
@@ -302,27 +306,22 @@ describe JsRoutes, "compatibility with Rails" do
302
306
  evaljs("Routes.inbox_path()")
303
307
  }.to raise_error(js_error_class)
304
308
  end
309
+
305
310
  it "should throw Exception if required parameter is not defined" do
306
311
  expect {
307
312
  evaljs("Routes.inbox_path(null)")
308
313
  }.to raise_error(js_error_class)
309
314
  end
310
315
 
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
316
+ it "should throw Exception if required parameter is not defined" do
318
317
  expect {
319
- evaljs("Routes.inbox_path({id: null})")
318
+ evaljs("Routes.inbox_path(undefined)")
320
319
  }.to raise_error(js_error_class)
321
320
  end
322
321
 
323
- it "should throw Exceptions if when pass to_param with null" do
322
+ it "should throw Exceptions if when there is too many parameters" do
324
323
  expect {
325
- evaljs("Routes.inbox_path({to_param: null})")
324
+ evaljs("Routes.inbox_path(1,2,3)")
326
325
  }.to raise_error(js_error_class)
327
326
  end
328
327
  end
@@ -341,8 +340,19 @@ describe JsRoutes, "compatibility with Rails" do
341
340
  let(:klass) { Struct.new(:id, :to_param) }
342
341
  let(:inbox) { klass.new(1,"my") }
343
342
 
343
+ it "should throw Exceptions if when pass id with null" do
344
+ expect {
345
+ evaljs("Routes.inbox_path({id: null})")
346
+ }.to raise_error(js_error_class)
347
+ end
348
+
349
+ it "should throw Exceptions if when pass to_param with null" do
350
+ expect {
351
+ evaljs("Routes.inbox_path({to_param: null})")
352
+ }.to raise_error(js_error_class)
353
+ end
344
354
  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))
355
+ expect(evaljs("Routes.inbox_path({to_param: 0})")).to eq(test_routes.inbox_path(Struct.new(:to_param).new('0')))
346
356
  end
347
357
 
348
358
  it "should check for options special key" do
@@ -379,6 +389,14 @@ describe JsRoutes, "compatibility with Rails" do
379
389
  )).to eq(test_routes.inbox_message_path(inbox, 2, :custom => true, :format => "json"))
380
390
  end
381
391
 
392
+ it "supports camel case property name" do
393
+ expect(evaljs("Routes.inbox_path({id: 1, toParam: 'my'})")).to eq(test_routes.inbox_path(inbox))
394
+ end
395
+
396
+ it "supports camel case method name" do
397
+ expect(evaljs("Routes.inbox_path({id: 1, toParam: function(){ return 'my';}})")).to eq(test_routes.inbox_path(inbox))
398
+ end
399
+
382
400
  context "when globbing" do
383
401
  it "should prefer to_param property over id property" do
384
402
  expect(evaljs("Routes.book_path({id: 1, to_param: 'my'}, 1)")).to eq(test_routes.book_path(inbox, 1))
@@ -398,6 +416,7 @@ describe JsRoutes, "compatibility with Rails" do
398
416
  )).to eq(test_routes.book_path(inbox, 2, :custom => true, :format => "json"))
399
417
  end
400
418
  end
419
+
401
420
  end
402
421
 
403
422
  context "when specs" do
@@ -418,13 +437,13 @@ describe JsRoutes, "compatibility with Rails" do
418
437
  end
419
438
  end
420
439
 
421
- describe "required_params" do
440
+ describe "requiredParams" do
422
441
  it "should show inbox spec" do
423
- expect(evaljs("Routes.inbox_path.required_params").to_a).to eq(["id"])
442
+ expect(evaljs("Routes.inbox_path.requiredParams()").to_a).to eq(["id"])
424
443
  end
425
444
 
426
445
  it "should show inbox message spec" do
427
- expect(evaljs("Routes.inbox_message_path.required_params").to_a).to eq(["inbox_id", "id"])
446
+ expect(evaljs("Routes.inbox_message_path.requiredParams()").to_a).to eq(["inbox_id", "id"])
428
447
  end
429
448
  end
430
449
 
@@ -93,7 +93,7 @@ describe "after Rails initialization" do
93
93
  Rails.application.config.assets.initialize_on_precompile = true
94
94
  end
95
95
  it "should render some javascript" do
96
- expect(evaluate(ctx, 'js-routes.js')).to match(/routes = /)
96
+ expect(evaluate(ctx, 'js-routes.js')).to match(/Utils\.define_module/)
97
97
  end
98
98
  end
99
99
  context "and not initialize on precompile" do
@@ -101,7 +101,7 @@ describe "after Rails initialization" do
101
101
  Rails.application.config.assets.initialize_on_precompile = false
102
102
  end
103
103
  it "should raise an exception if 3 version" do
104
- expect(evaluate(ctx, 'js-routes.js')).to match(/routes = /)
104
+ expect(evaluate(ctx, 'js-routes.js')).to match(/Utils\.define_module/)
105
105
  end
106
106
  end
107
107
 
data/spec/spec_helper.rb CHANGED
@@ -6,7 +6,14 @@ require 'rspec'
6
6
  require 'rails/all'
7
7
  require 'js-routes'
8
8
  require 'active_support/core_ext/hash/slice'
9
- require 'coffee-script'
9
+
10
+ unless ENV['TRAVIS_CI']
11
+ code = system("yarn tsc")
12
+ unless code
13
+ exit(1)
14
+ end
15
+ end
16
+
10
17
 
11
18
  if defined?(JRUBY_VERSION)
12
19
  require 'rhino'
@@ -32,8 +39,15 @@ def js_error_class
32
39
  end
33
40
  end
34
41
 
35
- def evaljs(string, force = false)
36
- jscontext(force).eval(string)
42
+ def evaljs(string, force: false, filename: 'context.js')
43
+ jscontext(force).eval(string, filename: filename)
44
+ rescue MiniRacer::ParseError => e
45
+ message = e.message
46
+ _, _, line, _ = message.split(':')
47
+ code = line && string.split("\n")[line.to_i-1]
48
+ raise "#{message}. Code: #{code.strip}";
49
+ rescue MiniRacer::RuntimeError => e
50
+ raise e
37
51
  end
38
52
 
39
53
  def test_routes
@@ -79,28 +93,22 @@ RSpec.configure do |config|
79
93
  c.syntax = :expect
80
94
  end
81
95
 
82
- config.before(:all) do
83
- # compile all js files begin
84
- Dir["#{File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))}/**/*.coffee"].each do |coffee|
85
- File.open(coffee.gsub(/\.coffee$/, ""), 'w') do |f|
86
- f.write(CoffeeScript.compile(File.read(coffee)).lstrip)
87
- end
88
- end
89
- # compile all js files end
96
+ config.before(:suite) do
90
97
  draw_routes
91
98
  end
92
99
 
93
100
  config.before :each do
94
- evaljs("var window = this;", true)
101
+ evaljs("var window = this;", {force: true})
95
102
 
103
+ log = proc do |*values|
104
+ puts values.map(&:inspect).join(", ")
105
+ end
96
106
  if defined?(JRUBY_VERSION)
97
- jscontext[:log] = lambda do |context, value|
98
- puts value.inspect
107
+ jscontext[:"console.log"] = lambda do |context, *values|
108
+ log(*values)
99
109
  end
100
110
  else
101
- jscontext.attach("log", proc do |value|
102
- puts value.inspect
103
- end)
111
+ jscontext.attach("console.log", log)
104
112
  end
105
113
  end
106
114
  end