attribute_normalizer 0.2.0 → 0.2.1

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/README.textile CHANGED
@@ -4,6 +4,10 @@ p. A little normalization goes a long way in helping maintain data integrity.
4
4
 
5
5
  h2. Recent Changes
6
6
 
7
+ * 0.2.1
8
+ ** ActiveModel Support Built-in
9
+ ** Fix for :with option getting dropped when normalizing several attributes
10
+
7
11
  * 0.2.0
8
12
  ** Removed the normalization on reads.
9
13
  ** Added out of the box support for CassandraObjects
@@ -11,11 +15,9 @@ h2. Recent Changes
11
15
  ** Added the ability to define global normalizers
12
16
  ** *Strings are no longer get 'strip' called on them before getting passed on to your defined normalization blocks*
13
17
 
14
- * 0.1.2
15
- ** Changed post-normalization attribute assignment to call super to avoid preventing plugins/gems/hooks to work on the same attribute.
16
-
17
18
  h2. Supported ORMs
18
19
 
20
+ * _Active Model_
19
21
  * Active Record
20
22
  * CassandraObjects
21
23
 
@@ -31,12 +33,18 @@ h2. Install
31
33
 
32
34
  p. Then just required it. Rails usages is as follows.
33
35
 
36
+ h3. Rails 2
37
+
34
38
  <pre><code># config/environment.rb
35
- gem.config 'attribute_normalizer'</code></pre>
39
+ config.gem 'attribute_normalizer'</code></pre>
40
+
41
+ h3. Rails 3
42
+ <pre><code># Gemfile
43
+ gem 'attribute_normalizer'</code></pre>
36
44
 
37
45
  p. It also still works as a traditional Rails plugin.
38
46
 
39
- ./script/plugin install git://github.com/mdeering/attribute_normalizer.git
47
+ <pre><code>./script/plugin install git://github.com/mdeering/attribute_normalizer.git</code></pre>
40
48
 
41
49
  h2. Usage
42
50
 
@@ -109,14 +117,24 @@ h2. Test Helpers
109
117
 
110
118
  p. If you are running RSpec there is matcher available for use. Usage can been seen above. Include it as follows.
111
119
 
120
+ h3. Rails 2
121
+
112
122
  <pre><code># spec/spec_helper.rb
113
123
  # ...
114
-
115
124
  Spec::Runner.configure do |config|
116
125
  # ...
117
126
  config.include AttributeNormalizer::RSpecMatcher, :type => :models
118
127
  end</code></pre>
119
128
 
129
+ h3. Rails 3
130
+
131
+ <pre><code># spec/spec_helper.rb
132
+ # ...
133
+ Spec::Runner.configure do |config|
134
+ # ...
135
+ config.include AttributeNormalizer::RSpecMatcher # Models group type is missing at this time rspec-rails 2.0.0.beta.11
136
+ end</code></pre>
137
+
120
138
  p. _I will gladly take a patch to add a macro to Test::Unit if someone submits it._
121
139
 
122
140
  h2. Credits
@@ -0,0 +1,36 @@
1
+ module AttributeNormalizer
2
+
3
+ def self.included(base)
4
+ base.extend ClassMethods
5
+ end
6
+
7
+ module ClassMethods
8
+ def normalize_attributes(*attributes, &block)
9
+ options = attributes.extract_options!
10
+ with = options.delete(:with)
11
+
12
+ attributes.each do |attribute|
13
+ define_method "normalize_#{attribute}" do |value|
14
+ normalized = if block_given? && !value.blank?
15
+ yield(value)
16
+ elsif !with.nil? && !value.blank?
17
+ unless AttributeNormalizer.configuration.normalizers.has_key?(with)
18
+ raise AttributeNormalizer::MissingNormalizer.new("No normalizer was found for #{with}")
19
+ end
20
+ AttributeNormalizer.configuration.normalizers[with].call(value, options)
21
+ else
22
+ value.is_a?(String) ? value.strip : value
23
+ end
24
+ normalized.nil? || (normalized.is_a?(String) && normalized == '') ? nil : normalized
25
+ end
26
+ self.send :private, "normalize_#{attribute}"
27
+
28
+ define_method "#{attribute}=" do |value|
29
+ super(self.send(:"normalize_#{attribute}", value))
30
+ end
31
+
32
+ end
33
+ end
34
+ alias :normalize_attribute :normalize_attributes
35
+ end
36
+ end
@@ -0,0 +1,45 @@
1
+ module AttributeNormalizer
2
+
3
+ module RSpecMatcher
4
+
5
+ def normalize_attribute(attribute)
6
+ NormalizeAttribute.new(attribute)
7
+ end
8
+
9
+ class NormalizeAttribute
10
+
11
+ def initialize(attribute)
12
+ @attribute = attribute
13
+ @from = ''
14
+ end
15
+
16
+ def description
17
+ "normalize #{@attribute} from #{@from.nil? ? 'nil' : "\"#{@from}\""} to #{@to.nil? ? 'nil' : "\"#{@to}\""}"
18
+ end
19
+
20
+ def failure_message
21
+ "#{@attribute} did not normalize as expected! \"#{@subject.send(@attribute)}\" != #{@to.nil? ? 'nil' : "\"#{@to}\""}"
22
+ end
23
+
24
+ def from(value)
25
+ @from = value
26
+ self
27
+ end
28
+
29
+ def to(value)
30
+ @to = value
31
+ self
32
+ end
33
+
34
+ def matches?(subject)
35
+ @subject = subject
36
+ @subject.send("#{@attribute}=", @from)
37
+
38
+ @subject.send(@attribute) == @to
39
+ end
40
+
41
+ end
42
+
43
+ end
44
+
45
+ end
@@ -11,102 +11,27 @@ module AttributeNormalizer
11
11
  yield(configuration)
12
12
  end
13
13
 
14
- def self.included(base)
15
- base.extend ClassMethods
16
- end
17
-
18
14
  class Configuration
19
-
20
15
  attr_accessor :normalizers
21
-
22
16
  def initialize
23
17
  @normalizers = {}
24
18
  end
25
-
26
19
  end
27
20
 
28
- module ClassMethods
29
-
30
- def normalize_attributes(*attributes, &block)
31
- options = attributes.extract_options!
32
-
33
- attributes.each do |attribute|
34
-
35
- klass = class << self; self end
36
-
37
- klass.send :define_method, "normalize_#{attribute}" do |value|
38
- normalized = if block_given? && !value.blank?
39
- yield(value)
40
- elsif !options[:with].nil? && !value.blank?
41
- raise AttributeNormalizer::MissingNormalizer.new("No normalizer was found for #{options[:with]}") unless AttributeNormalizer.configuration.normalizers.has_key?(options[:with])
42
- this = AttributeNormalizer.configuration.normalizers[options.delete(:with)].call(value, options)
43
- else
44
- value.is_a?(String) ? value.strip : value
45
- end
46
- normalized.nil? || (normalized.is_a?(String) && normalized == '') ? nil : normalized
47
- end
48
-
49
- klass.send :private, "normalize_#{attribute}"
50
-
51
- src = <<-end_src
52
- def #{attribute}=(value)
53
- super(self.class.send(:normalize_#{attribute}, value))
54
- end
55
- end_src
56
-
57
- module_eval src, __FILE__, __LINE__
58
-
59
- end
60
-
61
- end
62
-
63
- alias :normalize_attribute :normalize_attributes
64
-
65
- end
66
-
67
- module RSpecMatcher
68
-
69
- def normalize_attribute(attribute)
70
- NormalizeAttribute.new(attribute)
71
- end
72
-
73
- class NormalizeAttribute
74
-
75
- def description
76
- "normalize #{@attribute} from #{@from.nil? ? 'nil' : "\"#{@from}\""} to #{@to.nil? ? 'nil' : "\"#{@to}\""}"
77
- end
78
-
79
- def failure_message
80
- "#{@attribute} did not normalize as expected! \"#{@subject.send(@attribute)}\" != #{@to.nil? ? 'nil' : "\"#{@to}\""}"
81
- end
82
-
83
- def from(value)
84
- @from = value
85
- self
86
- end
87
-
88
- def initialize(attribute)
89
- @attribute = attribute
90
- @from = ''
91
- end
21
+ end
92
22
 
93
- def matches?(subject)
94
- @subject = subject
95
- @subject.send("#{@attribute}=", @from)
96
- return false unless @subject.send(@attribute) == @to
97
- true
98
- end
99
23
 
100
- def to(value)
101
- @to = value
102
- self
103
- end
24
+ require 'attribute_normalizer/model_inclusions'
25
+ require 'attribute_normalizer/rspec_matcher'
104
26
 
105
- end
106
27
 
28
+ def include_attribute_normalizer(class_or_module)
29
+ return if class_or_module.include?(AttributeNormalizer)
30
+ class_or_module.class_eval do
31
+ extend AttributeNormalizer::ClassMethods
107
32
  end
108
-
109
33
  end
110
34
 
111
- ActiveRecord::Base.send(:include, AttributeNormalizer) if defined?(ActiveRecord::Base)
112
- CassandraObject::Base.send(:include, AttributeNormalizer) if defined?(CassandraObject::Base)
35
+ include_attribute_normalizer(ActiveModel::Base) if defined?(ActiveModel::Base)
36
+ include_attribute_normalizer(ActiveRecord::Base) if defined?(ActiveRecord::Base)
37
+ include_attribute_normalizer(CassandraObject::Base) if defined?(CassandraObject::Base)
data/rails/init.rb CHANGED
@@ -1 +1 @@
1
- require File.join(File.dirname(__FILE__), *%w[.. lib attribute_normalizer])
1
+ require 'attribute_normalizer'
data/spec/book_spec.rb CHANGED
@@ -4,14 +4,14 @@ describe Book do
4
4
 
5
5
  it { should normalize_attribute(:author).from(' Michael Deering ').to('Michael Deering') }
6
6
 
7
- it { should normalize_attribute(:price).from('$3,450.98').to(3450.98) }
7
+ it { should normalize_attribute(:us_price).from('$3.50').to(3.50) }
8
+ it { should normalize_attribute(:cnd_price).from('$3,450.98').to(3450.98) }
8
9
 
9
10
  it { should normalize_attribute(:summary).from('Here is my summary that is a little to long').to('Here is m...') }
10
11
 
11
- it { should normalize_attribute(:title).from('pick up chicks with magic tricks').to('Pick Up Chicks With Magic Tricks')}
12
+ it { should normalize_attribute(:title).from('pick up chicks with magic tricks').to('Pick Up Chicks With Magic Tricks') }
12
13
 
13
14
  context 'normalization should not interfear with other hooks and aliases on the attribute assignment' do
14
-
15
15
  before do
16
16
  @book = Book.create!(:title => 'Original Title')
17
17
  end
@@ -19,11 +19,9 @@ describe Book do
19
19
  it 'should still reflect that the attribute has been changed through the call to super' do
20
20
  lambda { @book.title = 'New Title' }.should change(@book, :title_changed?).from(false).to(true)
21
21
  end
22
-
23
22
  end
24
23
 
25
24
  context 'when another instance of the same saved record has been changed' do
26
-
27
25
  before do
28
26
  @book = Book.create!(:title => 'Original Title')
29
27
  @book2 = Book.find(@book.id)
@@ -33,7 +31,17 @@ describe Book do
33
31
  it "should reflect the change when the record is reloaded" do
34
32
  lambda { @book.reload }.should change(@book, :title).from('Original Title').to('New Title')
35
33
  end
34
+ end
35
+
36
+ context 'normalization should work with multiple attributes at the same time' do
37
+ before do
38
+ @book = Book.new(:title => ' Bad Title ', :author => ' Bad Author ')
39
+ end
36
40
 
41
+ it "should apply normalizations to both attributes" do
42
+ @book.title.should == 'Bad Title'
43
+ @book.author.should == 'Bad Author'
44
+ end
37
45
  end
38
46
 
39
47
  end
@@ -0,0 +1,16 @@
1
+ ActiveRecord::Base.establish_connection({
2
+ :database => ":memory:",
3
+ :adapter => 'sqlite3',
4
+ :timeout => 500
5
+ })
6
+
7
+ ActiveRecord::Schema.define do
8
+ create_table :books, :force => true do |t|
9
+ t.string :author
10
+ t.string :isbn
11
+ t.decimal :cnd_price
12
+ t.decimal :us_price
13
+ t.string :summary
14
+ t.string :title
15
+ end
16
+ end
@@ -0,0 +1,13 @@
1
+ class Author < ActiveModel::Base
2
+
3
+ normalize_attribute :name
4
+
5
+ normalize_attribute :hourly_cost, :with => :currency
6
+
7
+ normalize_attributes :biography, :with => :truncate, :length => 12
8
+
9
+ normalize_attributes :email_address do |value|
10
+ value.is_a?(String) ? value.titleize.strip : value
11
+ end
12
+
13
+ end
@@ -0,0 +1,13 @@
1
+ class Book < ActiveRecord::Base
2
+
3
+ normalize_attribute :author
4
+
5
+ normalize_attribute :us_price, :cnd_price, :with => :currency
6
+
7
+ normalize_attributes :summary, :with => :truncate, :length => 12
8
+
9
+ normalize_attributes :title do |value|
10
+ value.is_a?(String) ? value.titleize.strip : value
11
+ end
12
+
13
+ end
data/spec/test_helper.rb CHANGED
@@ -1,11 +1,11 @@
1
1
  require 'rubygems'
2
2
  require 'spec'
3
- require 'active_support'
4
3
  require 'active_record'
5
4
 
6
5
  $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib')
7
6
  require 'attribute_normalizer'
8
7
 
8
+
9
9
  AttributeNormalizer.configure do |config|
10
10
 
11
11
  config.normalizers[:currency] = lambda do |value, options|
@@ -25,33 +25,11 @@ AttributeNormalizer.configure do |config|
25
25
 
26
26
  end
27
27
 
28
- ActiveRecord::Base.establish_connection({ :database => ":memory:", :adapter => 'sqlite3', :timeout => 500 })
29
-
30
- ActiveRecord::Schema.define do
31
- create_table :books, :force => true do |t|
32
- t.string :author
33
- t.string :isbn
34
- t.decimal :price
35
- t.string :summary
36
- t.string :title
37
- end
38
- end
39
-
40
- class Book < ActiveRecord::Base
41
-
42
- normalize_attribute :author
43
28
 
44
- normalize_attribute :price, :with => :currency
29
+ require 'connection_and_schema'
30
+ require 'models/book'
45
31
 
46
- normalize_attributes :summary, :with => :truncate, :length => 12
47
-
48
- normalize_attributes :title do |value|
49
- value.is_a?(String) ? value.titleize.strip : value
50
- end
51
-
52
- end
53
32
 
54
33
  Spec::Runner.configure do |config|
55
- config.include AttributeNormalizer::RSpecMatcher, :type => :models
56
- end
57
-
34
+ config.include AttributeNormalizer::RSpecMatcher
35
+ end
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: attribute_normalizer
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 21
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
8
  - 2
8
- - 0
9
- version: 0.2.0
9
+ - 1
10
+ version: 0.2.1
10
11
  platform: ruby
11
12
  authors:
12
13
  - Michael Deering
@@ -14,7 +15,7 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-05-14 00:00:00 -06:00
18
+ date: 2010-08-18 00:00:00 -06:00
18
19
  default_executable:
19
20
  dependencies: []
20
21
 
@@ -33,9 +34,14 @@ files:
33
34
  - install.rb
34
35
  - install.txt
35
36
  - lib/attribute_normalizer.rb
37
+ - lib/attribute_normalizer/model_inclusions.rb
38
+ - lib/attribute_normalizer/rspec_matcher.rb
36
39
  - rails/init.rb
37
40
  - spec/attribute_normalizer_spec.rb
38
41
  - spec/book_spec.rb
42
+ - spec/connection_and_schema.rb
43
+ - spec/models/author.rb
44
+ - spec/models/book.rb
39
45
  - spec/test_helper.rb
40
46
  has_rdoc: true
41
47
  homepage: http://github.com/mdeering/attribute_normalizer
@@ -49,27 +55,34 @@ rdoc_options:
49
55
  require_paths:
50
56
  - lib
51
57
  required_ruby_version: !ruby/object:Gem::Requirement
58
+ none: false
52
59
  requirements:
53
60
  - - ">="
54
61
  - !ruby/object:Gem::Version
62
+ hash: 3
55
63
  segments:
56
64
  - 0
57
65
  version: "0"
58
66
  required_rubygems_version: !ruby/object:Gem::Requirement
67
+ none: false
59
68
  requirements:
60
69
  - - ">="
61
70
  - !ruby/object:Gem::Version
71
+ hash: 3
62
72
  segments:
63
73
  - 0
64
74
  version: "0"
65
75
  requirements: []
66
76
 
67
77
  rubyforge_project:
68
- rubygems_version: 1.3.6
78
+ rubygems_version: 1.3.7
69
79
  signing_key:
70
80
  specification_version: 3
71
81
  summary: Attribute normalizer that excepts code blocks.
72
82
  test_files:
73
83
  - spec/attribute_normalizer_spec.rb
74
84
  - spec/book_spec.rb
85
+ - spec/connection_and_schema.rb
86
+ - spec/models/author.rb
87
+ - spec/models/book.rb
75
88
  - spec/test_helper.rb