js-routes 0.7.5 → 0.8.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/Gemfile CHANGED
@@ -1,6 +1,6 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- gem "rails", ">= 3.0"
3
+ gem "rails", ">= 3.2"
4
4
 
5
5
  group :development do
6
6
  gem "therubyracer"
data/Gemfile.lock CHANGED
@@ -1,37 +1,34 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- actionmailer (3.1.0)
5
- actionpack (= 3.1.0)
6
- mail (~> 2.3.0)
7
- actionpack (3.1.0)
8
- activemodel (= 3.1.0)
9
- activesupport (= 3.1.0)
4
+ actionmailer (3.2.1)
5
+ actionpack (= 3.2.1)
6
+ mail (~> 2.4.0)
7
+ actionpack (3.2.1)
8
+ activemodel (= 3.2.1)
9
+ activesupport (= 3.2.1)
10
10
  builder (~> 3.0.0)
11
11
  erubis (~> 2.7.0)
12
- i18n (~> 0.6)
13
- rack (~> 1.3.2)
14
- rack-cache (~> 1.0.3)
15
- rack-mount (~> 0.8.2)
12
+ journey (~> 1.0.1)
13
+ rack (~> 1.4.0)
14
+ rack-cache (~> 1.1)
16
15
  rack-test (~> 0.6.1)
17
- sprockets (~> 2.0.0)
18
- activemodel (3.1.0)
19
- activesupport (= 3.1.0)
20
- bcrypt-ruby (~> 3.0.0)
16
+ sprockets (~> 2.1.2)
17
+ activemodel (3.2.1)
18
+ activesupport (= 3.2.1)
21
19
  builder (~> 3.0.0)
22
- i18n (~> 0.6)
23
- activerecord (3.1.0)
24
- activemodel (= 3.1.0)
25
- activesupport (= 3.1.0)
26
- arel (~> 2.2.1)
20
+ activerecord (3.2.1)
21
+ activemodel (= 3.2.1)
22
+ activesupport (= 3.2.1)
23
+ arel (~> 3.0.0)
27
24
  tzinfo (~> 0.3.29)
28
- activeresource (3.1.0)
29
- activemodel (= 3.1.0)
30
- activesupport (= 3.1.0)
31
- activesupport (3.1.0)
25
+ activeresource (3.2.1)
26
+ activemodel (= 3.2.1)
27
+ activesupport (= 3.2.1)
28
+ activesupport (3.2.1)
29
+ i18n (~> 0.6)
32
30
  multi_json (~> 1.0)
33
- arel (2.2.1)
34
- bcrypt-ruby (3.0.1)
31
+ arel (3.0.0)
35
32
  builder (3.0.0)
36
33
  diff-lcs (1.1.3)
37
34
  erubis (2.7.0)
@@ -42,41 +39,42 @@ GEM
42
39
  bundler (~> 1.0)
43
40
  git (>= 1.2.5)
44
41
  rake
42
+ journey (1.0.1)
43
+ json (1.6.5)
45
44
  libv8 (3.3.10.4)
46
- mail (2.3.0)
45
+ mail (2.4.1)
47
46
  i18n (>= 0.4.0)
48
47
  mime-types (~> 1.16)
49
48
  treetop (~> 1.4.8)
50
- mime-types (1.16)
51
- multi_json (1.0.3)
52
- polyglot (0.3.2)
53
- rack (1.3.3)
54
- rack-cache (1.0.3)
49
+ mime-types (1.17.2)
50
+ multi_json (1.0.4)
51
+ polyglot (0.3.3)
52
+ rack (1.4.1)
53
+ rack-cache (1.1)
55
54
  rack (>= 0.4)
56
- rack-mount (0.8.3)
57
- rack (>= 1.0.0)
58
55
  rack-ssl (1.3.2)
59
56
  rack
60
57
  rack-test (0.6.1)
61
58
  rack (>= 1.0)
62
- rails (3.1.0)
63
- actionmailer (= 3.1.0)
64
- actionpack (= 3.1.0)
65
- activerecord (= 3.1.0)
66
- activeresource (= 3.1.0)
67
- activesupport (= 3.1.0)
59
+ rails (3.2.1)
60
+ actionmailer (= 3.2.1)
61
+ actionpack (= 3.2.1)
62
+ activerecord (= 3.2.1)
63
+ activeresource (= 3.2.1)
64
+ activesupport (= 3.2.1)
68
65
  bundler (~> 1.0)
69
- railties (= 3.1.0)
70
- railties (3.1.0)
71
- actionpack (= 3.1.0)
72
- activesupport (= 3.1.0)
66
+ railties (= 3.2.1)
67
+ railties (3.2.1)
68
+ actionpack (= 3.2.1)
69
+ activesupport (= 3.2.1)
73
70
  rack-ssl (~> 1.3.2)
74
71
  rake (>= 0.8.7)
75
72
  rdoc (~> 3.4)
76
73
  thor (~> 0.14.6)
77
74
  rake (0.9.2)
78
75
  rcov (0.9.9)
79
- rdoc (3.9.4)
76
+ rdoc (3.12)
77
+ json (~> 1.4)
80
78
  rspec (2.7.0)
81
79
  rspec-core (~> 2.7.0)
82
80
  rspec-expectations (~> 2.7.0)
@@ -85,7 +83,7 @@ GEM
85
83
  rspec-expectations (2.7.0)
86
84
  diff-lcs (~> 1.1.2)
87
85
  rspec-mocks (2.7.0)
88
- sprockets (2.0.0)
86
+ sprockets (2.1.2)
89
87
  hike (~> 1.2)
90
88
  rack (~> 1.0)
91
89
  tilt (~> 1.1, != 1.3.0)
@@ -96,7 +94,7 @@ GEM
96
94
  treetop (1.4.10)
97
95
  polyglot
98
96
  polyglot (>= 0.3.1)
99
- tzinfo (0.3.29)
97
+ tzinfo (0.3.31)
100
98
 
101
99
  PLATFORMS
102
100
  ruby
@@ -104,7 +102,7 @@ PLATFORMS
104
102
  DEPENDENCIES
105
103
  bundler (~> 1.0.0)
106
104
  jeweler (~> 1.6.2)
107
- rails (>= 3.0)
105
+ rails (>= 3.2)
108
106
  rcov
109
107
  rspec (~> 2.7.0)
110
108
  therubyracer
data/Readme.md CHANGED
@@ -1,8 +1,8 @@
1
- ## JsRoutes
1
+ # JsRoutes
2
2
 
3
3
  Generates javascript file that defines all Rails named routes as javascript helpers
4
4
 
5
- ### Intallation
5
+ ## Intallation
6
6
 
7
7
  Your Rails Gemfile:
8
8
 
@@ -10,44 +10,53 @@ Your Rails Gemfile:
10
10
  gem "js-routes"
11
11
  ```
12
12
 
13
- Your application initializer, like `config/initializers/jsroutes.rb`:
13
+ ### Basic Setup (Asset Pipeline)
14
+
15
+ Require js routes file in `application.js` or other bundle
16
+
17
+ ``` js
18
+ /*
19
+ = require js-routes
20
+ */
21
+ ```
22
+
23
+ **Optional**: If you need to customize routes file create initializer, like `config/initializers/jsroutes.rb`:
14
24
 
15
25
  ``` ruby
16
- JsRoutes.generate!({
17
- #options
26
+ JsRoutes.setup do |config|
27
+ config.option = value
18
28
  })
19
29
  ```
20
30
 
21
31
  Available options:
22
32
 
23
- * `:file` - the file to generate the routes. Default:
24
- * `#{Rails.root}/app/assets/javascripts/routes.js` for Rails >= 3.1
25
- * `#{Rails.root}/public/javascripts/routes.js` for Rails < 3.1
26
- * `:default_format` - Format to append to urls. Default: blank
27
- * `:exclude` - Array of regexps to exclude from js routes. Default: []
33
+ * `default_format` - Format to append to urls. Default: blank
34
+ * `exclude` - Array of regexps to exclude from js routes. Default: []
28
35
  * Note that regexp applied to **named route** not to *URL*
29
- * `:include` - Array of regexps to include in js routes. Default: []
36
+ * `include` - Array of regexps to include in js routes. Default: []
30
37
  * Note that regexp applied to **named route** not to *URL*
31
- * `:namespace` - global object used to access routes. Default: `Routes`
38
+ * `namespace` - global object used to access routes. Default: `Routes`
32
39
  * Supports nested namespace like `MyProject.routes`
33
- * `:prefix` - String representing a url path to prepend to all paths
34
- * `Should be specified via :prefix => "/myprefix"`
40
+ * `prefix` - String representing a url path to prepend to all paths. Default: blank
41
+
42
+
43
+ ### Advanced Setup
35
44
 
36
- This is how you can generate separated routes files for different parts of application:
45
+ You can generate routes files on the application side like this:
37
46
 
38
47
  ``` 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")
48
+ JsRoutes.generate!("#{path}/app_routes.js", :namespace => "AppRoutes", :exclude => /^admin_/, :default_format => "json")
49
+ JsRoutes.generate!("#{path}/adm_routes.js", :namespace => "AdmRoutes", :include => /^admin_/, :default_format => "json")
41
50
  ```
42
51
 
43
- In order to generate routes to string and manipulate them yourself use:
52
+ In order to generate javascript to string and manipulate them yourself use:
44
53
  Like:
45
54
 
46
55
  ``` ruby
47
56
  routes_js = JsRoutes.generate(options)
48
57
  ```
49
58
 
50
- ### Usage
59
+ ## Usage
51
60
 
52
61
  Configuration above will create a nice javascript file with `Routes` object that has all the rails routes available:
53
62
 
@@ -75,13 +84,13 @@ In order to make routes helpers available globally:
75
84
  jQuery.extend(window, Routes)
76
85
  ```
77
86
 
78
- ### What about security?
87
+ ## What about security?
79
88
 
80
89
  js-routes itself do not have security holes. It makes URLs
81
90
  without access protection more reachable by potential attacker.
82
91
  In order to prevent this use `:exclude` option for sensitive urls like `/admin_/`
83
92
 
84
- ### Spork
93
+ ## Spork
85
94
 
86
95
  When using Spork and `Spork.trap_method(Rails::Application::RoutesReloader, :reload!)` you should also do:
87
96
 
@@ -89,7 +98,7 @@ When using Spork and `Spork.trap_method(Rails::Application::RoutesReloader, :rel
89
98
  Spork.trap_method(JsRoutes, :generate!)
90
99
  ```
91
100
 
92
- ### Advantages over alternatives
101
+ ## Advantages over alternatives
93
102
 
94
103
  There are some alternatives available. Most of them has only basic feature and don't reach the level of quality I accept.
95
104
  Advantages of this one are:
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.7.5
1
+ 0.8.0
data/js-routes.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "js-routes"
8
- s.version = "0.7.5"
8
+ s.version = "0.8.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 = "2012-02-13"
12
+ s.date = "2012-03-02"
13
13
  s.description = "Generates javascript file that defines all Rails named routes as javascript helpers"
14
14
  s.email = "agresso@gmail.com"
15
15
  s.extra_rdoc_files = [
@@ -46,14 +46,14 @@ Gem::Specification.new do |s|
46
46
  s.specification_version = 3
47
47
 
48
48
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
49
- s.add_runtime_dependency(%q<rails>, [">= 3.0"])
49
+ s.add_runtime_dependency(%q<rails>, [">= 3.2"])
50
50
  s.add_development_dependency(%q<therubyracer>, [">= 0"])
51
51
  s.add_development_dependency(%q<rspec>, ["~> 2.7.0"])
52
52
  s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
53
53
  s.add_development_dependency(%q<jeweler>, ["~> 1.6.2"])
54
54
  s.add_development_dependency(%q<rcov>, [">= 0"])
55
55
  else
56
- s.add_dependency(%q<rails>, [">= 3.0"])
56
+ s.add_dependency(%q<rails>, [">= 3.2"])
57
57
  s.add_dependency(%q<therubyracer>, [">= 0"])
58
58
  s.add_dependency(%q<rspec>, ["~> 2.7.0"])
59
59
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
@@ -61,7 +61,7 @@ Gem::Specification.new do |s|
61
61
  s.add_dependency(%q<rcov>, [">= 0"])
62
62
  end
63
63
  else
64
- s.add_dependency(%q<rails>, [">= 3.0"])
64
+ s.add_dependency(%q<rails>, [">= 3.2"])
65
65
  s.add_dependency(%q<therubyracer>, [">= 0"])
66
66
  s.add_dependency(%q<rspec>, ["~> 2.7.0"])
67
67
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
data/lib/js_routes.rb CHANGED
@@ -4,11 +4,7 @@ class JsRoutes
4
4
  # OPTIONS
5
5
  #
6
6
 
7
- DEFAULT_PATH = if Rails.version >= "3.1"
8
- File.join('app','assets','javascripts','routes.js')
9
- else
10
- File.join('public','javascripts','routes.js')
11
- end
7
+ DEFAULT_PATH = File.join('app','assets','javascripts','routes.js')
12
8
 
13
9
  DEFAULTS = {
14
10
  :namespace => "Routes",
@@ -19,6 +15,18 @@ class JsRoutes
19
15
  :prefix => ""
20
16
  }
21
17
 
18
+ # We encode node symbols as integer to reduce the routes.js file size
19
+ NODE_TYPES = {
20
+ :GROUP => 1,
21
+ :CAT => 2,
22
+ :SYMBOL => 3,
23
+ :OR => 4,
24
+ :STAR => 5,
25
+ :LITERAL => 6,
26
+ :SLASH => 7,
27
+ :DOT => 8
28
+ }
29
+
22
30
  class Options < Struct.new(*DEFAULTS.keys)
23
31
  def to_hash
24
32
  Hash[*members.zip(values).flatten(1)].symbolize_keys
@@ -44,19 +52,27 @@ class JsRoutes
44
52
  new(opts).generate
45
53
  end
46
54
 
47
- def generate!(opts = {})
48
- new(opts).generate!
55
+ def generate!(file_name, opts = {})
56
+ if file_name.is_a?(Hash)
57
+ opts = file_name
58
+ file_name = opts[:file]
59
+ end
60
+ new(opts).generate!(file_name)
49
61
  end
50
62
 
51
63
  # Under rails 3.1.1 and higher, perform a check to ensure that the
52
64
  # full environment will be available during asset compilation.
53
65
  # This is required to ensure routes are loaded.
54
66
  def assert_usable_configuration!
55
- if Rails.version > "3.1.0" && !Rails.application.config.assets.initialize_on_precompile
67
+ unless Rails.application.config.assets.initialize_on_precompile
56
68
  raise("Cannot precompile js-routes unless environment is initialized. Please set config.assets.initialize_on_precompile to true.")
57
69
  end
58
70
  true
59
71
  end
72
+
73
+ def json(string)
74
+ ActiveSupport::JSON.encode(string)
75
+ end
60
76
  end
61
77
 
62
78
  #
@@ -72,15 +88,16 @@ class JsRoutes
72
88
  js.gsub!("NAMESPACE", @options[:namespace])
73
89
  js.gsub!("DEFAULT_FORMAT", @options[:default_format].to_s)
74
90
  js.gsub!("PREFIX", @options[:prefix])
91
+ js.gsub!("NODE_TYPES", json(NODE_TYPES))
75
92
  js.gsub!("ROUTES", js_routes)
76
93
  end
77
94
 
78
- def generate!
95
+ def generate!(file_name)
79
96
  # Some libraries like Devise do not yet loaded their routes so we will wait
80
97
  # until initialization process finish
81
98
  # https://github.com/railsware/js-routes/issues/7
82
99
  Rails.configuration.after_initialize do
83
- File.open(Rails.root.join(@options[:file]), 'w') do |f|
100
+ File.open(Rails.root.join(file_name || DEFAULT_PATH), 'w') do |f|
84
101
  f.write generate
85
102
  end
86
103
  end
@@ -107,68 +124,38 @@ class JsRoutes
107
124
  end
108
125
 
109
126
  def build_js(route)
110
- params = build_params route
111
127
  _ = <<-JS.strip!
112
- // #{route.name} => #{route_spec(route)}
113
- #{route.name}_path: function(#{(params + ["options"]).join(", ")}) {
114
- return Utils.build_path(#{params.size}, #{path_parts(route).inspect}, #{optional_params(route).inspect}, arguments)
128
+ // #{route.name} => #{route.path.spec}
129
+ #{route.name}_path: function(#{build_params(route)}) {
130
+ return Utils.build_path(#{json(route.required_parts)}, #{json(serialize(route.path.spec))}, arguments)
115
131
  }
116
132
  JS
117
133
  end
118
134
 
119
- # TODO: might be possible to simplify this to use route.path
120
- # instead of all this path_info.source madness
121
- def optional_params(route)
122
- if Rails.version >= "3.2.0"
123
- return route.optional_parts.map(&:to_s)
124
- end
125
- path_info = route.conditions[:path_info]
126
- path_info_source = path_info.source
127
- if RUBY_VERSION >= '1.9.2'
128
- optional_named_captures_regexp = /\?\:.+?\(\?\<(.+?)\>/
129
- path_info_source.scan(optional_named_captures_regexp).flatten
130
- else
131
- re = Regexp.escape("([^/.?]+)")
132
- optional_named_captures_regexp = /#{re}|\(\?\:.+?\)\?/
133
- captures = path_info_source.scan(optional_named_captures_regexp).flatten
134
- named_captures = path_info.named_captures.to_a.sort_by {|cap|cap.last.first}
135
- captures.zip(named_captures).map do |type, (name, pos)|
136
- name unless type == '([^/.?]+)'
137
- end.compact
138
- end
135
+ def json(string)
136
+ self.class.json(string)
139
137
  end
140
138
 
141
139
  def build_params route
142
- required_params(route).map do |name|
140
+ params = route.required_parts.map do |name|
143
141
  # prepending each parameter name with underscore
144
142
  # to prevent conflict with JS reserved words
145
143
  "_" + name.to_s
146
- end
147
- end
148
-
149
-
150
- def path_parts route
151
- route_spec(route).gsub(/\(\.:format\)$/, "").split(/:[a-z\-_]+/)
144
+ end << "options"
145
+ params.join(", ")
152
146
  end
153
147
 
154
- def route_spec route
155
- if Rails.version >= "3.2.0"
156
- route.path.spec
157
- else
158
- route.path
159
- end.to_s
160
- end
161
-
162
- def required_params(route)
163
- if Rails.version >= "3.2.0"
164
- return route.required_parts.map(&:to_s)
165
- end # if
166
- optional_named_captures = optional_params(route)
167
- route.conditions[:path_info].named_captures.to_a.sort_by do |cap1|
168
- # Hash is not ordered in Ruby 1.8.7
169
- cap1.last.first
170
- end.map(&:first).reject do |name|
171
- optional_named_captures.include?(name.to_s)
172
- end
148
+ # This function serializes Journey route into JSON structure
149
+ # We do not use Hash for human readable serialization
150
+ # And preffer Array serialization because it is shorter.
151
+ # Routes.js file will be smaller.
152
+ def serialize(spec)
153
+ return nil unless spec
154
+ return spec.tr(':', '') if spec.is_a?(String)
155
+ [
156
+ NODE_TYPES[spec.type],
157
+ serialize(spec.left),
158
+ spec.respond_to?(:right) && serialize(spec.right)
159
+ ]
173
160
  end
174
161
  end
@@ -1,4 +1,4 @@
1
- if defined?(Rails) && Rails.version >= "3.1"
1
+ if defined?(Rails)
2
2
  class JsRoutes
3
3
  class Engine < Rails::Engine
4
4
  JS_ROUTES_ASSET = 'js-routes'
data/lib/routes.js CHANGED
@@ -1,9 +1,16 @@
1
1
  (function(){
2
2
 
3
+ function ParameterMissing(message) {
4
+ this.message = message;
5
+ }
6
+ ParameterMissing.prototype = new Error();
7
+
3
8
  var defaults = {
4
9
  prefix: 'PREFIX',
5
10
  format: 'DEFAULT_FORMAT'
6
11
  };
12
+
13
+ var NodeTypes = NODE_TYPES
7
14
 
8
15
  var Utils = {
9
16
 
@@ -32,21 +39,8 @@
32
39
  return path.replace(/\/+/g, "/").replace(/[\)\(]/g, "").replace(/\.$/m, '').replace(/\/$/m, '');
33
40
  },
34
41
 
35
- extract: function(name, options) {
36
- var o = undefined;
37
- if (options.hasOwnProperty(name)) {
38
- o = options[name];
39
- delete options[name];
40
- } else if (defaults.hasOwnProperty(name)) {
41
- o = defaults[name];
42
- }
43
- return o;
44
- },
45
-
46
- extract_format: function(options) {
47
- var format = options.hasOwnProperty("format") ? options.format : defaults.format;
48
- delete options.format;
49
- return format ? "." + format : "";
42
+ set_default_format: function(options) {
43
+ if (!options.hasOwnProperty("format")) options.format = defaults.format;
50
44
  },
51
45
 
52
46
  extract_anchor: function(options) {
@@ -74,49 +68,87 @@
74
68
  }
75
69
  },
76
70
 
77
- build_path: function(number_of_params, parts, optional_params, args) {
71
+ clone: function (obj) {
72
+ if (null == obj || "object" != typeof obj) return obj;
73
+ var copy = obj.constructor();
74
+ for (var attr in obj) {
75
+ if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
76
+ }
77
+ return copy;
78
+ },
79
+
80
+ prepare_parameters: function(required_parameters, actual_parameters, options) {
81
+ var result = this.clone(options);
82
+ for (var i=0; i < required_parameters.length; i++) {
83
+ result[required_parameters[i]] = actual_parameters[i];
84
+ }
85
+ return result;
86
+ },
87
+
88
+ build_path: function(required_parameters, route, args) {
78
89
  args = Array.prototype.slice.call(args);
79
- var result = Utils.get_prefix();
80
- var opts = Utils.extract_options(number_of_params, args);
81
- if (args.length > number_of_params) {
90
+ var opts = this.extract_options(required_parameters.length, args);
91
+ if (args.length > required_parameters.length) {
82
92
  throw new Error("Too many parameters provided for path");
83
93
  }
84
- var params_count = 0, optional_params_count = 0;
85
- for (var i=0; i < parts.length; i++) {
86
- var part = parts[i];
87
- if (Utils.optional_part(part)) {
88
- var name = optional_params[optional_params_count];
89
- optional_params_count++;
90
- // try and find the option in opts
91
- var optional = Utils.extract(name, opts);
92
- if (Utils.specified(optional)) {
93
- result += part;
94
- result += Utils.path_identifier(optional);
95
- }
96
- } else {
97
- result += part;
98
- if (params_count < number_of_params) {
99
- params_count++;
100
- var value = args.shift();
101
- if (Utils.specified(value)) {
102
- result += Utils.path_identifier(value);
94
+
95
+ parameters = this.prepare_parameters(required_parameters, args, opts);
96
+ this.set_default_format(parameters);
97
+ var result = Utils.get_prefix();
98
+ var anchor = Utils.extract_anchor(parameters);
99
+
100
+ result += this.visit(route, parameters)
101
+ return Utils.clean_path(result + anchor) + Utils.serialize(parameters);
102
+ },
103
+
104
+ /*
105
+ * This function is JavaScript impelementation of the
106
+ * Journey::Visitors::Formatter that builds route by given parameters
107
+ * and parsed route binary tree.
108
+ * Binary tree is serialized in the following way:
109
+ * [node type, left node, right node ]
110
+ */
111
+ visit: function(route, options) {
112
+ var type = route[0];
113
+ var left = route[1];
114
+ var right = route[2];
115
+ switch (type) {
116
+ case NodeTypes.GROUP:
117
+ try {
118
+ return this.visit(left, options);
119
+ } catch(e) {
120
+ if (e instanceof ParameterMissing) {
121
+ return "";
103
122
  } else {
104
- throw new Error("Insufficient parameters to build path");
123
+ throw e;
105
124
  }
106
125
  }
107
- }
126
+ case NodeTypes.CAT:
127
+ return this.visit(left, options) + this.visit(right, options);
128
+ case NodeTypes.SYMBOL:
129
+ var value = options[left];
130
+ if (value) {
131
+ delete options[left];
132
+ return this.path_identifier(value);
133
+ } else {
134
+ throw new ParameterMissing("Route parameter missing: " + left);
135
+ }
136
+ /*
137
+ * I don't know what are these node types
138
+ * Please send your PR if you do
139
+ */
140
+ //case NodeTypes.OR:
141
+ //case NodeTypes.STAR:
142
+ case NodeTypes.LITERAL:
143
+ return left;
144
+ case NodeTypes.SLASH:
145
+ return left;
146
+ case NodeTypes.DOT:
147
+ return left;
148
+ default:
149
+ throw new Error("Unknown Rails node type");
108
150
  }
109
- var format = Utils.extract_format(opts);
110
- var anchor = Utils.extract_anchor(opts);
111
- return Utils.clean_path(result + format + anchor) + Utils.serialize(opts);
112
- },
113
-
114
- specified: function(value) {
115
- return !(value === undefined || value === null);
116
- },
117
-
118
- optional_part: function(part) {
119
- return part.match(/\(/);
151
+
120
152
  },
121
153
 
122
154
  get_prefix: function(){
@@ -193,6 +193,12 @@ describe JsRoutes do
193
193
  end
194
194
 
195
195
  context "using optional path fragments" do
196
+ context "including not optional parts" do
197
+ it "should include everything that is not optional" do
198
+ evaljs("Routes.foo_path()").should == routes.foo_path
199
+ end
200
+ end
201
+
196
202
  context "but not including them" do
197
203
  it "should not include the optional parts" do
198
204
  evaljs("Routes.things_path()").should == routes.things_path
@@ -7,7 +7,8 @@ describe "after Rails initialization" do
7
7
  before(:all) do
8
8
 
9
9
  FileUtils.rm_f(name)
10
- JsRoutes.generate!({:file => name})
10
+ JsRoutes.generate!(name)
11
+
11
12
 
12
13
  Rails.application.initialize!
13
14
  end
@@ -16,91 +17,74 @@ describe "after Rails initialization" do
16
17
  FileUtils.rm_f(name)
17
18
  end
18
19
 
19
- context '.generate!' do
20
- it "should generate routes file" do
21
- File.exists?(name).should be_true
22
- end
20
+ it "should generate routes file" do
21
+ File.exists?(name).should be_true
23
22
  end
24
23
 
25
- if Rails.version >= "3.1"
26
- context "JsRoutes::Engine" do
24
+ context "JsRoutes::Engine" do
27
25
 
28
- let(:test_asset_path) {
29
- Rails.root.join('app','assets','javascripts','test.js')
30
- }
26
+ let(:test_asset_path) {
27
+ Rails.root.join('app','assets','javascripts','test.js')
28
+ }
31
29
 
32
- before(:all) do
33
- File.open(test_asset_path,'w') do |f|
34
- f.puts "function() {}"
35
- end
36
- end
37
- after(:all) do
38
- FileUtils.rm_f(test_asset_path)
30
+ before(:all) do
31
+ File.open(test_asset_path,'w') do |f|
32
+ f.puts "function() {}"
39
33
  end
34
+ end
35
+ after(:all) do
36
+ FileUtils.rm_f(test_asset_path)
37
+ end
38
+
39
+ it "should have registered a preprocessor" do
40
+ pps = Rails.application.assets.preprocessors
41
+ js_pps = pps['application/javascript']
42
+ js_pps.map(&:name).should include('Sprockets::Processor (js-routes_dependent_on_routes)')
43
+ end
40
44
 
41
- it "should have registered a preprocessor" do
42
- pps = Rails.application.assets.preprocessors
43
- js_pps = pps['application/javascript']
44
- js_pps.map(&:name).should include('Sprockets::Processor (js-routes_dependent_on_routes)')
45
+ context "the preprocessor" do
46
+ before(:each) do
47
+ ctx.should_receive(:depend_on).with(Rails.root.join('config','routes.rb'))
45
48
  end
49
+ let!(:ctx) do
50
+ Sprockets::Context.new(Rails.application.assets,
51
+ 'js-routes.js',
52
+ Pathname.new('js-routes.js'))
46
53
 
47
- context "the preprocessor" do
48
- before(:each) do
49
- ctx.should_receive(:depend_on).with(Rails.root.join('config','routes.rb'))
50
- end
51
- let!(:ctx) do
52
- Sprockets::Context.new(Rails.application.assets,
53
- 'js-routes.js',
54
- Pathname.new('js-routes.js'))
54
+ end
55
+ context "when dealing with js-routes.js" do
55
56
 
56
- end
57
- context "when dealing with js-routes.js" do
58
57
 
59
- #TODO: check why doesn't work with let callbacks
60
- context 'with Rails 3.1.0' do
58
+ context "with Rails 3.1.1" do
59
+ context "and initialize on precompile" do
61
60
  before(:each) do
62
- Rails.stub!("version").and_return("3.1.0")
61
+ Rails.application.config.assets.initialize_on_precompile = true
63
62
  end
64
-
65
63
  it "should render some javascript" do
66
64
  ctx.evaluate('js-routes.js').should =~ /window\.Routes/
67
65
  end
68
66
  end
69
-
70
- context "with Rails 3.1.1" do
67
+ context "and not initialize on precompile" do
71
68
  before(:each) do
72
- Rails.stub!("version").and_return("3.1.1")
69
+ Rails.application.config.assets.initialize_on_precompile = false
73
70
  end
74
- context "and initialize on precompile" do
75
- before(:each) do
76
- Rails.application.config.assets.initialize_on_precompile = true
77
- end
78
- it "should render some javascript" do
79
- ctx.evaluate('js-routes.js').should =~ /window\.Routes/
80
- end
71
+ it "should raise an exception" do
72
+ lambda { ctx.evaluate('js-routes.js') }.should raise_error(/Cannot precompile/)
81
73
  end
82
- context "and not initialize on precompile" do
83
- before(:each) do
84
- Rails.application.config.assets.initialize_on_precompile = false
85
- end
86
- it "should raise an exception" do
87
- lambda { ctx.evaluate('js-routes.js') }.should raise_error(/Cannot precompile/)
88
- end
89
- end
90
-
91
74
  end
75
+
92
76
  end
77
+ end
93
78
 
94
79
 
95
- end
96
- context "when not dealing with js-routes.js" do
97
- it "should not depend on routes.rb" do
98
- ctx = Sprockets::Context.new(Rails.application.assets,
99
- 'test.js',
100
- test_asset_path)
101
- ctx.should_not_receive(:depend_on)
102
- ctx.evaluate('test.js')
103
- end
80
+ end
81
+ context "when not dealing with js-routes.js" do
82
+ it "should not depend on routes.rb" do
83
+ ctx = Sprockets::Context.new(Rails.application.assets,
84
+ 'test.js',
85
+ test_asset_path)
86
+ ctx.should_not_receive(:depend_on)
87
+ ctx.evaluate('test.js')
104
88
  end
105
89
  end
106
90
  end
data/spec/spec_helper.rb CHANGED
@@ -20,10 +20,8 @@ end
20
20
 
21
21
 
22
22
  class App < Rails::Application
23
- if Rails.version >= '3.1'
24
- # Enable the asset pipeline
25
- config.assets.enabled = true
26
- end
23
+ # Enable the asset pipeline
24
+ config.assets.enabled = true
27
25
 
28
26
  self.routes.draw do
29
27
  resources :inboxes do
@@ -44,6 +42,8 @@ class App < Rails::Application
44
42
  scope "(/optional/:optional_id)" do
45
43
  resources :things
46
44
  end
45
+
46
+ match "/other_optional/(:optional_id)" => "foo#foo", :as => :foo
47
47
  end
48
48
 
49
49
  end
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.7.5
4
+ version: 0.8.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,22 +9,22 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-13 00:00:00.000000000 Z
12
+ date: 2012-03-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
16
- requirement: &20189100 !ruby/object:Gem::Requirement
16
+ requirement: &85230710 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
- version: '3.0'
21
+ version: '3.2'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *20189100
24
+ version_requirements: *85230710
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: therubyracer
27
- requirement: &20199080 !ruby/object:Gem::Requirement
27
+ requirement: &85229560 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *20199080
35
+ version_requirements: *85229560
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rspec
38
- requirement: &20194300 !ruby/object:Gem::Requirement
38
+ requirement: &85245130 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 2.7.0
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *20194300
46
+ version_requirements: *85245130
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: bundler
49
- requirement: &20205180 !ruby/object:Gem::Requirement
49
+ requirement: &85244440 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 1.0.0
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *20205180
57
+ version_requirements: *85244440
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: jeweler
60
- requirement: &20213600 !ruby/object:Gem::Requirement
60
+ requirement: &85243690 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 1.6.2
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *20213600
68
+ version_requirements: *85243690
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rcov
71
- requirement: &20219180 !ruby/object:Gem::Requirement
71
+ requirement: &85242750 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,7 +76,7 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *20219180
79
+ version_requirements: *85242750
80
80
  description: Generates javascript file that defines all Rails named routes as javascript
81
81
  helpers
82
82
  email: agresso@gmail.com
@@ -119,7 +119,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
119
119
  version: '0'
120
120
  segments:
121
121
  - 0
122
- hash: 2245053018798616872
122
+ hash: -314330307
123
123
  required_rubygems_version: !ruby/object:Gem::Requirement
124
124
  none: false
125
125
  requirements: