js-routes 0.8.8 → 0.9.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/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:
|