link2 0.1.1 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.textile CHANGED
@@ -6,15 +6,20 @@ h2. Introduction
6
6
 
7
7
  A better link helper for Rails designed with the principle of making smart assumptions based on what's known to avoid repeated and unnecessary code declarations; and at the same time making the code more semantic/readable/beautiful (my subjective opinion). On top of that - for even more maintainable views - scoped I18n translations without lean defaults for fast prototyping. WIN-WIN-WIN.
8
8
 
9
- This is *not* a re-implementation of @link_to@/@button_to@-helpers; rather it wraps these but parses the specified method arguments and extracts as much known information as possible to fill in the missing pieces. The core helpers are not altered at all: You can call them old-school like there was no tomorrow (after using Link2 for a while you'll spoiled and the core helpers will feel so yesterday, really).
9
+ *Helpers:*
10
+
11
+ * *@link_to@* enhanced by @link@
12
+ * *@button_to@* enhanced by @button@
13
+
14
+ This is *not* a re-implementation of these helpers; rather it wraps these but parses the specified method arguments and extracts as much known information as possible to fill in the missing pieces. The core helpers are not altered at all: You can call them old-school like there was no tomorrow (after using Link2 for a while you'll spoiled and the core helpers will feel so yesterday, really).
10
15
 
11
16
  *Goals/Features:*
12
17
 
13
- * Rapid prototyping-friendly link helpers - with no trade-offs, really.
14
- * Based on specified arguments: Use what's know to make smart assumptions => DRYer - and more maintainable view code.
15
- * Use power of I18n: Lookup scoped translations based on action, model, etc., for more flexible translations - with lean defaults. Enhanced with some nifty interpolation features as well. Code first, translate later.
16
- * Full test-coverage for stability.
17
- * Well-documented code.
18
+ * *Rapid & flexible* - prototyping-friendly link helpers - with no trade-offs, really.
19
+ * *DRY* - based on specified arguments: Use what's know to make smart assumptions => DRYer - and more maintainable view code.
20
+ * *I18n deluxe* - Lookup scoped translations based on action, model, etc., for more flexible translations - with lean defaults. Enhanced with some nifty interpolation features as well. Code first, translate later.
21
+ * *Stable* - Full test-coverage for stability. Unit + Rails integration tests, check: @44 tests: all passed@
22
+ * *Maintainable* - Well-documented code.
18
23
 
19
24
  h2. Installation
20
25
 
@@ -28,7 +33,7 @@ h2. Installation
28
33
 
29
34
  * *"rails 2.3.x":http://github.com/rails/rails* only. Might as well work with Rails 3 already, but I didn't write that.
30
35
 
31
- For testing: test-unit, "mocha":http://github.com/floehopper/mocha, and "webrat":http://github.com/brynary/webrat. Optional: "left-right":http://github.com/jordi/leftright
36
+ For testing: test-unit, "mocha":http://github.com/floehopper/mocha, and "webrat":http://github.com/brynary/webrat. Optional: "leftright":http://github.com/jordi/leftright
32
37
 
33
38
  h2. Setup
34
39
 
@@ -108,7 +113,7 @@ h2. Options hashes: URL Options + HTML Options
108
113
 
109
114
  Link2 link helpers accept options in the same way as the core helpers @link_to@/@button_to@: first @options@ (a.k.a. @url_options@) and then @html_options@. See the "Rails core UrlHelpers documentation":http://railsapi.com/doc/rails-v2.3.5/classes/ActionView/Helpers/UrlHelper.html#M002452 for details on this. Link2 helpers just pass any non-Link2-related options to the Rails core helpers. In other words no need to learn a new API; just pass the needed options like in the past.
110
115
 
111
- h2. Expected arguments
116
+ h2. Expected arguments (...but the examples should be enough)
112
117
 
113
118
  A summary of the expected argument flavors if the examples for the curious minds:
114
119
 
@@ -198,6 +203,35 @@ Now - with the config and translations setup - let the unicorn free:
198
203
  # => link_to "Slurp Captain #8 like a pirate", drink_captain_morgan_path(@captain_morgan_no_8) # See: CaptainMorgan#to_s
199
204
  </pre>
200
205
 
206
+ h2. DOM Selectors
207
+
208
+ To make a web-designer's life easier Link2 generates some semantic selector classes based on specified/known link properties for easier DOM-manipulation with CSS and javascript.
209
+
210
+ *Examples:*
211
+
212
+ <pre>
213
+ link :new, Post
214
+ # => <a class="new post" ...>...<a/>
215
+
216
+ link :edit, @post_14
217
+ # => <a class="edit post id_14" ...>...<a/>
218
+
219
+ link :back
220
+ # => <a class="back" ...>...<a/>
221
+
222
+ ...
223
+ </pre>
224
+
225
+ *Configuration:*
226
+
227
+ This behavior is enabled by default but can be disabled just in case; preferably in the initializer:
228
+
229
+ <pre>
230
+ Link2.setup do |config|
231
+ config.dom_selectors = false
232
+ end
233
+ </pre>
234
+
201
235
  h2. TODO
202
236
 
203
237
  See "TODO":http://github.com/grimen/link2/blob/master/TODO
data/Rakefile CHANGED
@@ -40,6 +40,9 @@ begin
40
40
  spec.add_dependency 'actionpack', '>= 2.3.0'
41
41
 
42
42
  spec.add_development_dependency 'test-unit', '= 1.2.3'
43
+ spec.add_development_dependency 'mocha', '>= 0.9.8'
44
+ spec.add_development_dependency 'webrat', '>= 0.7.0'
45
+ spec.add_development_dependency 'leftright', '>= 0.0.3'
43
46
  spec.add_development_dependency 'activerecord', '>= 2.3.0'
44
47
  end
45
48
 
data/TODO CHANGED
@@ -1,38 +1,17 @@
1
1
  TODO
2
2
 
3
- 1) [BUG:] I18n lookup scope interpolations should not be same as I18n.t interpolations.
4
-
5
- 2) Generate proper DOM ID selectors, e.g. class="new post"
6
-
7
- DOM Selectors
8
-
9
- To make a web-designer's life easier Link2 generates some semantic selector classes based on specified/known link properties for easier DOM-manipulation with CSS and javascript:
10
-
11
- <pre>
12
- link :new, Post
13
- # => <a class="new post" ...>...<a/>
14
-
15
- link :edit, @post_14
16
- # => <a id="edit_post_14_action" class="edit post" ...>...<a/>
17
-
18
- link :back
19
- # => <a class="back" ...>...<a/>
20
- </pre>
21
-
22
- 3) Auto-detect current resource instance for member views (non-collection)
3
+ 1) Auto-detect current resource instance for member views (non-collection)
23
4
 
24
5
  link(:edit) => link(:edit, @post)
25
6
 
26
7
  Detect using "self.controller_name.singularize", or use "resource" if InheritedResources is used.
27
8
 
28
- * [ISSUE:] Implement the problematic one: link(:action, [@parent, @resource])
9
+ 2) [ISSUE:] Implement the problematic one: link(:action, [@parent, @resource])
29
10
 
30
11
  * Collections detection:
31
12
 
32
13
  link(:index) => link(@posts) => link(:index, @posts) => link("Index", @posts)
33
14
 
34
- * Allow customization of alternatives to Object#to_s for parsing object label, i.e. {{name}} interpolation.
35
-
36
15
  * Fix action mapping procs to handle named scopes. Should work, but do not for some reason. =/
37
16
 
38
17
  * Fix action mapping procs to receive session, params, etc in a options hash. My mocking/stubbing don't want to work. ='(
@@ -47,6 +26,6 @@ TODO
47
26
 
48
27
  * ORM-tests: DataMapper, MongoMapper
49
28
 
50
- Consider:
29
+ NOT SURE:
51
30
 
52
- * Possible parse TITLE-attribute from the model, say Object#link_title or similar.
31
+ * Make Link2 parse label and title-attribute for the link based on configuration: Link2.label_method = :to_s, Link2.attr_methods = {:title => :description}
@@ -10,5 +10,8 @@ if defined?(::Link2)
10
10
  # :home => lambda { root_path },
11
11
  # :back => lambda { |url| url || session[:return_to] || :back }
12
12
  # }
13
+ #
14
+ # Enable/Disable Link2 DOM selectors generation.
15
+ # config.dom_selectors = true
13
16
  end
14
17
  end
data/lib/link2.rb CHANGED
@@ -56,20 +56,19 @@ module Link2
56
56
  :back => lambda { |url| url || :back }
57
57
  }
58
58
 
59
- mattr_accessor :i18n_scope
60
- @@i18n_scope = DEFAULT_I18N_SCOPE
61
-
62
59
  # I18n lookup scopes in ascending order of priority.
63
- # Used for scoped I18n translations based on model, action, etc.,
64
- # for flexability.
60
+ # Used for scoped I18n translations based on model, action, etc., for flexability.
65
61
  mattr_accessor :i18n_scopes
66
62
  @@i18n_scopes = DEFAULT_I18N_SCOPES
67
63
 
68
- # Action mappings - a.k.a. "link value shortcuts" - that should
69
- # be recognized.
64
+ # Action mappings - a.k.a. "link value shortcuts" - that should be recognized.
70
65
  mattr_accessor :action_mappings
71
66
  @@action_mappings = DEFAULT_ACTION_MAPPINGS
72
67
 
68
+ # DOM selectors for easier manipulation of Link2 linksusing CSS/JavaScript.
69
+ mattr_accessor :dom_selectors
70
+ @dom_selectors = true
71
+
73
72
  class << self
74
73
 
75
74
  # Yield self for configuration block:
data/lib/link2/brain.rb CHANGED
@@ -27,57 +27,56 @@ module Link2
27
27
  html_options = args.pop if args.last.is_a?(Hash)
28
28
  url_options = args.pop if args.last.is_a?(Hash)
29
29
 
30
- #puts [url_options, html_options].compact.inspect
31
-
32
30
  case args.size
33
- when 0
34
- raise "No arguments specified. A least specify action or url."
35
- when 1
36
- if args.first.is_a?(String)
37
- if args.first =~ URL_PATH_REGEX
38
- # link 'http://example.com' => link_to 'http://example.com', 'http://example.com'
39
- label = url = args.shift
40
- else
41
- # link "Hello" => link_to 'Hello', '#'
42
- url = ::Link2::DEFAULT_LINK
43
- label = args.shift
44
- end
45
- elsif args.first.is_a?(Symbol)
46
- # link :new => link_to I18n.t(:new, ...), new_{auto_detected_resource}_path
47
- # link :back => link_to I18n.t(:back, ...), (session[:return_to] || :back)
48
- action = args.shift
49
- label = self.localized_label(action, url_options)
50
- resource = nil # TODO: auto-detect resource.
51
- url = self.url_for_args(action, resource, url_options)
52
- elsif args.first.is_a?(Object)
53
- # link @user => link_to I18n.t(:show, ...), user_path(@user)
54
- # link [:admin, @user] => link_to I18n.t(:show, ...), admin_user_path(@user)
55
- resource = args.shift
56
- label, url = self.label_and_url_for_resource(resource, url_options)
57
- else
58
- raise "Invalid 1st argument: #{args.inspect}"
59
- end
60
- when 2
61
- if args.first.is_a?(String)
62
- if args.second.is_a?(String)
63
- # link "Hello", hello_path => link_to "Hello", hello_path
64
- label, url = args.slice!(0..1)
65
- elsif self.resource_identifier_class?(args.second)
66
- # link "New", :new => link_to "New", new_{auto_detected_resource}_path
67
- # link "<<", :back => link_to "<<", (session[:return_to] || :back)
68
- label, action = args.slice!(0..1)
31
+ when 0
32
+ raise "No arguments specified. A least specify action or url."
33
+ when 1
34
+ if args.first.is_a?(String)
35
+ if args.first =~ URL_PATH_REGEX
36
+ # link 'http://example.com' => link_to 'http://example.com', 'http://example.com'
37
+ label = url = args.shift
38
+ else
39
+ # link "Hello" => link_to 'Hello', '#'
40
+ url = ::Link2::DEFAULT_LINK
41
+ label = args.shift
42
+ end
43
+ elsif args.first.is_a?(Symbol)
44
+ # link :new => link_to I18n.t(:new, ...), new_{auto_detected_resource}_path
45
+ # link :back => link_to I18n.t(:back, ...), (session[:return_to] || :back)
46
+ action = args.shift
69
47
  resource = nil # TODO: auto-detect resource.
48
+ label = self.localized_label(action, resource, url_options)
70
49
  url = self.url_for_args(action, resource, url_options)
50
+ elsif args.first.is_a?(Object)
51
+ # link @user => link_to I18n.t(:show, ...), user_path(@user)
52
+ # link [:admin, @user] => link_to I18n.t(:show, ...), admin_user_path(@user)
53
+ resource = args.shift
54
+ label, url = self.label_and_url_for_resource(resource, url_options)
71
55
  else
72
- raise "Invalid 2nd argument: #{args.inspect}"
56
+ raise "Invalid 1st argument: #{args.inspect}"
73
57
  end
74
- elsif args.first.is_a?(Symbol)
75
- # TODO: Implement this:
76
- if args.second.is_a?(Array)
77
- raise ::Link2::NotImplementedYetError, "case link(:action, [...]) not yet supported. Need to refactor some stuff."
58
+ when 2
59
+ if args.first.is_a?(String)
60
+ if args.second.is_a?(String)
61
+ # link "Hello", hello_path => link_to "Hello", hello_path
62
+ label, url = args.slice!(0..1)
63
+ elsif ::Link2::Support.resource_identifier_class?(args.second)
64
+ # link "New", :new => link_to "New", new_{auto_detected_resource}_path
65
+ # link "<<", :back => link_to "<<", (session[:return_to] || :back)
66
+ label, action = args.slice!(0..1)
67
+ resource = nil # TODO: auto-detect resource.
68
+ url = self.url_for_args(action, resource, url_options)
69
+ else
70
+ raise "Invalid 2nd argument: #{args.inspect}"
71
+ end
72
+ elsif args.first.is_a?(Symbol)
73
+ # TODO: Implement support for aray of nested resources.
74
+ if args.second.is_a?(Array)
75
+ raise ::Link2::NotImplementedYetError, "case link(:action, [...]) not yet supported. Need to refactor some stuff."
78
76
  end
77
+
79
78
  # TODO: Cleanup.
80
- if self.resource_identifier_class?(args.second)
79
+ if ::Link2::Support.resource_identifier_class?(args.second)
81
80
  # link :new, Post => link_to I18n.t(:new, ...), new_post_path
82
81
  # link :edit, @post => link_to I18n.t(:edit, ...), edit_post_path(@post)
83
82
  # link :show, [:admin, @user] => link_to I18n.t(:show, ...), admin_user_path(@user)
@@ -87,14 +86,19 @@ module Link2
87
86
  url = self.url_for_args(action, resource, url_options)
88
87
  else
89
88
  raise "Invalid 2nd argument: #{args.inspect}"
90
- end
91
- else
92
- raise "Invalid 1st argument: #{args.inspect}"
93
- end
94
- when 3
95
- if args.first.is_a?(String)
96
- if args.second.is_a?(Symbol)
97
- if self.resource_identifier_class?(args.third)
89
+ end
90
+ else
91
+ raise "Invalid 1st argument: #{args.inspect}"
92
+ end
93
+ when 3
94
+ if args.first.is_a?(String)
95
+ if args.second.is_a?(Symbol)
96
+ # TODO: Implement support for aray of nested resources.
97
+ if args.third.is_a?(Array)
98
+ raise ::Link2::NotImplementedYetError, 'case link("Label", :action, [...]) not yet supported. Need to refactor some stuff.'
99
+ end
100
+
101
+ if ::Link2::Support.resource_identifier_class?(args.third)
98
102
  # link "New", :new, Post => link_to "New", new_post_path
99
103
  # link "Edit", :edit, @post => link_to "Edit", edit_post_path(@post)
100
104
  label, action, resource = args.slice!(0..2)
@@ -111,8 +115,14 @@ module Link2
111
115
  else
112
116
  raise "Invalid number of arguments: #{args.inspect}."
113
117
  end
118
+
119
+ if ::Link2.dom_selectors == true
120
+ html_options = self.merge_link2_dom_selectors(action, resource, html_options)
121
+ end
122
+
114
123
  args << url_options if url_options
115
124
  args << html_options if html_options
125
+
116
126
  [label, url, *args]
117
127
  rescue => e
118
128
  raise ::ArgumentError, e
@@ -138,16 +148,11 @@ module Link2
138
148
  #
139
149
  def label_and_url_for_resource(resource, options = {})
140
150
  options ||= {}
141
- resource.compact! if resource.is_a?(Array)
142
- last_resource = [resource].flatten.last
143
151
  url_for_options = options.slice(*POLYMORPHIC_OPTION_KEYS).reverse_merge(:routing_type => :path)
144
152
  i18n_options = options.except(url_for_options.keys)
153
+ last_resource = ::Link2::Support.extract_resource(resource)
145
154
 
146
- # Skip any ugly default to_s-value.
147
- custom_name = last_resource.to_s =~ CLASS_INSTANCE_STRING ? last_resource.class.human_name.downcase : last_resource.to_s
148
- custom_name = last_resource.class.human_name.downcase if custom_name.blank?
149
-
150
- label = self.localized_label(:show, last_resource.class, i18n_options.merge(:name => custom_name))
155
+ label = self.localized_label(:show, last_resource, i18n_options)
151
156
  url = polymorphic_url(resource, url_for_options)
152
157
 
153
158
  [label, url]
@@ -190,7 +195,7 @@ module Link2
190
195
  else
191
196
  options[:controller] ||= self.controller_name_for_resource(resource)
192
197
  options[:action] = action
193
- options[:id] = resource.id if !resource.is_a?(Class) && self.record_class?(resource)
198
+ options[:id] = resource.id if !resource.is_a?(Class) && ::Link2::Support.record_class?(resource)
194
199
 
195
200
  url_for(options.except(*IGNORED_OPTION_KEYS))
196
201
  end
@@ -201,11 +206,11 @@ module Link2
201
206
  #
202
207
  def localized_label(action, resource, options = {})
203
208
  options ||= {}
204
- i18n_options = options.merge(:controller => self.controller_name_for_resource(resource))
209
+ i18n_options = options.merge(:controller => self.controller_name_for_resource(resource), :name => self.human_name_for_resource(resource))
205
210
  ::Link2::I18n.t(action, resource, i18n_options)
206
211
  end
207
212
 
208
- # Get controller name based for a specified resource.
213
+ # Parse controller name based for a specified resource.
209
214
  #
210
215
  # == Example/Usage:
211
216
  #
@@ -225,33 +230,82 @@ module Link2
225
230
  #
226
231
  def controller_name_for_resource(resource = nil)
227
232
  resource_class = ::Link2::Support.find_resource_class(resource)
228
- if self.record_class?(resource_class)
233
+ if ::Link2::Support.record_class?(resource_class)
229
234
  resource_class.to_s.tableize # rescue nil
230
235
  end || self.controller.controller_name
231
236
  end
232
237
 
233
- # Check if the specified object is a valid resource identifier class. Used
234
- # for detecting current resource based on controller, action, etc.
238
+ # Parse human resource name for a specified resource.
239
+ #
240
+ # == Example/Usage:
235
241
  #
236
- def resource_identifier_class?(object)
237
- object.is_a?(NilClass) || object.is_a?(Symbol) || self.record_class?(object)
242
+ # human_name_for_resource(@post)
243
+ # # => "post"
244
+ #
245
+ # human_name_for_resource(@post)
246
+ # # => "post"
247
+ #
248
+ # class Post < ActiveRecord::Base
249
+ # def to_s
250
+ # self.title
251
+ # end
252
+ # end
253
+ #
254
+ # human_name_for_resource(Post.create(:title => "Hello"))
255
+ # # => "Hello"
256
+ #
257
+ def human_name_for_resource(resource)
258
+ return nil unless resource_class = ::Link2::Support.find_resource_class(resource)
259
+ raise ArgumentError unless ::Link2::Support.record_class?(resource_class)
260
+
261
+ if ::Link2::Support.record_object?(resource)
262
+ # Skip any ugly default to_s-value:
263
+ custom_name = resource.to_s =~ CLASS_INSTANCE_STRING ? resource_class.human_name.downcase : resource.to_s
264
+ end
265
+ custom_name = resource_class.human_name.downcase if custom_name.blank?
266
+ custom_name
238
267
  end
239
268
 
240
- # Check if a specified objec is a record class type.
269
+ # Attach Link2 semantic DOM selector attributes (attributes "id" and "class") based on
270
+ # action and resource - if any can be parsed.
241
271
  #
242
272
  # == Usage/Examples:
243
273
  #
244
- # record_class?(ActiveRecord::Base)
245
- # # => true
274
+ # attach_link2_dom_selectors(:new, Post, {})
275
+ # # => {:class => "new post"}
246
276
  #
247
- # record_class?(String)
248
- # # => false
277
+ # attach_link2_dom_selectors(:new, Post, {:id => "one", :class => "two"})
278
+ # # => {:id => "one", :class => "new post two"}
249
279
  #
250
- def record_class?(object_or_class)
251
- return false if object_or_class == NilClass || object_or_class.is_a?(NilClass)
252
- object_or_class = object_or_class.new if object_or_class.is_a?(Class)
253
- object_or_class.respond_to?(:new_record?)
280
+ # attach_link2_dom_selectors(:new, @post_14, {})
281
+ # # => {:class => "edit post id_14"}
282
+ #
283
+ # attach_link2_dom_selectors(:new, @post_14, {:id => "one", :class => "two"})
284
+ # # => {:id => "one", :class => "edit post two"}
285
+ #
286
+ def merge_link2_dom_selectors(action, resource = nil, html_options = {})
287
+ html_options ||= {}
288
+ link2_attributes = self.link2_attrbutes_for(action, resource)
289
+
290
+ html_options[:class] = [link2_attributes[:class],html_options[:class]].compact.join(' ')
291
+ html_options[:class] = nil if html_options[:class].blank?
292
+
293
+ html_options
294
+ end
295
+
296
+ # Generate semantic Link2 HTML attributes.
297
+ #
298
+ # See: +merge_link2_dom_selectors+.
299
+ #
300
+ def link2_attrbutes_for(action, resource = nil)
301
+ resource_class = ::Link2::Support.find_resource_class(resource)
302
+
303
+ resource_name_dom_class = resource_class.name.underscore if resource_class.present?
304
+ resource_id_dom_class = "id_#{resource.id}" if ::Link2::Support.record_object?(resource)
305
+ dom_class = [action.to_s, resource_name_dom_class, resource_id_dom_class].compact.join(' ')
306
+
307
+ {:class => dom_class}
254
308
  end
255
309
 
256
310
  end
257
- end
311
+ end
data/lib/link2/helpers.rb CHANGED
@@ -11,7 +11,7 @@ module Link2
11
11
 
12
12
  # Enhanced +link_to+ helper.
13
13
  #
14
- # TODO: Documentation for this helper.
14
+ # TODO: Documentation for this helper. For now the README should be sufficient.
15
15
  #
16
16
  def link(*args, &block)
17
17
  args = self.link_to_args(*args)
data/lib/link2/i18n.rb CHANGED
@@ -61,13 +61,14 @@ module Link2
61
61
  #
62
62
  # == Valid lookup scope interpolations:
63
63
  #
64
+ # * +controller+ - current controller name (note: must be passed from view template)
65
+ # * +action+ - the link action name
64
66
  # * +model+ - link model name, e.g. CaptainMorgan / @captain_morgan => "captain_morgan"
65
67
  # * +models+ - pluralized link model name, e.g. CaptainMorgan / @captain_morgan => "captain_morgans"
66
- # * +controller+ - current controller name
67
- # * +action+ - the link action name
68
68
  #
69
69
  def substituted_scopes_for(action, resource, options = {})
70
- model_name = self.localized_resource_class_name(resource) # TODO: Should not be localized. Maybe use "model"/"models" to avoid confusion?
70
+ resource_class = ::Link2::Support.find_resource_class(resource)
71
+ model_name = resource_class.name.underscore rescue ''
71
72
  substitutions = options.merge(
72
73
  :action => action.to_s.underscore,
73
74
  :model => model_name,
data/lib/link2/support.rb CHANGED
@@ -12,7 +12,9 @@ module Link2
12
12
  # # => Post, Post, Post
13
13
  #
14
14
  def find_resource_class(arg)
15
- if arg.is_a?(Symbol)
15
+ if arg.is_a?(NilClass)
16
+ nil
17
+ elsif arg.is_a?(Symbol)
16
18
  resource_class_name = arg.to_s.singularize.camelize
17
19
  resource_class_name.constantize
18
20
  elsif arg.is_a?(Class)
@@ -25,6 +27,48 @@ module Link2
25
27
  rescue
26
28
  raise "No such class: #{resource_class_name}"
27
29
  end
30
+
31
+ def extract_resource(resource)
32
+ resource.compact! if resource.is_a?(Array)
33
+ [resource].flatten.last
34
+ end
35
+
36
+ # Check if the specified object is a valid resource identifier class. Used
37
+ # for detecting current resource based on controller, action, etc.
38
+ #
39
+ def resource_identifier_class?(object)
40
+ object.is_a?(NilClass) || object.is_a?(Symbol) || self.record_class?(object)
41
+ end
42
+
43
+ # Check if a specified objec is a record class type.
44
+ #
45
+ # == Usage/Examples:
46
+ #
47
+ # record_class?(ActiveRecord::Base)
48
+ # # => true
49
+ #
50
+ # record_class?(String)
51
+ # # => false
52
+ #
53
+ def record_class?(object_or_class)
54
+ return false if object_or_class == NilClass || object_or_class.is_a?(NilClass)
55
+ object_or_class = object_or_class.new if object_or_class.is_a?(Class)
56
+ self.record_object?(object_or_class)
57
+ end
58
+
59
+ # Check if a specified objec is a record instance.
60
+ #
61
+ # == Usage/Examples:
62
+ #
63
+ # record_object?(Post.new) # if: Post < ActiveRecord::Base, or similar.
64
+ # # => true
65
+ #
66
+ # record_object?(Post)
67
+ # # => false
68
+ #
69
+ def record_object?(object)
70
+ object.respond_to?(:new_record?)
71
+ end
28
72
  end
29
73
 
30
74
  end
data/lib/link2/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Link2
4
- VERSION = '0.1.1'.freeze
4
+ VERSION = '0.1.3'.freeze
5
5
  end
data/test/brain_test.rb CHANGED
@@ -9,26 +9,43 @@ class BrainTest < ActionView::TestCase
9
9
  ::I18n.locale = :en
10
10
 
11
11
  @mookey = ::Fraggle.create(:name => 'Mookey')
12
+ @tweaked_mookey = ::Fraggle.create(:name => 'Mookey 2.0')
13
+ @tweaked_mookey.class_eval do
14
+ def to_s
15
+ self.name
16
+ end
17
+ end
12
18
  end
13
19
 
14
- test "#resource_identifier_class?: should only be true for valid classes" do
15
- assert resource_identifier_class?(nil)
16
- assert resource_identifier_class?(:hello)
17
- assert resource_identifier_class?(::Fraggle)
18
-
19
- assert_not resource_identifier_class?(::Unicorn)
20
+ test "#link2_attrbutes_for: should generate Link2-specific DOM classes reflecting on action, resource class, and resource id - if given" do
21
+ assert_equal ({:class => 'home'}), link2_attrbutes_for(:home)
22
+ assert_equal ({:class => 'new fraggle'}), link2_attrbutes_for(:new, :fraggle)
23
+ assert_equal ({:class => 'new fraggle'}), link2_attrbutes_for(:new, ::Fraggle)
24
+ assert_equal ({:class => "new fraggle id_#{@mookey.id}"}), link2_attrbutes_for(:new, @mookey)
25
+ assert_equal ({:class => "edit fraggle id_#{@mookey.id}"}), link2_attrbutes_for(:edit, @mookey)
20
26
  end
21
27
 
22
- test "#record_class?: should only be true for record classes" do
23
- assert record_class?(::Fraggle)
28
+ test "#merge_link2_dom_selectors: should generate Link2-specific DOM classes, but respect any passed values" do
29
+ assert_equal ({:class => 'home'}), merge_link2_dom_selectors(:home)
30
+ assert_equal ({:id => "one", :class => 'home two three'}), merge_link2_dom_selectors(:home, nil, :id => "one", :class => "two three")
31
+
32
+ assert_equal ({:class => 'new fraggle'}), merge_link2_dom_selectors(:new, :fraggle)
33
+ assert_equal ({:id => "one", :class => 'new fraggle two three'}), merge_link2_dom_selectors(:new, :fraggle, :id => "one", :class => "two three")
34
+
35
+ assert_equal ({:class => 'new fraggle'}), merge_link2_dom_selectors(:new, ::Fraggle)
36
+ assert_equal ({:id => "one", :class => 'new fraggle two three'}), merge_link2_dom_selectors(:new, ::Fraggle, :id => "one", :class => "two three")
37
+
38
+ assert_equal ({:class => "new fraggle id_#{@mookey.id}"}), merge_link2_dom_selectors(:new, @mookey)
39
+ assert_equal ({:id => "one", :class => "new fraggle id_#{@mookey.id} two three"}), merge_link2_dom_selectors(:new, @mookey, :id => "one", :class => "two three")
24
40
 
25
- assert_not record_class?(::Unicorn)
41
+ assert_equal ({:class => "edit fraggle id_#{@mookey.id}"}), merge_link2_dom_selectors(:edit, @mookey)
42
+ assert_equal ({:id => "one", :class => "edit fraggle id_#{@mookey.id} two three"}), merge_link2_dom_selectors(:edit, @mookey, :id => "one", :class => "two three")
26
43
  end
27
44
 
28
45
  test "#controller_name_for_resource: should return controller name based on resource" do
29
- assert_equal 'fraggles', controller_name_for_resource(::Fraggle)
30
- assert_equal 'fraggles', controller_name_for_resource(::Fraggle.new)
31
46
  assert_equal 'fraggles', controller_name_for_resource(:fraggle)
47
+ assert_equal 'fraggles', controller_name_for_resource(::Fraggle)
48
+ assert_equal 'fraggles', controller_name_for_resource(@mookey)
32
49
  end
33
50
 
34
51
  test "#controller_name_for_resource: should return current controller if no resource is specified or is nil" do
@@ -36,6 +53,13 @@ class BrainTest < ActionView::TestCase
36
53
  assert_equal 'test', controller_name_for_resource(nil)
37
54
  end
38
55
 
56
+ test "#human_name_for_resource: should return reosurce name based on resource using #to_s or #human_name" do
57
+ assert_equal 'fraggle', human_name_for_resource(:fraggle)
58
+ assert_equal 'fraggle', human_name_for_resource(::Fraggle)
59
+ assert_equal 'fraggle', human_name_for_resource(@mookey)
60
+ assert_equal 'Mookey 2.0', human_name_for_resource(@tweaked_mookey)
61
+ end
62
+
39
63
  test "#localized_label: should pass current controller to I18n options" do
40
64
  swap ::Link2, :i18n_scopes => ['{{controller}}.links.{{action}}'] do
41
65
  store_translations :en, {:fraggles => {:links => {:hello => "Wassup?!"}}} do
@@ -77,7 +101,6 @@ class BrainTest < ActionView::TestCase
77
101
  self.name
78
102
  end
79
103
  end
80
-
81
104
  assert_equal ["Show Super-tasty", fraggle_cool_aid_path(@mookey, @mookeys_cool_aid)], label_and_url_for_resource([@mookey, @mookeys_cool_aid])
82
105
  end
83
106
  end
data/test/helpers_test.rb CHANGED
@@ -10,9 +10,11 @@ class HelpersTest < ActionView::TestCase
10
10
 
11
11
  def setup
12
12
  ::I18n.locale = :en
13
+ ::Link2.dom_selectors = false
14
+ ::Link2.i18n_scopes = [] # Keep it simple - no scoped lookups by default.
13
15
 
14
- @mookey = ::Fraggle.create(:name => 'Mookey')
15
- @mookeys_cool_aid = ::CoolAid.create(:name => 'Super-tasty')
16
+ @mookey = ::Fraggle.create(:name => 'Mookey')
17
+ @mookeys_cool_aid = ::CoolAid.create(:name => 'Super-tasty')
16
18
  end
17
19
 
18
20
  # link({}, {})
@@ -33,41 +35,33 @@ class HelpersTest < ActionView::TestCase
33
35
  end
34
36
 
35
37
  test "link(:action) should render link_to(t(:action, ...), url_for(:action => :action, ...)), auto-detecting resource" do
36
- swap ::Link2, :i18n_scopes => ['link.{{action}}'] do
37
- # assert_equal link_to("New Fraggle"), link(:new)
38
- assert_raise(::Link2::NotImplementedYetError) { link(:new) }
39
- end
38
+ # assert_equal link_to("New Fraggle"), link(:new)
39
+ assert_raise(::Link2::NotImplementedYetError) { link(:new) }
40
40
  end
41
41
 
42
42
  test "link(:mapping) should render link_to(t(:mapping, ...), url_for_mapping(:mapping, ...)), auto-detecting resource" do
43
- swap ::Link2, :i18n_scopes => ['link.{{action}}'] do
44
- assert_equal link_to("Home", '/'), link(:home)
45
- assert_equal link_to("Home", '/', ONE_HASH), link(:home, ONE_HASH)
46
- assert_equal link_to("Home", '/', *TWO_HASHES), link(:home, *TWO_HASHES)
47
-
48
- swap ::Link2, :action_mappings => {:secret => '/secret'} do
49
- assert_equal link_to("Secret", '/secret'), link(:secret)
50
- assert_equal link_to("Secret", '/secret', ONE_HASH), link(:secret, ONE_HASH)
51
- assert_equal link_to("Secret", '/secret', *TWO_HASHES), link(:secret, *TWO_HASHES)
52
- end
43
+ assert_equal link_to("Home", '/'), link(:home)
44
+ assert_equal link_to("Home", '/', ONE_HASH), link(:home, ONE_HASH)
45
+ assert_equal link_to("Home", '/', *TWO_HASHES), link(:home, *TWO_HASHES)
46
+
47
+ swap ::Link2, :action_mappings => {:secret => '/secret'} do
48
+ assert_equal link_to("Secret", '/secret'), link(:secret)
49
+ assert_equal link_to("Secret", '/secret', ONE_HASH), link(:secret, ONE_HASH)
50
+ assert_equal link_to("Secret", '/secret', *TWO_HASHES), link(:secret, *TWO_HASHES)
53
51
  end
54
52
  end
55
53
 
56
54
  test "link(@resource) should render link_to(t(:show, ...), @object)" do
57
- swap ::Link2, :i18n_scopes => ['link.{{action}}'] do
58
- assert_equal link_to("Show", "/fraggles/#{@mookey.id}"), link(@mookey)
59
- assert_equal link_to("Show", "/fraggles/#{@mookey.id}", ONE_HASH), link(@mookey, ONE_HASH)
60
- assert_equal link_to("Show", "/fraggles/#{@mookey.id}", *TWO_HASHES), link(@mookey, *TWO_HASHES)
61
- # assert_equal link_to("Show", "?"), link(::Fraggle) # test this stupid case?
62
- end
55
+ assert_equal link_to("Show", "/fraggles/#{@mookey.id}"), link(@mookey)
56
+ assert_equal link_to("Show", "/fraggles/#{@mookey.id}", ONE_HASH), link(@mookey, ONE_HASH)
57
+ assert_equal link_to("Show", "/fraggles/#{@mookey.id}", *TWO_HASHES), link(@mookey, *TWO_HASHES)
58
+ # assert_equal link_to("Show", "?"), link(::Fraggle) # test this stupid case?
63
59
  end
64
60
 
65
61
  test "link([@parent, @resource]) should render link_to(t(:show, ...), polymorphic_path([@parent, @resource]))" do
66
- swap ::Link2, :i18n_scopes => ['link.{{action}}'] do
67
- assert_equal link_to("Show", "/fraggles/#{@mookey.id}/cool_aids/#{@mookeys_cool_aid.id}"), link([@mookey, @mookeys_cool_aid])
68
- assert_equal link_to("Show", "/fraggles/#{@mookey.id}/cool_aids/#{@mookeys_cool_aid.id}", ONE_HASH), link([@mookey, @mookeys_cool_aid], ONE_HASH)
69
- assert_equal link_to("Show", "/fraggles/#{@mookey.id}/cool_aids/#{@mookeys_cool_aid.id}", *TWO_HASHES), link([@mookey, @mookeys_cool_aid], *TWO_HASHES)
70
- end
62
+ assert_equal link_to("Show", "/fraggles/#{@mookey.id}/cool_aids/#{@mookeys_cool_aid.id}"), link([@mookey, @mookeys_cool_aid])
63
+ assert_equal link_to("Show", "/fraggles/#{@mookey.id}/cool_aids/#{@mookeys_cool_aid.id}", ONE_HASH), link([@mookey, @mookeys_cool_aid], ONE_HASH)
64
+ assert_equal link_to("Show", "/fraggles/#{@mookey.id}/cool_aids/#{@mookeys_cool_aid.id}", *TWO_HASHES), link([@mookey, @mookeys_cool_aid], *TWO_HASHES)
71
65
  end
72
66
 
73
67
  # link(x, y, {}, {})
@@ -83,66 +77,56 @@ class HelpersTest < ActionView::TestCase
83
77
  end
84
78
 
85
79
  test "link(:action) should render link_to(label, url_for(:action => :action, ...)), auto-detecting resource" do
86
- swap ::Link2, :i18n_scopes => ['link.{{action}}'] do
87
- # assert_equal link_to("New Fraggle!!"), link("New Fraggle!!", :new)
88
- assert_raise(::Link2::NotImplementedYetError) { link("New Fraggle!!", :new) }
89
- assert_raise(::Link2::NotImplementedYetError) { link("New Fraggle!!", :new, ONE_HASH) }
90
- assert_raise(::Link2::NotImplementedYetError) { link("New Fraggle!!", :new, *TWO_HASHES) }
91
- end
80
+ # assert_equal link_to("New Fraggle!!"), link("New Fraggle!!", :new)
81
+ assert_raise(::Link2::NotImplementedYetError) { link("New Fraggle!!", :new) }
82
+ assert_raise(::Link2::NotImplementedYetError) { link("New Fraggle!!", :new, ONE_HASH) }
83
+ assert_raise(::Link2::NotImplementedYetError) { link("New Fraggle!!", :new, *TWO_HASHES) }
92
84
  end
93
85
 
94
86
  test "link(label, action) should render link_to(label, url_for_mapping(:mapping, ...)), auto-detecting resource" do
95
- swap ::Link2, :i18n_scopes => ['link.{{action}}'] do
96
- assert_equal link_to("Home!!", '/'), link("Home!!", :home)
97
- assert_equal link_to("Home!!", '/', ONE_HASH), link("Home!!", :home, ONE_HASH)
98
- assert_equal link_to("Home!!", '/', *TWO_HASHES), link("Home!!", :home, *TWO_HASHES)
99
-
100
- swap ::Link2, :action_mappings => {:secret => '/secret'} do
101
- assert_equal link_to("Damn you!!", '/secret'), link("Damn you!!", :secret)
102
- assert_equal link_to("Damn you!!", '/secret', ONE_HASH), link("Damn you!!", :secret, ONE_HASH)
103
- assert_equal link_to("Damn you!!", '/secret', *TWO_HASHES), link("Damn you!!", :secret, *TWO_HASHES)
104
- end
87
+ assert_equal link_to("Home!!", '/'), link("Home!!", :home)
88
+ assert_equal link_to("Home!!", '/', ONE_HASH), link("Home!!", :home, ONE_HASH)
89
+ assert_equal link_to("Home!!", '/', *TWO_HASHES), link("Home!!", :home, *TWO_HASHES)
90
+
91
+ swap ::Link2, :action_mappings => {:secret => '/secret'} do
92
+ assert_equal link_to("Damn you!!", '/secret'), link("Damn you!!", :secret)
93
+ assert_equal link_to("Damn you!!", '/secret', ONE_HASH), link("Damn you!!", :secret, ONE_HASH)
94
+ assert_equal link_to("Damn you!!", '/secret', *TWO_HASHES), link("Damn you!!", :secret, *TWO_HASHES)
105
95
  end
106
96
  end
107
97
 
108
98
  test "link(:action, Resource) should render link_to(t(:action, ...), url_for(:action => :action, ...))" do
109
- swap ::Link2, :i18n_scopes => ['link.{{action}}'] do
110
- assert_equal link_to("New", "/fraggles/new"), link(:new, ::Fraggle)
111
- assert_equal link_to("New", "/fraggles/new", ONE_HASH), link(:new, ::Fraggle, ONE_HASH)
112
- assert_equal link_to("New", "/fraggles/new", *TWO_HASHES), link(:new, ::Fraggle, *TWO_HASHES)
113
- end
99
+ assert_equal link_to("New", "/fraggles/new"), link(:new, ::Fraggle)
100
+ assert_equal link_to("New", "/fraggles/new", ONE_HASH), link(:new, ::Fraggle, ONE_HASH)
101
+ assert_equal link_to("New", "/fraggles/new", *TWO_HASHES), link(:new, ::Fraggle, *TWO_HASHES)
114
102
  end
115
103
 
116
104
  test "link(:action, @resource) should render link_to(t(:action, ...), url_for(:action => :action, ...)), non-RESTful vs. RESTful routes" do
117
- swap ::Link2, :i18n_scopes => ['link.{{action}}'] do
118
- assert_equal link_to("New", "/fraggles/new?id=#{@mookey.id}"), link(:new, @mookey)
119
- assert_equal link_to("New", "/fraggles/new?id=#{@mookey.id}", ONE_HASH), link(:new, @mookey, ONE_HASH)
120
- assert_equal link_to("New", "/fraggles/new?id=#{@mookey.id}", *TWO_HASHES), link(:new, @mookey, *TWO_HASHES)
121
-
122
- assert_equal link_to("Edit", "/fraggles/#{@mookey.id}/edit"), link(:edit, @mookey)
123
- assert_equal link_to("Edit", "/fraggles/#{@mookey.id}/edit", ONE_HASH), link(:edit, @mookey, ONE_HASH)
124
- assert_equal link_to("Edit", "/fraggles/#{@mookey.id}/edit", *TWO_HASHES), link(:edit, @mookey, *TWO_HASHES)
125
- end
105
+ assert_equal link_to("New", "/fraggles/new?id=#{@mookey.id}"), link(:new, @mookey)
106
+ assert_equal link_to("New", "/fraggles/new?id=#{@mookey.id}", ONE_HASH), link(:new, @mookey, ONE_HASH)
107
+ assert_equal link_to("New", "/fraggles/new?id=#{@mookey.id}", *TWO_HASHES), link(:new, @mookey, *TWO_HASHES)
108
+
109
+ assert_equal link_to("Edit", "/fraggles/#{@mookey.id}/edit"), link(:edit, @mookey)
110
+ assert_equal link_to("Edit", "/fraggles/#{@mookey.id}/edit", ONE_HASH), link(:edit, @mookey, ONE_HASH)
111
+ assert_equal link_to("Edit", "/fraggles/#{@mookey.id}/edit", *TWO_HASHES), link(:edit, @mookey, *TWO_HASHES)
126
112
  end
127
113
 
128
114
  test "link(:action, [@parent, @resource]) should render link_to(t(:action, ...), polymorphic_path([@parent, @resource]), :action => :action)" do
129
- swap ::Link2, :i18n_scopes => ['link.{{action}}'] do
130
- # assert_equal link_to("Edit", "/fraggles/#{@mookey.id}/cool_aids/#{@mookeys_cool_aid.id}/edit"), link(:edit, [@mookey, @mookeys_cool_aid])
131
- assert_raise(::Link2::NotImplementedYetError) { link(:edit, [@mookey, @mookeys_cool_aid]) }
132
- assert_raise(::Link2::NotImplementedYetError) { link(:edit, [@mookey, @mookeys_cool_aid], ONE_HASH) }
133
- assert_raise(::Link2::NotImplementedYetError) { link(:edit, [@mookey, @mookeys_cool_aid], *TWO_HASHES) }
134
- end
115
+ # assert_equal link_to("Edit", "/fraggles/#{@mookey.id}/cool_aids/#{@mookeys_cool_aid.id}/edit"), link(:edit, [@mookey, @mookeys_cool_aid])
116
+ assert_raise(::Link2::NotImplementedYetError) { link(:edit, [@mookey, @mookeys_cool_aid]) }
117
+ assert_raise(::Link2::NotImplementedYetError) { link(:edit, [@mookey, @mookeys_cool_aid], ONE_HASH) }
118
+ assert_raise(::Link2::NotImplementedYetError) { link(:edit, [@mookey, @mookeys_cool_aid], *TWO_HASHES) }
135
119
  end
136
120
 
137
121
  # link(x, y, z, {}, {})
138
122
 
139
123
  test "link(label, action, resource)" do
140
- assert_equal link_to("Newish", "/fraggles/new"), link("Newish", :new, ::Fraggle)
141
- assert_equal link_to("Newish", "/fraggles/new", ONE_HASH), link("Newish", :new, ::Fraggle, ONE_HASH)
124
+ assert_equal link_to("Newish", "/fraggles/new"), link("Newish", :new, ::Fraggle)
125
+ assert_equal link_to("Newish", "/fraggles/new", ONE_HASH), link("Newish", :new, ::Fraggle, ONE_HASH)
142
126
  assert_equal link_to("Newish", "/fraggles/new", *TWO_HASHES), link("Newish", :new, ::Fraggle, *TWO_HASHES)
143
127
 
144
- assert_equal link_to("Editish", "/fraggles/#{@mookey.id}/edit"), link("Editish", :edit, @mookey)
145
- assert_equal link_to("Editish", "/fraggles/#{@mookey.id}/edit", ONE_HASH), link("Editish", :edit, @mookey, ONE_HASH)
128
+ assert_equal link_to("Editish", "/fraggles/#{@mookey.id}/edit"), link("Editish", :edit, @mookey)
129
+ assert_equal link_to("Editish", "/fraggles/#{@mookey.id}/edit", ONE_HASH), link("Editish", :edit, @mookey, ONE_HASH)
146
130
  assert_equal link_to("Editish", "/fraggles/#{@mookey.id}/edit", *TWO_HASHES), link("Editish", :edit, @mookey, *TWO_HASHES)
147
131
  end
148
132
 
@@ -156,4 +140,45 @@ class HelpersTest < ActionView::TestCase
156
140
  assert_raise(::Link2::NotImplementedYetError) { ajax_button(:home, {}, {}) }
157
141
  end
158
142
 
159
- end
143
+ # DOM selectors
144
+
145
+ test "link should generate DOM ID and class reflecting action and resource class - if any" do
146
+ swap ::Link2, :dom_selectors => true do
147
+ assert_equal link_to("New", "/fraggles/new", :class => 'new fraggle'),
148
+ link(:new, ::Fraggle)
149
+
150
+ assert_equal link_to("Edit", "/fraggles/#{@mookey.id}/edit", :class => "edit fraggle id_#{@mookey.id}"),
151
+ link(:edit, @mookey)
152
+
153
+ # TODO: Should pass when implemented.
154
+ # assert_equal link_to("Edit fraggle", "/fraggles/#{@mookeys_cool_aid.id}/edit", :class => "edit cool_aid id_#{@mookeys_cool_aid.id}"),
155
+ # link(:edit, [@mookey, @mookeys_cool_aid])
156
+
157
+ assert_equal link_to("Home", '/', :class => 'home'), link(:home)
158
+ end
159
+ end
160
+
161
+ # I18n
162
+
163
+ test "link should lookup proper I18n labels" do
164
+ swap ::Link2, :i18n_scopes => ['links.{{action}}'] do
165
+ assert_match /\>Home\</, link(:home)
166
+ assert_match /\>Back\</, link(:back)
167
+ assert_match /\>New fraggle\</, link(:new, :fraggle)
168
+ assert_match /\>New fraggle\</, link(:new, ::Fraggle)
169
+ assert_match /\>New fraggle\</, link(:new, @mookey)
170
+ assert_match /\>Edit fraggle\</, link(:edit, @mookey)
171
+ # assert_match /\>Delete fraggle\</, link(:delete, @mookey)
172
+ assert_match /\>Show fraggle\</, link(:show, @mookey)
173
+ assert_match /\>Index of fraggles\</, link(:index, ::Fraggle)
174
+
175
+ @mookey.class_eval do
176
+ def to_s
177
+ "off"
178
+ end
179
+ end
180
+ assert_match /\>Show off\</, link(:show, @mookey)
181
+ end
182
+ end
183
+
184
+ end
data/test/i18n_test.rb CHANGED
@@ -5,6 +5,7 @@ class I18nTest < ActiveSupport::TestCase
5
5
 
6
6
  def setup
7
7
  ::I18n.locale = :en
8
+ ::Link2.i18n_scopes = ['links.{{action}}']
8
9
  end
9
10
 
10
11
  test "i18n: should load default translations automatically" do
@@ -25,21 +26,25 @@ class I18nTest < ActiveSupport::TestCase
25
26
  test "i18n: should substitute scopes with parsed values for: controller, action, resource, resources" do
26
27
  dummie_scopes = ['{{controller}}.{{models}}.{{model}}.{{action}}.label', 'links.{{action}}']
27
28
  expected_substitution = [:'fraggles.fraggles.fraggle.new.label', :'links.new']
29
+ expected_substitution_underscored = [:'fraggles.cool_aids.cool_aid.new.label', :'links.new']
28
30
 
29
31
  swap ::Link2, :i18n_scopes => dummie_scopes do
30
32
  assert_raise(::Link2::I18n::ScopeInterpolationError) { ::Link2::I18n.send(:substituted_scopes_for, :new, ::Fraggle) }
31
33
 
32
34
  assert_nothing_raised(::KeyError) { ::Link2::I18n.send(:substituted_scopes_for, :new, ::Fraggle, :controller => 'fraggles') }
33
35
  assert_equal expected_substitution, ::Link2::I18n.send(:substituted_scopes_for, :new, ::Fraggle, :controller => 'fraggles')
36
+ assert_equal expected_substitution_underscored, ::Link2::I18n.send(:substituted_scopes_for, :new, ::CoolAid, :controller => 'fraggles')
34
37
  end
35
38
  end
36
39
 
37
40
  test "i18n: should be able to translate action without any options" do
38
- i18n_options = {:scope => 'links', :resource => 'fraggle', :resources => 'fraggles'}
41
+ swap ::Link2, :i18n_scopes => ['links.{{action}}'] do
42
+ i18n_options = {:scope => 'links', :resource => 'fraggle', :resources => 'fraggles'}
39
43
 
40
- assert_equal ::I18n.t(:new, i18n_options), ::Link2::I18n.t(:new, ::Fraggle)
41
- assert_equal ::I18n.t(:new, i18n_options), ::Link2::I18n.t(:new, ::Fraggle.new)
42
- assert_equal ::I18n.t(:new, i18n_options), ::Link2::I18n.t(:new, :fraggle)
44
+ assert_equal ::I18n.t(:new, i18n_options), ::Link2::I18n.t(:new, ::Fraggle)
45
+ assert_equal ::I18n.t(:new, i18n_options), ::Link2::I18n.t(:new, ::Fraggle.new)
46
+ assert_equal ::I18n.t(:new, i18n_options), ::Link2::I18n.t(:new, :fraggle)
47
+ end
43
48
  end
44
49
 
45
50
  test "i18n: should be able to translate action with respect to any valid extra interpolation arguments" do
data/test/link2_test.rb CHANGED
@@ -16,6 +16,10 @@ class Link2Test < ActiveSupport::TestCase
16
16
  swap Link2, :action_mappings => {:home => '/'} do
17
17
  assert_equal ({:home => '/'}), Link2.action_mappings
18
18
  end
19
+
20
+ swap Link2, :dom_selectors => true do
21
+ assert_equal true, Link2.dom_selectors
22
+ end
19
23
  end
20
24
 
21
25
  test "#url_for_mapping: should only map mapped action keys" do
data/test/support_test.rb CHANGED
@@ -7,6 +7,8 @@ class SupportTest < ActiveSupport::TestCase
7
7
  end
8
8
 
9
9
  test "#find_resource_class: should find proper class based on class, class instance, or (symbol) name" do
10
+ assert_nil ::Link2::Support.find_resource_class(nil)
11
+
10
12
  assert_equal ::Fraggle, ::Link2::Support.find_resource_class(::Fraggle)
11
13
  assert_equal ::Fraggle, ::Link2::Support.find_resource_class(::Fraggle.new)
12
14
  assert_equal ::Fraggle, ::Link2::Support.find_resource_class(:fraggle)
@@ -16,4 +18,18 @@ class SupportTest < ActiveSupport::TestCase
16
18
  assert_not_equal ::Fraggle, ::Link2::Support.find_resource_class(:unicorn)
17
19
  end
18
20
 
21
+ test "#resource_identifier_class?: should only be true for valid classes" do
22
+ assert ::Link2::Support.resource_identifier_class?(nil)
23
+ assert ::Link2::Support.resource_identifier_class?(:hello)
24
+ assert ::Link2::Support.resource_identifier_class?(::Fraggle)
25
+
26
+ assert_not ::Link2::Support.resource_identifier_class?(::Unicorn)
27
+ end
28
+
29
+ test "#record_class?: should only be true for record classes" do
30
+ assert ::Link2::Support.record_class?(::Fraggle)
31
+
32
+ assert_not ::Link2::Support.record_class?(::Unicorn)
33
+ end
34
+
19
35
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: link2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonas Grimfelt
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-02-28 00:00:00 +01:00
12
+ date: 2010-03-02 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -42,6 +42,36 @@ dependencies:
42
42
  - !ruby/object:Gem::Version
43
43
  version: 1.2.3
44
44
  version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: mocha
47
+ type: :development
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 0.9.8
54
+ version:
55
+ - !ruby/object:Gem::Dependency
56
+ name: webrat
57
+ type: :development
58
+ version_requirement:
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: 0.7.0
64
+ version:
65
+ - !ruby/object:Gem::Dependency
66
+ name: leftright
67
+ type: :development
68
+ version_requirement:
69
+ version_requirements: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: 0.0.3
74
+ version:
45
75
  - !ruby/object:Gem::Dependency
46
76
  name: activerecord
47
77
  type: :development