normatron 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []