normatron 0.1.1 → 0.2.0

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,12 +1,260 @@
1
- require "normatron/filters/conversions"
2
- require "normatron/filters/string_inflections"
1
+ # encoding: UTF-8
2
+
3
+ require 'active_support/multibyte/chars'
4
+ require 'active_support/core_ext/string'
3
5
 
4
6
  module Normatron
5
7
  module Filters
6
- class << self
7
- def is_a_string?(value)
8
- value.is_a?(ActiveSupport::Multibyte::Chars) || value.is_a?(String)
9
- end
8
+ ##
9
+ # Converts a blank string on a nil object.
10
+ #
11
+ # @example
12
+ # blank("") #=> nil
13
+ # blank(" ") #=> nil
14
+ # blank(" \n ") #=> nil
15
+ # blank("1") #=> "1"
16
+ # blank("It's blank?") #=> "It's blank?"
17
+ # blank(123) #=> 123
18
+ #
19
+ # # For normalizations
20
+ # normalize :attribute, :with => [:custom_filter, :blank]
21
+ # @param [String] value A character sequence
22
+ # @return [String, Nil] The object itself or nil
23
+ # @see http://api.rubyonrails.org/classes/String.html#method-i-blank-3F String#blank?
24
+ def self.blank(value)
25
+ return value unless string?(value) && value.to_s.blank?
26
+ nil
27
+ end
28
+
29
+ ##
30
+ # Converts the first character to uppercase and others to lowercase.
31
+ #
32
+ # @example
33
+ # capitalize("walter white") #=> "Walter white"
34
+ # capitalize("wALTER WHITE") #=> "Walter white"
35
+ # capitalize(123) #=> 123
36
+ #
37
+ # # For normalizations
38
+ # normalize :attribute, :with => [:custom_filter, :capitalize]
39
+ # @param [String] value A character sequence
40
+ # @return [String, Object] The capitalized String or the object itself
41
+ # @see http://www.ruby-doc.org/core-1.9.3/String.html#method-i-capitalize String#capitalize
42
+ # @see http://api.rubyonrails.org/classes/ActiveSupport/Multibyte/Chars.html#method-i-capitalize ActiveSupport::Multibyte::Chars#capitalize
43
+ def self.capitalize(value)
44
+ (string?(value) && eval_send(:capitalize, value)) || value
45
+ end
46
+
47
+ ##
48
+ # Replaces all underscores with dashes.
49
+ #
50
+ # @example
51
+ # dasherize("monty_python") #=> "monty-python"
52
+ # dasherize("_.·-'*'-·._") #=> "-.·-'*'-·.-"
53
+ # dasherize(123) #=> 123
54
+ #
55
+ # # For normalizations
56
+ # normalize :attribute, :with => [:custom_filter, :dasherize]
57
+ # @param [String] value A character sequence
58
+ # @return [String, Object] The dasherized String or the object itself
59
+ # @see http://api.rubyonrails.org/classes/String.html#method-i-dasherize String#dasherize
60
+ def self.dasherize(value)
61
+ (string?(value) && eval_send(:dasherize, value)) || value
62
+ end
63
+
64
+ ##
65
+ # Converts all characters to lowercase.
66
+ #
67
+ # @example
68
+ # downcase("VEGETA!!!") #=> "vegeta!!!"
69
+ # downcase(123) #=> 123
70
+ #
71
+ # # For normalizations
72
+ # normalize :attribute, :with => [:custom_filter, :downcase]
73
+ # @param [String] value A character sequence
74
+ # @return [String, Object] The lowercased String or the object itself
75
+ # @see http://www.ruby-doc.org/core-1.9.3/String.html#method-i-downcase String#downcase
76
+ # @see http://api.rubyonrails.org/classes/ActiveSupport/Multibyte/Chars.html#method-i-downcase ActiveSupport::Multibyte::Chars#downcase
77
+ def self.downcase(value)
78
+ (string?(value) && eval_send(:downcase, value)) || value
79
+ end
80
+
81
+ ##
82
+ # Keep only the specified characters.
83
+ # Details about the options can be found in the Regexp class documentation.
84
+ #
85
+ # @example
86
+ # keep("Doom 3", :L) #=> "Doom" equivalent to /\p{L}/u
87
+ # keep("Doom 3", :N) #=> "3" equivalent to /\p{N}/u
88
+ # keep("Doom 3", :L, :N) #=> "Doom3" equivalent to /\p{L}\p{N}/u
89
+ # keep("Doom 3", :Lu, :N) #=> "D3" equivalent to /\p{Lu}\p{N}/u
90
+ # keep("Doom ˩", :Latin) #=> "Doom" equivalent to /\p{Latin}/u
91
+ #
92
+ # # For normalizations
93
+ # normalize :attribute_a, :with => [[:keep, :Lu, :N]]
94
+ # normalize :attribute_b, :with => [:custom_filter, [:keep, :L, :Nd]]
95
+ # normalize :attribute_c, :with => [:custom_filter, {:keep => [:Latin, :Z]}]
96
+ # @param [String] value A character sequence
97
+ # @param [[Symbol]*] args Array of Symbols equivalent to Regexp for \\p{} construct.
98
+ # @return [String, Object] The clean character sequence or the object itself
99
+ # @see http://www.ruby-doc.org/core-1.9.3/Regexp.html Regexp
100
+ def self.keep(value, *args)
101
+ eval_regexp(value, true, args)
102
+ end
103
+
104
+ ##
105
+ # Remove trailing spaces.
106
+ #
107
+ # @example
108
+ # lstrip(" copyleft ") #=> "copyleft "
109
+ #
110
+ # # For normalizations
111
+ # normalize :attribute, :with => [:custom_filter, :lstrip]
112
+ # @param [String] value A character sequence
113
+ # @return [String, Object] The character sequence without trailing spaces or the object itself
114
+ # @see http://www.ruby-doc.org/core-1.9.3/String.html#method-i-lstrip String#lstrip
115
+ def self.lstrip(value)
116
+ (string?(value) && eval_strip(value, true, false)) || value
117
+ end
118
+
119
+ ##
120
+ # Remove only the specified characters.
121
+ # Details about the options can be found in the Regexp class documentation.
122
+ #
123
+ # @example
124
+ # remove("Quake 3", :L) #=> "3" equivalent to /\p{L}/u
125
+ # remove("Quake 3", :N) #=> "Quake " equivalent to /\p{N}/u
126
+ # remove("Quake 3", :L, :N) #=> " " equivalent to /\p{L}\p{N}/u
127
+ # remove("Quake 3", :Lu, :N) #=> "uake " equivalent to /\p{Lu}\p{N}/u
128
+ # remove("Quake ˩", :Latin) #=> "Quake" equivalent to /\p{Latin}/u
129
+ #
130
+ # # For normalizations
131
+ # normalize :attribute_a, :with => [[:remove, :Lu, :N]]
132
+ # normalize :attribute_b, :with => [:custom_filter, [:remove, :L, :Nd]]
133
+ # normalize :attribute_c, :with => [:custom_filter, {:remove => [:Latin, :Z]}]
134
+ # @param [String] value A character sequence
135
+ # @param [[Symbol]*] args Array of Symbols equivalent to Regexp for \\p{} construct.
136
+ # @return [String, Object] The clean character sequence or the object itself
137
+ # @see http://www.ruby-doc.org/core-1.9.3/Regexp.html Regexp
138
+ def self.remove(value, *args)
139
+ eval_regexp(value, false, args)
140
+ end
141
+
142
+ ##
143
+ # Remove leading spaces.
144
+ #
145
+ # @example
146
+ # rstrip(" copyright ") #=> " copyright"
147
+ #
148
+ # # For normalizations
149
+ # normalize :attribute, :with => [:custom_filter, :rstrip]
150
+ # @param [String] value A character sequence
151
+ # @return [String, Object] The character sequence without leading spaces or the object itself
152
+ # @see http://www.ruby-doc.org/core-1.9.3/String.html#method-i-rstrip String#rstrip
153
+ def self.rstrip(value)
154
+ (string?(value) && eval_strip(value, false, true)) || value
155
+ end
156
+
157
+ ##
158
+ # Remove multiple occurences of the same character.
159
+ # If no option are given, all runs of identical characters are replaced by a single character.
160
+ #
161
+ # @example
162
+ # squeeze("yellow moon") #=> "yelow mon"
163
+ # squeeze(" now is the", " ") #=> " now is the"
164
+ # squeeze("putters shoot balls", "m-z") #=> "puters shot balls"
165
+ #
166
+ # # For normalizations
167
+ # normalize :attribute_a, :with => [:custom_filter, :squeeze]
168
+ # normalize :attribute_b, :with => [:custom_filter, [:squeeze, "a-f"]]
169
+ # normalize :attribute_c, :with => [:custom_filter, {:squeeze => ["a-f"]}]
170
+ # @param [String] value A character sequence
171
+ # @param [[String]*] args Chars to be affected
172
+ # @return [String, Object] The clean character sequence or the object itself
173
+ # @see http://www.ruby-doc.org/core-1.9.3/String.html#method-i-squeeze String#squeeze
174
+ def self.squeeze(value, *args)
175
+ return value unless string?(value)
176
+ (args.any? && value.squeeze(args.first)) || value.squeeze
177
+ end
178
+
179
+ ##
180
+ # Strip and remove multiple spaces.
181
+ #
182
+ # @example
183
+ # squish(" the \n simpsons ") #=> "the simpsons"
184
+ #
185
+ # # For normalizations
186
+ # normalize :attribute, :with => [:custom_filter, :squish]
187
+ # @param [String] value A character sequence
188
+ # @return [String, Object] The clean character sequence or the object itself
189
+ #
190
+ # @see http://api.rubyonrails.org/classes/String.html#method-i-squish String#squish
191
+ def self.squish(value)
192
+ (string?(value) && value.squish) || value
193
+ end
194
+
195
+ ##
196
+ # Remove traling and leading spaces from the string.
197
+ #
198
+ # @example
199
+ # strip(" copy ") #=> "copy"
200
+ #
201
+ # # For normalizations
202
+ # normalize :attribute, :with => [:custom_filter, :strip]
203
+ # @param [String] value A character sequence
204
+ # @return [String, Object] The stripped character sequence or the object itself
205
+ def self.strip(value)
206
+ (string?(value) && eval_strip(value, true, true)) || value
207
+ end
208
+
209
+ ##
210
+ # Converts all characters to uppercase.
211
+ #
212
+ # @example
213
+ # downcase("kakarotto!!!") #=> "KAKAROTTO!!!"
214
+ # downcase(123) #=> 123
215
+ #
216
+ # # For normalizations
217
+ # normalize :attribute, :with => [:custom_filter, :upcase]
218
+ # @param [String] value A character sequence
219
+ # @return [String, Object] The lowercased String or the object itself
220
+ # @see http://www.ruby-doc.org/core-1.9.3/String.html#method-i-upcase String#upcase
221
+ # @see http://api.rubyonrails.org/classes/ActiveSupport/Multibyte/Chars.html#method-i-upcase ActiveSupport::Multibyte::Chars#upcase
222
+ def self.upcase(value)
223
+ (string?(value) && eval_send(:upcase, value)) || value
224
+ end
225
+
226
+ protected
227
+
228
+ def self.eval_regexp(value, keep, *args)
229
+ return value unless string?(value)
230
+
231
+ options = args.flatten.compact.uniq
232
+
233
+ regex = options.map{|s| "\\p{#{s.to_s}}"} * ""
234
+ regex.prepend('^') if keep
235
+ regex = eval "/[#{regex}]/u"
236
+
237
+ value.gsub(regex, "")
238
+ end
239
+
240
+ def self.eval_send(method, value)
241
+ type = value.class
242
+ value = value.mb_chars if type == String
243
+ value = value.send(method)
244
+ (type == String && value.to_s) || value
245
+ end
246
+
247
+ def self.eval_strip(value, start, ending)
248
+ regex = []
249
+ regex << '\A\p{Zs}*' if start
250
+ regex << '\p{Zs}*\z' if ending
251
+ regex = eval "/#{regex * '|'}/u"
252
+
253
+ value.gsub(regex, '')
254
+ end
255
+
256
+ def self.string?(value)
257
+ value.is_a?(ActiveSupport::Multibyte::Chars) || value.is_a?(String)
10
258
  end
11
259
  end
12
260
  end
@@ -0,0 +1,53 @@
1
+ require "spec_helper"
2
+
3
+ describe Normatron::Configuration do
4
+ before :each do
5
+ @instance = described_class.new
6
+ end
7
+
8
+ subject { @instance }
9
+
10
+ describe "#default_filters" do
11
+ it "should initializate" do
12
+ subject.default_filters.should == { squish: [], blank: [] }
13
+ end
14
+ it "should parse and set filters properly" do
15
+ subject.default_filters = :upcase, :blank, { keep: [:L, :N] }, [:remove, :S, :Z]
16
+ subject.default_filters.should == { upcase: [], blank: [], keep: [:L, :N], remove: [:S, :Z] }
17
+ end
18
+ it "should raise error for empty filters" do
19
+ lambda{ subject.default_filters = [] }.should raise_error
20
+ end
21
+ end
22
+
23
+ describe "::clean_filters" do
24
+ context "with wrong arguments" do
25
+ it { expect{ described_class.clean_filters(nil) }.to raise_error }
26
+ it { expect{ described_class.clean_filters([]) }.to raise_error }
27
+ it { expect{ described_class.clean_filters(1) }.to raise_error }
28
+ it { expect{ described_class.clean_filters([1]) }.to raise_error }
29
+ it { expect{ described_class.clean_filters([:a, 1]) }.to raise_error }
30
+ it { expect{ described_class.clean_filters([[1]]) }.to raise_error }
31
+ end
32
+
33
+ context "with single filter hash" do
34
+ it { described_class.clean_filters(:a ).should == { a:[] } }
35
+ it { described_class.clean_filters([:a] ).should == { a:[] } }
36
+ it { described_class.clean_filters([[:a]] ).should == { a:[] } }
37
+ it { described_class.clean_filters([[:a, :b]] ).should == { a:[:b] } }
38
+ it { described_class.clean_filters([a: [:b]] ).should == { a:[:b] } }
39
+ end
40
+
41
+ context "with double filters hash" do
42
+ it { described_class.clean_filters([:a, :b] ).should == { a:[], b:[] } }
43
+ it { described_class.clean_filters([:a, b:[:c, :d]] ).should == { a:[], b:[:c, :d] } }
44
+ it { described_class.clean_filters([:a, [:b, :c, :d]] ).should == { a:[], b:[:c, :d] } }
45
+ end
46
+
47
+ context "with trible filters hash" do
48
+ it { described_class.clean_filters([:a, [:b, :c, :d], { e: [:f, :g] }] ).should == { a:[], b:[:c, :d], e: [:f, :g] } }
49
+ it { described_class.clean_filters([:a, { b: [:c, :d] }, { e: [:f, :g] }] ).should == { a:[], b:[:c, :d], e: [:f, :g] } }
50
+ it { described_class.clean_filters([:a, { b: [:c, :d], e: [:f, :g] }] ).should == { a:[], b:[:c, :d], e: [:f, :g] } }
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,114 @@
1
+ require "spec_helper"
2
+
3
+ describe Normatron::Extensions::ActiveRecord do
4
+ let(:model) { Model }
5
+ before(:each) { model.normalize_options = nil }
6
+
7
+ describe "::normalize" do
8
+ subject { model.normalize_options }
9
+
10
+ specify("unknown attribute") { expect { model.normalize :abcdef }.to raise_error }
11
+ specify("nil attribute") { expect { model.normalize nil }.to raise_error }
12
+
13
+ context "with no filters" do
14
+ it "should use default filters" do
15
+ model.normalize :field_a
16
+ should == { field_a: { squish: [], blank: [] } }
17
+ end
18
+
19
+ it "should assoc to multiple attributes" do
20
+ model.normalize :field_a, :field_b, :field_c
21
+ should == { field_a: { squish: [], blank: [] },
22
+ field_b: { squish: [], blank: [] },
23
+ field_c: { squish: [], blank: [] } }
24
+ end
25
+
26
+ it "should stack attributes for multiple calls" do
27
+ model.normalize :field_a, :field_b
28
+ model.normalize :field_c
29
+ should == { field_a: { squish: [], blank: [] },
30
+ field_b: { squish: [], blank: [] },
31
+ field_c: { squish: [], blank: [] } }
32
+ end
33
+ end
34
+
35
+ context "with single filter" do
36
+ it "should set it" do
37
+ model.normalize :field_a, with: :upcase
38
+ should == { field_a: { upcase: [] } }
39
+ end
40
+
41
+ it "should set it as an array" do
42
+ model.normalize :field_a, with: [:upcase]
43
+ should == { field_a: { upcase: [] } }
44
+ end
45
+
46
+ it "should set it as an array" do
47
+ model.normalize :field_a, with: [[:keep, :L, :Z, :N]]
48
+ should == { field_a: { keep: [:L, :Z, :N] } }
49
+ end
50
+ end
51
+
52
+ context "with multiple filters" do
53
+ it "should set it" do
54
+ model.normalize :field_a, with: [:upcase, :dasherize]
55
+ should == { field_a: { upcase: [], dasherize: [] } }
56
+ end
57
+
58
+ it "should stack filters for multiple calls" do
59
+ model.normalize :field_a, with: :upcase
60
+ model.normalize :field_a, :field_b, with: [:blank, :squish]
61
+ should == { field_a: { upcase: [], blank: [], squish: [] },
62
+ field_b: { blank: [], squish: []} }
63
+ end
64
+
65
+ it "should use filters with arguments passed as an array" do
66
+ model.normalize :field_a, with: [:upcase, [:keep, :L, :N], :blank]
67
+ should == { field_a: { upcase: [], keep: [:L, :N], blank: [] } }
68
+ end
69
+
70
+ it "should use filters with arguments passed as a hash" do
71
+ model.normalize :field_a, with: [:upcase, { keep: [:L, :N] }, :blank]
72
+ should == { field_a: { upcase: [], keep: [:L, :N], blank: [] } }
73
+ end
74
+ end
75
+ end
76
+
77
+ describe "#normalize_attributes" do
78
+ before(:each) { @instance = model.new }
79
+ let(:instance) { @instance }
80
+
81
+ it "should run instance method filter" do
82
+ model.class_eval do
83
+ define_method :test_filter do |value, glue, size|
84
+ v = value.gsub(/\p{Z}/u, '').split(//) * glue
85
+ v[0..size-1]
86
+ end
87
+ end
88
+
89
+ model.normalize :field_a, with: [[:test_filter, ".", 5]]
90
+ instance.field_a = " bla bla bla"
91
+ instance.normalize_attributes
92
+ instance.field_a.should == "b.l.a"
93
+ end
94
+
95
+ it "should run native filter" do
96
+ model.normalize :field_a, with: [keep: [:N]]
97
+ instance.field_a = "abc123"
98
+ instance.normalize_attributes
99
+ instance.field_a.should == "123"
100
+ end
101
+
102
+ it "should be called before validation" do
103
+ model.normalize :field_a, with: :downcase
104
+ instance.field_a = "XXXXXX"
105
+ instance.valid?
106
+ instance.field_a.should == "xxxxxx"
107
+ end
108
+
109
+ it "should raise error for wrong filters" do
110
+ model.normalize :field_a, with: :down
111
+ expect { instance.normalize_attributes }.to raise_error "Filter 'down' wasn't found."
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,199 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Normatron::Filters do
6
+
7
+ subject { described_class }
8
+ let(:mb_chars) { ActiveSupport::Multibyte::Chars }
9
+
10
+ describe "::blank" do
11
+ it { subject.blank(" . " ).should eq " . " }
12
+ it { subject.blank(" " ).should be_nil }
13
+ it { subject.blank("\n \t \r \f" ).should be_nil }
14
+ it { subject.blank(" . " ).should be_a String }
15
+ it { subject.blank(" . ".mb_chars).should be_a mb_chars }
16
+ it { subject.blank(100 ).should eq 100 }
17
+ it { subject.blank(nil ).should be_nil }
18
+ end
19
+
20
+ describe "::capitalize" do
21
+ it { subject.capitalize("abcDEF GhI" ).should eq "Abcdef ghi" }
22
+ it { subject.capitalize("ébcDEF GhI" ).should eq "Ébcdef ghi" }
23
+ it { subject.capitalize(" bcDEF GhI" ).should eq " bcdef ghi" }
24
+ it { subject.capitalize("abcDEF GhI" ).should be_a String }
25
+ it { subject.capitalize("abcDEF GhI".mb_chars).should be_a mb_chars }
26
+ it { subject.capitalize(100 ).should eq 100 }
27
+ it { subject.capitalize(nil ).should be_nil }
28
+ end
29
+
30
+ describe "::dasherize" do
31
+ it { subject.dasherize("string_inflections" ).should eq "string-inflections" }
32
+ it { subject.dasherize("string_inflections" ).should be_a String }
33
+ it { subject.dasherize("string_inflections".mb_chars).should be_a mb_chars }
34
+ it { subject.dasherize(100 ).should eq 100 }
35
+ it { subject.dasherize(nil ).should be_nil }
36
+ end
37
+
38
+ describe "::downcase" do
39
+ it { subject.downcase("ÇSDF !@# JHAS" ).should eq "çsdf !@# jhas" }
40
+ it { subject.downcase("ÇSDF !@# JHAS" ).should be_a String }
41
+ it { subject.downcase("ÇSDF !@# JHAS".mb_chars).should be_a mb_chars }
42
+ it { subject.downcase(100 ).should eq 100 }
43
+ it { subject.downcase(nil ).should be_nil }
44
+ end
45
+
46
+ describe "::keep" do
47
+ it { subject.keep("1111aaaa", :L ).should eq "aaaa" }
48
+ it { subject.keep("1111ܑܑܑܑ", :M ).should eq "ܑܑܑܑ" }
49
+ it { subject.keep("1111!!!!", :P ).should eq "!!!!" }
50
+ it { subject.keep("1111££££", :S ).should eq "££££" }
51
+ it { subject.keep("11 ££", :Z ).should eq " " }
52
+ it { subject.keep("11\n\n££", :C ).should eq "\n\n" }
53
+ it { subject.keep("1111aaaa", :L ).should be_a String }
54
+ it { subject.keep("1111aaaa".mb_chars, :L).should be_a mb_chars }
55
+ it { subject.keep(1, :L ).should eq 1 }
56
+ it { subject.keep(1, :M ).should eq 1 }
57
+ it { subject.keep(1, :P ).should eq 1 }
58
+ it { subject.keep(1, :S ).should eq 1 }
59
+ it { subject.keep(1, :Z ).should eq 1 }
60
+ it { subject.keep(1, :C ).should eq 1 }
61
+ it { subject.keep(nil, :L ).should be_nil }
62
+ it { subject.keep(nil, :M ).should be_nil }
63
+ it { subject.keep(nil, :P ).should be_nil }
64
+ it { subject.keep(nil, :S ).should be_nil }
65
+ it { subject.keep(nil, :Z ).should be_nil }
66
+ it { subject.keep(nil, :C ).should be_nil }
67
+
68
+ context "with multiple options" do
69
+ it { subject.keep("1111aaaa!!!!", [:L, :N]).should eq "1111aaaa" }
70
+ it { subject.keep("1111ܑܑܑܑ!!!!", [:M, :N]).should eq "1111ܑܑܑܑ" }
71
+ it { subject.keep("1111!!!!aaaa", [:P, :L]).should eq "!!!!aaaa" }
72
+ it { subject.keep("1111££££aaaa", [:S, :N]).should eq "1111££££" }
73
+ it { subject.keep("11 ££aaaa", [:Z, :S]).should eq " ££" }
74
+ it { subject.keep("11\n\n££aaaa", [:C, :N]).should eq "11\n\n" }
75
+ end
76
+
77
+ context "with wrong option" do
78
+ it { lambda { subject.keep("1111aaaa", :J) }.should raise_error }
79
+ it { lambda { subject.keep("1111ܑܑܑܑ", :J) }.should raise_error }
80
+ it { lambda { subject.keep("1111!!!!", :J) }.should raise_error }
81
+ it { lambda { subject.keep("1111££££", :J) }.should raise_error }
82
+ it { lambda { subject.keep("11 ££", :J) }.should raise_error }
83
+ it { lambda { subject.keep("11\n\n££", :J) }.should raise_error }
84
+ end
85
+
86
+ context "with wrong option inside multiple options array" do
87
+ it { lambda { subject.keep("1111aaaa", [:J, :N]) }.should raise_error }
88
+ it { lambda { subject.keep("1111ܑܑܑܑ", [:J, :N]) }.should raise_error }
89
+ it { lambda { subject.keep("1111!!!!", [:J, :N]) }.should raise_error }
90
+ it { lambda { subject.keep("1111££££", [:J, :N]) }.should raise_error }
91
+ it { lambda { subject.keep("11 ££", [:J, :N]) }.should raise_error }
92
+ it { lambda { subject.keep("11\n\n££", [:J, :N]) }.should raise_error }
93
+ end
94
+ end
95
+
96
+ describe "::lstrip" do
97
+ it { subject.lstrip(" 1111 " ).should eq "1111 " }
98
+ it { subject.lstrip(" 1111 " ).should be_a String }
99
+ it { subject.lstrip(" 1111 ".mb_chars).should be_a mb_chars }
100
+ it { subject.lstrip(1).should eq 1 }
101
+ it { subject.lstrip(nil).should be_nil }
102
+ end
103
+
104
+ describe "::remove" do
105
+ it { subject.remove("1111aaaa", :L ).should eq "1111" }
106
+ it { subject.remove("1111ܑܑܑܑ", :M ).should eq "1111" }
107
+ it { subject.remove("1111!!!!", :P ).should eq "1111" }
108
+ it { subject.remove("1111££££", :S ).should eq "1111" }
109
+ it { subject.remove("11 ££", :Z ).should eq "11££" }
110
+ it { subject.remove("11\n\n££", :C ).should eq "11££" }
111
+ it { subject.remove("1111aaaa", :L ).should be_a String }
112
+ it { subject.remove("1111aaaa".mb_chars, :L).should be_a mb_chars }
113
+ it { subject.remove(1, :L ).should eq 1 }
114
+ it { subject.remove(1, :M ).should eq 1 }
115
+ it { subject.remove(1, :P ).should eq 1 }
116
+ it { subject.remove(1, :S ).should eq 1 }
117
+ it { subject.remove(1, :Z ).should eq 1 }
118
+ it { subject.remove(1, :C ).should eq 1 }
119
+ it { subject.remove(nil, :L ).should be_nil }
120
+ it { subject.remove(nil, :M ).should be_nil }
121
+ it { subject.remove(nil, :P ).should be_nil }
122
+ it { subject.remove(nil, :S ).should be_nil }
123
+ it { subject.remove(nil, :Z ).should be_nil }
124
+ it { subject.remove(nil, :C ).should be_nil }
125
+
126
+ context "with multiple options" do
127
+ it { subject.remove("1111aaaa!!!!", [:L, :N]).should eq "!!!!" }
128
+ it { subject.remove("1111ܑܑܑܑ!!!!", [:M, :N]).should eq "!!!!" }
129
+ it { subject.remove("1111!!!!aaaa", [:P, :L]).should eq "1111" }
130
+ it { subject.remove("1111££££aaaa", [:S, :N]).should eq "aaaa" }
131
+ it { subject.remove("11 ££aaaa", [:Z, :S]).should eq "11aaaa" }
132
+ it { subject.remove("11\n\n££aaaa", [:C, :N]).should eq "££aaaa" }
133
+ end
134
+
135
+ context "with wrong option" do
136
+ it { lambda { subject.remove("1111aaaa", :J) }.should raise_error }
137
+ it { lambda { subject.remove("1111ܑܑܑܑ", :J) }.should raise_error }
138
+ it { lambda { subject.remove("1111!!!!", :J) }.should raise_error }
139
+ it { lambda { subject.remove("1111££££", :J) }.should raise_error }
140
+ it { lambda { subject.remove("11 ££", :J) }.should raise_error }
141
+ it { lambda { subject.remove("11\n\n££", :J) }.should raise_error }
142
+ end
143
+
144
+ context "with wrong option inside multiple options array" do
145
+ it { lambda { subject.remove("1111aaaa", [:J, :N]) }.should raise_error }
146
+ it { lambda { subject.remove("1111ܑܑܑܑ", [:J, :N]) }.should raise_error }
147
+ it { lambda { subject.remove("1111!!!!", [:J, :N]) }.should raise_error }
148
+ it { lambda { subject.remove("1111££££", [:J, :N]) }.should raise_error }
149
+ it { lambda { subject.remove("11 ££", [:J, :N]) }.should raise_error }
150
+ it { lambda { subject.remove("11\n\n££", [:J, :N]) }.should raise_error }
151
+ end
152
+ end
153
+
154
+ describe "::rstrip" do
155
+ it { subject.rstrip(" 1111 " ).should eq " 1111" }
156
+ it { subject.rstrip(" 1111 " ).should be_a String }
157
+ it { subject.rstrip(" 1111 ".mb_chars).should be_a mb_chars }
158
+ it { subject.rstrip(1 ).should eq 1 }
159
+ it { subject.rstrip(nil ).should be_nil }
160
+ end
161
+
162
+ describe "::squeeze" do
163
+ it { subject.squeeze(" 1 22 333 4444 " ).should eq " 1 2 3 4 " }
164
+ it { subject.squeeze(" 1 22 333 4444 " ).should be_a String }
165
+ it { subject.squeeze(" 1 22 333 4444 ".mb_chars).should be_a mb_chars }
166
+ it { subject.squeeze(1 ).should eq 1 }
167
+ it { subject.squeeze(nil ).should be_nil }
168
+
169
+ context "with options" do
170
+ it { subject.squeeze("aaabbbcccdddeeefff", "b-d" ).should eq "aaabcdeeefff" }
171
+ it { subject.squeeze("aaabbbcccdddeeefff".mb_chars, "b-d").should eq "aaabcdeeefff".mb_chars }
172
+ end
173
+ end
174
+
175
+ describe "::squish" do
176
+ it { subject.squish(" 11 11 " ).should eq "11 11" }
177
+ it { subject.squish(" 11\n\n11 " ).should eq "11 11" }
178
+ it { subject.squish(" 11 11 " ).should be_a String }
179
+ it { subject.squish(" 11 11 ".mb_chars).should be_a mb_chars }
180
+ it { subject.squish(1 ).should eq 1 }
181
+ it { subject.squish(nil ).should be_nil }
182
+ end
183
+
184
+ describe "::strip" do
185
+ it { subject.strip(" 1111 " ).should eq "1111" }
186
+ it { subject.strip(" 1111 " ).should be_a String }
187
+ it { subject.strip(" 1111 ".mb_chars).should be_a mb_chars }
188
+ it { subject.strip(1 ).should eq 1 }
189
+ it { subject.strip(nil ).should be_nil }
190
+ end
191
+
192
+ describe "::upcase" do
193
+ it { subject.upcase("Çsdf !@# éhas" ).should eq "ÇSDF !@# ÉHAS" }
194
+ it { subject.upcase("Çsdf !@# éhas" ).should be_a String }
195
+ it { subject.upcase("Çsdf !@# éhas".mb_chars).should be_a mb_chars }
196
+ it { subject.upcase(100 ).should eq 100 }
197
+ it { subject.upcase(nil ).should be_nil }
198
+ end
199
+ end