js-routes 0.8.8 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Readme.md +2 -0
- data/lib/js_routes/version.rb +1 -1
- data/lib/js_routes.rb +29 -9
- data/lib/routes.js +63 -13
- data/lib/routes.js.coffee +78 -20
- data/spec/js_routes/options_spec.rb +47 -0
- data/spec/js_routes/rails_routes_compatibility_spec.rb +40 -5
- data/spec/spec_helper.rb +1 -0
- metadata +2 -2
data/Readme.md
CHANGED
@@ -61,6 +61,8 @@ Available options:
|
|
61
61
|
* Default: blank
|
62
62
|
* `camel_case` (version >= 0.8.8) - Generate camel case route names.
|
63
63
|
* Default: false
|
64
|
+
* `url_links` (version >= 0.8.9) - Generate additional url links, where url_links value is beginning of url routes (ex: http[s]://example.com).
|
65
|
+
* Default: false
|
64
66
|
|
65
67
|
You can generate routes files on the application side like this:
|
66
68
|
|
data/lib/js_routes/version.rb
CHANGED
data/lib/js_routes.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
+
require 'uri'
|
1
2
|
require 'js_routes/version'
|
3
|
+
|
2
4
|
class JsRoutes
|
3
5
|
|
4
6
|
#
|
@@ -12,7 +14,8 @@ class JsRoutes
|
|
12
14
|
:exclude => [],
|
13
15
|
:include => //,
|
14
16
|
:file => DEFAULT_PATH,
|
15
|
-
:prefix =>
|
17
|
+
:prefix => nil,
|
18
|
+
:url_links => nil,
|
16
19
|
:camel_case => false,
|
17
20
|
:default_url_options => {}
|
18
21
|
}
|
@@ -29,6 +32,8 @@ class JsRoutes
|
|
29
32
|
:DOT => 8
|
30
33
|
}
|
31
34
|
|
35
|
+
LAST_OPTIONS_KEY = "options".freeze
|
36
|
+
|
32
37
|
class Options < Struct.new(*DEFAULTS.keys)
|
33
38
|
def to_hash
|
34
39
|
Hash[*members.zip(values).flatten(1)].symbolize_keys
|
@@ -89,7 +94,7 @@ class JsRoutes
|
|
89
94
|
js = File.read(File.dirname(__FILE__) + "/routes.js")
|
90
95
|
js.gsub!("NAMESPACE", @options[:namespace])
|
91
96
|
js.gsub!("DEFAULT_URL_OPTIONS", json(@options[:default_url_options].merge(deprecated_default_format)))
|
92
|
-
js.gsub!("PREFIX", @options[:prefix])
|
97
|
+
js.gsub!("PREFIX", @options[:prefix] || "")
|
93
98
|
js.gsub!("NODE_TYPES", json(NODE_TYPES))
|
94
99
|
js.gsub!("ROUTES", js_routes)
|
95
100
|
end
|
@@ -148,19 +153,34 @@ class JsRoutes
|
|
148
153
|
def build_js(route, parent_route)
|
149
154
|
name = [parent_route.try(:name), route.name].compact
|
150
155
|
parent_spec = parent_route.try(:path).try(:spec)
|
151
|
-
required_parts = route.required_parts.clone
|
152
|
-
optional_parts = route.optional_parts.clone
|
156
|
+
required_parts, optional_parts = route.required_parts.clone, route.optional_parts.clone
|
153
157
|
optional_parts.push(required_parts.delete :format) if required_parts.include?(:format)
|
154
|
-
route_name =
|
155
|
-
|
158
|
+
route_name = generate_route_name(name)
|
159
|
+
url_link = generate_url_link(name, route_name, required_parts)
|
156
160
|
_ = <<-JS.strip!
|
157
161
|
// #{name.join('.')} => #{parent_spec}#{route.path.spec}
|
158
162
|
#{route_name}: function(#{build_params(required_parts)}) {
|
163
|
+
if (!#{LAST_OPTIONS_KEY}){ #{LAST_OPTIONS_KEY} = {}; }
|
159
164
|
return Utils.build_path(#{json(required_parts)}, #{json(optional_parts)}, #{json(serialize(route.path.spec, parent_spec))}, arguments);
|
160
|
-
}
|
165
|
+
}#{",\n" + url_link if url_link.length > 0}
|
161
166
|
JS
|
162
167
|
end
|
163
168
|
|
169
|
+
def generate_url_link(name, route_name, required_parts)
|
170
|
+
return "" unless @options[:url_links]
|
171
|
+
raise "invalid URL format in url_links (ex: http[s]://example.com)" if @options[:url_links].match(URI::regexp(%w(http https))).nil?
|
172
|
+
_ = <<-JS.strip!
|
173
|
+
#{generate_route_name(name, true)}: function(#{build_params(required_parts)}) {
|
174
|
+
return "" + #{@options[:url_links].inspect} + this.#{route_name}(#{build_params(required_parts)});
|
175
|
+
}
|
176
|
+
JS
|
177
|
+
end
|
178
|
+
|
179
|
+
def generate_route_name(name, is_url = false)
|
180
|
+
route_name = "#{name.join('_')}_#{is_url ? "url" : "path"}"
|
181
|
+
@options[:camel_case] ? route_name.camelize(:lower) : route_name
|
182
|
+
end
|
183
|
+
|
164
184
|
def json(string)
|
165
185
|
self.class.json(string)
|
166
186
|
end
|
@@ -169,8 +189,8 @@ class JsRoutes
|
|
169
189
|
params = required_parts.map do |name|
|
170
190
|
# prepending each parameter name with underscore
|
171
191
|
# to prevent conflict with JS reserved words
|
172
|
-
"_"
|
173
|
-
end <<
|
192
|
+
"_#{name}"
|
193
|
+
end << LAST_OPTIONS_KEY
|
174
194
|
params.join(", ")
|
175
195
|
end
|
176
196
|
|
data/lib/routes.js
CHANGED
@@ -24,14 +24,14 @@
|
|
24
24
|
}
|
25
25
|
if (window.jQuery) {
|
26
26
|
result = window.jQuery.param(obj);
|
27
|
-
return (!result ? "" :
|
27
|
+
return (!result ? "" : result);
|
28
28
|
}
|
29
29
|
s = [];
|
30
30
|
for (key in obj) {
|
31
31
|
if (!__hasProp.call(obj, key)) continue;
|
32
32
|
prop = obj[key];
|
33
33
|
if (prop != null) {
|
34
|
-
if (prop
|
34
|
+
if (this.getObjectType(prop) === "array") {
|
35
35
|
for (i = _i = 0, _len = prop.length; _i < _len; i = ++_i) {
|
36
36
|
val = prop[i];
|
37
37
|
s.push("" + key + (encodeURIComponent("[]")) + "=" + (encodeURIComponent(val.toString())));
|
@@ -44,7 +44,7 @@
|
|
44
44
|
if (!s.length) {
|
45
45
|
return "";
|
46
46
|
}
|
47
|
-
return
|
47
|
+
return s.join("&");
|
48
48
|
},
|
49
49
|
clean_path: function(path) {
|
50
50
|
var last_index;
|
@@ -74,7 +74,7 @@
|
|
74
74
|
anchor = "";
|
75
75
|
if (options.hasOwnProperty("anchor")) {
|
76
76
|
anchor = "#" + options.anchor;
|
77
|
-
options.anchor
|
77
|
+
delete options.anchor;
|
78
78
|
}
|
79
79
|
return anchor;
|
80
80
|
},
|
@@ -82,7 +82,7 @@
|
|
82
82
|
var ret_value;
|
83
83
|
|
84
84
|
ret_value = {};
|
85
|
-
if (args.length > number_of_params &&
|
85
|
+
if (args.length > number_of_params && this.getObjectType(args[args.length - 1]) === "object") {
|
86
86
|
ret_value = args.pop();
|
87
87
|
}
|
88
88
|
return ret_value;
|
@@ -97,9 +97,9 @@
|
|
97
97
|
return "";
|
98
98
|
}
|
99
99
|
property = object;
|
100
|
-
if (
|
100
|
+
if (this.getObjectType(object) === "object") {
|
101
101
|
property = object.to_param || object.id || object;
|
102
|
-
if (
|
102
|
+
if (this.getObjectType(property) === "function") {
|
103
103
|
property = property.call(object);
|
104
104
|
}
|
105
105
|
}
|
@@ -108,7 +108,7 @@
|
|
108
108
|
clone: function(obj) {
|
109
109
|
var attr, copy, key;
|
110
110
|
|
111
|
-
if (
|
111
|
+
if ((obj == null) || "object" !== this.getObjectType(obj)) {
|
112
112
|
return obj;
|
113
113
|
}
|
114
114
|
copy = obj.constructor();
|
@@ -130,7 +130,7 @@
|
|
130
130
|
return result;
|
131
131
|
},
|
132
132
|
build_path: function(required_parameters, optional_parts, route, args) {
|
133
|
-
var opts, parameters, result;
|
133
|
+
var opts, parameters, result, url, url_params;
|
134
134
|
|
135
135
|
args = Array.prototype.slice.call(args);
|
136
136
|
opts = this.extract_options(required_parameters.length, args);
|
@@ -139,17 +139,25 @@
|
|
139
139
|
}
|
140
140
|
parameters = this.prepare_parameters(required_parameters, args, opts);
|
141
141
|
this.set_default_url_options(optional_parts, parameters);
|
142
|
-
result = "" + (
|
143
|
-
|
142
|
+
result = "" + (this.get_prefix()) + (this.visit(route, parameters));
|
143
|
+
url = Utils.clean_path("" + result + (this.extract_anchor(parameters)));
|
144
|
+
if ((url_params = this.serialize(parameters)).length) {
|
145
|
+
url += "?" + url_params;
|
146
|
+
}
|
147
|
+
return url;
|
144
148
|
},
|
145
149
|
visit: function(route, parameters, optional) {
|
146
150
|
var left, left_part, right, right_part, type, value;
|
147
151
|
|
152
|
+
if (optional == null) {
|
153
|
+
optional = false;
|
154
|
+
}
|
148
155
|
type = route[0], left = route[1], right = route[2];
|
149
156
|
switch (type) {
|
150
157
|
case NodeTypes.GROUP:
|
151
|
-
case NodeTypes.STAR:
|
152
158
|
return this.visit(left, parameters, true);
|
159
|
+
case NodeTypes.STAR:
|
160
|
+
return this.visit_globbing(left, parameters, true);
|
153
161
|
case NodeTypes.LITERAL:
|
154
162
|
case NodeTypes.SLASH:
|
155
163
|
case NodeTypes.DOT:
|
@@ -164,7 +172,7 @@
|
|
164
172
|
case NodeTypes.SYMBOL:
|
165
173
|
value = parameters[left];
|
166
174
|
if (value != null) {
|
167
|
-
parameters[left]
|
175
|
+
delete parameters[left];
|
168
176
|
return this.path_identifier(value);
|
169
177
|
}
|
170
178
|
if (optional) {
|
@@ -177,6 +185,24 @@
|
|
177
185
|
throw new Error("Unknown Rails node type");
|
178
186
|
}
|
179
187
|
},
|
188
|
+
visit_globbing: function(route, parameters, optional) {
|
189
|
+
var left, right, type, value;
|
190
|
+
|
191
|
+
type = route[0], left = route[1], right = route[2];
|
192
|
+
value = parameters[left];
|
193
|
+
if (value == null) {
|
194
|
+
return this.visit(route, parameters, optional);
|
195
|
+
}
|
196
|
+
parameters[left] = (function() {
|
197
|
+
switch (this.getObjectType(value)) {
|
198
|
+
case "array":
|
199
|
+
return value.join("/");
|
200
|
+
default:
|
201
|
+
return value;
|
202
|
+
}
|
203
|
+
}).call(this);
|
204
|
+
return this.visit(route, parameters, optional);
|
205
|
+
},
|
180
206
|
get_prefix: function() {
|
181
207
|
var prefix;
|
182
208
|
|
@@ -186,6 +212,30 @@
|
|
186
212
|
}
|
187
213
|
return prefix;
|
188
214
|
},
|
215
|
+
_classToTypeCache: null,
|
216
|
+
_classToType: function() {
|
217
|
+
var name, _i, _len, _ref;
|
218
|
+
|
219
|
+
if (this._classToTypeCache != null) {
|
220
|
+
return this._classToTypeCache;
|
221
|
+
}
|
222
|
+
this._classToTypeCache = {};
|
223
|
+
_ref = "Boolean Number String Function Array Date RegExp Undefined Null".split(" ");
|
224
|
+
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
225
|
+
name = _ref[_i];
|
226
|
+
this._classToTypeCache["[object " + name + "]"] = name.toLowerCase();
|
227
|
+
}
|
228
|
+
return this._classToTypeCache;
|
229
|
+
},
|
230
|
+
getObjectType: function(obj) {
|
231
|
+
var strType;
|
232
|
+
|
233
|
+
if (window.jQuery && (window.jQuery.type != null)) {
|
234
|
+
return window.jQuery.type(obj);
|
235
|
+
}
|
236
|
+
strType = Object.prototype.toString.call(obj);
|
237
|
+
return this._classToType()[strType] || "object";
|
238
|
+
},
|
189
239
|
namespace: function(root, namespaceString) {
|
190
240
|
var current, parts;
|
191
241
|
|
data/lib/routes.js.coffee
CHANGED
@@ -6,21 +6,21 @@ defaults =
|
|
6
6
|
|
7
7
|
NodeTypes = NODE_TYPES
|
8
8
|
Utils =
|
9
|
+
|
9
10
|
serialize: (obj) ->
|
10
11
|
return "" unless obj
|
11
12
|
if window.jQuery
|
12
13
|
result = window.jQuery.param(obj)
|
13
|
-
return (if not result then "" else
|
14
|
+
return (if not result then "" else result)
|
14
15
|
s = []
|
15
|
-
for own key, prop of obj
|
16
|
-
if prop
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
s.push "#{key}=#{encodeURIComponent(prop.toString())}"
|
16
|
+
for own key, prop of obj when prop?
|
17
|
+
if @getObjectType(prop) is "array"
|
18
|
+
for val, i in prop
|
19
|
+
s.push "#{key}#{encodeURIComponent("[]")}=#{encodeURIComponent(val.toString())}"
|
20
|
+
else
|
21
|
+
s.push "#{key}=#{encodeURIComponent(prop.toString())}"
|
22
22
|
return "" unless s.length
|
23
|
-
|
23
|
+
s.join("&")
|
24
24
|
|
25
25
|
clean_path: (path) ->
|
26
26
|
path = path.split("://")
|
@@ -37,12 +37,12 @@ Utils =
|
|
37
37
|
anchor = ""
|
38
38
|
if options.hasOwnProperty("anchor")
|
39
39
|
anchor = "##{options.anchor}"
|
40
|
-
options.anchor
|
40
|
+
delete options.anchor
|
41
41
|
anchor
|
42
42
|
|
43
43
|
extract_options: (number_of_params, args) ->
|
44
44
|
ret_value = {}
|
45
|
-
if args.length > number_of_params and
|
45
|
+
if args.length > number_of_params and @getObjectType(args[args.length - 1]) is "object"
|
46
46
|
ret_value = args.pop()
|
47
47
|
ret_value
|
48
48
|
|
@@ -51,13 +51,13 @@ Utils =
|
|
51
51
|
# null, undefined, false or ''
|
52
52
|
return "" unless object
|
53
53
|
property = object
|
54
|
-
if
|
54
|
+
if @getObjectType(object) is "object"
|
55
55
|
property = object.to_param or object.id or object
|
56
|
-
property = property.call(object) if
|
56
|
+
property = property.call(object) if @getObjectType(property) is "function"
|
57
57
|
property.toString()
|
58
58
|
|
59
59
|
clone: (obj) ->
|
60
|
-
return obj if
|
60
|
+
return obj if !obj? or "object" isnt @getObjectType(obj)
|
61
61
|
copy = obj.constructor()
|
62
62
|
copy[key] = attr for own key, attr of obj
|
63
63
|
copy
|
@@ -73,8 +73,10 @@ Utils =
|
|
73
73
|
throw new Error("Too many parameters provided for path") if args.length > required_parameters.length
|
74
74
|
parameters = @prepare_parameters(required_parameters, args, opts)
|
75
75
|
@set_default_url_options optional_parts, parameters
|
76
|
-
result = "#{
|
77
|
-
Utils.clean_path("#{result}#{
|
76
|
+
result = "#{@get_prefix()}#{@visit(route, parameters)}"
|
77
|
+
url = Utils.clean_path("#{result}#{@extract_anchor(parameters)}")
|
78
|
+
url += "?#{url_params}" if (url_params = @serialize(parameters)).length
|
79
|
+
url
|
78
80
|
#
|
79
81
|
# This function is JavaScript impelementation of the
|
80
82
|
# Journey::Visitors::Formatter that builds route by given parameters
|
@@ -86,11 +88,13 @@ Utils =
|
|
86
88
|
# If set to `true`, this method will not throw when encountering
|
87
89
|
# a missing parameter (used in recursive calls).
|
88
90
|
#
|
89
|
-
visit: (route, parameters, optional) ->
|
91
|
+
visit: (route, parameters, optional = false) ->
|
90
92
|
[type, left, right] = route
|
91
93
|
switch type
|
92
|
-
when NodeTypes.GROUP
|
94
|
+
when NodeTypes.GROUP
|
93
95
|
@visit left, parameters, true
|
96
|
+
when NodeTypes.STAR
|
97
|
+
@visit_globbing left, parameters, true
|
94
98
|
when NodeTypes.LITERAL, NodeTypes.SLASH, NodeTypes.DOT
|
95
99
|
left
|
96
100
|
when NodeTypes.CAT
|
@@ -101,7 +105,7 @@ Utils =
|
|
101
105
|
when NodeTypes.SYMBOL
|
102
106
|
value = parameters[left]
|
103
107
|
if value?
|
104
|
-
parameters[left]
|
108
|
+
delete parameters[left]
|
105
109
|
return @path_identifier(value)
|
106
110
|
if optional
|
107
111
|
"" # missing parameter
|
@@ -115,11 +119,65 @@ Utils =
|
|
115
119
|
else
|
116
120
|
throw new Error("Unknown Rails node type")
|
117
121
|
|
122
|
+
#
|
123
|
+
# This method convert value for globbing in right value for rails route
|
124
|
+
#
|
125
|
+
visit_globbing: (route, parameters, optional) ->
|
126
|
+
[type, left, right] = route
|
127
|
+
value = parameters[left]
|
128
|
+
return @visit(route, parameters, optional) unless value?
|
129
|
+
parameters[left] = switch @getObjectType(value)
|
130
|
+
when "array"
|
131
|
+
value.join("/")
|
132
|
+
else
|
133
|
+
value
|
134
|
+
@visit route, parameters, optional
|
135
|
+
|
136
|
+
#
|
137
|
+
# This method check and return prefix from options
|
138
|
+
#
|
118
139
|
get_prefix: ->
|
119
140
|
prefix = defaults.prefix
|
120
141
|
prefix = (if prefix.match("/$") then prefix else "#{prefix}/") if prefix isnt ""
|
121
142
|
prefix
|
122
143
|
|
144
|
+
#
|
145
|
+
# This is helper method to define object type.
|
146
|
+
# The typeof operator is probably the biggest design flaw of JavaScript, simply because it's basically completely broken.
|
147
|
+
#
|
148
|
+
# Value Class Type
|
149
|
+
# -------------------------------------
|
150
|
+
# "foo" String string
|
151
|
+
# new String("foo") String object
|
152
|
+
# 1.2 Number number
|
153
|
+
# new Number(1.2) Number object
|
154
|
+
# true Boolean boolean
|
155
|
+
# new Boolean(true) Boolean object
|
156
|
+
# new Date() Date object
|
157
|
+
# new Error() Error object
|
158
|
+
# [1,2,3] Array object
|
159
|
+
# new Array(1, 2, 3) Array object
|
160
|
+
# new Function("") Function function
|
161
|
+
# /abc/g RegExp object
|
162
|
+
# new RegExp("meow") RegExp object
|
163
|
+
# {} Object object
|
164
|
+
# new Object() Object object
|
165
|
+
#
|
166
|
+
# What is why I use Object.prototype.toString() to know better type of variable. Or use jQuery.type, if it available.
|
167
|
+
# _classToTypeCache used for perfomance cache of types map (underscore at the beginning mean private method - of course it doesn't realy private).
|
168
|
+
#
|
169
|
+
_classToTypeCache: null
|
170
|
+
_classToType: ->
|
171
|
+
return @_classToTypeCache if @_classToTypeCache?
|
172
|
+
@_classToTypeCache = {}
|
173
|
+
for name in "Boolean Number String Function Array Date RegExp Undefined Null".split(" ")
|
174
|
+
@_classToTypeCache["[object " + name + "]"] = name.toLowerCase()
|
175
|
+
@_classToTypeCache
|
176
|
+
getObjectType: (obj) ->
|
177
|
+
return window.jQuery.type(obj) if window.jQuery and window.jQuery.type?
|
178
|
+
strType = Object::toString.call(obj)
|
179
|
+
@_classToType()[strType] or "object"
|
180
|
+
|
123
181
|
namespace: (root, namespaceString) ->
|
124
182
|
parts = (if namespaceString then namespaceString.split(".") else [])
|
125
183
|
return unless parts.length
|
@@ -129,4 +187,4 @@ Utils =
|
|
129
187
|
|
130
188
|
Utils.namespace window, "NAMESPACE"
|
131
189
|
window.NAMESPACE = ROUTES
|
132
|
-
window.NAMESPACE.options = defaults
|
190
|
+
window.NAMESPACE.options = defaults
|
@@ -172,4 +172,51 @@ describe JsRoutes, "options" do
|
|
172
172
|
end
|
173
173
|
end
|
174
174
|
end
|
175
|
+
|
176
|
+
describe "url_links" do
|
177
|
+
context "with default option" do
|
178
|
+
let(:_options) { Hash.new }
|
179
|
+
it "should generate only path links" do
|
180
|
+
evaljs("Routes.inbox_path(1)").should == routes.inbox_path(1)
|
181
|
+
evaljs("Routes.inbox_url").should be_nil
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
context "with host" do
|
186
|
+
let(:_options) { { :url_links => "http://localhost" } }
|
187
|
+
it "should generate path and url links" do
|
188
|
+
evaljs("Routes.inbox_path").should_not be_nil
|
189
|
+
evaljs("Routes.inbox_url").should_not be_nil
|
190
|
+
evaljs("Routes.inbox_path(1)").should == routes.inbox_path(1)
|
191
|
+
evaljs("Routes.inbox_url(1)").should == "http://localhost#{routes.inbox_path(1)}"
|
192
|
+
evaljs("Routes.inbox_url(1, { test_key: \"test_val\" })").should == "http://localhost#{routes.inbox_path(1, :test_key => "test_val")}"
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
context "with invalid host" do
|
197
|
+
it "should raise error" do
|
198
|
+
expect { JsRoutes.generate({ :url_links => "localhost" }) }.to raise_error RuntimeError
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
context "with host and camel_case" do
|
203
|
+
let(:_options) { { :camel_case => true, :url_links => "http://localhost" } }
|
204
|
+
it "should generate path and url links" do
|
205
|
+
evaljs("Routes.inboxPath").should_not be_nil
|
206
|
+
evaljs("Routes.inboxUrl").should_not be_nil
|
207
|
+
evaljs("Routes.inboxPath(1)").should == routes.inbox_path(1)
|
208
|
+
evaljs("Routes.inboxUrl(1)").should == "http://localhost#{routes.inbox_path(1)}"
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
context "with host and prefix" do
|
213
|
+
let(:_options) { { :prefix => "/api", :url_links => "https://example.com" } }
|
214
|
+
it "should generate path and url links" do
|
215
|
+
evaljs("Routes.inbox_path").should_not be_nil
|
216
|
+
evaljs("Routes.inbox_url").should_not be_nil
|
217
|
+
evaljs("Routes.inbox_path(1)").should == "/api#{routes.inbox_path(1)}"
|
218
|
+
evaljs("Routes.inbox_url(1)").should == "https://example.com/api#{routes.inbox_path(1)}"
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
175
222
|
end
|
@@ -76,14 +76,28 @@ describe JsRoutes, "compatibility with Rails" do
|
|
76
76
|
evaljs("Routes.book_path('thrillers', 1)").should == routes.book_path('thrillers', 1)
|
77
77
|
end
|
78
78
|
|
79
|
-
it "should support routes globbing as
|
80
|
-
|
81
|
-
|
79
|
+
it "should support routes globbing as array" do
|
80
|
+
evaljs("Routes.book_path(['thrillers'], 1)").should == routes.book_path(['thrillers'], 1)
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should bee support routes globbing as array" do
|
84
|
+
evaljs("Routes.book_path([1, 2, 3], 1)").should == routes.book_path([1, 2, 3], 1)
|
82
85
|
end
|
83
86
|
|
84
87
|
it "should bee support routes globbing as hash" do
|
85
|
-
|
86
|
-
|
88
|
+
evaljs("Routes.book_path('a_test/b_test/c_test', 1)").should == routes.book_path('a_test/b_test/c_test', 1)
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should support routes globbing as array with optional params" do
|
92
|
+
evaljs("Routes.book_path([1, 2, 3, 5], 1, {c: '1'})").should == routes.book_path([1, 2, 3, 5], 1, { :c => "1" })
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should support routes globbing in book_title route as array" do
|
96
|
+
evaljs("Routes.book_title_path('john', ['thrillers', 'comedian'])").should == routes.book_title_path('john', ['thrillers', 'comedian'])
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should support routes globbing in book_title route as array with optional params" do
|
100
|
+
evaljs("Routes.book_title_path('john', ['thrillers', 'comedian'], {some_key: 'some_value'})").should == routes.book_title_path('john', ['thrillers', 'comedian'], {:some_key => 'some_value'})
|
87
101
|
end
|
88
102
|
end
|
89
103
|
|
@@ -98,6 +112,7 @@ describe JsRoutes, "compatibility with Rails" do
|
|
98
112
|
it "should support serialization of objects" do
|
99
113
|
evaljs("window.jQuery.param(#{_value.to_json})").should == _value.to_param
|
100
114
|
evaljs("Routes.inboxes_path(#{_value.to_json})").should == routes.inboxes_path(_value)
|
115
|
+
evaljs("Routes.inbox_path(1, #{_value.to_json})").should == routes.inbox_path(1, _value)
|
101
116
|
end
|
102
117
|
end
|
103
118
|
context "when parameters is a hash" do
|
@@ -202,5 +217,25 @@ describe JsRoutes, "compatibility with Rails" do
|
|
202
217
|
"Routes.inbox_message_path({id:1, to_param: 'my'}, {id:2}, {custom: true, format: 'json'})"
|
203
218
|
).should == routes.inbox_message_path(inbox, 2, :custom => true, :format => "json")
|
204
219
|
end
|
220
|
+
|
221
|
+
context "when globbing" do
|
222
|
+
it "should prefer to_param property over id property" do
|
223
|
+
evaljs("Routes.book_path({id: 1, to_param: 'my'}, 1)").should == routes.book_path(inbox, 1)
|
224
|
+
end
|
225
|
+
|
226
|
+
it "should call to_param if it is a function" do
|
227
|
+
evaljs("Routes.book_path({id: 1, to_param: function(){ return 'my';}}, 1)").should == routes.book_path(inbox, 1)
|
228
|
+
end
|
229
|
+
|
230
|
+
it "should call id if it is a function" do
|
231
|
+
evaljs("Routes.book_path({id: function() { return 'technical';}}, 1)").should == routes.book_path('technical', 1)
|
232
|
+
end
|
233
|
+
|
234
|
+
it "should support options argument" do
|
235
|
+
evaljs(
|
236
|
+
"Routes.book_path({id:1, to_param: 'my'}, {id:2}, {custom: true, format: 'json'})"
|
237
|
+
).should == routes.book_path(inbox, 2, :custom => true, :format => "json")
|
238
|
+
end
|
239
|
+
end
|
205
240
|
end
|
206
241
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -68,6 +68,7 @@ def draw_routes
|
|
68
68
|
match "/other_optional/(:optional_id)" => "foo#foo", :as => :foo
|
69
69
|
|
70
70
|
match 'books/*section/:title' => 'books#show', :as => :book
|
71
|
+
match 'books/:title/*section' => 'books#show', :as => :book_title
|
71
72
|
|
72
73
|
mount BlogEngine::Engine => "/blog", :as => :blog_app
|
73
74
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: js-routes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -169,7 +169,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
169
169
|
version: '0'
|
170
170
|
segments:
|
171
171
|
- 0
|
172
|
-
hash:
|
172
|
+
hash: 1949067975122087130
|
173
173
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
174
174
|
none: false
|
175
175
|
requirements:
|