js-routes 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/Readme.md CHANGED
@@ -26,12 +26,22 @@ Available options:
26
26
  * `#{Rails.root}/app/assets/javascripts/routes.js` for Rails >= 3.1
27
27
  * `#{Rails.root}/public/javascripts/routes.js` for Rails < 3.1
28
28
  * `:default_format` - Format to append to urls. Default: blank
29
- * `:exclude` - Array of regexps to exclude form js routes. Default: []
29
+ * `:exclude` - Array of regexps to exclude from js routes. Default: []
30
+ * Note that regexp applied to **named route** not to *URL*
31
+ * `:include` - Array of regexps to include in js routes. Default: []
30
32
  * Note that regexp applied to **named route** not to *URL*
31
33
  * `:namespace` - global object used to access routes. Default: `Routes`
32
34
  * Possible variants: `MyProject.routes`, `MyProjectRoutes`
33
35
 
34
- In order to generate routes to string and manipulate them yourself:
36
+ Example options usage:
37
+
38
+ ``` ruby
39
+ JsRoutes.generate!(:file => "#{path}/app_routes.js", :namespace => "AppRoutes", :exclude => /^admin_/, :default_format => "json")
40
+ JsRoutes.generate!(:file => "#{path}/adm_routes.js", :namespace => "AdmRoutes", :include => /^admin_/, :default_format => "json")
41
+ ```
42
+
43
+ In order to generate routes to string and manipulate them yourself use `JsRoutes.generate`:
44
+ Like:
35
45
 
36
46
  ``` ruby
37
47
  JsRoutes.generate(options)
@@ -43,8 +53,11 @@ This will create a nice javascript file with `Routes` object that has all the ra
43
53
 
44
54
  ``` js
45
55
  Routes.users_path() // => "/users"
56
+ Routes.user_path(1) // => "/users/1"
46
57
  Routes.user_path(1, {format: 'json'}) // => "/users/1.json"
58
+ Routes.new_user_project_path(1, {format: 'json'}) // => "/users/1/projects/new.json"
47
59
  Routes.user_project_path(1,2, {q: 'hello', custom: true}) // => "/users/1/projects/2?q=hello&custom=true"
60
+
48
61
  ```
49
62
 
50
63
  In order to make routes helpers available globally:
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.1
1
+ 0.4.0
data/js-routes.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{js-routes}
8
- s.version = "0.3.1"
8
+ s.version = "0.4.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Bogdan Gusiev"]
12
- s.date = %q{2011-08-07}
12
+ s.date = %q{2011-08-18}
13
13
  s.description = %q{Generates javascript file that defines all Rails named routes as javascript helpers}
14
14
  s.email = %q{agresso@gmail.com}
15
15
  s.extra_rdoc_files = [
data/lib/js_routes.rb CHANGED
@@ -25,64 +25,53 @@ module JsRoutes
25
25
  def js_routes(options = {})
26
26
 
27
27
  options[:default_format] ||= ""
28
- exclude = Array(options[:exclude])
28
+ excludes = options[:exclude] || []
29
+ includes = options[:include] || //
29
30
 
30
31
  Rails.application.reload_routes!
31
- Rails.application.routes.named_routes.routes.map do |_, route|
32
- if exclude.find {|e| route.name =~ e}
32
+ js_routes = Rails.application.routes.named_routes.routes.map do |_, route|
33
+ if any_match?(route, excludes) || !any_match?(route, includes)
33
34
  nil
34
35
  else
35
36
  build_js(route, options)
36
37
  end
37
- end.compact.join(",\n")
38
+ end.compact
39
+
40
+ "{\n" + js_routes.join(",\n") + "}\n"
41
+ end
42
+
43
+ def any_match?(route, matchers)
44
+ matchers = Array(matchers)
45
+ matchers.any? {|regex| route.name =~ regex}
38
46
  end
39
47
 
40
48
  def build_js(route, options)
41
49
  _ = <<-JS.strip!
42
50
  // #{route.name} => #{route.path}
43
51
  #{route.name}_path: function(#{build_params route}) {
44
- var opts = options || {};
45
- var format = Utils.extract_format(opts);
46
- #{build_default_params route};
47
- return Utils.check_path('#{build_path route}' + format) + Utils.serialize(opts);
52
+ return Utils.build_path(#{path_parts(route).inspect}, arguments)
48
53
  }
49
54
  JS
50
55
  end
51
56
 
52
57
 
53
58
  def build_params route
54
- route.conditions[:path_info].captures.map do |cap|
55
- if cap.is_a?(Rack::Mount::GeneratableRegexp::DynamicSegment) && !(cap.name.to_s == "format")
56
- cap.name.to_s.gsub(':', '')
59
+ route.conditions[:path_info].named_captures.map do |cap|
60
+ name = cap.first
61
+ if !(name.to_s == "format")
62
+ # prepending each parameter name with underscore
63
+ # to prevent conflict with JS reserved words
64
+ "_" + name.to_s.gsub(/^:/, '')
57
65
  end
58
66
  end.compact.<<("options").join(', ')
59
67
  end
60
68
 
61
- def build_default_params route
62
- route.conditions[:path_info].captures.map do |cap|
63
- if cap.is_a?(Rack::Mount::GeneratableRegexp::DynamicSegment)
64
- segg = cap.name.to_s.gsub(':', '')
65
- "#{segg} = Utils.check_parameter(#{segg});"
66
- end
67
- end.join("\n")
68
- end
69
-
70
- def build_path route
71
- s = route.path.gsub(/\(\.:format\)$/, ".")
72
-
73
- route.conditions[:path_info].captures.each do |cap|
74
- unless cap.name.to_s == "format"
75
- if route.conditions[:path_info].required_params.include?(cap.name)
76
- s.gsub!(/:#{cap.name.to_s}/){ "' + #{cap.name.to_s.gsub(':','')} + '" }
77
- else
78
- s.gsub!(/\((\.)?:#{cap.name.to_s}\)/){ "#{$1}' + #{cap.name.to_s.gsub(':','')} + '" }
79
- end
80
- end
81
- end
82
- s
83
69
 
70
+ def path_parts route
71
+ route.path.gsub(/\(\.:format\)$/, "").split(/:[a-z\-_]+/)
84
72
  end
85
73
 
74
+
86
75
  def default_file
87
76
  if Rails.version >= "3.1"
88
77
  "#{Rails.root}/app/assets/javascripts/routes.js"
data/lib/routes.js CHANGED
@@ -5,37 +5,45 @@
5
5
  default_format: 'DEFAULT_FORMAT',
6
6
 
7
7
  serialize: function(obj){
8
- if (obj == null) {return '';}
8
+ if (obj === null) {return '';}
9
9
  var s = [];
10
10
  for (prop in obj){
11
11
  s.push(prop + "=" + obj[prop]);
12
12
  }
13
- if (s.length == 0) {
13
+ if (s.length === 0) {
14
14
  return '';
15
15
  }
16
16
  return "?" + s.join('&');
17
17
  },
18
18
 
19
-
20
- check_parameter: function(param) {
21
- if (param === undefined) {
22
- param = '';
23
- }
24
- return param;
25
- },
26
-
27
- check_path: function(path) {
28
- return path.replace(/\.$/m, '');
19
+ clean_path: function(path) {
20
+ return path.replace(/\.$/m, '').replace(/\/$/m, '');
29
21
  },
30
22
 
31
23
  extract_format: function(options) {
32
24
  var format = options.hasOwnProperty("format") ? options.format : Utils.default_format;
33
25
  delete options.format;
34
- return format || "";
26
+ return format ? "." + format : "";
27
+ },
28
+
29
+ extract_options: function(args) {
30
+ return typeof(args[args.length-1]) == "object" ? args.pop() : {};
31
+ },
32
+
33
+ build_path: function(parts, args) {
34
+ args = Array.prototype.slice.call(args);
35
+ result = "";
36
+ var opts = Utils.extract_options(args);
37
+ for (var i=0; i < parts.length; i++) {
38
+ part = parts[i];
39
+ result += part;
40
+ result += args.shift() || "";
41
+ }
42
+ var format = Utils.extract_format(opts);
43
+ return Utils.clean_path(result + format) + Utils.serialize(opts);
35
44
  }
36
45
  };
37
46
 
38
- window.NAMESPACE = {
39
- ROUTES
40
- };
47
+ window.NAMESPACE = ROUTES;
48
+
41
49
  })();
@@ -21,6 +21,10 @@ describe JsRoutes do
21
21
  evaljs("Routes.inbox_path(1)").should == "/inboxes/1"
22
22
  end
23
23
 
24
+ it "should generate nested routing with one parameter" do
25
+ evaljs("Routes.inbox_message_path(1)").should == "/inboxes/1/messages"
26
+ end
27
+
24
28
  it "should generate nested routing" do
25
29
  evaljs("Routes.inbox_message_path(1,2)").should == "/inboxes/1/messages/2"
26
30
  end
@@ -33,6 +37,13 @@ describe JsRoutes do
33
37
  evaljs("Routes.inbox_path(1, {format: 'json', q: 'hello', lang: 'ua'})").should == "/inboxes/1.json?q=hello&lang=ua"
34
38
  end
35
39
 
40
+ it "should support routes with reserved javascript words as parameters" do
41
+ #TODO: this doesn't actually test what it should test
42
+ #because the parameter name is return_id
43
+ #need to find the real way to test
44
+ evaljs("Routes.return_path(1)").should == "/returns/1"
45
+ end
46
+
36
47
  context "when exclude is specified" do
37
48
 
38
49
  let(:_options) { {:exclude => /^admin_/} }
@@ -45,6 +56,18 @@ describe JsRoutes do
45
56
  evaljs("Routes.inboxes_path()").should_not be_nil
46
57
  end
47
58
  end
59
+ context "when include is specified" do
60
+
61
+ let(:_options) { {:include => /^admin_/} }
62
+
63
+ it "should exclude specified routes from file" do
64
+ evaljs("Routes.admin_users_path()").should_not be_nil
65
+ end
66
+
67
+ it "should not exclude routes not under specified pattern" do
68
+ evaljs("Routes.inboxes_path").should be_nil
69
+ end
70
+ end
48
71
 
49
72
  context "when default_format is specified" do
50
73
  let(:_options) { {:default_format => "json"} }
@@ -80,6 +103,13 @@ describe JsRoutes do
80
103
 
81
104
  end
82
105
 
106
+ describe "generated js" do
107
+ subject { JsRoutes.generate }
108
+ it "should have correct function signature" do
109
+ subject.should include("inbox_message_path: function(_inbox_id, _id, options)")
110
+ end
111
+ end
112
+
83
113
  describe ".generate!" do
84
114
  let(:name) { "#{File.dirname(__FILE__)}/../routes.js" }
85
115
  it "should generate routes file" do
data/spec/spec_helper.rb CHANGED
@@ -21,6 +21,8 @@ class App < Rails::Application
21
21
  namespace :admin do
22
22
  resources :users
23
23
  end
24
+
25
+ resources :returns
24
26
  end
25
27
  end
26
28
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: js-routes
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
4
+ hash: 15
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 3
9
- - 1
10
- version: 0.3.1
8
+ - 4
9
+ - 0
10
+ version: 0.4.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Bogdan Gusiev
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-08-07 00:00:00 +03:00
18
+ date: 2011-08-18 00:00:00 +03:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency