attribute_normalizer 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.textile CHANGED
@@ -4,6 +4,11 @@ p. A little normalization goes a long way in helping maintain data integrity.
4
4
 
5
5
  h2. Recent Changes
6
6
 
7
+ * 0.3.0
8
+ ** Normalizer Chaining
9
+ ** Built-in common normalizers
10
+ ** Ability to change the default attribute normalization.
11
+
7
12
  * 0.2.1
8
13
  ** ActiveModel Support Built-in
9
14
  ** Fix for :with option getting dropped when normalizing several attributes
@@ -54,10 +59,16 @@ p. Lets create a quick test/spec for what we want to accomplish as far as normal
54
59
  describe Book do
55
60
  it { should normalize_attribute(:author) }
56
61
  it { should normalize_attribute(:price).from('$3,450.98').to(3450.98) }
57
- it { should normalize_attribute(:summary).from('Here is my summary that is a little to long').to('Here is m...') }
58
- it { should normalize_attribute(:title).from('pick up chicks with magic tricks').to('Pick Up Chicks With Magic Tricks')}
62
+ it { should normalize_attribute(:summary).from(' Here is my summary that is a little to long ').to('Here is m...') }
63
+ it { should normalize_attribute(:title).from(' pick up chicks with magic tricks ').to('Pick Up Chicks With Magic Tricks')}
59
64
  end</code></pre>
60
65
 
66
+ p. The following normalizers are already included with the +0.3 version of the gem.
67
+
68
+ * _:blank_ Will return _nil_ on empty strings
69
+ * _:phone_ Will strip out all non-digit characters and return nil on empty strings
70
+ * _:strip_ Will strip leading and trailing whitespace.
71
+
61
72
  p. And lets predefine some normalizers that we may use in other classes/models or that we don't want to clutter up our class/model's readability with.
62
73
 
63
74
  <pre><code># config/initializers/attribute_normalizer.rb
@@ -78,6 +89,10 @@ AttributeNormalizer.configure do |config|
78
89
  end
79
90
  end
80
91
 
92
+ # The default normalizers if no :with option or block is given is to apply the :strip and :blank normalizers (in that order).
93
+ # You can change this if you would like as follows:
94
+ # config.default_normalizers = :strip, :blank
95
+
81
96
  end
82
97
  </code></pre>
83
98
 
@@ -92,8 +107,8 @@ The _normalize_attributes_ method is eager loaded into your ORM. _normalize_att
92
107
  # Using one of our predefined normalizers.
93
108
  normalize_attribute :price, :with => :currency
94
109
 
95
- # Using one of our predefined normalizers with options
96
- normalize_attribute :summary, :with => :truncate, :length => 12
110
+ # Using more then one of our predefined normalizers including one with options
111
+ normalize_attribute :summary, :with => [ :strip, { :truncate => { :length => 12 } } ]
97
112
 
98
113
  # You can also define your normalization block inline.
99
114
  normalize_attribute :title do |value|
@@ -6,23 +6,37 @@ module AttributeNormalizer
6
6
 
7
7
  module ClassMethods
8
8
  def normalize_attributes(*attributes, &block)
9
- options = attributes.extract_options!
10
- with = options.delete(:with)
9
+ options = attributes.last.is_a?(::Hash) ? attributes.pop : {}
10
+
11
+ normalizers = [options.delete(:with)].flatten.compact
12
+ if normalizers.empty? && !block_given?
13
+ normalizers = AttributeNormalizer.configuration.default_normalizers # the default normalizers
14
+ end
11
15
 
12
16
  attributes.each do |attribute|
13
- define_method "normalize_#{attribute}" do |value|
14
- normalized = if block_given? && !value.blank?
17
+ if block_given?
18
+ define_method "normalize_#{attribute}" do |value|
15
19
  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}")
20
+ end
21
+ else
22
+ define_method "normalize_#{attribute}" do |value|
23
+ normalized=value
24
+ normalizers.each do |normalizer_name|
25
+ unless normalizer_name.kind_of?(Symbol)
26
+ normalizer_name,options=normalizer_name.keys[0],normalizer_name[normalizer_name.keys[0]]
27
+ end
28
+
29
+ normalizer=AttributeNormalizer.configuration.normalizers[normalizer_name]
30
+ raise AttributeNormalizer::MissingNormalizer.new("No normalizer was found for #{normalizer_name}") unless normalizer
31
+
32
+ normalized= normalizer.respond_to?(:normalize) ? normalizer.normalize(normalized,options) :
33
+ normalizer.call(normalized, options)
34
+ #puts "#{normalizer_name} : ->'#{normalized}' (#{normalized.class})"
19
35
  end
20
- AttributeNormalizer.configuration.normalizers[with].call(value, options)
21
- else
22
- value.is_a?(String) ? value.strip : value
36
+ normalized
23
37
  end
24
- normalized.nil? || (normalized.is_a?(String) && normalized == '') ? nil : normalized
25
38
  end
39
+
26
40
  self.send :private, "normalize_#{attribute}"
27
41
 
28
42
  define_method "#{attribute}=" do |value|
@@ -0,0 +1,9 @@
1
+ module AttributeNormalizer
2
+ module Normalizers
3
+ module BlankNormalizer
4
+ def self.normalize(value, options)
5
+ value.nil? || (value.is_a?(String) && value.empty?) ? nil : value
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ module AttributeNormalizer
2
+ module Normalizers
3
+ module PhoneNormalizer
4
+ def self.normalize(value, options)
5
+ value = value.is_a?(String) ? value.gsub(/[^0-9]+/, '') : value
6
+ value.is_a?(String) && value.empty? ? nil : value
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ module AttributeNormalizer
2
+ module Normalizers
3
+ module StripNormalizer
4
+ def self.normalize(value, options)
5
+ value.is_a?(String) ? value.strip : value
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,3 +1,7 @@
1
+ require 'attribute_normalizer/normalizers/blank_normalizer'
2
+ require 'attribute_normalizer/normalizers/phone_normalizer'
3
+ require 'attribute_normalizer/normalizers/strip_normalizer'
4
+
1
5
  module AttributeNormalizer
2
6
 
3
7
  class MissingNormalizer < ArgumentError; end
@@ -11,11 +15,23 @@ module AttributeNormalizer
11
15
  yield(configuration)
12
16
  end
13
17
 
18
+
14
19
  class Configuration
15
- attr_accessor :normalizers
20
+ attr_accessor :default_normalizers, :normalizers
21
+
22
+ def default_normalizers=(normalizers)
23
+ @default_normalizers = normalizers.is_a?(Array) ? normalizers : [ normalizers ]
24
+ end
25
+
16
26
  def initialize
17
27
  @normalizers = {}
28
+ @normalizers[ :blank ] = AttributeNormalizer::Normalizers::BlankNormalizer
29
+ @normalizers[ :phone ] = AttributeNormalizer::Normalizers::PhoneNormalizer
30
+ @normalizers[ :strip ] = AttributeNormalizer::Normalizers::StripNormalizer
31
+ @default_normalizers = [ :strip, :blank ]
18
32
  end
33
+
34
+
19
35
  end
20
36
 
21
37
  end
@@ -24,7 +40,6 @@ end
24
40
  require 'attribute_normalizer/model_inclusions'
25
41
  require 'attribute_normalizer/rspec_matcher'
26
42
 
27
-
28
43
  def include_attribute_normalizer(class_or_module)
29
44
  return if class_or_module.include?(AttributeNormalizer)
30
45
  class_or_module.class_eval do
@@ -0,0 +1,25 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ describe Author do
4
+
5
+ context 'Testing the built in normalizers' do
6
+ # default normalization [ :strip, :blank ]
7
+ it { should normalize_attribute(:name) }
8
+ it { should normalize_attribute(:name).from(' this ').to('this') }
9
+ it { should normalize_attribute(:name).from(' ').to(nil) }
10
+
11
+ # :strip normalizer
12
+ it { should normalize_attribute(:first_name).from(' this ').to('this') }
13
+ it { should normalize_attribute(:first_name).from(' ').to('') }
14
+
15
+ # :blank normalizer
16
+ it { should normalize_attribute(:last_name).from('').to(nil) }
17
+ it { should normalize_attribute(:last_name).from(' this ').to(' this ') }
18
+
19
+ # :phone normalizer
20
+ it { should normalize_attribute(:phone_number).from('no-numbers-here').to(nil) }
21
+ it { should normalize_attribute(:phone_number).from('1.877.987.9875').to('18779879875') }
22
+ it { should normalize_attribute(:phone_number).from('+ 1 (877) 987-9875').to('18779879875') }
23
+ end
24
+
25
+ end
data/spec/book_spec.rb CHANGED
@@ -7,7 +7,7 @@ describe Book do
7
7
  it { should normalize_attribute(:us_price).from('$3.50').to(3.50) }
8
8
  it { should normalize_attribute(:cnd_price).from('$3,450.98').to(3450.98) }
9
9
 
10
- it { should normalize_attribute(:summary).from('Here is my summary that is a little to long').to('Here is m...') }
10
+ it { should normalize_attribute(:summary).from(' Here is my summary that is a little to long ').to('Here is m...') }
11
11
 
12
12
  it { should normalize_attribute(:title).from('pick up chicks with magic tricks').to('Pick Up Chicks With Magic Tricks') }
13
13
 
@@ -44,4 +44,9 @@ describe Book do
44
44
  end
45
45
  end
46
46
 
47
+ context 'with the default normalizer changed' do
48
+ @book = Book.new :author => 'testing the default normalizer'
49
+ @book.author.should == 'testing the default normalizer'
50
+ end
51
+
47
52
  end
@@ -5,6 +5,13 @@ ActiveRecord::Base.establish_connection({
5
5
  })
6
6
 
7
7
  ActiveRecord::Schema.define do
8
+ create_table :authors, :force => true do |t|
9
+ t.string :name
10
+ t.string :first_name
11
+ t.string :last_name
12
+ t.string :phone_number
13
+ end
14
+
8
15
  create_table :books, :force => true do |t|
9
16
  t.string :author
10
17
  t.string :isbn
@@ -1,13 +1,8 @@
1
- class Author < ActiveModel::Base
1
+ class Author < ActiveRecord::Base
2
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
3
+ normalize_attribute :name
4
+ normalize_attribute :first_name, :with => :strip
5
+ normalize_attribute :last_name, :with => :blank
6
+ normalize_attribute :phone_number, :with => :phone
12
7
 
13
8
  end
data/spec/models/book.rb CHANGED
@@ -4,7 +4,11 @@ class Book < ActiveRecord::Base
4
4
 
5
5
  normalize_attribute :us_price, :cnd_price, :with => :currency
6
6
 
7
- normalize_attributes :summary, :with => :truncate, :length => 12
7
+ normalize_attributes :summary, :with => [ :strip,
8
+ { :truncate => { :length => 12 } },
9
+ :blank
10
+ ]
11
+
8
12
 
9
13
  normalize_attributes :title do |value|
10
14
  value.is_a?(String) ? value.titleize.strip : value
data/spec/test_helper.rb CHANGED
@@ -3,6 +3,7 @@ require 'spec'
3
3
  require 'active_record'
4
4
 
5
5
  $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib')
6
+
6
7
  require 'attribute_normalizer'
7
8
 
8
9
 
@@ -23,11 +24,18 @@ AttributeNormalizer.configure do |config|
23
24
  end
24
25
  end
25
26
 
27
+ config.normalizers[:special_normalizer] = lambda do |value, options|
28
+ (value.is_a?(String) && value.match(/testing the default normalizer/)) ? 'testing the default normalizer' : value
29
+ end
30
+
31
+ config.default_normalizers = :strip, :special_normalizer, :blank
32
+
26
33
  end
27
34
 
28
35
 
29
36
  require 'connection_and_schema'
30
37
  require 'models/book'
38
+ require 'models/author'
31
39
 
32
40
 
33
41
  Spec::Runner.configure do |config|
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: attribute_normalizer
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 2
9
- - 1
10
- version: 0.2.1
8
+ - 3
9
+ - 0
10
+ version: 0.3.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Michael Deering
@@ -35,9 +35,13 @@ files:
35
35
  - install.txt
36
36
  - lib/attribute_normalizer.rb
37
37
  - lib/attribute_normalizer/model_inclusions.rb
38
+ - lib/attribute_normalizer/normalizers/blank_normalizer.rb
39
+ - lib/attribute_normalizer/normalizers/phone_normalizer.rb
40
+ - lib/attribute_normalizer/normalizers/strip_normalizer.rb
38
41
  - lib/attribute_normalizer/rspec_matcher.rb
39
42
  - rails/init.rb
40
43
  - spec/attribute_normalizer_spec.rb
44
+ - spec/author_spec.rb
41
45
  - spec/book_spec.rb
42
46
  - spec/connection_and_schema.rb
43
47
  - spec/models/author.rb
@@ -81,6 +85,7 @@ specification_version: 3
81
85
  summary: Attribute normalizer that excepts code blocks.
82
86
  test_files:
83
87
  - spec/attribute_normalizer_spec.rb
88
+ - spec/author_spec.rb
84
89
  - spec/book_spec.rb
85
90
  - spec/connection_and_schema.rb
86
91
  - spec/models/author.rb