vacuum_cleaner 1.0.1 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -9,7 +9,7 @@ require 'vacuum_cleaner/normalizations'
9
9
  # @see VacuumCleaner::Normalizer
10
10
  module VacuumCleaner
11
11
  # +VacuumCleaner+ version
12
- VERSION = "1.0.1".freeze
12
+ VERSION = "1.0.3".freeze
13
13
  end
14
14
 
15
15
  if defined?(ActiveSupport) && ActiveSupport.respond_to?(:on_load)
@@ -14,6 +14,17 @@ module VacuumCleaner
14
14
 
15
15
  module ClassMethods
16
16
 
17
+ # List of already normalized attributes, to keep everything safe
18
+ # when calling `normalizes` twice for a certain attribute.
19
+ #
20
+ # When called for the first time checks it's `superclass` for any
21
+ # normalized attributes.
22
+ def normalized_attributes
23
+ @normalized_attributes ||= [].tap do |ary|
24
+ superclass.normalized_attributes.each { |a| ary << a } if superclass && superclass.respond_to?(:normalized_attributes)
25
+ end
26
+ end
27
+
17
28
  # Enables normalization chain for supplied attributes.
18
29
  #
19
30
  # @example Basic usage for plain old ruby objects.
@@ -35,8 +46,6 @@ module VacuumCleaner
35
46
  # @yield [instance, attribute, value] optional (extended) block with all arguments, like the +object+ and
36
47
  # current +attribute+ name. Everything else behaves the same es the single-value +yield+
37
48
  def normalizes(*attributes, &block)
38
- metaklass = class << self; self; end
39
-
40
49
  normalizations = attributes.last.is_a?(Hash) ? attributes.pop : {}
41
50
  raise ArgumentError, "You need to supply at least one attribute" if attributes.empty?
42
51
 
@@ -53,23 +62,27 @@ module VacuumCleaner
53
62
 
54
63
  attributes.each do |attribute|
55
64
  attribute = attribute.to_sym
56
- send(:define_method, :"normalize_#{attribute}") do |value|
57
- value = normalizers.inject(value) { |v,n| n.normalize(self, attribute, v) }
58
- block_given? ? (block.arity == 1 ? yield(value) : yield(self, attribute, value)) : value
59
- end
60
- original_setter = "#{attribute}#{VacuumCleaner::WITHOUT_NORMALIZATION_SUFFIX}=".to_sym
61
- send(:alias_method, original_setter, "#{attribute}=") if instance_methods.include?(RUBY_VERSION =~ /^1.9/ ? :"#{attribute}=" : "#{attribute}=")
62
-
63
- rb_src = <<-RUBY
64
- def #{attribute}=(value) # 1. def name=(value)
65
- value = send(:'normalize_#{attribute}', value) # 2. value = send(:'normalize_name', value)
66
- return send(#{original_setter.inspect}, value) if respond_to?(#{original_setter.inspect}) # 3. return send(:'name_wi...=', value) if respond_to?(:'name_wi...=')
67
- return self[#{attribute.inspect}] = value if respond_to?(:[]=) # 4. return self[:name] = value if respond_to?(:write_attribute)
68
- @#{attribute} = value # 5. @name = value
69
- end # 6. end
70
- RUBY
71
65
 
72
- module_eval rb_src, __FILE__, __LINE__
66
+ # guard against calling it twice!
67
+ unless normalized_attributes.include?(attribute)
68
+ send(:define_method, :"normalize_#{attribute}") do |value|
69
+ value = normalizers.inject(value) { |v,n| n.normalize(self, attribute, v) }
70
+ block_given? ? (block.arity == 1 ? yield(value) : yield(self, attribute, value)) : value
71
+ end
72
+ original_setter = "#{attribute}#{VacuumCleaner::WITHOUT_NORMALIZATION_SUFFIX}=".to_sym
73
+ send(:alias_method, original_setter, "#{attribute}=") if instance_methods.include?(RUBY_VERSION =~ /^1.9/ ? :"#{attribute}=" : "#{attribute}=")
74
+
75
+ class_eval <<-RUBY, __FILE__, __LINE__+1
76
+ def #{attribute}=(value) # 1. def name=(value)
77
+ value = send(:'normalize_#{attribute}', value) # 2. value = send(:'normalize_name', value)
78
+ return send(#{original_setter.inspect}, value) if respond_to?(#{original_setter.inspect}) # 3. return send(:'name_wi...=', value) if respond_to?(:'name_wi...=')
79
+ return send(:[]=, #{attribute.inspect}, value) if respond_to?(:[]=) # 4. return send(:[]=, :name, value) if respond_to?(:[]=)
80
+ @#{attribute} = value # 5. @name = value
81
+ end # 6. end
82
+ RUBY
83
+
84
+ normalized_attributes << attribute
85
+ end
73
86
  end
74
87
  end
75
88
  end
@@ -191,5 +191,31 @@ class VacuumCleaner::NormalizationsTest < Test::Unit::TestCase
191
191
  assert_equal [obj.object_id, :name, "Carla"], obj.name
192
192
  end
193
193
  end
194
+
195
+ context "ClassMethods#normalized_attributes" do
196
+ should "keep an array with all normalized attributes" do
197
+ assert_equal [:name], Doctor.normalized_attributes
198
+ assert_equal [:last_name, :first_name], Person.normalized_attributes
199
+ end
200
+
201
+ should "guard against calling `normalizes` twice for an attribute, to avoid stack level too deep error!" do
202
+ klass = Class.new(Doctor) do
203
+ attr_accessor :coolness
204
+ normalizes :coolness, :downcase => true
205
+ end
206
+
207
+ assert_equal [:name, :coolness], klass.normalized_attributes
208
+ assert_equal [:name], Doctor.normalized_attributes
209
+
210
+ klass.send(:normalizes, :coolness, :upcase => true) # should be ignored!
211
+ assert_equal [:name, :coolness], klass.normalized_attributes
212
+
213
+ obj = klass.new
214
+ assert_nothing_raised do
215
+ obj.coolness = "AWESOME"
216
+ end
217
+ assert_equal "awesome", obj.coolness
218
+ end
219
+ end
194
220
  end
195
221
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vacuum_cleaner
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
4
+ hash: 17
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
- - 1
10
- version: 1.0.1
9
+ - 3
10
+ version: 1.0.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Lukas Westermann
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-09-09 00:00:00 +02:00
18
+ date: 2010-10-07 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -71,7 +71,6 @@ files:
71
71
  - lib/vacuum_cleaner/normalizations/numeric.rb
72
72
  - lib/vacuum_cleaner/normalizations/url.rb
73
73
  - lib/vacuum_cleaner/normalizer.rb
74
- - lib/vacuum_cleaner/railtie.rb
75
74
  - test/integration/active_record_integration_test.rb
76
75
  - test/integration/active_support_integration_test.rb
77
76
  - test/test_helper.rb
@@ -1,7 +0,0 @@
1
- module VacuumCleaner
2
- class Railtie < Rails::Railtie
3
- config.after_initialize do
4
- ActiveRecord::Base.send(:include, VacuumCleaner::Normalizations)
5
- end
6
- end
7
- end