normatron 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.
@@ -1,29 +1,28 @@
1
1
  h1. Normatron
2
2
 
3
- Normatron is an attribute normalizer for ActiveRecord objects.
4
- With it you can convert attributes to the desired format before saving them in the database.
3
+ Normatron is an Ruby On Rails plugin that perform attribute normalizations for ActiveRecord objects.
4
+ With it you can normalize attributes to the desired format before saving them in the database.
5
5
  This gem inhibits the work of having to override attributes or create a specific method to perform most of the normalizations.
6
6
 
7
7
  h2. Installation
8
8
 
9
9
  Let the bundler install the gem by adding the following into your application gemfile:
10
10
 
11
- <pre>gem 'normatron'</pre>
11
+ pre. gem 'normatron'
12
12
 
13
13
  And then bundle it up:
14
14
 
15
- <pre>$ bundle install</pre>
15
+ pre. $ bundle install
16
16
 
17
17
  Or install it by yourself:
18
18
 
19
- <pre>$ gem install normatron</pre>
19
+ pre. $ gem install normatron
20
20
 
21
21
  h2. The problem
22
22
 
23
23
  Suppose you have a product model as the following:
24
24
 
25
- <pre>
26
- # ./db/migrate/20120101010000_create_products.rb
25
+ pre. # ./db/migrate/20120101010000_create_products.rb
27
26
  class CreateProducts < ActiveRecord::Migration
28
27
  def change
29
28
  create_table :products do |t|
@@ -33,88 +32,63 @@ class CreateProducts < ActiveRecord::Migration
33
32
  end
34
33
  end
35
34
 
36
- # ./app/models/products.rb
35
+ pre. # ./app/models/products.rb
37
36
  class Product < ActiveRecord::Base
38
37
  attr_accessible :name, :price
39
38
  end
40
- </pre>
41
39
 
42
40
  And we want the _name_ attribute be uppercased before saving it into the database.
43
41
  The most usual approach to do this includes:
44
42
 
45
43
  * Override the _name_ setter and convert the value to an uppercased string.
46
- * Use the _before_validation_ callback to run a method or block doing the task.
44
+ * Use the "_before_validation_":http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html callback to run a method or block doing the task.
47
45
 
48
46
  Both ways are ilenegant, boring, error prone and very expensive.
49
- What led me to make this gem and offer a third way to solve the problem:
47
+ What led me to make this gem and offer a third way to solve this issue:
50
48
 
51
49
  h2. Usage
52
50
 
53
- Normatron uses ":squish":http://rubydoc.info/gems/normatron/Normatron/Filters#squish-class_method and ":blank":http://rubydoc.info/gems/normatron/Normatron/Filters#blank-class_method as default filters.
54
- These filters are applied to all attributes in *normalize* function, since no options is given.
51
+ Normatron uses "_:squish_":http://rubydoc.info/gems/normatron/Normatron/Filters#squish-class_method and "_:blank_":http://rubydoc.info/gems/normatron/Normatron/Filters#blank-class_method as default filters.
52
+ These filters are applied to all attributes in @normalize@ function, since no options is given.
55
53
 
56
- <pre>
57
- # ./app/models/products.rb
54
+ pre. # ./app/models/products.rb
58
55
  class Product < ActiveRecord::Base
59
56
  attr_accessible :name, :price
60
57
  normalize :name
61
58
  end
62
59
 
63
- $ rails console
64
- > p1 = Product.create name: " memory card "
65
- > p1
60
+ pre. $ rails console
61
+ > p1 = Product.create name: " memory card "
66
62
  => #<Product id: nil, name: "memory card", price: nil>
67
- > p2 = Product.create name: " "
68
- > p2
63
+ > p2 = Product.create name: " "
69
64
  => #<Product id: nil, name: nil, price: nil>
70
- </pre>
71
65
 
72
66
  h3. The _normalize_attributes_ method
73
67
 
74
- All filters are automatically applied in the "before_validation":http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html callback.
75
- So, the changes occur when you call any method that validates the model.
68
+ Methods like "create":http://api.rubyonrails.org/classes/ActiveRecord/Persistence/ClassMethods.html#method-i-create, "valid?":http://api.rubyonrails.org/classes/ActiveRecord/Validations.html#method-i-valid-3F or "save":http://api.rubyonrails.org/classes/ActiveRecord/Validations.html#method-i-valid-3F always call the _normalize_attributes_ method, thought "before_validation":http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html callback.
69
+ This is the method that invokes all filters to their attributes. So you can perform the normalizations without necessarily having to perform the model validations.
76
70
 
77
- <pre>
78
- $ rails console
79
- > p = Product.create name: " "
80
- > p.name
81
- => nil
82
- > p = Product.new name: " keyboard \n "
83
- > p.valid?
84
- > p.name
85
- => "keyboard"
86
- > p = Product.new name: "\n\nblu ray\n\n"
87
- > p.save
88
- > p.name
89
- => "blu ray"
90
- </pre>
91
-
92
- We can call the *normalize_attributes* method to perform the normalization without do the validations.
93
-
94
- <pre>
95
- > p = Product.new name: " hard drive"
96
- > p.normalize_attributes
97
- > p.name
98
- => "hard drive"
99
- </pre>
71
+ pre. $ rails console
72
+ > p = Product.new name: " hard drive"
73
+ => #<Product id: nil, name: " hard drive", price: nil>
74
+ > p.normalize_attributes
75
+ > p
76
+ => #<Product id: nil, name: "hard drive", price: nil>
100
77
 
101
78
  h3. The _normalize_options_ method
102
79
 
103
- To read the normalization filters set for a model, just call the *normalize_options* method.
80
+ To read the normalization filters set for a model, just call the @normalize_options@ method.
104
81
 
105
- <pre>
106
- $ rails console
107
- > Product.normalize_options
82
+ pre. $ rails console
83
+ > Product.normalize_options
108
84
  => { name: { :squish => [], :blank => [] } }
109
- </pre>
110
85
 
111
- This method returns a Hash, where the keys are the attribute names and values ​​are another Hash with filter options.
112
- In Hash with filter options, keys represent the filter names and the values ​​are Arrays with the arguments that are passed to the methods of filtering.
113
- The following example is a data structure returned by the _normalize_options_ method.
86
+ This method returns a Hash, where the keys are the attribute names and values are another Hash with filter options.
87
+ In the filter options Hash, keys represent the filter names and the values are Arrays containing arguments to be passed to filter methods.
88
+ The following example is a data structure returned by the @normalize_options@ method:
114
89
 
115
- <pre>
116
- $ rails console
117
- > MyModel.normalize_options
90
+ pre. $ rails console
91
+ > MyModel.normalize_options
118
92
  => { :attribute_a => { :filter_a => [] },
119
93
  :attribute_b => { :filter_a => [],
120
94
  :filter_b => [arg_a, arg_b] },
@@ -124,76 +98,65 @@ $ rails console
124
98
  :attribute_d => { :filter_a => [],
125
99
  :filter_c => [arg],
126
100
  :filter_d => [arg_a, arg_b, arg_c, arg_d] } }
127
- </pre>
128
101
 
129
102
  h3. The _:with_ option
130
103
 
131
- The _:with_ option allows to bind filters to one attribute or more.
104
+ The @:with@ option allows to bind filters to one or more attribute.
132
105
 
133
- <pre>
134
- class Product < ActiveRecord::Base
106
+ pre. class Product < ActiveRecord::Base
135
107
  normalize :name, :with => :upcase
136
108
  end
137
109
 
138
- $ rails console
139
- > Product.normalize_options
110
+ pre. $ rails console
111
+ > Product.normalize_options
140
112
  => { :name => { :upcase => [] } }
141
- </pre>
142
113
 
143
- The filters passed throught _:with_ option will not stack with default filters.
144
- When _normalize_ method is used multiple times for the same attribute, it will stack the filter bindings.
114
+ The filters passed throught @:with@ option will not stack with default filters.
115
+ When @normalize@ method is used multiple times for the same attribute, it will stack the filter bindings.
145
116
 
146
- <pre>
147
- class Product < ActiveRecord::Base
117
+ pre. class Product < ActiveRecord::Base
148
118
  normalize :name
149
119
  normalize :name, :with => :upcase
150
120
  end
151
121
 
152
- $ rails console
153
- > Product.normalize_options
122
+ pre. $ rails console
123
+ > Product.normalize_options
154
124
  => { :name => { :squish => [],
155
125
  :blank => [],
156
126
  :upcase => [] } }
157
- </pre>
158
127
 
159
128
  The same result can be obtained using:
160
129
 
161
- <pre>normalize :name, :with => [:squish, :blank, :upcase]</pre>
130
+ pre. normalize :name, :with => [:squish, :blank, :upcase]
162
131
 
163
132
  Some filters may use arguments to perferm normalizations.
164
133
  There are two approaches to deal with filter arguments in Normatron:
165
134
 
166
- a) Using a Hash where the key is the filter name and the value is the filter arguments as an Array.
135
+ a) Using a Hash where the key is the filter name and the value is an arguments Array.
167
136
 
168
- <pre>
169
- class Product < ActiveRecord::Base
137
+ pre. class Product < ActiveRecord::Base
170
138
  normalize :name, :with => [ { :keep => [:Latin], :remove => [:Nd, :Zs] } ]
171
139
  normalize :description, :with => :squeeze
172
140
  normalize :brand, :with => [ { :squeeze => ["a-z"] }, { :keep => [:Word] } ]
173
141
  end
174
- </pre>
175
142
 
176
143
  b) Using an Array where the first element if the attribute name and rest is the filter arguments.
177
144
 
178
- <pre>
179
- class Product < ActiveRecord::Base
145
+ pre. class Product < ActiveRecord::Base
180
146
  normalize :name, :with => [ [:keep, :Latin], [:remove, :Nd, :Zs] ]
181
147
  normalize :description, :with => :squeeze
182
148
  normalize :brand, :with => [ [:squeeze, "a-z"], [:keep, :Word] ]
183
149
  end
184
- </pre>
185
150
 
186
151
  Both ways will produce the same result:
187
152
 
188
- <pre>
189
- $ rails console
190
- > Product.normalize_options
153
+ pre. $ rails console
154
+ > Product.normalize_options
191
155
  => { :name => { :keep => [:Latin],
192
156
  :remove => [:Nd, :Zs] },
193
157
  :description => { :squeeze => [] },
194
158
  :brand => { :squeeze => ["a-z"],
195
159
  :keep => [:Word] } }
196
- </pre>
197
160
 
198
161
  h3. Using instance method as filter
199
162
 
@@ -204,7 +167,8 @@ If you need to use aditional arguments or varargs, just add them after the first
204
167
  <pre>
205
168
  # ./app/models/client.rb
206
169
  class Client < ActiveRecord::Base
207
- normalize :phone, :with => [:custom_a, [:custom_b, :a, :b], { :custom_c => [:a, :b, :c] }]
170
+ normalize :phone, :with => [:custom_a, [:custom_b, :a, :b], {:custom_c => [:a, :b, :c]}]
171
+ normalize :mobile, :with => [:custom_a, {:custom_b => [:a, :b]}, [:custom_c, :a, :b, :c]]
208
172
 
209
173
  def custom_a(value)
210
174
  # ...
@@ -222,18 +186,21 @@ end
222
186
 
223
187
  h2. Filters
224
188
 
225
- Information about native filters and how to use them can be found in:
226
-
227
- * "Normatron::Filters Rubydoc (Normatron::Filters Rubydoc)":http://rubydoc.info/gems/normatron/Normatron/Filters
228
- * "Normatron::Filters Source (Normatron::Filters Source)":https://github.com/fernandors87/normatron/blob/master/lib/normatron/filters.rb
189
+ Information about native filters and how to use them can be found in "Normatron::Filters(Normatron::Filters Rubydoc)":http://rubydoc.info/gems/normatron/Normatron/Filters. All methods have a short description of what they do and some examples of how to use them.
229
190
 
230
191
  h1. Contributing
231
192
 
232
- * Fork it, add your new features or bug fixes, make your tests and commit.
233
- * Report any bug or unexpected behavior.
234
- * Share with your friends, forums, communities, job, etc...
235
- * Send me your feedback.
236
- * Offer me a job or pay me a beer. =]
193
+ There are several ways to make this gem even better:
194
+
195
+ * Forking this project
196
+ * Adding new features or bug fixes
197
+ * Making tests
198
+ * Commiting your changes
199
+ * Reporting any bug or unexpected behavior
200
+ * Suggesting any improvement
201
+ * Sharing with your friends, forums, communities, job, etc...
202
+ * Helping users with difficulty using this gem
203
+ * Paying me a beer =]
237
204
 
238
205
  h1. Credits
239
206
 
@@ -2,7 +2,7 @@ require "normatron/configuration"
2
2
  require "normatron/extensions/active_record"
3
3
 
4
4
  module Normatron
5
- VERSION = "0.2.0"
5
+ VERSION = "0.2.1"
6
6
 
7
7
  class << self
8
8
  def configuration
@@ -20,7 +20,7 @@ module Normatron
20
20
  end
21
21
 
22
22
  def initialize
23
- @default_filters = {squish: [], blank: []}
23
+ @default_filters = { squish: [], blank: [] }
24
24
  end
25
25
 
26
26
  def default_filters
@@ -2,11 +2,14 @@
2
2
 
3
3
  require 'active_support/multibyte/chars'
4
4
  require 'active_support/core_ext/string'
5
+ require 'active_support/inflector/inflections'
5
6
 
6
7
  module Normatron
7
8
  module Filters
9
+ extend self
10
+
8
11
  ##
9
- # Converts a blank string on a nil object.
12
+ # Returns a <tt>Nil</tt> object for a blank string or the string itself otherwise.
10
13
  #
11
14
  # @example
12
15
  # blank("") #=> nil
@@ -16,34 +19,111 @@ module Normatron
16
19
  # blank("It's blank?") #=> "It's blank?"
17
20
  # blank(123) #=> 123
18
21
  #
19
- # # For normalizations
20
- # normalize :attribute, :with => [:custom_filter, :blank]
22
+ # # ActiveRecord normalizer usage
23
+ # normalize :attribute_a, :with => :blank
24
+ # normalize :attribute_b, :with => [:custom_filter, :blank]
21
25
  # @param [String] value A character sequence
22
26
  # @return [String, Nil] The object itself or nil
23
27
  # @see http://api.rubyonrails.org/classes/String.html#method-i-blank-3F String#blank?
24
- def self.blank(value)
28
+ def blank(value)
25
29
  return value unless string?(value) && value.to_s.blank?
26
30
  nil
27
31
  end
28
32
 
29
33
  ##
30
- # Converts the first character to uppercase and others to lowercase.
34
+ # Converts strings to UpperCamelCase.
35
+ # If the argument to camelize is set to <tt>:lower</tt> then camelize produces lowerCamelCase.
36
+ # camelize will also convert <tt>'/'</tt> to <tt>'::'</tt> which is useful for converting paths to namespaces.
37
+ #
38
+ # @example
39
+ # camelize("active_record/errors") #=> "ActiveRecord::Errors"
40
+ # camelize("active_record/errors", :upper) #=> "ActiveRecord::Errors"
41
+ # camelize("active_record/errors", :lower) #=> "activeRecord::Errors"
42
+ # camelize(123) #=> 123
43
+ #
44
+ # # ActiveRecord normalizer usage
45
+ # normalize :attribute_a, :with => :camelize
46
+ # normalize :attribute_b, :with => [:custom_filter, :camelize]
47
+ # normalize :attribute_c, :with => [[:camelize, :lower]]
48
+ # normalize :attribute_d, :with => [{:camelize => :lower}]
49
+ # normalize :attribute_e, :with => [:custom_filter, [:camelize, :lower]]
50
+ # normalize :attribute_f, :with => [:custom_filter, {:camelize => :lower}]
51
+ # @param [String] value A character sequence
52
+ # @param [Symbol] first_letter_case <tt>:lower</tt> for lowerCamelCase or <tt>:upper</tt> for UpperCamelCase
53
+ # @return [String, Object] The camelized String or the object itself
54
+ def camelize(value, first_letter_case = :upper)
55
+ case value
56
+ when String
57
+ string = value
58
+ when ActiveSupport::Multibyte::Chars
59
+ string = value.to_s
60
+ else
61
+ return value
62
+ end
63
+
64
+ inflections = ActiveSupport::Inflector::Inflections.instance
65
+ if first_letter_case == :upper
66
+ string = string.sub(/^[\p{L}\d]*/u) { inflections.acronyms[$&] || capitalize($&) }
67
+ elsif first_letter_case == :lower
68
+ string = string.sub(/^(?:#{inflections.acronym_regex}(?=\b|[\p{L}_])|\p{Word}*_)/u) { downcase($&) }
69
+ else
70
+ raise "Use options :upper or :lower for Normatron::Filters#camelize"
71
+ end
72
+ string.gsub!(/(?:_|(\/))([\p{L}\d]*)/iu) { "#{$1}#{inflections.acronyms[$2] || capitalize($2)}" }.gsub!('/', '::')
73
+
74
+ (value.is_a?(String) && string) || string.mb_chars
75
+ end
76
+
77
+ ##
78
+ # Makes the first character uppercase and lowercase others.
31
79
  #
32
80
  # @example
33
- # capitalize("walter white") #=> "Walter white"
81
+ # capitalize("jESSE PINK") #=> "Jesse pink"
34
82
  # capitalize("wALTER WHITE") #=> "Walter white"
83
+ # capitalize(" mr. Fring") #=> " mr. fring"
35
84
  # capitalize(123) #=> 123
36
85
  #
37
- # # For normalizations
38
- # normalize :attribute, :with => [:custom_filter, :capitalize]
86
+ # # ActiveRecord normalizer usage
87
+ # normalize :attribute_a, :with => :capitalize
88
+ # normalize :attribute_b, :with => [:custom_filter, :capitalize]
39
89
  # @param [String] value A character sequence
40
90
  # @return [String, Object] The capitalized String or the object itself
41
91
  # @see http://www.ruby-doc.org/core-1.9.3/String.html#method-i-capitalize String#capitalize
42
92
  # @see http://api.rubyonrails.org/classes/ActiveSupport/Multibyte/Chars.html#method-i-capitalize ActiveSupport::Multibyte::Chars#capitalize
43
- def self.capitalize(value)
93
+ def capitalize(value)
44
94
  (string?(value) && eval_send(:capitalize, value)) || value
45
95
  end
46
96
 
97
+ ##
98
+ # Remove the given record separator from the end of the string (If present).
99
+ # If <tt>$/</tt> has not been changed from the default Ruby record separator,
100
+ # then chomp also removes carriage return characters (that is it will remove <tt>\n</tt>, <tt>\r</tt>, and <tt>\r\n</tt>).
101
+ #
102
+ # @example
103
+ # chomp("Bon \n Scott\n") #=> "Bon \n Scott"
104
+ # chomp("Bon \n Scott\r") #=> "Bon \n Scott"
105
+ # chomp("Bon \n Scott\r\n") #=> "Bon \n Scott"
106
+ # chomp("Bon \n Scott\n\r") #=> "Bon \n Scott\n"
107
+ # chomp("Bon \n Scott", "t") #=> "Bon \n Scot"
108
+ # chomp("Bon \n Scott", "Scott") #=> "Bon \n "
109
+ # chomp("Bon \n Scott", " \n Scott") #=> "Bon"
110
+ # chomp(100) #=> 100
111
+ #
112
+ # # ActiveRecord normalizer usage
113
+ # normalize :attribute_a, :with => :chomp
114
+ # normalize :attribute_b, :with => [:custom_filter, :chomp]
115
+ # normalize :attribute_c, :with => [[:chomp, "x"]]
116
+ # normalize :attribute_d, :with => [{:chomp => "y"}]
117
+ # normalize :attribute_e, :with => [:custom_filter, [:chomp, "z"]]
118
+ # normalize :attribute_f, :with => [:custom_filter, {:chomp => "\t"}]
119
+ # @param [String] value A character sequence
120
+ # @param [String] separator A character sequence
121
+ # @return [String, Object] The chopped String or the object itself
122
+ # @see http://www.ruby-doc.org/core-1.9.3/String.html#method-i-chomp String#chomp
123
+ def chomp(value, separator=$/)
124
+ (string?(value) && eval_send(:chomp, value, separator)) || value
125
+ end
126
+
47
127
  ##
48
128
  # Replaces all underscores with dashes.
49
129
  #
@@ -52,32 +132,55 @@ module Normatron
52
132
  # dasherize("_.·-'*'-·._") #=> "-.·-'*'-·.-"
53
133
  # dasherize(123) #=> 123
54
134
  #
55
- # # For normalizations
56
- # normalize :attribute, :with => [:custom_filter, :dasherize]
135
+ # # ActiveRecord normalizer usage
136
+ # normalize :attribute_a, :with => :dasherize
137
+ # normalize :attribute_b, :with => [:custom_filter, :dasherize]
57
138
  # @param [String] value A character sequence
58
139
  # @return [String, Object] The dasherized String or the object itself
59
140
  # @see http://api.rubyonrails.org/classes/String.html#method-i-dasherize String#dasherize
60
- def self.dasherize(value)
141
+ def dasherize(value)
61
142
  (string?(value) && eval_send(:dasherize, value)) || value
62
143
  end
63
144
 
64
145
  ##
65
- # Converts all characters to lowercase.
146
+ # Lowercase all characters.
66
147
  #
67
148
  # @example
68
149
  # downcase("VEGETA!!!") #=> "vegeta!!!"
69
150
  # downcase(123) #=> 123
70
151
  #
71
- # # For normalizations
72
- # normalize :attribute, :with => [:custom_filter, :downcase]
152
+ # # ActiveRecord normalizer usage
153
+ # normalize :attribute_a, :with => :downcase
154
+ # normalize :attribute_b, :with => [:custom_filter, :downcase]
73
155
  # @param [String] value A character sequence
74
156
  # @return [String, Object] The lowercased String or the object itself
75
157
  # @see http://www.ruby-doc.org/core-1.9.3/String.html#method-i-downcase String#downcase
76
158
  # @see http://api.rubyonrails.org/classes/ActiveSupport/Multibyte/Chars.html#method-i-downcase ActiveSupport::Multibyte::Chars#downcase
77
- def self.downcase(value)
159
+ def downcase(value)
78
160
  (string?(value) && eval_send(:downcase, value)) || value
79
161
  end
80
162
 
163
+ ##
164
+ # Creates a literal string representation with all nonprinting characters
165
+ # replaced by <tt>\\n</tt> notation and all special characters escaped.
166
+ #
167
+ # @example
168
+ # dump("I'm not\na \"clubber\"...") #=> "\"I'm not\\na \\\"clubber\\\"...\""
169
+ # dump("I'm not\na \"clubber\"...") #== '"I\'m not\na \"clubber\"..."'
170
+ # dump('I\'m not\na "clubber"...') #=> "\"I'm not\\\\na \\\"clubber\\\"...\""
171
+ # dump('I\'m not\na "clubber"...') #== '"I\'m not\\\na \"clubber\"..."'
172
+ # dump(100) #=> 100
173
+ #
174
+ # # ActiveRecord normalizer usage
175
+ # normalize :attribute_a, :with => :dump
176
+ # normalize :attribute_b, :with => [:custom_filter, :dump]
177
+ # @param [String] value A character sequence
178
+ # @return [String, Object] The dumpped String or the object itself
179
+ # @see http://www.ruby-doc.org/core-1.9.3/String.html#method-i-dump String#dump
180
+ def dump(value)
181
+ (string?(value) && eval_send(:dump, value)) || value
182
+ end
183
+
81
184
  ##
82
185
  # Keep only the specified characters.
83
186
  # Details about the options can be found in the Regexp class documentation.
@@ -97,7 +200,7 @@ module Normatron
97
200
  # @param [[Symbol]*] args Array of Symbols equivalent to Regexp for \\p{} construct.
98
201
  # @return [String, Object] The clean character sequence or the object itself
99
202
  # @see http://www.ruby-doc.org/core-1.9.3/Regexp.html Regexp
100
- def self.keep(value, *args)
203
+ def keep(value, *args)
101
204
  eval_regexp(value, true, args)
102
205
  end
103
206
 
@@ -112,7 +215,7 @@ module Normatron
112
215
  # @param [String] value A character sequence
113
216
  # @return [String, Object] The character sequence without trailing spaces or the object itself
114
217
  # @see http://www.ruby-doc.org/core-1.9.3/String.html#method-i-lstrip String#lstrip
115
- def self.lstrip(value)
218
+ def lstrip(value)
116
219
  (string?(value) && eval_strip(value, true, false)) || value
117
220
  end
118
221
 
@@ -135,7 +238,7 @@ module Normatron
135
238
  # @param [[Symbol]*] args Array of Symbols equivalent to Regexp for \\p{} construct.
136
239
  # @return [String, Object] The clean character sequence or the object itself
137
240
  # @see http://www.ruby-doc.org/core-1.9.3/Regexp.html Regexp
138
- def self.remove(value, *args)
241
+ def remove(value, *args)
139
242
  eval_regexp(value, false, args)
140
243
  end
141
244
 
@@ -150,7 +253,7 @@ module Normatron
150
253
  # @param [String] value A character sequence
151
254
  # @return [String, Object] The character sequence without leading spaces or the object itself
152
255
  # @see http://www.ruby-doc.org/core-1.9.3/String.html#method-i-rstrip String#rstrip
153
- def self.rstrip(value)
256
+ def rstrip(value)
154
257
  (string?(value) && eval_strip(value, false, true)) || value
155
258
  end
156
259
 
@@ -171,7 +274,7 @@ module Normatron
171
274
  # @param [[String]*] args Chars to be affected
172
275
  # @return [String, Object] The clean character sequence or the object itself
173
276
  # @see http://www.ruby-doc.org/core-1.9.3/String.html#method-i-squeeze String#squeeze
174
- def self.squeeze(value, *args)
277
+ def squeeze(value, *args)
175
278
  return value unless string?(value)
176
279
  (args.any? && value.squeeze(args.first)) || value.squeeze
177
280
  end
@@ -188,7 +291,7 @@ module Normatron
188
291
  # @return [String, Object] The clean character sequence or the object itself
189
292
  #
190
293
  # @see http://api.rubyonrails.org/classes/String.html#method-i-squish String#squish
191
- def self.squish(value)
294
+ def squish(value)
192
295
  (string?(value) && value.squish) || value
193
296
  end
194
297
 
@@ -202,10 +305,27 @@ module Normatron
202
305
  # normalize :attribute, :with => [:custom_filter, :strip]
203
306
  # @param [String] value A character sequence
204
307
  # @return [String, Object] The stripped character sequence or the object itself
205
- def self.strip(value)
308
+ def strip(value)
206
309
  (string?(value) && eval_strip(value, true, true)) || value
207
310
  end
208
311
 
312
+ ##
313
+ # Replaces uppercased characters by lowercased and vice versa.
314
+ #
315
+ # @example
316
+ # swapcase("AiNn Kmo éH BOM ser v1d4 l0k4") #=> "aInN kMO Éh bom SER V1D4 L0K4"
317
+ # swapcase(100) #=> 100
318
+ #
319
+ # # ActiveRecord normalizer usage
320
+ # normalize :attribute_a, :with => :swapcase
321
+ # normalize :attribute_b, :with => [:custom_filter, :swapcase]
322
+ # @param [String] value A character sequence
323
+ # @return [String, Object] The String with case swapped or the object itself
324
+ def swapcase(value)
325
+ return value unless string?(value)
326
+ value.gsub(/./) { |c| (/\p{Lu}/.match(c) && downcase(c) || (/\p{Ll}/.match(c) && upcase(c))) || c }
327
+ end
328
+
209
329
  ##
210
330
  # Converts all characters to uppercase.
211
331
  #
@@ -219,32 +339,36 @@ module Normatron
219
339
  # @return [String, Object] The lowercased String or the object itself
220
340
  # @see http://www.ruby-doc.org/core-1.9.3/String.html#method-i-upcase String#upcase
221
341
  # @see http://api.rubyonrails.org/classes/ActiveSupport/Multibyte/Chars.html#method-i-upcase ActiveSupport::Multibyte::Chars#upcase
222
- def self.upcase(value)
342
+ def upcase(value)
223
343
  (string?(value) && eval_send(:upcase, value)) || value
224
344
  end
225
345
 
226
346
  protected
227
347
 
228
- def self.eval_regexp(value, keep, *args)
348
+ def eval_regexp(value, keep, *args)
229
349
  return value unless string?(value)
230
350
 
231
351
  options = args.flatten.compact.uniq
232
352
 
233
- regex = options.map{|s| "\\p{#{s.to_s}}"} * ""
353
+ regex = options.map{ |s| "\\p{#{s.to_s}}" } * ""
234
354
  regex.prepend('^') if keep
235
355
  regex = eval "/[#{regex}]/u"
236
356
 
237
357
  value.gsub(regex, "")
238
358
  end
239
359
 
240
- def self.eval_send(method, value)
360
+ def eval_send(method, value, option=nil)
241
361
  type = value.class
242
362
  value = value.mb_chars if type == String
243
- value = value.send(method)
363
+ if option
364
+ value = value.send(method, option)
365
+ else
366
+ value = value.send(method)
367
+ end
244
368
  (type == String && value.to_s) || value
245
369
  end
246
370
 
247
- def self.eval_strip(value, start, ending)
371
+ def eval_strip(value, start, ending)
248
372
  regex = []
249
373
  regex << '\A\p{Zs}*' if start
250
374
  regex << '\p{Zs}*\z' if ending
@@ -253,7 +377,7 @@ module Normatron
253
377
  value.gsub(regex, '')
254
378
  end
255
379
 
256
- def self.string?(value)
380
+ def string?(value)
257
381
  value.is_a?(ActiveSupport::Multibyte::Chars) || value.is_a?(String)
258
382
  end
259
383
  end
@@ -7,15 +7,106 @@ describe Normatron::Filters do
7
7
  subject { described_class }
8
8
  let(:mb_chars) { ActiveSupport::Multibyte::Chars }
9
9
 
10
+ #
11
+ # BLANK
12
+ ###################################################################################################################
10
13
  describe "::blank" do
11
14
  it { subject.blank(" . " ).should eq " . " }
15
+ it { subject.blank(" . ".mb_chars).should eq " . ".mb_chars }
16
+
17
+ it { subject.blank(" . " ).should be_a String }
12
18
  it { subject.blank(" " ).should be_nil }
13
19
  it { subject.blank("\n \t \r \f" ).should be_nil }
14
- it { subject.blank(" . " ).should be_a String }
20
+
15
21
  it { subject.blank(" . ".mb_chars).should be_a mb_chars }
22
+ it { subject.blank(" ".mb_chars).should be_nil }
23
+ it { subject.blank("\n \t \r \f".mb_chars).should be_nil }
24
+
16
25
  it { subject.blank(100 ).should eq 100 }
17
26
  it { subject.blank(nil ).should be_nil }
18
27
  end
28
+
29
+ #
30
+ # CAMELIZE
31
+ ###################################################################################################################
32
+ describe "::camelize" do
33
+ it { subject.camelize("active_record/errors" ).should eq "ActiveRecord::Errors" }
34
+ it { subject.camelize("áctivé_record/érrórs" ).should eq "ÁctivéRecord::Érrórs" }
35
+ it { subject.camelize("ActivE_record/ErrOrs" ).should eq "ActiveRecord::Errors" }
36
+ it { subject.camelize("ÁctivÉ_record/ÉrrÓrs" ).should eq "ÁctivéRecord::Érrórs" }
37
+ it { subject.camelize("active_record/errors", :upper ).should eq "ActiveRecord::Errors" }
38
+ it { subject.camelize("áctivé_record/érrórs", :upper ).should eq "ÁctivéRecord::Érrórs" }
39
+ it { subject.camelize("ActivE_record/ErrOrs", :upper ).should eq "ActiveRecord::Errors" }
40
+ it { subject.camelize("ÁctivÉ_record/ÉrrÓrs", :upper ).should eq "ÁctivéRecord::Érrórs" }
41
+ it { subject.camelize("active_record/errors", :lower ).should eq "activeRecord::Errors" }
42
+ it { subject.camelize("áctivé_record/érrórs", :lower ).should eq "áctivéRecord::Érrórs" }
43
+ it { subject.camelize("ActivE_record/ErrOrs", :lower ).should eq "activeRecord::Errors" }
44
+ it { subject.camelize("ÁctivÉ_record/ÉrrÓrs", :lower ).should eq "áctivéRecord::Érrórs" }
45
+
46
+ it { subject.camelize("active_record/errors".mb_chars ).should eq "ActiveRecord::Errors".mb_chars }
47
+ it { subject.camelize("áctivé_record/érrórs".mb_chars ).should eq "ÁctivéRecord::Érrórs".mb_chars }
48
+ it { subject.camelize("ActivE_record/ErrOrs".mb_chars ).should eq "ActiveRecord::Errors".mb_chars }
49
+ it { subject.camelize("ÁctivÉ_record/ÉrrÓrs".mb_chars ).should eq "ÁctivéRecord::Érrórs".mb_chars }
50
+ it { subject.camelize("active_record/errors".mb_chars, :upper).should eq "ActiveRecord::Errors".mb_chars }
51
+ it { subject.camelize("áctivé_record/érrórs".mb_chars, :upper).should eq "ÁctivéRecord::Érrórs".mb_chars }
52
+ it { subject.camelize("ActivE_record/ErrOrs".mb_chars, :upper).should eq "ActiveRecord::Errors".mb_chars }
53
+ it { subject.camelize("ÁctivÉ_record/ÉrrÓrs".mb_chars, :upper).should eq "ÁctivéRecord::Érrórs".mb_chars }
54
+ it { subject.camelize("active_record/errors".mb_chars, :lower).should eq "activeRecord::Errors".mb_chars }
55
+ it { subject.camelize("áctivé_record/érrórs".mb_chars, :lower).should eq "áctivéRecord::Érrórs".mb_chars }
56
+ it { subject.camelize("ActivE_record/ErrOrs".mb_chars, :lower).should eq "activeRecord::Errors".mb_chars }
57
+ it { subject.camelize("ÁctivÉ_record/ÉrrÓrs".mb_chars, :lower).should eq "áctivéRecord::Érrórs".mb_chars }
58
+
59
+ it { subject.camelize("active_record/errors" ).should be_a String }
60
+ it { subject.camelize("áctivé_record/érrórs" ).should be_a String }
61
+ it { subject.camelize("ActivE_record/ErrOrs" ).should be_a String }
62
+ it { subject.camelize("ÁctivÉ_record/ÉrrÓrs" ).should be_a String }
63
+ it { subject.camelize("active_record/errors", :upper ).should be_a String }
64
+ it { subject.camelize("áctivé_record/érrórs", :upper ).should be_a String }
65
+ it { subject.camelize("ActivE_record/ErrOrs", :upper ).should be_a String }
66
+ it { subject.camelize("ÁctivÉ_record/ÉrrÓrs", :upper ).should be_a String }
67
+ it { subject.camelize("active_record/errors", :lower ).should be_a String }
68
+ it { subject.camelize("áctivé_record/érrórs", :lower ).should be_a String }
69
+ it { subject.camelize("ActivE_record/ErrOrs", :lower ).should be_a String }
70
+ it { subject.camelize("ÁctivÉ_record/ÉrrÓrs", :lower ).should be_a String }
71
+
72
+ it { subject.camelize("active_record/errors".mb_chars ).should be_a mb_chars }
73
+ it { subject.camelize("áctivé_record/érrórs".mb_chars ).should be_a mb_chars }
74
+ it { subject.camelize("ActivE_record/ErrOrs".mb_chars ).should be_a mb_chars }
75
+ it { subject.camelize("ÁctivÉ_record/ÉrrÓrs".mb_chars ).should be_a mb_chars }
76
+ it { subject.camelize("active_record/errors".mb_chars, :upper).should be_a mb_chars }
77
+ it { subject.camelize("áctivé_record/érrórs".mb_chars, :upper).should be_a mb_chars }
78
+ it { subject.camelize("ActivE_record/ErrOrs".mb_chars, :upper).should be_a mb_chars }
79
+ it { subject.camelize("ÁctivÉ_record/ÉrrÓrs".mb_chars, :upper).should be_a mb_chars }
80
+ it { subject.camelize("active_record/errors".mb_chars, :lower).should be_a mb_chars }
81
+ it { subject.camelize("áctivé_record/érrórs".mb_chars, :lower).should be_a mb_chars }
82
+ it { subject.camelize("ActivE_record/ErrOrs".mb_chars, :lower).should be_a mb_chars }
83
+ it { subject.camelize("ÁctivÉ_record/ÉrrÓrs".mb_chars, :lower).should be_a mb_chars }
84
+
85
+ it { subject.camelize(100 ).should eq 100 }
86
+ it { subject.camelize(100, :upper ).should eq 100 }
87
+ it { subject.camelize(100, :lower ).should eq 100 }
88
+ it { subject.camelize(nil ).should be_nil }
89
+ it { subject.camelize(nil, :upper ).should be_nil }
90
+ it { subject.camelize(nil, :lower ).should be_nil }
91
+
92
+ it { expect { subject.camelize("ÁctivÉ_record/ÉrrÓrs", :other) }.to raise_error }
93
+
94
+ context "should affect acronyms" do
95
+ let(:inflections) { ActiveSupport::Inflector::Inflections.instance }
96
+
97
+ before(:all) do
98
+ inflections.acronym 'HTTP'
99
+ inflections.acronym 'SSL'
100
+ end
101
+
102
+ it { subject.camelize("http_address/ssl", :upper).should eq "HTTPAddress::SSL" }
103
+ it { subject.camelize("http_address/ssl", :lower).should eq "httpAddress::SSL" }
104
+
105
+ after(:all) do
106
+ inflections.acronyms = {}
107
+ end
108
+ end
109
+ end
19
110
 
20
111
  describe "::capitalize" do
21
112
  it { subject.capitalize("abcDEF GhI" ).should eq "Abcdef ghi" }
@@ -27,6 +118,102 @@ describe Normatron::Filters do
27
118
  it { subject.capitalize(nil ).should be_nil }
28
119
  end
29
120
 
121
+ #
122
+ # CHOMP
123
+ ###################################################################################################################
124
+ describe "::chomp" do
125
+ it { subject.chomp("abcdef ghijkl" ).should eq "abcdef ghijkl" }
126
+ it { subject.chomp("abcdef ghij\n" ).should eq "abcdef ghij" }
127
+ it { subject.chomp("abc\nd efghij" ).should eq "abc\nd efghij" }
128
+ it { subject.chomp("abc\nd ef\n\r" ).should eq "abc\nd ef\n" }
129
+ it { subject.chomp("abc\nd ef\r\n" ).should eq "abc\nd ef" }
130
+ it { subject.chomp("abcdef ghijkl", "jkl" ).should eq "abcdef ghi" }
131
+ it { subject.chomp("abcdef ghij\n", "j\n" ).should eq "abcdef ghi" }
132
+ it { subject.chomp("abc\nd efghij", " efghij" ).should eq "abc\nd" }
133
+ it { subject.chomp("abc\nd ef\n\r", "\n\r" ).should eq "abc\nd ef" }
134
+ it { subject.chomp("abc\nd ef\r\n", "\n" ).should eq "abc\nd ef" }
135
+
136
+ it { subject.chomp("abcdef ghijkl" ).should eq "abcdef ghijkl" }
137
+ it { subject.chomp("abcdef ghij\n" ).should eq "abcdef ghij" }
138
+ it { subject.chomp("abc\nd efghij" ).should eq "abc\nd efghij" }
139
+ it { subject.chomp("abc\nd ef\n\r" ).should eq "abc\nd ef\n" }
140
+ it { subject.chomp("abc\nd ef\r\n" ).should eq "abc\nd ef" }
141
+ it { subject.chomp("abcdef ghijkl", "jkl" .mb_chars ).should eq "abcdef ghi" }
142
+ it { subject.chomp("abcdef ghij\n", "j\n" .mb_chars ).should eq "abcdef ghi" }
143
+ it { subject.chomp("abc\nd efghij", " efghij".mb_chars ).should eq "abc\nd" }
144
+ it { subject.chomp("abc\nd ef\n\r", "\n\r" .mb_chars ).should eq "abc\nd ef" }
145
+ it { subject.chomp("abc\nd ef\r\n", "\n" .mb_chars ).should eq "abc\nd ef" }
146
+
147
+ it { subject.chomp("abcdef ghijkl".mb_chars ).should eq "abcdef ghijkl".mb_chars }
148
+ it { subject.chomp("abcdef ghij\n".mb_chars ).should eq "abcdef ghij" .mb_chars }
149
+ it { subject.chomp("abc\nd efghij".mb_chars ).should eq "abc\nd efghij".mb_chars }
150
+ it { subject.chomp("abc\nd ef\n\r".mb_chars ).should eq "abc\nd ef\n" .mb_chars }
151
+ it { subject.chomp("abc\nd ef\r\n".mb_chars ).should eq "abc\nd ef" .mb_chars }
152
+ it { subject.chomp("abcdef ghijkl".mb_chars, "jkl" ).should eq "abcdef ghi" .mb_chars }
153
+ it { subject.chomp("abcdef ghij\n".mb_chars, "j\n" ).should eq "abcdef ghi" .mb_chars }
154
+ it { subject.chomp("abc\nd efghij".mb_chars, " efghij" ).should eq "abc\nd" .mb_chars }
155
+ it { subject.chomp("abc\nd ef\n\r".mb_chars, "\n\r" ).should eq "abc\nd ef" .mb_chars }
156
+ it { subject.chomp("abc\nd ef\r\n".mb_chars, "\n" ).should eq "abc\nd ef" .mb_chars }
157
+
158
+ it { subject.chomp("abcdef ghijkl".mb_chars ).should eq "abcdef ghijkl".mb_chars }
159
+ it { subject.chomp("abcdef ghij\n".mb_chars ).should eq "abcdef ghij" .mb_chars }
160
+ it { subject.chomp("abc\nd efghij".mb_chars ).should eq "abc\nd efghij".mb_chars }
161
+ it { subject.chomp("abc\nd ef\n\r".mb_chars ).should eq "abc\nd ef\n" .mb_chars }
162
+ it { subject.chomp("abc\nd ef\r\n".mb_chars ).should eq "abc\nd ef" .mb_chars }
163
+ it { subject.chomp("abcdef ghijkl".mb_chars, "jkl" .mb_chars).should eq "abcdef ghi" .mb_chars }
164
+ it { subject.chomp("abcdef ghij\n".mb_chars, "j\n" .mb_chars).should eq "abcdef ghi" .mb_chars }
165
+ it { subject.chomp("abc\nd efghij".mb_chars, " efghij".mb_chars).should eq "abc\nd" .mb_chars }
166
+ it { subject.chomp("abc\nd ef\n\r".mb_chars, "\n\r" .mb_chars).should eq "abc\nd ef" .mb_chars }
167
+ it { subject.chomp("abc\nd ef\r\n".mb_chars, "\n" .mb_chars).should eq "abc\nd ef" .mb_chars }
168
+
169
+ it { subject.chomp("abcdef ghijkl" ).should be_a String }
170
+ it { subject.chomp("abcdef ghij\n" ).should be_a String }
171
+ it { subject.chomp("abc\nd efghij" ).should be_a String }
172
+ it { subject.chomp("abc\nd ef\n\r" ).should be_a String }
173
+ it { subject.chomp("abc\nd ef\r\n" ).should be_a String }
174
+ it { subject.chomp("abcdef ghijkl", "jkl" ).should be_a String }
175
+ it { subject.chomp("abcdef ghij\n", "j\n" ).should be_a String }
176
+ it { subject.chomp("abc\nd efghij", " efghij" ).should be_a String }
177
+ it { subject.chomp("abc\nd ef\n\r", "\n\r" ).should be_a String }
178
+ it { subject.chomp("abc\nd ef\r\n", "\n" ).should be_a String }
179
+
180
+ it { subject.chomp("abcdef ghijkl" ).should be_a String }
181
+ it { subject.chomp("abcdef ghij\n" ).should be_a String }
182
+ it { subject.chomp("abc\nd efghij" ).should be_a String }
183
+ it { subject.chomp("abc\nd ef\n\r" ).should be_a String }
184
+ it { subject.chomp("abc\nd ef\r\n" ).should be_a String }
185
+ it { subject.chomp("abcdef ghijkl", "jkl" .mb_chars ).should be_a String }
186
+ it { subject.chomp("abcdef ghij\n", "j\n" .mb_chars ).should be_a String }
187
+ it { subject.chomp("abc\nd efghij", " efghij".mb_chars ).should be_a String }
188
+ it { subject.chomp("abc\nd ef\n\r", "\n\r" .mb_chars ).should be_a String }
189
+ it { subject.chomp("abc\nd ef\r\n", "\n" .mb_chars ).should be_a String }
190
+
191
+ it { subject.chomp("abcdef ghijkl".mb_chars ).should be_a mb_chars }
192
+ it { subject.chomp("abcdef ghij\n".mb_chars ).should be_a mb_chars }
193
+ it { subject.chomp("abc\nd efghij".mb_chars ).should be_a mb_chars }
194
+ it { subject.chomp("abc\nd ef\n\r".mb_chars ).should be_a mb_chars }
195
+ it { subject.chomp("abc\nd ef\r\n".mb_chars ).should be_a mb_chars }
196
+ it { subject.chomp("abcdef ghijkl".mb_chars, "jkl" ).should be_a mb_chars }
197
+ it { subject.chomp("abcdef ghij\n".mb_chars, "j\n" ).should be_a mb_chars }
198
+ it { subject.chomp("abc\nd efghij".mb_chars, " efghij" ).should be_a mb_chars }
199
+ it { subject.chomp("abc\nd ef\n\r".mb_chars, "\n\r" ).should be_a mb_chars }
200
+ it { subject.chomp("abc\nd ef\r\n".mb_chars, "\n" ).should be_a mb_chars }
201
+
202
+ it { subject.chomp("abcdef ghijkl".mb_chars ).should be_a mb_chars }
203
+ it { subject.chomp("abcdef ghij\n".mb_chars ).should be_a mb_chars }
204
+ it { subject.chomp("abc\nd efghij".mb_chars ).should be_a mb_chars }
205
+ it { subject.chomp("abc\nd ef\n\r".mb_chars ).should be_a mb_chars }
206
+ it { subject.chomp("abc\nd ef\r\n".mb_chars ).should be_a mb_chars }
207
+ it { subject.chomp("abcdef ghijkl".mb_chars, "jkl" .mb_chars).should be_a mb_chars }
208
+ it { subject.chomp("abcdef ghij\n".mb_chars, "j\n" .mb_chars).should be_a mb_chars }
209
+ it { subject.chomp("abc\nd efghij".mb_chars, " efghij".mb_chars).should be_a mb_chars }
210
+ it { subject.chomp("abc\nd ef\n\r".mb_chars, "\n\r" .mb_chars).should be_a mb_chars }
211
+ it { subject.chomp("abc\nd ef\r\n".mb_chars, "\n" .mb_chars).should be_a mb_chars }
212
+
213
+ it { subject.chomp(100 ).should eq 100 }
214
+ it { subject.chomp(nil ).should be_nil }
215
+ end
216
+
30
217
  describe "::dasherize" do
31
218
  it { subject.dasherize("string_inflections" ).should eq "string-inflections" }
32
219
  it { subject.dasherize("string_inflections" ).should be_a String }
@@ -43,6 +230,26 @@ describe Normatron::Filters do
43
230
  it { subject.downcase(nil ).should be_nil }
44
231
  end
45
232
 
233
+ #
234
+ # DUMP
235
+ ###################################################################################################################
236
+ describe "::dump" do
237
+ it { subject.dump("abc\ndef" ).should eq '"abc\ndef"' }
238
+ it { subject.dump('abc\ndef' ).should eq '"abc\\\ndef"' }
239
+
240
+ it { subject.dump("abc\ndef".mb_chars).should eq '"abc\ndef"' .mb_chars }
241
+ it { subject.dump('abc\ndef'.mb_chars).should eq '"abc\\\ndef"'.mb_chars }
242
+
243
+ it { subject.dump("abc\ndef" ).should be_a String }
244
+ it { subject.dump('abc\ndef' ).should be_a String }
245
+
246
+ it { subject.dump("abc\ndef".mb_chars).should be_a mb_chars }
247
+ it { subject.dump('abc\ndef'.mb_chars).should be_a mb_chars }
248
+
249
+ it { subject.dump(100 ).should eq 100 }
250
+ it { subject.dump(nil ).should be_nil }
251
+ end
252
+
46
253
  describe "::keep" do
47
254
  it { subject.keep("1111aaaa", :L ).should eq "aaaa" }
48
255
  it { subject.keep("1111ܑܑܑܑ", :M ).should eq "ܑܑܑܑ" }
@@ -189,6 +396,42 @@ describe Normatron::Filters do
189
396
  it { subject.strip(nil ).should be_nil }
190
397
  end
191
398
 
399
+ #
400
+ # SWAPCASE
401
+ ###################################################################################################################
402
+ describe "::swapcase" do
403
+ it { subject.swapcase("aeiouáéíóú" ).should eq "AEIOUÁÉÍÓÚ" }
404
+ it { subject.swapcase("AEIOUÁÉÍÓÚ" ).should eq "aeiouáéíóú" }
405
+ it { subject.swapcase("aEiOuÁéÍóÚ" ).should eq "AeIoUáÉíÓú" }
406
+ it { subject.swapcase("AeIoUáÉíÓú" ).should eq "aEiOuÁéÍóÚ" }
407
+
408
+ it { subject.swapcase("aeiouáéíóú".mb_chars).should eq "AEIOUÁÉÍÓÚ".mb_chars }
409
+ it { subject.swapcase("AEIOUÁÉÍÓÚ".mb_chars).should eq "aeiouáéíóú".mb_chars }
410
+ it { subject.swapcase("aEiOuÁéÍóÚ".mb_chars).should eq "AeIoUáÉíÓú".mb_chars }
411
+ it { subject.swapcase("AeIoUáÉíÓú".mb_chars).should eq "aEiOuÁéÍóÚ".mb_chars }
412
+
413
+ it { subject.swapcase("aeiouáéíóú" ).should be_a String }
414
+ it { subject.swapcase("AEIOUÁÉÍÓÚ" ).should be_a String }
415
+ it { subject.swapcase("aEiOuÁéÍóÚ" ).should be_a String }
416
+ it { subject.swapcase("AeIoUáÉíÓú" ).should be_a String }
417
+
418
+ it { subject.swapcase("aeiouáéíóú".mb_chars).should be_a mb_chars }
419
+ it { subject.swapcase("AEIOUÁÉÍÓÚ".mb_chars).should be_a mb_chars }
420
+ it { subject.swapcase("aEiOuÁéÍóÚ".mb_chars).should be_a mb_chars }
421
+ it { subject.swapcase("AeIoUáÉíÓú".mb_chars).should be_a mb_chars }
422
+
423
+ it { subject.swapcase(100 ).should eq 100 }
424
+ it { subject.swapcase(nil ).should be_nil }
425
+ end
426
+
427
+ describe "::titleize" do
428
+ pending
429
+ end
430
+
431
+ describe "::underscore" do
432
+ pending
433
+ end
434
+
192
435
  describe "::upcase" do
193
436
  it { subject.upcase("Çsdf !@# éhas" ).should eq "ÇSDF !@# ÉHAS" }
194
437
  it { subject.upcase("Çsdf !@# éhas" ).should be_a String }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: normatron
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-23 00:00:00.000000000 Z
12
+ date: 2012-10-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -75,10 +75,10 @@ dependencies:
75
75
  - - ! '>='
76
76
  - !ruby/object:Gem::Version
77
77
  version: 2.10.0
78
- description: ! " Normatron is an attribute normalizer for ActiveRecord objects.\n
79
- \ With it you can convert attributes to the desired format before saving them
80
- in the database.\n This gem inhibits the work of having to override attributes
81
- or create a specific method to perform most of the normalizations.\n"
78
+ description: ! " Normatron is an Ruby On Rails plugin that perform attribute normalizations
79
+ for ActiveRecord objects.\n With it you can normalize attributes to the desired
80
+ format before saving them in the database.\n This gem inhibits the work of having
81
+ to override attributes or create a specific method to perform most of the normalizations.\n"
82
82
  email:
83
83
  - fernandors87@gmail.com
84
84
  executables: []