js-routes-zigexn 1.3.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,15 @@
1
+ require "spec_helper"
2
+
3
+ describe JsRoutes, "#default_serializer" do
4
+
5
+ before(:each) do
6
+ evaljs(JsRoutes.generate({}))
7
+ end
8
+
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(
11
+ "a=1&b%5B%5D=2&b%5B%5D=3&c%5Bd%5D=4&c%5Be%5D=5&f="
12
+ )
13
+ end
14
+
15
+ end
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+ require "fileutils"
3
+
4
+
5
+ describe JsRoutes do
6
+ before(:each) do
7
+ evaljs(JsRoutes.generate)
8
+ end
9
+
10
+ describe "generated js" do
11
+ subject { JsRoutes.generate }
12
+
13
+ it "should set the default serializer when none is configured" do
14
+ is_expected.to match(%r(custom_serializer: null,\s+serialize: function\(object\) {\s+if \(\(this\.custom_serializer != null\) && this.get_object_type\(this\.custom_serializer\) === \"function\"\) {\s+return this\.custom_serializer\(object\);\s+} else {\s+return this\.default_serializer\(object\);\s+}\s+},))
15
+ end
16
+
17
+ it "should include a comment in the header" do
18
+ app_class = "App"
19
+
20
+ is_expected.to include("File generated by js-routes #{JsRoutes::VERSION}")
21
+ is_expected.to include("Based on Rails routes of #{app_class}")
22
+ end
23
+
24
+ it "should call route function for each route" do
25
+ is_expected.to include("inboxes_path: Utils.route(")
26
+ end
27
+ it "should have correct function without arguments signature" do
28
+ is_expected.to include("inboxes_path: Utils.route([[\"format\",false]]")
29
+ end
30
+ it "should have correct function with arguments signature" do
31
+ is_expected.to include("inbox_message_path: Utils.route([[\"inbox_id\",true],[\"id\",true],[\"format\",false]]")
32
+ end
33
+ it "should have correct function signature with unordered hash" do
34
+ is_expected.to include("inbox_message_attachment_path: Utils.route([[\"inbox_id\",true],[\"message_id\",true],[\"id\",true],[\"format\",false]]")
35
+ end
36
+
37
+ it "should have correct function comment with options argument" do
38
+ is_expected.to include("// function(options)\n inboxes_path: Utils.route")
39
+ end
40
+ it "should have correct function comment with arguments" do
41
+ is_expected.to include("// function(inbox_id, message_id, options)\n new_inbox_message_attachment_path: Utils.route")
42
+ end
43
+
44
+ it "routes should be sorted in alphabetical order" do
45
+ expect(subject.index("book_path")).to be <= subject.index("inboxes_path")
46
+ end
47
+ end
48
+
49
+ describe ".generate!" do
50
+
51
+ let(:name) { Rails.root.join('app', 'assets', 'javascripts', 'routes.js') }
52
+
53
+ before(:each) do
54
+ FileUtils.rm_f(name)
55
+ JsRoutes.generate!({:file => name})
56
+ end
57
+
58
+ after(:each) do
59
+ FileUtils.rm_f(name)
60
+ end
61
+
62
+ after(:all) do
63
+ FileUtils.rm_f("#{File.dirname(__FILE__)}/../routes.js") # let(:name) is not available here
64
+ end
65
+
66
+ it "should not generate file before initialization" do
67
+ # This method is alread fixed in Rails master
68
+ # But in 3.2 stable we need to hack it like this
69
+ if Rails.application.instance_variable_get("@initialized")
70
+ pending
71
+ end
72
+ expect(File.exists?(name)).to be_falsey
73
+ end
74
+
75
+ end
76
+
77
+ describe "compiled javascript asset" do
78
+ subject { ERB.new(File.read("app/assets/javascripts/js-routes.js.erb")).result(binding) }
79
+ it "should have js routes code" do
80
+ is_expected.to include("inbox_message_path: Utils.route([[\"inbox_id\",true],[\"id\",true],[\"format\",false]]")
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,450 @@
1
+ require 'spec_helper'
2
+
3
+ describe JsRoutes, "options" do
4
+
5
+ before(:each) do
6
+ evaljs(_presetup) if _presetup
7
+ with_warnings(_warnings) do
8
+ evaljs(JsRoutes.generate(_options))
9
+ end
10
+ end
11
+
12
+ let(:_presetup) { nil }
13
+ let(:_options) { {} }
14
+ let(:_warnings) { true }
15
+
16
+ context "when serializer is specified" do
17
+ # define custom serializer
18
+ # this is a nonsense serializer, which always returns foo=bar
19
+ # for all inputs
20
+ let(:_presetup){ %q(function myCustomSerializer(object, prefix) { return "foo=bar"; }) }
21
+ let(:_options) { {:serializer => "myCustomSerializer"} }
22
+
23
+ it "should set configurable serializer" do
24
+ # expect the nonsense serializer above to have appened foo=bar
25
+ # to the end of the path
26
+ expect(evaljs(%q(Routes.inboxes_path()))).to eql("/inboxes?foo=bar")
27
+ end
28
+ end
29
+
30
+ context "when serializer is specified, but not function" do
31
+ let(:_presetup){ %q(var myCustomSerializer = 1) }
32
+ let(:_options) { {:serializer => "myCustomSerializer"} }
33
+
34
+ it "should set configurable serializer" do
35
+ # expect to use default
36
+ expect(evaljs(%q(Routes.inboxes_path({a: 1})))).to eql("/inboxes?a=1")
37
+ end
38
+ end
39
+
40
+ context "when exclude is specified" do
41
+
42
+ let(:_options) { {:exclude => /^admin_/} }
43
+
44
+ it "should exclude specified routes from file" do
45
+ expect(evaljs("Routes.admin_users_path")).to be_nil
46
+ end
47
+
48
+ it "should not exclude routes not under specified pattern" do
49
+ expect(evaljs("Routes.inboxes_path()")).not_to be_nil
50
+ end
51
+
52
+ context "for rails engine" do
53
+ let(:_options) { {:exclude => /^blog_app_posts/} }
54
+
55
+ it "should exclude specified engine route" do
56
+ expect(evaljs("Routes.blog_app_posts_path")).to be_nil
57
+ end
58
+ end
59
+ end
60
+
61
+ context "when include is specified" do
62
+
63
+ let(:_options) { {:include => /^admin_/} }
64
+
65
+ it "should exclude specified routes from file" do
66
+ expect(evaljs("Routes.admin_users_path()")).not_to be_nil
67
+ end
68
+
69
+ it "should not exclude routes not under specified pattern" do
70
+ expect(evaljs("Routes.inboxes_path")).to be_nil
71
+ end
72
+
73
+ context "for rails engine" do
74
+ let(:_options) { {:include => /^blog_app_posts/} }
75
+
76
+ it "should include specified engine route" do
77
+ expect(evaljs("Routes.blog_app_posts_path()")).not_to be_nil
78
+ end
79
+ end
80
+ end
81
+
82
+ context "when prefix with trailing slash is specified" do
83
+
84
+ let(:_options) { {:prefix => "/myprefix/" } }
85
+
86
+ it "should render routing with prefix" do
87
+ expect(evaljs("Routes.inbox_path(1)")).to eq("/myprefix#{routes.inbox_path(1)}")
88
+ end
89
+
90
+ it "should render routing with prefix set in JavaScript" do
91
+ evaljs("Routes.options.prefix = '/newprefix/'")
92
+ expect(evaljs("Routes.inbox_path(1)")).to eq("/newprefix#{routes.inbox_path(1)}")
93
+ end
94
+
95
+ end
96
+
97
+ context "when prefix with http:// is specified" do
98
+
99
+ let(:_options) { {:prefix => "http://localhost:3000" } }
100
+
101
+ it "should render routing with prefix" do
102
+ expect(evaljs("Routes.inbox_path(1)")).to eq(_options[:prefix] + routes.inbox_path(1))
103
+ end
104
+ end
105
+
106
+ context "when prefix without trailing slash is specified" do
107
+
108
+ let(:_options) { {:prefix => "/myprefix" } }
109
+
110
+ it "should render routing with prefix" do
111
+ expect(evaljs("Routes.inbox_path(1)")).to eq("/myprefix#{routes.inbox_path(1)}")
112
+ end
113
+
114
+ it "should render routing with prefix set in JavaScript" do
115
+ evaljs("Routes.options.prefix = '/newprefix'")
116
+ expect(evaljs("Routes.inbox_path(1)")).to eq("/newprefix#{routes.inbox_path(1)}")
117
+ end
118
+
119
+ end
120
+
121
+ context "when default format is specified" do
122
+ let(:_options) { {:default_url_options => {format: "json"}} }
123
+ let(:_warnings) { nil }
124
+
125
+ it "should render routing with default_format" do
126
+ expect(evaljs("Routes.inbox_path(1)")).to eq(routes.inbox_path(1, :format => "json"))
127
+ end
128
+
129
+ it "should render routing with default_format and zero object" do
130
+ expect(evaljs("Routes.inbox_path(0)")).to eq(routes.inbox_path(0, :format => "json"))
131
+ end
132
+
133
+ it "should override default_format when spefified implicitly" do
134
+ expect(evaljs("Routes.inbox_path(1, {format: 'xml'})")).to eq(routes.inbox_path(1, :format => "xml"))
135
+ end
136
+
137
+ it "should override nullify implicitly when specified implicitly" do
138
+ expect(evaljs("Routes.inbox_path(1, {format: null})")).to eq(routes.inbox_path(1))
139
+ end
140
+
141
+
142
+ it "shouldn't require the format" do
143
+ pending if Rails.version < "4.0"
144
+ expect(evaljs("Routes.json_only_path()")).to eq(routes.json_only_path(:format => 'json'))
145
+ end
146
+ end
147
+
148
+ it "shouldn't include the format when {:format => false} is specified" do
149
+ expect(evaljs("Routes.no_format_path()")).to eq(routes.no_format_path())
150
+ expect(evaljs("Routes.no_format_path({format: 'json'})")).to eq(routes.no_format_path(format: 'json'))
151
+ end
152
+
153
+ describe "when namespace option is specified" do
154
+ let(:_options) { {:namespace => "PHM"} }
155
+ it "should use this namespace for routing" do
156
+ expect(evaljs("window.Routes")).to be_nil
157
+ expect(evaljs("PHM.inbox_path")).not_to be_nil
158
+ end
159
+ end
160
+
161
+ describe "when nested namespace option is specified" do
162
+ context "and defined on client" do
163
+ let(:_presetup) { "window.PHM = {}" }
164
+ let(:_options) { {:namespace => "PHM.Routes"} }
165
+ it "should use this namespace for routing" do
166
+ expect(evaljs("PHM.Routes.inbox_path")).not_to be_nil
167
+ end
168
+ end
169
+
170
+ context "but undefined on client" do
171
+ let(:_options) { {:namespace => "PHM.Routes"} }
172
+ it "should initialize namespace" do
173
+ expect(evaljs("window.PHM.Routes.inbox_path")).not_to be_nil
174
+ end
175
+ end
176
+
177
+ context "and some parts are defined" do
178
+ let(:_presetup) { "window.PHM = { Utils: {} };" }
179
+ let(:_options) { {:namespace => "PHM.Routes"} }
180
+ it "should not overwrite existing parts" do
181
+ expect(evaljs("window.PHM.Utils")).not_to be_nil
182
+ expect(evaljs("window.PHM.Routes.inbox_path")).not_to be_nil
183
+ end
184
+ end
185
+ end
186
+
187
+ describe "default_url_options" do
188
+ context "with optional route parts" do
189
+ context "provided" do
190
+ let(:_options) { { :default_url_options => { :optional_id => "12", :format => "json" } } }
191
+ it "should use this opions to fill optional parameters" do
192
+ expect(evaljs("Routes.things_path()")).to eq(routes.things_path(:optional_id => 12, :format => "json"))
193
+ end
194
+ end
195
+
196
+ context "not provided" do
197
+ let(:_options) { { :default_url_options => { :format => "json" } } }
198
+ it "breaks" do
199
+ expect(evaljs("Routes.foo_all_path()")).to eq(routes.foo_all_path(:format => "json"))
200
+ end
201
+ end
202
+ end
203
+
204
+ context "with required route parts" do
205
+ let(:_options) { {:default_url_options => {:inbox_id => "12"}} }
206
+ it "should use this opions to fill optional parameters" do
207
+ expect(evaljs("Routes.inbox_messages_path()")).to eq(routes.inbox_messages_path(:inbox_id => 12))
208
+ end
209
+ end
210
+ end
211
+
212
+ describe "trailing_slash" do
213
+ context "with default option" do
214
+ let(:_options) { Hash.new }
215
+ it "should working in params" do
216
+ expect(evaljs("Routes.inbox_path(1, {trailing_slash: true})")).to eq(routes.inbox_path(1, :trailing_slash => true))
217
+ end
218
+
219
+ it "should working with additional params" do
220
+ expect(evaljs("Routes.inbox_path(1, {trailing_slash: true, test: 'params'})")).to eq(routes.inbox_path(1, :trailing_slash => true, :test => 'params'))
221
+ end
222
+ end
223
+
224
+ context "with default_url_options option" do
225
+ let(:_options) { {:default_url_options => {:trailing_slash => true}} }
226
+ it "should working" do
227
+ expect(evaljs("Routes.inbox_path(1, {test: 'params'})")).to eq(routes.inbox_path(1, :trailing_slash => true, :test => 'params'))
228
+ end
229
+
230
+ it "should remove it by params" do
231
+ expect(evaljs("Routes.inbox_path(1, {trailing_slash: false})")).to eq(routes.inbox_path(1))
232
+ end
233
+ end
234
+
235
+ context "with disabled default_url_options option" do
236
+ let(:_options) { {:default_url_options => {:trailing_slash => false}} }
237
+ it "should not use trailing_slash" do
238
+ expect(evaljs("Routes.inbox_path(1, {test: 'params'})")).to eq(routes.inbox_path(1, :test => 'params'))
239
+ end
240
+
241
+ it "should use it by params" do
242
+ expect(evaljs("Routes.inbox_path(1, {trailing_slash: true})")).to eq(routes.inbox_path(1, :trailing_slash => true))
243
+ end
244
+ end
245
+ end
246
+
247
+ describe "camel_case" do
248
+ context "with default option" do
249
+ let(:_options) { Hash.new }
250
+ it "should use snake case routes" do
251
+ expect(evaljs("Routes.inbox_path(1)")).to eq(routes.inbox_path(1))
252
+ expect(evaljs("Routes.inboxPath")).to be_nil
253
+ end
254
+ end
255
+
256
+ context "with true" do
257
+ let(:_options) { { :camel_case => true } }
258
+ it "should generate camel case routes" do
259
+ expect(evaljs("Routes.inbox_path")).to be_nil
260
+ expect(evaljs("Routes.inboxPath")).not_to be_nil
261
+ expect(evaljs("Routes.inboxPath(1)")).to eq(routes.inbox_path(1))
262
+ expect(evaljs("Routes.inboxMessagesPath(10)")).to eq(routes.inbox_messages_path(:inbox_id => 10))
263
+ end
264
+ end
265
+ end
266
+
267
+ describe "url_links" do
268
+ context "with default option" do
269
+ let(:_options) { Hash.new }
270
+ it "should generate only path links" do
271
+ expect(evaljs("Routes.inbox_path(1)")).to eq(routes.inbox_path(1))
272
+ expect(evaljs("Routes.inbox_url")).to be_nil
273
+ end
274
+ end
275
+
276
+ context "when configuring with default_url_options" do
277
+ context "when only host option is specified" do
278
+ let(:_options) { { :url_links => true, :default_url_options => {:host => "example.com"} } }
279
+
280
+ it "uses the specified host, defaults protocol to http, defaults port to 80 (leaving it blank)" do
281
+ expect(evaljs("Routes.inbox_url(1)")).to eq("http://example.com#{routes.inbox_path(1)}")
282
+ end
283
+
284
+ it "does not override protocol when specified in route" do
285
+ expect(evaljs("Routes.new_session_url()")).to eq("https://example.com#{routes.new_session_path}")
286
+ end
287
+
288
+ it "does not override host when specified in route" do
289
+ expect(evaljs("Routes.sso_url()")).to eq(routes.sso_url)
290
+ end
291
+
292
+ it "does not override port when specified in route" do
293
+ expect(evaljs("Routes.portals_url()")).to eq("http://example.com:8080#{routes.portals_path}")
294
+ end
295
+ end
296
+
297
+ context "when default host and protocol are specified" do
298
+ let(:_options) { { :url_links => true, :default_url_options => {:host => "example.com", :protocol => "ftp"} } }
299
+
300
+ it "uses the specified protocol and host, defaults port to 80 (leaving it blank)" do
301
+ expect(evaljs("Routes.inbox_url(1)")).to eq("ftp://example.com#{routes.inbox_path(1)}")
302
+ end
303
+
304
+ it "does not override protocol when specified in route" do
305
+ expect(evaljs("Routes.new_session_url()")).to eq("https://example.com#{routes.new_session_path}")
306
+ end
307
+
308
+ it "does not override host when host is specified in route" do
309
+ expect(evaljs("Routes.sso_url()")).to eq("ftp://sso.example.com#{routes.sso_path}")
310
+ end
311
+
312
+ it "does not override port when specified in route" do
313
+ expect(evaljs("Routes.portals_url()")).to eq("ftp://example.com:8080#{routes.portals_path}")
314
+ end
315
+ end
316
+
317
+ context "when default host and port are specified" do
318
+ let(:_options) { { :url_links => true, :default_url_options => {:host => "example.com", :port => 3000} } }
319
+
320
+ it "uses the specified host and port, defaults protocol to http" do
321
+ expect(evaljs("Routes.inbox_url(1)")).to eq("http://example.com:3000#{routes.inbox_path(1)}")
322
+ end
323
+
324
+ it "does not override protocol when specified in route" do
325
+ expect(evaljs("Routes.new_session_url()")).to eq("https://example.com:3000#{routes.new_session_path}")
326
+ end
327
+
328
+ it "does not override host, protocol, or port when host is specified in route" do
329
+ expect(evaljs("Routes.sso_url()")).to eq("http://sso.example.com:3000" + routes.sso_path)
330
+ end
331
+
332
+ it "does not override port when specified in route" do
333
+ expect(evaljs("Routes.portals_url()")).to eq("http://example.com:8080#{routes.portals_path}")
334
+ end
335
+ end
336
+
337
+ context "with camel_case option" do
338
+ let(:_options) { { :camel_case => true, :url_links => true, :default_url_options => {:host => "example.com"} } }
339
+ it "should generate path and url links" do
340
+ expect(evaljs("Routes.inboxUrl(1)")).to eq("http://example.com#{routes.inbox_path(1)}")
341
+ expect(evaljs("Routes.newSessionUrl()")).to eq("https://example.com#{routes.new_session_path}")
342
+ expect(evaljs("Routes.ssoUrl()")).to eq(routes.sso_url)
343
+ expect(evaljs("Routes.portalsUrl()")).to eq("http://example.com:8080#{routes.portals_path}")
344
+ end
345
+ end
346
+
347
+ context "with prefix option" do
348
+ let(:_options) { { :prefix => "/api", :url_links => true, :default_url_options => {:host => 'example.com'} } }
349
+ it "should generate path and url links" do
350
+ expect(evaljs("Routes.inbox_url(1)")).to eq("http://example.com/api#{routes.inbox_path(1)}")
351
+ expect(evaljs("Routes.new_session_url()")).to eq("https://example.com/api#{routes.new_session_path}")
352
+ expect(evaljs("Routes.sso_url()")).to eq("http://sso.example.com/api#{routes.sso_path}")
353
+ expect(evaljs("Routes.portals_url()")).to eq("http://example.com:8080/api#{routes.portals_path}")
354
+ end
355
+ end
356
+
357
+ context "with compact option" do
358
+ let(:_options) { { :compact => true, :url_links => true, :default_url_options => {:host => 'example.com'} } }
359
+ it "does not affect url helpers" do
360
+ expect(evaljs("Routes.inbox_url(1)")).to eq("http://example.com#{routes.inbox_path(1)}")
361
+ expect(evaljs("Routes.new_session_url()")).to eq("https://example.com#{routes.new_session_path}")
362
+ expect(evaljs("Routes.sso_url()")).to eq(routes.sso_url)
363
+ expect(evaljs("Routes.portals_url()")).to eq("http://example.com:8080#{routes.portals_path}")
364
+ end
365
+ end
366
+ end
367
+
368
+ context 'when window.location is present' do
369
+ let(:current_protocol) { 'http:' } # window.location.protocol includes the colon character
370
+ let(:current_hostname) { 'current.example.com' }
371
+ let(:current_port){ '' } # an empty string means port 80
372
+ let(:current_host) do
373
+ host = "#{current_hostname}"
374
+ host += ":#{current_port}" unless current_port == ''
375
+ host
376
+ end
377
+
378
+ before do
379
+ jscontext.eval("window = {'location': {'protocol': '#{current_protocol}', 'hostname': '#{current_hostname}', 'port': '#{current_port}', 'host': '#{current_host}'}}")
380
+ end
381
+
382
+ context "without specifying a default host" do
383
+ let(:_options) { { :url_links => true } }
384
+
385
+ it "uses the current host" do
386
+ expect(evaljs("Routes.inbox_path")).not_to be_nil
387
+ expect(evaljs("Routes.inbox_url")).not_to be_nil
388
+ expect(evaljs("Routes.inbox_url(1)")).to eq("http://current.example.com#{routes.inbox_path(1)}")
389
+ expect(evaljs("Routes.inbox_url(1, { test_key: \"test_val\" })")).to eq("http://current.example.com#{routes.inbox_path(1, :test_key => "test_val")}")
390
+ expect(evaljs("Routes.new_session_url()")).to eq("https://current.example.com#{routes.new_session_path}")
391
+ expect(evaljs("Routes.sso_url()")).to eq("http://sso.example.com#{routes.sso_path}")
392
+
393
+ end
394
+
395
+ it "uses host option as an argument" do
396
+ expect(evaljs("Routes.portals_url({host: 'another.com'})")).to eq(routes.portals_url(host: 'another.com'))
397
+ end
398
+
399
+ it "uses port option as an argument" do
400
+ expect(evaljs("Routes.portals_url({host: 'localhost', port: 8080})")).to eq(routes.portals_url(host: 'localhost', port: 8080))
401
+ end
402
+
403
+ it "uses protocol option as an argument" do
404
+ expect(evaljs("Routes.portals_url({host: 'localhost', protocol: 'https'})")).to eq(routes.portals_url(protocol: 'https', host: 'localhost'))
405
+ end
406
+ end
407
+ end
408
+ end
409
+
410
+ describe "when the compact mode is enabled" do
411
+ let(:_options) { { :compact => true } }
412
+ it "removes _path suffix from path helpers" do
413
+ expect(evaljs("Routes.inbox_path")).to be_nil
414
+ expect(evaljs("Routes.inboxes()")).to eq(routes.inboxes_path())
415
+ expect(evaljs("Routes.inbox(2)")).to eq(routes.inbox_path(2))
416
+ end
417
+
418
+ context "with url_links option" do
419
+ around(:each) do |example|
420
+ ActiveSupport::Deprecation.silence do
421
+ example.run
422
+ end
423
+ end
424
+
425
+ let(:_options) { { :compact => true, :url_links => true, default_url_options: {host: 'localhost'} } }
426
+ it "should not strip urls" do
427
+ expect(evaljs("Routes.inbox(1)")).to eq(routes.inbox_path(1))
428
+ expect(evaljs("Routes.inbox_url(1)")).to eq("http://localhost#{routes.inbox_path(1)}")
429
+ end
430
+ end
431
+ end
432
+
433
+ describe "special_options_key" do
434
+ let(:_options) { { special_options_key: :__options__ } }
435
+ it "can be redefined" do
436
+ expect {
437
+ expect(evaljs("Routes.inbox_message_path({inbox_id: 1, id: 2, _options: true})")).to eq("")
438
+ }.to raise_error(js_error_class)
439
+ expect(evaljs("Routes.inbox_message_path({inbox_id: 1, id: 2, __options__: true})")).to eq(routes.inbox_message_path(inbox_id: 1, id: 2))
440
+ end
441
+ end
442
+
443
+ describe "when application is specified" do
444
+ let(:_options) { {:application => BlogEngine::Engine} }
445
+
446
+ it "should include specified engine route" do
447
+ expect(evaljs("Routes.posts_path()")).not_to be_nil
448
+ end
449
+ end
450
+ end