vacuum_cleaner 1.0.1 → 1.0.3

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.
@@ -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