Skip to content

Commit

Permalink
Merge pull request #155 from jordanstephens/issue-153
Browse files Browse the repository at this point in the history
Allow Configurable Serializer Function (Solves #153)
  • Loading branch information
bogdan committed Jul 31, 2015
2 parents 4aad04e + 6f42a7d commit 2b42621
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 61 deletions.
4 changes: 3 additions & 1 deletion lib/js_routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ class JsRoutes
url_links: nil,
camel_case: false,
default_url_options: {},
compact: false
compact: false,
serializer: nil
}

NODE_TYPES = {
Expand Down Expand Up @@ -104,6 +105,7 @@ def generate
js.gsub!("DEFAULT_URL_OPTIONS", json(@options[:default_url_options].merge(deprecated_default_format)))
js.gsub!("PREFIX", @options[:prefix] || "")
js.gsub!("NODE_TYPES", json(NODE_TYPES))
js.gsub!("SERIALIZER", @options[:serializer] || "null")
js.gsub!("ROUTES", js_routes)
end

Expand Down
21 changes: 13 additions & 8 deletions lib/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ Based on Rails routes of APP_CLASS
NodeTypes = NODE_TYPES;

Utils = {
serialize: function(object, prefix) {
var element, i, j, key, len, prop, result, s;
default_serializer: function(object, prefix) {
var element, i, j, key, len, prop, s;
if (prefix == null) {
prefix = null;
}
Expand All @@ -34,16 +34,12 @@ Based on Rails routes of APP_CLASS
if (!prefix && !(this.get_object_type(object) === "object")) {
throw new Error("Url parameters should be a javascript hash");
}
if (root.jQuery) {
result = root.jQuery.param(object);
return (!result ? "" : result);
}
s = [];
switch (this.get_object_type(object)) {
case "array":
for (i = j = 0, len = object.length; j < len; i = ++j) {
element = object[i];
s.push(this.serialize(element, prefix + "[]"));
s.push(this.default_serializer(element, prefix + "[]"));
}
break;
case "object":
Expand All @@ -56,7 +52,7 @@ Based on Rails routes of APP_CLASS
if (prefix != null) {
key = prefix + "[" + key + "]";
}
s.push(this.serialize(prop, key));
s.push(this.default_serializer(prop, key));
}
break;
default:
Expand All @@ -69,6 +65,15 @@ Based on Rails routes of APP_CLASS
}
return s.join("&");
},
serialize: function(object) {
var custom_serializer;
custom_serializer = SERIALIZER;
if (custom_serializer) {
return custom_serializer(object);
} else {
return this.default_serializer(object);
}
},
clean_path: function(path) {
var last_index;
path = path.split("://");
Expand Down
17 changes: 10 additions & 7 deletions lib/routes.js.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -15,31 +15,34 @@ NodeTypes = NODE_TYPES

Utils =

serialize: (object, prefix = null) ->
default_serializer: (object, prefix = null) ->
return "" unless object
if !prefix and !(@get_object_type(object) is "object")
throw new Error("Url parameters should be a javascript hash")

if root.jQuery
result = root.jQuery.param(object)
return (if not result then "" else result)

s = []
switch @get_object_type(object)
when "array"
for element, i in object
s.push @serialize(element, prefix + "[]")
s.push @default_serializer(element, prefix + "[]")
when "object"
for own key, prop of object when prop?
key = "#{prefix}[#{key}]" if prefix?
s.push @serialize(prop, key)
s.push @default_serializer(prop, key)
else
if object
s.push "#{encodeURIComponent(prefix.toString())}=#{encodeURIComponent(object.toString())}"

return "" unless s.length
s.join("&")

serialize: (object) ->
custom_serializer = SERIALIZER
if custom_serializer
custom_serializer(object)
else
@default_serializer(object)

clean_path: (path) ->
path = path.split("://")
last_index = path.length - 1
Expand Down
4 changes: 4 additions & 0 deletions spec/js_routes/generated_javascript_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
describe "generated js" do
subject { JsRoutes.generate }

it "should set the default serializer when none is configured" do
is_expected.to match(%r(serialize: function\(object\) {\s+var custom_serializer;\s+custom_serializer = null;\s+if \(custom_serializer\) {\s+return custom_serializer\(object\);\s+} else {\s+return this.default_serializer\(object\);\s+}\s+},))
end

it "should include a comment in the header" do
app_class = "App"

Expand Down
27 changes: 21 additions & 6 deletions spec/js_routes/options_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,21 @@
let(:_options) { {} }
let(:_warnings) { true }

context "when serializer is specified" do
let(:_options) { {:serializer => "myCustomSerializer"} }

it "should set configurable serializer" do
# define custom serializer
# this is a nonsense serializer, which always returns foo=bar
# for all inputs
evaljs(%q(function myCustomSerializer(object, prefix) { return "foo=bar"; }))

# expect the nonsense serializer above to have appened foo=bar
# to the end of the path
expect(evaljs(%q(Routes.inboxes_path()))).to eql("/inboxes?foo=bar")
end
end

context "when exclude is specified" do

let(:_options) { {:exclude => /^admin_/} }
Expand Down Expand Up @@ -292,11 +307,11 @@

context "when only host option is specified" do
let(:_options) { { :url_links => true, :default_url_options => {:host => "example.com"} } }

it "uses the specified host, defaults protocol to http, defaults port to 80 (leaving it blank)" do
expect(evaljs("Routes.inbox_url(1)")).to eq("http://example.com#{routes.inbox_path(1)}")
end

it "does not override protocol when specified in route" do
expect(evaljs("Routes.new_session_url()")).to eq("https://example.com#{routes.new_session_path}")
end
Expand All @@ -316,7 +331,7 @@
it "uses the specified protocol and host, defaults port to 80 (leaving it blank)" do
expect(evaljs("Routes.inbox_url(1)")).to eq("ftp://example.com#{routes.inbox_path(1)}")
end

it "does not override protocol when specified in route" do
expect(evaljs("Routes.new_session_url()")).to eq("https://example.com#{routes.new_session_path}")
end
Expand All @@ -340,11 +355,11 @@
it "does not override protocol when specified in route" do
expect(evaljs("Routes.new_session_url()")).to eq("https://example.com:3000#{routes.new_session_path}")
end

it "does not override host, protocol, or port when host is specified in route" do
expect(evaljs("Routes.sso_url()")).to eq(routes.sso_url)
end

it "does not override port when specified in route" do
expect(evaljs("Routes.portals_url()")).to eq("http://example.com:8080#{routes.portals_path}")
end
Expand Down Expand Up @@ -397,7 +412,7 @@
example.run
end
end

let(:_options) { { :compact => true, :url_links => "http://localhost" } }
it "should not strip urls" do
expect(evaljs("Routes.inbox(1)")).to eq(routes.inbox_path(1))
Expand Down
39 changes: 0 additions & 39 deletions spec/js_routes/rails_routes_compatibility_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -147,45 +147,6 @@
end
end

context "when jQuery is present" do
before do
evaljs("window.jQuery = {};")
jscontext[:parameterizeFunc] = lambda {|object| _value.to_param}
evaljs("window.jQuery.param = parameterizeFunc")
end

shared_examples_for "serialization" do
it "should support serialization of objects" do
expect(evaljs("window.jQuery.param(#{_value.to_json})")).to eq(_value.to_param)
expect(evaljs("Routes.inboxes_path(#{_value.to_json})")).to eq(routes.inboxes_path(_value))
expect(evaljs("Routes.inbox_path(1, #{_value.to_json})")).to eq(routes.inbox_path(1, _value))
end
end
context "when parameters is a hash" do
let(:_value) do
{:a => {:b => 'c'}, :q => [1,2]}
end
it_should_behave_like 'serialization'
end
context "when parameters is null" do
let(:_value) do
{:hello => {world: nil}}
end
it_should_behave_like 'serialization'
end
context "when parameters is null" do
let(:_value) do
nil
end

before do
pending("This test is invalid for nil/null and jruby #{JRUBY_VERSION}") if defined?(JRUBY_VERSION) && '1.7.13' == JRUBY_VERSION
end

it_should_behave_like 'serialization'
end
end

context "using optional path fragments" do
context "including not optional parts" do
it "should include everything that is not optional" do
Expand Down

0 comments on commit 2b42621

Please sign in to comment.