js-routes 1.4.14 → 2.0.0

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,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