vacuum_cleaner 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ doc
2
+ pkg
3
+ .yardoc
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Lukas Westermann
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,6 @@
1
+ Vacuum Cleaner
2
+ ==============
3
+
4
+ A Ruby (and Rails) attribute normalization gem.
5
+
6
+ ** TODO **
data/Rakefile ADDED
@@ -0,0 +1,88 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'yard'
4
+ require File.join(File.dirname(__FILE__), 'lib', 'vacuum_cleaner')
5
+
6
+ desc 'Test the vacuum_cleaner plugin.'
7
+ Rake::TestTask.new(:test) do |t|
8
+ t.libs << 'lib'
9
+ t.libs << 'test'
10
+ t.pattern = 'test/**/*_test.rb'
11
+ t.verbose = true
12
+ end
13
+
14
+ desc 'Generate documentation for vacuum_cleaner. (requires yard)'
15
+ YARD::Rake::YardocTask.new(:doc) do |t|
16
+ t.files = ['lib/**/*.rb']
17
+ t.options = [
18
+ "--readme", "README.md",
19
+ "--title", "vacuum_cleaner (v#{VacuumCleaner::VERSION}) API Documentation"
20
+ ]
21
+ end
22
+
23
+ begin
24
+ require 'jeweler'
25
+ Jeweler::Tasks.new do |gemspec|
26
+ gemspec.name = "vacuum_cleaner"
27
+ gemspec.version = VacuumCleaner::VERSION
28
+ gemspec.summary = "Ruby (and Rails) attribute cleaning support, provides some nice default normalization strategies."
29
+ description = <<-DESC
30
+ ** Swoooosh ** - and all those leading and trailing whitespaces are gone, or ** Frooom ** - and the value
31
+ is normalized to always be prefixed by 'http://' and much more. Works with both plain old Ruby, and Rails (ActiveModel
32
+ and ActiveSupport).
33
+ DESC
34
+ gemspec.description = description.strip
35
+ gemspec.email = "lukas.westermann@gmail.com"
36
+ gemspec.homepage = "http://github.com/lwe/vacuum_cleaner"
37
+ gemspec.authors = ["Lukas Westermann"]
38
+ gemspec.licenses = %w{LICENSE}
39
+ gemspec.extra_rdoc_files = %w{README.md}
40
+
41
+ gemspec.add_development_dependency('shoulda', '>= 2.10.2')
42
+ gemspec.add_development_dependency('rr', '>= 0.10.5')
43
+ # gemspec.add_development_dependency('activesupport', '>= 2.3.5')
44
+ end
45
+ Jeweler::GemcutterTasks.new
46
+ rescue LoadError
47
+ puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install jeweler"
48
+ end
49
+
50
+ desc 'Clean all generated files (.yardoc and doc/*)'
51
+ task :clean do |t|
52
+ FileUtils.rm_rf "doc"
53
+ FileUtils.rm_rf "pkg"
54
+ FileUtils.rm_rf ".yardoc"
55
+ end
56
+
57
+ namespace :metrics do
58
+ desc 'Report all metrics, i.e. stats and code coverage.'
59
+ task :all => [:stats, :coverage]
60
+
61
+ desc 'Report code statistics for library and tests to shell.'
62
+ task :stats do |t|
63
+ require 'code_statistics'
64
+ dirs = {
65
+ 'Libraries' => 'lib',
66
+ 'Unit tests' => 'test/unit'
67
+ }.map { |name,dir| [name, File.join(File.dirname(__FILE__), dir)] }
68
+ CodeStatistics.new(*dirs).to_s
69
+ end
70
+
71
+ desc 'Report code coverage to HTML (doc/coverage) and shell (requires rcov).'
72
+ task :coverage do |t|
73
+ rm_f "doc/coverage"
74
+ mkdir_p "doc/coverage"
75
+ rcov = %(rcov -Ilib:test --exclude '\/gems\/' -o doc/coverage -T test/unit/vacuum_cleaner/*_test.rb -T test/unit/vacuum_cleaner/*/*_test.rb)
76
+ system rcov
77
+ end
78
+
79
+ desc 'Report the fishy smell of bad code (requires reek)'
80
+ task :smelly do |t|
81
+ puts
82
+ puts "* * * NOTE: reek currently reports several false positives,"
83
+ puts " eventhough it's probably good to check once in a while!"
84
+ puts
85
+ reek = %(reek -s lib)
86
+ system reek
87
+ end
88
+ end
data/init.rb ADDED
@@ -0,0 +1,4 @@
1
+ require 'vacuum_cleaner'
2
+
3
+ ActiveRecord::Base.class_eval { include VacuumCleaner::Normalizations } # all versions of rails
4
+ ActiveModel::Base.class_eval { include VacuumCleaner::Normalizations } if defined?(ActiveModel::Base) # Rails 3+
@@ -0,0 +1,6 @@
1
+ module VacuumCleaner
2
+ VERSION = "0.1.0".freeze
3
+
4
+ autoload :Normalizer, 'vacuum_cleaner/normalizer'
5
+ autoload :Normalizations, 'vacuum_cleaner/normalizations'
6
+ end
@@ -0,0 +1,69 @@
1
+ module VacuumCleaner
2
+ # Suffix added to existing setter methods
3
+ WITHOUT_NORMALIZATION_SUFFIX = "_without_normalization"
4
+
5
+ module Normalizations
6
+
7
+ def self.included(base)
8
+ base.extend(ClassMethods)
9
+ end
10
+
11
+ module ClassMethods
12
+ def normalizes(*attributes, &block)
13
+ metaklass = class << self; self; end
14
+
15
+ normalizations = attributes.last.is_a?(Hash) ? attributes.pop : {}
16
+ raise ArgumentError, "You need to supply at least one attribute" if attributes.empty?
17
+
18
+ normalizers = []
19
+ normalizers << Normalizer.new unless normalizations.delete(:default) === false
20
+
21
+ normalizations.each do |key, options|
22
+ begin
23
+ normalizers << const_get("#{VacuumCleaner.camelize_value(key)}Normalizer").new(options === true ? {} : options)
24
+ rescue NameError
25
+ raise ArgumentError, "Unknown normalizer: '#{key}'"
26
+ end
27
+ end
28
+
29
+ attributes.each do |attribute|
30
+ attribute = attribute.to_sym
31
+ send(:define_method, :"normalize_#{attribute}") do |value|
32
+ value = normalizers.inject(value) { |v,n| n.normalize(self, attribute, v) }
33
+ block_given? ? (block.arity == 1 ? yield(value) : yield(self, attribute, value)) : value
34
+ end
35
+ original_setter = "#{attribute}#{VacuumCleaner::WITHOUT_NORMALIZATION_SUFFIX}=".to_sym
36
+ send(:alias_method, original_setter, "#{attribute}=") if instance_methods.include?("#{attribute}=")
37
+
38
+ rb_src = <<-RUBY
39
+ def #{attribute}=(value) # 1. def name=(value)
40
+ value = send(:'normalize_#{attribute}', value) # 2. value = send(:'normalize_name', value)
41
+ return send(#{original_setter.inspect}, value) if respond_to?(#{original_setter.inspect}) # 3. return send(:'name_wo...=', value) if respond_to?(:'name_wo...=')
42
+ return send(:write_attribute, #{attribute.inspect}, value) if respond_to?(:write_attribute) # 4. return send(:write_attribute, :name, value) if respond_to?(:write_attribute)
43
+ @#{attribute} = value # 5. @name = value
44
+ end # 6. end
45
+ RUBY
46
+
47
+ module_eval rb_src, __FILE__, __LINE__
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ # Okay, because this library currently does not depend on
54
+ # <tt>ActiveSupport</tt> or anything similar an "independent" camelizing process is
55
+ # required. So it works pretty easy.
56
+ #
57
+ # If <tt>value.to_s</tt> responds to <tt>:camelize</tt>, then call it else use implementation
58
+ # taken from http://github.com/rails/rails/blob/master/activesupport/lib/active_support/inflector/methods.rb#L25
59
+ def camelize_value(value)
60
+ value = value.to_s
61
+ value.respond_to?(:camelize) ? value.camelize : value.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
62
+ end
63
+ module_function :camelize_value
64
+ end
65
+
66
+ # load standard normalizations
67
+ Dir[File.dirname(__FILE__) + "/normalizations/*.rb"].sort.each do |path|
68
+ require "vacuum_cleaner/normalizations/#{File.basename(path)}"
69
+ end
@@ -0,0 +1,48 @@
1
+ module VacuumCleaner
2
+ module Normalizations
3
+
4
+ # Generic method based normalizer which just calls supplied method
5
+ # on value (unless nil).
6
+ #
7
+ # normalizes :name, :method => :titelize
8
+ #
9
+ # Custom instances accept a <tt>:method</tt> option.
10
+ #
11
+ # MethodNormalizer.new(:method => :titelize)
12
+ #
13
+ # Subclasses of the +MethodNormalizer+ can take advantage of it's
14
+ # +normalize_if_respond_to+ method, to easily create custom
15
+ # normalizers based on methods availble on the result value.
16
+ class MethodNormalizer < Normalizer
17
+ # Ensure access to default normalization method
18
+ alias_method :default_normalize_value, :normalize_value
19
+
20
+ # Helper method to "bake" a method normalizer from a method, enabling us to do stuff like.
21
+ #
22
+ # TitelizeNormalizer = MethodNormalizer.build(:titleize)
23
+ #
24
+ def self.build(sym)
25
+ module_eval "Class.new(MethodNormalizer) do; def initialize(*args); super({ :method => #{sym.inspect}}) end; end", __FILE__, __LINE__
26
+ end
27
+
28
+ # Accept either a hash or symbol name.
29
+ def initialize(args = {})
30
+ args = { :method => args } unless args.is_a?(Hash)
31
+ super(args)
32
+ end
33
+
34
+ # Normalize value by calling the default normalizer (strip + nil if empty)
35
+ # and then if not <tt>nil</tt> call the method defined.
36
+ def normalize_value(value)
37
+ sym = options[:method]
38
+ value.respond_to?(sym) ? value.send(sym) : value
39
+ end
40
+ end
41
+
42
+ # Downcase value unless nil or empty.
43
+ DowncaseNormalizer = MethodNormalizer.build(:downcase)
44
+
45
+ # Upcases value unless nil or empty.
46
+ UpcaseNormalizer = MethodNormalizer.build(:upcase)
47
+ end
48
+ end
@@ -0,0 +1,15 @@
1
+ module VacuumCleaner
2
+ module Normalizations
3
+ class UrlNormalizer < Normalizer
4
+ def initialize(options = {})
5
+ options = { :scheme => "http://", :unless => %r{\Ahttps?://}i } if options.nil? || options.empty?
6
+ options = { :scheme => options, :unless => %r{\A#{options}}i } unless options.is_a?(Hash)
7
+ super(options)
8
+ end
9
+
10
+ def normalize_value(value)
11
+ value =~ options[:unless] ? value : "#{options[:scheme]}#{value}" unless value.nil?
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,67 @@
1
+ module VacuumCleaner #:nodoc:
2
+
3
+ # A small base class for implementing custom value normalizers.
4
+ # Might seem like a slight overkill, yet makes the library pretty
5
+ # reusable and all. Based on Rails 3 validator stuff.
6
+ #
7
+ #
8
+ # class Person
9
+ # include VacuumCleaner::Normalizations
10
+ # normalizes :name, :titleize => true
11
+ # end
12
+ #
13
+ # class TitleizeNormalizer < VacuumCleaner::Normalizer
14
+ # def normalize_value(value)
15
+ # value.titelize unless value.blank?
16
+ # end
17
+ # end
18
+ #
19
+ # Any class that inherits from +VacuumCleaner::Normalizer+ must implement
20
+ # a method called <tt>normalize_value</tt> which accepts the <tt>value</tt> to normalize. Furthermore
21
+ # the value returned by <tt>normalize</tt> is used as the new value for
22
+ # the attribute.
23
+ #
24
+ # To reuse the behaviour as defined by the default normalizer (strip & empty),
25
+ # just use <tt>super</tt>.
26
+ #
27
+ # class TitleizeNormalizer < VacuumCleaner::Normalizer
28
+ # def normalize_value(value)
29
+ # super(value).try(:titelize)
30
+ # end
31
+ # end
32
+ #
33
+ # If access to the record or attribute being normalized is required the method
34
+ # +normalize+ can be overriden instead.
35
+ #
36
+ # class FancyNormalizer < VacuumCleaner::Normalizer
37
+ # def normalize(object, attribute, value)
38
+ # ...
39
+ # end
40
+ # end
41
+ #
42
+ # This can be used together with the +normalizes+ method (see
43
+ # VacuumCleaner::Normalizers.normalizes for more on this).
44
+ class Normalizer
45
+ attr_reader :options
46
+
47
+ # Accepts an array of options, which will be made available through the +options+ reader.
48
+ def initialize(options = {})
49
+ @options = options
50
+ end
51
+
52
+ # Only override this method if access to the <tt>object</tt> or <tt>attribute</tt> name
53
+ # is required, else override +normalize_value+, makes life much simpler :)
54
+ #
55
+ # Default behaviour just calls <tt>normalize_value(value)</tt>.
56
+ def normalize(object, attribute, value); normalize_value(value) end
57
+
58
+ # Override this method in subclasses to specifiy custom normalization steps and magic.
59
+ #
60
+ # The standard implementation strips the value of trailing/leading whitespace and then
61
+ # either returns that value or +nil+ if it's <tt>empty?</tt>.
62
+ def normalize_value(value)
63
+ value = value.strip if value.respond_to?(:strip)
64
+ value.nil? || (value.respond_to?(:empty?) && value.empty?) ? nil : value
65
+ end
66
+ end
67
+ end
data/rails/init.rb ADDED
@@ -0,0 +1,4 @@
1
+ require 'vacuum_cleaner'
2
+
3
+ ActiveRecord::Base.class_eval { include VacuumCleaner::Normalizations } # all versions of rails
4
+ ActiveModel::Base.class_eval { include VacuumCleaner::Normalizations } if defined?(ActiveModel::Base) # Rails 3+
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+ require 'rr'
5
+
6
+ # require 'normalo'
7
+
8
+ Test::Unit::TestCase.send(:include, RR::Adapters::TestUnit)
9
+
10
+ # Dir[File.dirname(__FILE__) + "/fixtures/*.rb"].each { |fixture| require fixture }
@@ -0,0 +1,33 @@
1
+ require 'test_helper'
2
+ require 'vacuum_cleaner/normalizer'
3
+ require 'vacuum_cleaner/normalizations/method'
4
+
5
+ class VacuumCleaner::Normalizations::MethodTest < Test::Unit::TestCase
6
+ include VacuumCleaner::Normalizations
7
+
8
+ context "MethodNormalizer" do
9
+ should "accept method name as initialization argument" do
10
+ downcaser = MethodNormalizer.new(:downcase)
11
+ assert_equal "elliot\n", downcaser.normalize_value("Elliot\n")
12
+ assert_equal " \t", downcaser.normalize_value(" \t")
13
+ end
14
+
15
+ should "accept hash with :method key as initializer" do
16
+ upcaser = MethodNormalizer.new(:method => :upcase)
17
+ assert_equal "ELLIOT\n", upcaser.normalize_value("Elliot\n")
18
+ assert_equal " \t", upcaser.normalize_value(" \t")
19
+ end
20
+ end
21
+
22
+ context "DowncaseNormalizer#normalize_value" do
23
+ should "downcase input" do
24
+ assert_equal "elliot", DowncaseNormalizer.new.normalize_value("Elliot")
25
+ end
26
+ end
27
+
28
+ context "UpcaseNormalizer#normalize_value" do
29
+ should "upcase input" do
30
+ assert_equal "J.D.", UpcaseNormalizer.new.normalize_value("j.d.")
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,39 @@
1
+ require 'test_helper'
2
+ require 'vacuum_cleaner/normalizer'
3
+ require 'vacuum_cleaner/normalizations/url'
4
+
5
+ class VacuumCleaner::Normalizations::UrlTest < Test::Unit::TestCase
6
+ include VacuumCleaner::Normalizations
7
+
8
+ #
9
+ # normalizes :homepage, :url => true
10
+ # normalizes :ftp, :url => "ftp://"
11
+ # normalizes :uri, :url => { :scheme => "http://", :unless => %r{\A(https?://|ftp://|jabber:)} }
12
+ #
13
+ context "UrlNormalizer#normalize_value" do
14
+ should "ignore <nil>" do
15
+ assert_nil UrlNormalizer.new.normalize_value(nil)
16
+ end
17
+
18
+ should "prefix string with 'http://' if string does not begin with it" do
19
+ assert_equal "http://google.com", UrlNormalizer.new.normalize_value("google.com")
20
+ end
21
+
22
+ should "not prefix string with 'http://' if string already begins with http or https" do
23
+ assert_equal "http://google.com/", UrlNormalizer.new.normalize_value("http://google.com/")
24
+ assert_equal "https://docs.google.com/", UrlNormalizer.new.normalize_value("https://docs.google.com/")
25
+ end
26
+
27
+ should "allow to specify custom scheme, like ftp://" do
28
+ assert_equal "ftp://ftp.sacred-heart.com", UrlNormalizer.new("ftp://").normalize_value("ftp.sacred-heart.com")
29
+ assert_equal "ftp://ftp.sacred-heart.com", UrlNormalizer.new("ftp://").normalize_value("ftp://ftp.sacred-heart.com")
30
+ end
31
+
32
+ should "allow to specify :scheme and custom regex to exclude/allow certain protocols" do
33
+ n = UrlNormalizer.new(:scheme => "http://", :unless => %r{\A(https?://|ftp://|jabber:)})
34
+ assert_equal "http://google.com", n.normalize_value("google.com")
35
+ assert_equal "jabber:jd@sh.com", n.normalize_value("jabber:jd@sh.com")
36
+ assert_equal "https://docs.google.com", n.normalize_value("https://docs.google.com")
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,192 @@
1
+ require 'test_helper'
2
+
3
+ require 'vacuum_cleaner/normalizer'
4
+ require 'vacuum_cleaner/normalizations'
5
+
6
+ class PrefixDoctorNormalizer < VacuumCleaner::Normalizer
7
+ def normalize_value(value)
8
+ "Dr. #{value}"
9
+ end
10
+ end
11
+
12
+ class Person
13
+ include VacuumCleaner::Normalizations
14
+
15
+ attr_accessor :last_name, :first_name
16
+
17
+ normalizes :last_name
18
+ normalizes :first_name
19
+ end
20
+
21
+ class Doctor
22
+ include VacuumCleaner::Normalizations
23
+ attr_accessor :name
24
+
25
+ class GirlifyNormalizer < VacuumCleaner::Normalizer
26
+ def normalize_value(value)
27
+ value == "J.D." ? "Maria" : value
28
+ end
29
+ end
30
+
31
+ normalizes :name, :girlify => true
32
+ end
33
+
34
+ class VacuumCleaner::NormalizationsTest < Test::Unit::TestCase
35
+ context "VacuumCleaner::Normalizations" do
36
+ context "ClassMethods#normalizes" do
37
+ should "throw ArgumentError if no attributes are passed in" do
38
+ assert_raise ArgumentError do
39
+ klass = Class.new do
40
+ include VacuumCleaner::Normalizations
41
+ normalizes
42
+ end
43
+ end
44
+ end
45
+
46
+ should "take a symbol as argument" do
47
+ assert_respond_to Class.new { include VacuumCleaner::Normalizations; normalizes(:name) }, :normalizes
48
+ end
49
+
50
+ should "take multiple symbols as argument" do
51
+ klass = Class.new { include VacuumCleaner::Normalizations; normalizes(:name, :first_name) }
52
+ assert_respond_to klass, :normalizes
53
+ #assert_respond_to klass, :normalize_name
54
+ #assert_respond_to klass, :normalize_first_name
55
+ end
56
+
57
+ should "create a setter for supplied attribute" do
58
+ obj = Class.new { include VacuumCleaner::Normalizations; normalizes(:name) }.new
59
+ assert_respond_to obj, :name=
60
+ end
61
+
62
+ should "set the instance variable using the setter" do
63
+ obj = Class.new { include VacuumCleaner::Normalizations; normalizes(:name) }.new
64
+ obj.name = "J.D."
65
+ assert_equal "J.D.", obj.instance_variable_get(:@name)
66
+ end
67
+
68
+ should "alias method to <attr>_without_normalization= if <attr>= already defined" do
69
+ klass = Class.new do
70
+ include VacuumCleaner::Normalizations
71
+ def name=(name); @foo = name end
72
+ normalizes :name
73
+ end
74
+ obj = klass.new
75
+ obj.name = "Elliot Reid"
76
+ assert_respond_to obj, :name_without_normalization=
77
+ assert_equal "Elliot Reid", obj.instance_variable_get(:@foo)
78
+ assert_nil obj.instance_variable_get(:@name)
79
+ end
80
+
81
+ should "convert any blank input, like empty string, nil etc. to => <nil>" do
82
+ obj = Person.new
83
+ obj.first_name = " "
84
+ obj.last_name = ''
85
+ assert_nil obj.first_name
86
+ assert_nil obj.last_name
87
+ end
88
+
89
+ should "strip leading and trailing white-space" do
90
+ obj = Person.new
91
+ obj.first_name = "\nElliot\t "
92
+ obj.last_name = nil
93
+ assert_nil obj.last_name
94
+ assert_equal "Elliot", obj.first_name
95
+ end
96
+
97
+ should "accept a block which overrides the default to_nil_if_empty strategy" do
98
+ klass = Class.new do
99
+ include VacuumCleaner::Normalizations
100
+ attr_accessor :name
101
+ normalizes :name do |value|
102
+ value ? value.upcase : value
103
+ end
104
+ end
105
+ obj = klass.new
106
+ obj.name = "Turk"
107
+ assert_equal "TURK", obj.name
108
+ end
109
+
110
+ should "accept custom options hash to define other normalizers to run" do
111
+ klass = Class.new do
112
+ include VacuumCleaner::Normalizations
113
+ attr_accessor :email
114
+ normalizes :email, :downcase => true
115
+ end
116
+ obj = klass.new
117
+ obj.email = "\nJ.D.Dorian@Sacred-Heart.com "
118
+ assert_equal "j.d.dorian@sacred-heart.com", obj.email
119
+ end
120
+
121
+ should "raise ArgumentError if invalid/unknown normalizer is called" do
122
+ assert_raise ArgumentError do
123
+ Class.new do
124
+ include VacuumCleaner::Normalizations
125
+ normalizes :foo, :invalid_unknown_normalizer => true
126
+ end
127
+ end
128
+ end
129
+
130
+ should "ignore default split/empty? normalizer if :default => false" do
131
+ klass = Class.new do
132
+ include VacuumCleaner::Normalizations
133
+ attr_accessor :name
134
+ normalizes :name, :default => false, :upcase => true
135
+ end
136
+ obj = klass.new
137
+ obj.name = "Dr. Dorian\n\t"
138
+ assert_equal "DR. DORIAN\n\t", obj.name
139
+ end
140
+
141
+ should "be able to use normalizers from the global namespace" do
142
+ klass = Class.new do
143
+ include VacuumCleaner::Normalizations
144
+ attr_accessor :name
145
+ normalizes :name, :prefix_doctor => true
146
+ end
147
+ obj = klass.new
148
+ obj.name = "Elliot Reid"
149
+ assert_equal "Dr. Elliot Reid", obj.name
150
+ end
151
+
152
+ should "be able to use normalizers from within the class itself" do
153
+ obj = Doctor.new
154
+ obj.name = "Elliot Reid"
155
+ assert_equal "Elliot Reid", obj.name
156
+ obj = Doctor.new
157
+ obj.name = "J.D."
158
+ assert_equal "Maria", obj.name
159
+ end
160
+
161
+ should "be able to combine normalizers and custom blocks" do
162
+ klass = Class.new do
163
+ include VacuumCleaner::Normalizations
164
+ attr_accessor :name, :first_name
165
+ normalizes(:name, :first_name, :downcase => true) do |value|
166
+ value.nil? ? value : "#{value.to_s[0,1].upcase}#{value.to_s[1..-1]}"
167
+ end
168
+ end
169
+
170
+ obj = klass.new
171
+ obj.name = "REID"
172
+ obj.first_name = "ELLIOT"
173
+ assert_equal "Reid", obj.name
174
+ assert_equal "Elliot", obj.first_name
175
+ end
176
+
177
+ should "provide block with all values if asking for them!" do
178
+ klass = Class.new do
179
+ include VacuumCleaner::Normalizations
180
+ attr_accessor :name
181
+ normalizes(:name) do |object, attribute, value|
182
+ [object.object_id, attribute, value]
183
+ end
184
+ end
185
+
186
+ obj = klass.new
187
+ obj.name = "Carla"
188
+ assert_equal [obj.object_id, :name, "Carla"], obj.name
189
+ end
190
+ end
191
+ end
192
+ end
@@ -0,0 +1,47 @@
1
+ require 'test_helper'
2
+ require 'vacuum_cleaner/normalizer'
3
+
4
+ class VacuumCleaner::NormalizerTest < Test::Unit::TestCase
5
+ context "VacuumCleaner::Normalizer" do
6
+ should "take an optional hash as argument during #initialize and expose that hash when calling #options" do
7
+ expected = { :doctor => "Dr. Dorian", :nurse => "Carla" }
8
+ normalizer = VacuumCleaner::Normalizer.new({ :doctor => "Dr. Dorian", :nurse => "Carla" })
9
+ assert_equal "Dr. Dorian", normalizer.options[:doctor]
10
+ assert_equal expected, normalizer.options
11
+ end
12
+
13
+ context "#normalize_value" do
14
+ should "leave <nil>" do
15
+ assert_nil VacuumCleaner::Normalizer.new.normalize_value(nil)
16
+ end
17
+
18
+ should "convert empty string to <nil>" do
19
+ assert_nil VacuumCleaner::Normalizer.new.normalize_value('')
20
+ end
21
+
22
+ should "convert string with only space characters to <nil>" do
23
+ assert_nil VacuumCleaner::Normalizer.new.normalize_value(" ")
24
+ assert_nil VacuumCleaner::Normalizer.new.normalize_value(" \n\t ")
25
+ end
26
+
27
+ should "strip leading and trailing whitespace" do
28
+ assert_equal "Dr. Reid", VacuumCleaner::Normalizer.new.normalize_value(" \nDr. Reid\t ")
29
+ assert_equal "Dr. Dorian", VacuumCleaner::Normalizer.new.normalize_value("Dr. Dorian\t \r")
30
+ end
31
+ end
32
+
33
+ context "#normalize" do
34
+ should "return always the same as #normalize_value and ignore object and attribute parameters" do
35
+ normalizer = VacuumCleaner::Normalizer.new
36
+ object = Object.new
37
+ attribute = :name
38
+
39
+ [["Dr. Reid", "\t Dr. Reid"], ["Dr. Dorian", "Dr. Dorian\n "], [nil, nil], [nil, "\n "], [nil, ""]].each do |tests|
40
+ expected, value = *tests
41
+ assert_equal expected, normalizer.normalize_value(value)
42
+ assert_equal expected, normalizer.normalize(object, attribute, value)
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,69 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{vacuum_cleaner}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Lukas Westermann"]
12
+ s.date = %q{2010-02-24}
13
+ s.description = %q{** Swoooosh ** - and all those leading and trailing whitespaces are gone, or ** Frooom ** - and the value
14
+ is normalized to always be prefixed by 'http://' and much more. Works with both plain old Ruby, and Rails (ActiveModel
15
+ and ActiveSupport).}
16
+ s.email = %q{lukas.westermann@gmail.com}
17
+ s.extra_rdoc_files = [
18
+ "README.md"
19
+ ]
20
+ s.files = [
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.md",
24
+ "Rakefile",
25
+ "init.rb",
26
+ "lib/vacuum_cleaner.rb",
27
+ "lib/vacuum_cleaner/normalizations.rb",
28
+ "lib/vacuum_cleaner/normalizations/method.rb",
29
+ "lib/vacuum_cleaner/normalizations/url.rb",
30
+ "lib/vacuum_cleaner/normalizer.rb",
31
+ "rails/init.rb",
32
+ "test/test_helper.rb",
33
+ "test/unit/vacuum_cleaner/normalizations/method_test.rb",
34
+ "test/unit/vacuum_cleaner/normalizations/url_test.rb",
35
+ "test/unit/vacuum_cleaner/normalizations_test.rb",
36
+ "test/unit/vacuum_cleaner/normalizer_test.rb",
37
+ "vacuum_cleaner.gemspec"
38
+ ]
39
+ s.homepage = %q{http://github.com/lwe/vacuum_cleaner}
40
+ s.licenses = ["LICENSE"]
41
+ s.rdoc_options = ["--charset=UTF-8"]
42
+ s.require_paths = ["lib"]
43
+ s.rubygems_version = %q{1.3.6}
44
+ s.summary = %q{Ruby (and Rails) attribute cleaning support, provides some nice default normalization strategies.}
45
+ s.test_files = [
46
+ "test/test_helper.rb",
47
+ "test/unit/vacuum_cleaner/normalizations/method_test.rb",
48
+ "test/unit/vacuum_cleaner/normalizations/url_test.rb",
49
+ "test/unit/vacuum_cleaner/normalizations_test.rb",
50
+ "test/unit/vacuum_cleaner/normalizer_test.rb"
51
+ ]
52
+
53
+ if s.respond_to? :specification_version then
54
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
55
+ s.specification_version = 3
56
+
57
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
58
+ s.add_development_dependency(%q<shoulda>, [">= 2.10.2"])
59
+ s.add_development_dependency(%q<rr>, [">= 0.10.5"])
60
+ else
61
+ s.add_dependency(%q<shoulda>, [">= 2.10.2"])
62
+ s.add_dependency(%q<rr>, [">= 0.10.5"])
63
+ end
64
+ else
65
+ s.add_dependency(%q<shoulda>, [">= 2.10.2"])
66
+ s.add_dependency(%q<rr>, [">= 0.10.5"])
67
+ end
68
+ end
69
+
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vacuum_cleaner
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Lukas Westermann
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-02-24 00:00:00 +01:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: shoulda
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 2
29
+ - 10
30
+ - 2
31
+ version: 2.10.2
32
+ type: :development
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: rr
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ - 10
44
+ - 5
45
+ version: 0.10.5
46
+ type: :development
47
+ version_requirements: *id002
48
+ description: |-
49
+ ** Swoooosh ** - and all those leading and trailing whitespaces are gone, or ** Frooom ** - and the value
50
+ is normalized to always be prefixed by 'http://' and much more. Works with both plain old Ruby, and Rails (ActiveModel
51
+ and ActiveSupport).
52
+ email: lukas.westermann@gmail.com
53
+ executables: []
54
+
55
+ extensions: []
56
+
57
+ extra_rdoc_files:
58
+ - README.md
59
+ files:
60
+ - .gitignore
61
+ - LICENSE
62
+ - README.md
63
+ - Rakefile
64
+ - init.rb
65
+ - lib/vacuum_cleaner.rb
66
+ - lib/vacuum_cleaner/normalizations.rb
67
+ - lib/vacuum_cleaner/normalizations/method.rb
68
+ - lib/vacuum_cleaner/normalizations/url.rb
69
+ - lib/vacuum_cleaner/normalizer.rb
70
+ - rails/init.rb
71
+ - test/test_helper.rb
72
+ - test/unit/vacuum_cleaner/normalizations/method_test.rb
73
+ - test/unit/vacuum_cleaner/normalizations/url_test.rb
74
+ - test/unit/vacuum_cleaner/normalizations_test.rb
75
+ - test/unit/vacuum_cleaner/normalizer_test.rb
76
+ - vacuum_cleaner.gemspec
77
+ has_rdoc: true
78
+ homepage: http://github.com/lwe/vacuum_cleaner
79
+ licenses:
80
+ - LICENSE
81
+ post_install_message:
82
+ rdoc_options:
83
+ - --charset=UTF-8
84
+ require_paths:
85
+ - lib
86
+ required_ruby_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ segments:
91
+ - 0
92
+ version: "0"
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ segments:
98
+ - 0
99
+ version: "0"
100
+ requirements: []
101
+
102
+ rubyforge_project:
103
+ rubygems_version: 1.3.6
104
+ signing_key:
105
+ specification_version: 3
106
+ summary: Ruby (and Rails) attribute cleaning support, provides some nice default normalization strategies.
107
+ test_files:
108
+ - test/test_helper.rb
109
+ - test/unit/vacuum_cleaner/normalizations/method_test.rb
110
+ - test/unit/vacuum_cleaner/normalizations/url_test.rb
111
+ - test/unit/vacuum_cleaner/normalizations_test.rb
112
+ - test/unit/vacuum_cleaner/normalizer_test.rb