turkish_support 1.1.0 → 2.1.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,15 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module TurkishSupport
4
+ # :nodoc:
2
5
  refine Array do
3
6
  def sort
4
- sort_by do |item|
5
- item.chars.map do |ch|
6
- if ALPHABET.include?(ch)
7
- ASCII_ALPHABET[ch]
8
- else
9
- ch.ord
10
- end
11
- end
12
- end
7
+ return super if block_given?
8
+
9
+ sort_by { _1.chars.map { |ch| TurkishRanges::TrText.new(ch).code } }
13
10
  end
14
11
 
15
12
  def sort!
@@ -1,56 +1,30 @@
1
- module TurkishSupportHelpers
2
- ALPHA = {
3
- lower: 'abcçdefgğhıijklmnoöpqrsştuüvwxyz',
4
- upper: 'ABCÇDEFGĞHIİJKLMNOÖPQRSŞTUÜVWXYZ',
5
- tr_lower: 'çğıiöşü',
6
- tr_upper: 'ÇĞIİÖŞÜ'
7
- }.freeze
1
+ # frozen_string_literal: true
8
2
 
9
- ALPHABET = ALPHA[:upper] + ALPHA[:lower]
10
-
11
- ASCII_ALPHABET = ALPHABET.chars.map.with_index do |ch, i|
12
- # Add 65 to put special chars and numbers in correct order
13
- [ch, i + 65]
14
- end.to_h
15
-
16
- META_CHARS = {
17
- '\w' => '[\p{Latin}\d_]',
18
- '\W' => '[^\p{Latin}\d_]'
19
- }.freeze
3
+ module TurkishSupport
4
+ CASE_METHODS = %i[downcase
5
+ downcase!
6
+ upcase
7
+ upcase!
8
+ capitalize
9
+ capitalize!
10
+ swapcase
11
+ swapcase!].freeze
20
12
 
21
- # Regexp required methods
22
- RE_RE_METHS = %i(match scan).freeze
23
-
24
- # Regexp optional methods
25
- RE_OP_METHS = %i(
26
- []
27
- []=
28
- =~
29
- index
30
- rindex
31
- partition
32
- rpartition
33
- slice
34
- slice!
35
- split
36
- sub
37
- sub!
38
- gsub
39
- gsub!
40
- ).freeze
41
-
42
- CASE_RELATED_METHS = %i(
43
- downcase
44
- downcase!
45
- upcase
46
- upcase!
47
- capitalize
48
- capitalize!
49
- ).freeze
50
-
51
- RANGE_REGEXP = /\[[^\]]*?([#{ALPHABET}]-[#{ALPHABET}])[^\[]*?\]/
52
-
53
- CONJUCTIONS = %w(ve ile veya).freeze
54
-
55
- SPECIAL_CHARS = %q{("'}.freeze
13
+ REGEX_METHODS = %i[[]
14
+ []=
15
+ index
16
+ gsub
17
+ gsub!
18
+ match
19
+ rindex
20
+ partition
21
+ rpartition
22
+ scan
23
+ slice
24
+ slice!
25
+ split
26
+ sub
27
+ sub!
28
+ gsub
29
+ gsub!].freeze
56
30
  end
@@ -1,78 +1,56 @@
1
+ # frozen_string_literal: false
2
+
1
3
  module TurkishSupport
2
4
  refine String do # rubocop:disable Metrics/BlockLength
3
- (RE_RE_METHS + RE_OP_METHS).each do |meth|
5
+ REGEX_METHODS.each do |meth|
4
6
  define_method meth do |*args|
5
- extend(TurkishSupportHelpers)
6
-
7
- if RE_RE_METHS.include?(meth) || args[0].is_a?(Regexp)
8
- args[0] = translate_regexp(args[0])
7
+ if args[0].is_a?(Regexp) || %i[match scan].include?(meth)
8
+ args[0] = TurkishRegexps::TrRegexp.new(args[0]).translate
9
9
  end
10
10
 
11
- super(*args)
11
+ instance_exec { super(*args) }
12
12
  end
13
13
  end
14
14
 
15
- CASE_RELATED_METHS.each do |meth|
16
- non_destructive = meth.to_s.chomp('!').to_sym
17
- define_method(meth) do
18
- extend(TurkishSupportHelpers)
19
- str = prepare_for(non_destructive, self).public_send(non_destructive)
20
- return meth.to_s.end_with?('!') ? public_send(:replace, str) : str
21
- end
22
- end
15
+ CASE_METHODS.each { define_method(_1) { super(:turkic) } }
23
16
 
24
- def titleize(conjuctions = true) # rubocop:disable Metrics/AbcSize
25
- split.map do |word|
26
- word.downcase!
27
- if conjuction?(word) && !conjuctions
28
- word
29
- elsif start_with_a_special_char?(word)
30
- word.size > 1 ? word[0] + word[1..-1].capitalize : word.chr
31
- else
32
- word.capitalize
33
- end
34
- end.join(' ')
17
+ # capitalize all words and returns a copy of the string
18
+ #
19
+ # @return [String]
20
+ def titleize
21
+ downcase.gsub(/\b\S/u).each { _1.upcase }
35
22
  end
36
23
 
37
- def titleize!(conjuctions = true)
38
- replace(titleize(conjuctions))
24
+ # capitalize all words in place
25
+ # @return [String]
26
+ def titleize!
27
+ replace(titleize)
39
28
  end
40
29
 
41
- def swapcase
42
- extend(TurkishSupportHelpers)
43
- chars.map do |ch|
44
- if tr_char?(ch)
45
- tr_lower?(ch) ? ch.upcase : ch.downcase
46
- else
47
- ch.public_send(:swapcase)
48
- end
49
- end.join
30
+ def casecmp(other) # :nodoc:
31
+ upcase.instance_exec { super(other.upcase) }
50
32
  end
51
33
 
52
- def swapcase!
53
- replace(swapcase)
54
- end
34
+ def <=>(other) # :nodoc:
35
+ return nil unless other.is_a? String
55
36
 
56
- def casecmp(other_string)
57
- upcase.public_send(:casecmp, other_string.upcase)
37
+ TurkishRanges::TrText.new(to_s) <=> TurkishRanges::TrText.new(other)
58
38
  end
59
39
 
60
- def <=>(other_string)
61
- return nil unless other_string.is_a? String
40
+ def >(other) # :nodoc:
41
+ (self <=> other) == 1
42
+ end
62
43
 
63
- each_char.with_index do |ch, i|
64
- position1 = ASCII_ALPHABET[ch]
65
- position2 = ASCII_ALPHABET[other_string[i]]
44
+ def <(other) # :nodoc:
45
+ (self <=> other) == -1
46
+ end
66
47
 
67
- return (position2.nil? ? 0 : -1) if position1.nil?
68
- return 1 if position2.nil?
69
- return (position1 < position2 ? -1 : 1) if position1 != position2
70
- end
48
+ def >=(other) # :nodoc:
49
+ (self <=> other) != -1
50
+ end
71
51
 
72
- return 0 if length == other_string.length
73
- return -1 if length < other_string.length
74
- return 1
75
-
52
+ def <=(other) # :nodoc:
53
+ (self <=> other) != 1
76
54
  end
77
55
  end
78
56
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module TurkishSupport
2
- VERSION = '1.1.0'.freeze
4
+ VERSION = '2.1.0'
3
5
  end
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: false
2
+
3
+ using TurkishSupport
4
+
5
+ describe 'Array' do
6
+ describe '#sort' do
7
+ let(:samples) do
8
+ [{ mixed: %w[bağcılar bahçelievler şimdi çüNKÜ olmalı üç\ kere düş ılık duy],
9
+ sorted: %w[bağcılar bahçelievler çüNKÜ duy düş ılık olmalı şimdi üç\ kere] },
10
+ { mixed: %w[iki Üç dört ılık İğne iyne Ul],
11
+ sorted: %w[İğne Ul Üç dört ılık iki iyne] },
12
+ { mixed: %w[Sıtkı1\ Bağdat Sıtkı\ Bağdat a 3s 2\ b ab\ ],
13
+ sorted: %w[2\ b 3s Sıtkı\ Bağdat Sıtkı1\ Bağdat a ab\ ] }]
14
+ end
15
+ let(:block_samples) do
16
+ [{ mixed: %w[ağa aça aşa aöa aüa aua afa aba],
17
+ sorted: { "a[1]<=>b[1]": %w[aba aça afa ağa aöa aşa aua aüa],
18
+ "b[1]<=>a[1]": %w[aüa aua aşa aöa ağa afa aça aba] } },
19
+ { mixed: %w[iki Üç dört ılık İğne iyne Ul],
20
+ sorted: { "a.length<=>b.length": %w[Üç Ul iki dört ılık İğne iyne],
21
+ "b.length<=>a.length": %w[dört ılık İğne iyne iki Üç Ul] } },
22
+ { mixed: [['Şakir', 2], ['İsmet', 0], ['Zeliha', 1]],
23
+ sorted: { "a[1]<=>b[1]": [['İsmet', 0], ['Zeliha', 1], ['Şakir', 2]],
24
+ "b[0]<=>a[0]": [['Zeliha', 1], ['Şakir', 2], ['İsmet', 0]] } }]
25
+ end
26
+
27
+ context 'nondestructive version' do
28
+ context 'no block given' do
29
+ it 'does not change the original value of the array' do
30
+ samples.each do |sample|
31
+ expect { sample[:mixed].sort }.to_not(change { sample[:mixed] })
32
+ end
33
+ end
34
+
35
+ it 'sorts array in alphabetical order' do
36
+ samples.each do |sample|
37
+ expect(sample[:mixed].sort).to eq(sample[:sorted])
38
+ end
39
+ end
40
+ end
41
+
42
+ context 'block given' do
43
+ it 'sorts array for random conditions' do
44
+ sample = block_samples.first
45
+ expect(sample[:mixed].sort { |a, b| a[1] <=> b[1] })
46
+ .to eq(sample[:sorted][:"a[1]<=>b[1]"])
47
+ expect(sample[:mixed].sort { |a, b| b[1] <=> a[1] })
48
+ .to eq(sample[:sorted][:"b[1]<=>a[1]"])
49
+ sample = block_samples[1]
50
+ expect(sample[:mixed].sort { |a, b| a.length <=> b.length })
51
+ .to eq(sample[:sorted][:"a.length<=>b.length"])
52
+ expect(sample[:mixed].sort { |a, b| b.length <=> a.length })
53
+ .to eq(sample[:sorted][:"b.length<=>a.length"])
54
+ end
55
+
56
+ it 'sorts nested arrays' do
57
+ sample = block_samples[2]
58
+ expect(sample[:mixed].sort { |a, b| a[1] <=> b[1] })
59
+ .to eq(sample[:sorted][:"a[1]<=>b[1]"])
60
+ expect(sample[:mixed].sort { |a, b| b[0] <=> a[0] })
61
+ .to eq(sample[:sorted][:"b[0]<=>a[0]"])
62
+ end
63
+ end
64
+ end
65
+
66
+ context 'with destructive version' do
67
+ it 'changes the original value of the array' do
68
+ samples.each do |sample|
69
+ expect { sample[:mixed].sort! }.to(change { sample[:mixed] })
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -1,2 +1,4 @@
1
- $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift File.expand_path('../lib', __dir__)
2
4
  require 'turkish_support'
@@ -0,0 +1,467 @@
1
+ # frozen_string_literal: false
2
+
3
+ using TurkishSupport
4
+
5
+ module TurkishSupport # rubocop:disable Metrics/ModuleLength
6
+ describe String do
7
+ let(:downcased_turkish_alphabet) { 'abcçdefgğhıijklmnoöprsştuüvyz' }
8
+ let(:upcased_turkish_alphabet) { 'ABCÇDEFGĞHIİJKLMNOÖPRSŞTUÜVYZ' }
9
+ let(:downcased_english_alphabet) { ('a'..'z').to_a.join }
10
+ let(:upcased_english_alphabet) { ('A'..'Z').to_a.join }
11
+ let(:turkish_words) { %w[çamur ıhlamur insan ördek şahika ümraniye] }
12
+
13
+ describe '#[]' do
14
+ context 'with non-destructive version' do
15
+ it 'does not change the original value of the string' do
16
+ word = turkish_words.sample
17
+
18
+ expect { word[/\w+/] }.to_not(change { word })
19
+ end
20
+
21
+ it 'is able to capture Turkish characters' do
22
+ expect(turkish_words.all? { |w| w[/\w+/] == w }).to be true
23
+ expect(turkish_words.all? { |w| w[/[a-z]+/] == w }).to be true
24
+ expect(turkish_words.map(&:upcase).all? { |w| w[/[a-z]+/i] == w }).to be true
25
+ end
26
+ end
27
+
28
+ context 'with destructive version' do
29
+ it 'changes the original value of the string' do
30
+ word = turkish_words.sample
31
+
32
+ expect { word[/\w+/] = 'new value' }.to(change { word })
33
+ expect(word).to eq('new value')
34
+ end
35
+ end
36
+ end
37
+
38
+ describe '#index' do
39
+ it 'does not change the original value of the string' do
40
+ word = turkish_words.sample
41
+
42
+ expect { word.index(/\w+/) }.to_not(change { word })
43
+ end
44
+
45
+ it 'is able to capture Turkish characters' do
46
+ expect(turkish_words.all? { |w| w.index(/\w+/).zero? }).to be true
47
+ expect(turkish_words.all? { |w| w.index(/[a-z]+/).zero? }).to be true
48
+ expect(turkish_words.map(&:upcase).all? { |w| w.index(/[a-z]+/i).zero? }).to be true
49
+ end
50
+
51
+ it 'begins to search from the right position' do
52
+ expect('şç-!+*/-ğüı'.index(/\w+/, 2)).to be 8
53
+ end
54
+ end
55
+
56
+ describe '#rindex' do
57
+ it 'does not change the original value of the string' do
58
+ word = turkish_words.sample
59
+
60
+ expect { word.rindex(/\w+/) }.to_not(change { word })
61
+ end
62
+
63
+ it 'is able to capture Turkish characters' do
64
+ expect(turkish_words.map(&:reverse).all? { |w| w.rindex(/\w+/) == w.size - 1 }).to be true
65
+ expect(turkish_words.map(&:reverse).all? { |w| w.rindex(/[a-z]+/) == w.size - 1 }).to be true
66
+ expect(turkish_words.map { |w| w.upcase.reverse }.all? { |w| w.rindex(/[a-z]+/i) == w.size - 1 }).to be true
67
+ end
68
+
69
+ it 'finishes the searching to the right position' do
70
+ expect('şç-!+*/-ğüı'.rindex(/\w+/, 7)).to be 1
71
+ end
72
+ end
73
+
74
+ describe '#partition' do
75
+ let(:word1) { turkish_words.sample }
76
+ let(:word2) { turkish_words.sample }
77
+ let(:two_words) { "#{word1} #{word2}" }
78
+
79
+ it 'does not change the original value of the string' do
80
+ expect { two_words.partition(/\W+/) }.to_not(change { two_words })
81
+ end
82
+
83
+ it 'is able to capture Turkish characters' do
84
+ expect(two_words.partition(/\W+/)).to(eq([word1, ' ', word2]))
85
+ end
86
+ end
87
+
88
+ describe '#rpartition' do
89
+ let(:word1) { turkish_words.sample }
90
+ let(:word2) { turkish_words.sample }
91
+ let(:word3) { turkish_words.sample }
92
+ let(:three_words) { "#{word1} #{word2} #{word3}" }
93
+
94
+ it 'does not change the original value of the string' do
95
+ expect { three_words.rpartition(/\W+/) }.to_not(change { three_words })
96
+ end
97
+
98
+ it 'is able to capture Turkish characters' do
99
+ expect(three_words.rpartition(/\W+/)).to(eq(["#{word1} #{word2}", ' ', word3]))
100
+ end
101
+ end
102
+
103
+ describe '#slice' do
104
+ context 'with non-destructive version' do
105
+ it 'does not change the original value of the string' do
106
+ sentence = turkish_words * ' '
107
+
108
+ expect { sentence.slice(/\w+/) }.to_not(change { sentence })
109
+ end
110
+
111
+ it 'is able to capture Turkish characters' do
112
+ expect(turkish_words.all? { |w| w.slice(/\w+/) == w }).to be true
113
+ expect(turkish_words.all? { |w| w.slice(/[a-z]+/) == w }).to be true
114
+ expect(turkish_words.map(&:upcase).all? { |w| w.slice(/[a-z]+/i) == w }).to be true
115
+ end
116
+ end
117
+
118
+ context 'with destructive version' do
119
+ it 'changes the original value of the string' do
120
+ sentence = turkish_words * ' '
121
+
122
+ expect { sentence.slice!(/\w+/) }.to(change { sentence })
123
+ expect(sentence).to eq(" #{turkish_words[1..] * ' '}")
124
+ end
125
+ end
126
+ end
127
+
128
+ describe '#split' do
129
+ it 'is able to capture Turkish characters' do
130
+ expect(turkish_words.join(' ').split(/\w+/).join.strip.empty?).to be true
131
+ expect(turkish_words.join(' ').split(/[a-z]+/).join.strip.empty?).to be true
132
+ expect(turkish_words.join(' ').upcase.split(/[a-z]+/i).join.strip.empty?).to be true
133
+ end
134
+ end
135
+
136
+ describe '#upcase' do
137
+ context 'with non-destructive version' do
138
+ it 'does not change the original value of the string' do
139
+ expect { downcased_turkish_alphabet.upcase }.to_not(change { downcased_turkish_alphabet })
140
+ end
141
+
142
+ it 'upcases all of Turkish characters' do
143
+ upcased_string = downcased_turkish_alphabet.upcase
144
+
145
+ expect(upcased_string).to(eq(upcased_turkish_alphabet))
146
+ end
147
+
148
+ it 'upcases English characters except i as I' do
149
+ upcased_string = downcased_english_alphabet.upcase
150
+
151
+ expect(upcased_string).to eq upcased_english_alphabet.tr('I', 'İ')
152
+ end
153
+ end
154
+
155
+ context 'with destructive version' do
156
+ it 'changes the original value of the string' do
157
+ expect { downcased_turkish_alphabet.upcase! }.to(change { downcased_turkish_alphabet })
158
+ expect(downcased_turkish_alphabet).to(eq(upcased_turkish_alphabet))
159
+ end
160
+ end
161
+ end
162
+
163
+ describe '#downcase' do
164
+ context 'with non-destructive version' do
165
+ it 'does not change the original value of the string' do
166
+ expect { upcased_turkish_alphabet.downcase }.to_not(change { upcased_turkish_alphabet })
167
+ end
168
+
169
+ it 'downcases all of Turkish characters' do
170
+ downcased_string = upcased_turkish_alphabet.downcase
171
+ expect(downcased_string).to eq downcased_turkish_alphabet
172
+ end
173
+
174
+ it 'downcases English characters except I as ı' do
175
+ downcased_string = upcased_english_alphabet.downcase
176
+ expect(downcased_string).to eq downcased_english_alphabet.tr('i', 'ı')
177
+ end
178
+ end
179
+
180
+ context 'with destructive version' do
181
+ it 'changes the original value of the string' do
182
+ expect { upcased_turkish_alphabet.downcase! }.to(change { upcased_turkish_alphabet })
183
+ expect(upcased_turkish_alphabet).to(eq(downcased_turkish_alphabet))
184
+ end
185
+ end
186
+ end
187
+
188
+ describe '#capitalize' do
189
+ context 'with non-destructive version' do
190
+ it 'does not change the original value of the string' do
191
+ turkish_word = turkish_words.sample
192
+
193
+ expect { turkish_word.capitalize }.to_not(change { turkish_word })
194
+ end
195
+
196
+ it 'capitalizes the leading first Turkish character' do
197
+ capitalized_words = turkish_words.map(&:capitalize)
198
+
199
+ expect(capitalized_words).to eq %w[Çamur Ihlamur İnsan Ördek Şahika Ümraniye]
200
+ end
201
+
202
+ it 'capitalizes the first character of a string and downcase others' do
203
+ expect('türkÇE desteĞİ'.capitalize).to eq 'Türkçe desteği'
204
+ end
205
+
206
+ it 'capitalizes the first character of an English string' do
207
+ english_word = 'spy'
208
+
209
+ expect(english_word.capitalize).to eq 'Spy'
210
+ end
211
+ end
212
+
213
+ context 'with destructive version' do
214
+ it 'changes the original value of the string' do
215
+ turkish_word = 'çamur'
216
+
217
+ expect { turkish_word.capitalize! }.to(change { turkish_word })
218
+ expect(turkish_word).to eq('Çamur')
219
+ end
220
+ end
221
+ end
222
+
223
+ describe '#casecmp' do
224
+ it 'compares Turkish characters correctly' do
225
+ result = downcased_turkish_alphabet.casecmp(upcased_turkish_alphabet)
226
+
227
+ expect(result.zero?).to be true
228
+ end
229
+
230
+ it 'compares Turkish characters correctly' do
231
+ expect('sıtkı'.casecmp('SıTKI')&.zero?).to be true
232
+ end
233
+ end
234
+
235
+ describe '#titleize' do
236
+ context 'with non-destructive version' do
237
+ it 'does not change the original value of the string' do
238
+ word = 'mERHABA çAMUR iSMETOĞULLARI'
239
+
240
+ expect { word.titleize }.to_not(change { word })
241
+ end
242
+
243
+ it 'upcases first character of all words' do
244
+ titleized = 'merhaba çamur ismet'.titleize
245
+
246
+ expect(titleized).to(eq('Merhaba Çamur İsmet'))
247
+ end
248
+
249
+ it 'no problem with words that consist of special chars only' do
250
+ titleized = '(( merhaba çamur ismet'.titleize
251
+
252
+ expect(titleized).to(eq('(( Merhaba Çamur İsmet'))
253
+ end
254
+
255
+ it 'downcases characters other than first characters of all words' do
256
+ titleized = 'mERHABA çAMUR iSMETOĞULLARI'.titleize
257
+
258
+ expect(titleized).to(eq('Merhaba Çamur İsmetoğulları'))
259
+ end
260
+
261
+ it 'support strings that include paranthesis, quotes, etc.' do
262
+ titleized = "rUBY roCkS... (really! 'tRUSt' ME)".titleize
263
+
264
+ expect(titleized).to(eq("Ruby Rocks... (Really! 'Trust' Me)"))
265
+ end
266
+ end
267
+
268
+ context 'with destructive version' do
269
+ it 'changes the original value of the string' do
270
+ word = 'mERHABA çAMUR iSMETOĞULLARI'
271
+
272
+ expect { word.titleize! }.to(change { word })
273
+ expect(word).to(eq('Merhaba Çamur İsmetoğulları'))
274
+ end
275
+ end
276
+ end
277
+
278
+ describe '#swapcase' do
279
+ context 'with non-destructive version' do
280
+ it 'does not change the original value of the string' do
281
+ word = 'mErHaba çamur ismetoğullarI'
282
+
283
+ expect { word.swapcase }.to_not(change { word })
284
+ end
285
+
286
+ it 'swaps characters correctly' do
287
+ word = 'mErHaba çamur ismetoğullarI'.swapcase
288
+
289
+ expect(word).to(eq('MeRhABA ÇAMUR İSMETOĞULLARı'))
290
+ end
291
+ end
292
+
293
+ context 'with destructive version' do
294
+ it 'changes the original value of the string' do
295
+ word = 'mErHaba çamur ismetoğullarI'
296
+
297
+ expect { word.swapcase! }.to(change { word })
298
+ expect(word).to(eq('MeRhABA ÇAMUR İSMETOĞULLARı'))
299
+ end
300
+ end
301
+ end
302
+
303
+ describe '#match' do
304
+ it "matches Turkish characters when regex include '\\w'" do
305
+ expect('Aşağı'.match(/\w+/).to_s).to(eq('Aşağı'))
306
+ expect('Aşağı Ayrancı'.match(/^\w+\s\w+$/).to_s).to(eq('Aşağı Ayrancı'))
307
+ end
308
+
309
+ it 'matches Turkish characters when regex include lowercase range' do
310
+ expect('aüvvağğ öövvaağ'.match(/^[a-z]+\s[a-z]+$/).to_s).to(eq('aüvvağğ öövvaağ'))
311
+ end
312
+
313
+ it 'matches Turkish characters when regex include uppercase range' do
314
+ expect('BAĞCIlar'.match(/[A-Z]+/).to_s).to(eq('BAĞCI'))
315
+ end
316
+
317
+ it "doesn't match Turkish characters when regex include '\\W'" do
318
+ expect('Aşağı Ayrancı'.match(/\W+/).to_s).to(eq(' '))
319
+ end
320
+ end
321
+
322
+ describe '#scan' do
323
+ it "matches Turkish characters when regex include '\\w'" do
324
+ expect(turkish_words.join(' ').scan(/\w+/)).to eq(turkish_words)
325
+ end
326
+
327
+ it 'matches Turkish characters when regex include lowercase range' do
328
+ expect(turkish_words.join(' ').scan(/^[a-z\s]+$/)).to(eq([turkish_words.join(' ')]))
329
+ end
330
+
331
+ it 'matches Turkish characters when regex include uppercase range' do
332
+ expect(turkish_words.join(' ').upcase.scan(/^[A-Z\s]+$/)).to(eq([turkish_words.join(' ').upcase]))
333
+ end
334
+
335
+ it "matches Turkish characters when regex include '\\w'" do
336
+ expect(turkish_words.join(' ').scan(/\W+/).map(&:strip).all?(&:empty?)).to be true
337
+ end
338
+ end
339
+
340
+ describe '#sub' do
341
+ context 'non-destructive version' do
342
+ it 'does not affect the object' do
343
+ word = 'ağapaşa ağa'
344
+
345
+ expect { word.sub(/\w+/, 'bey') }.to_not(change { word })
346
+ end
347
+
348
+ it 'matches Turkish characters, and replaces them' do
349
+ expect('ağapaşa ağa'.sub(/\w+/, 'bey')).to(eq('bey ağa'))
350
+ expect('ağapaşa ağa şapka'.sub(/\W+/, 'bey')).to(eq('ağapaşabeyağa şapka'))
351
+ expect('ağapaşaağa'.sub(/[a-h]+/, 'bey')).to(eq('beypaşaağa'))
352
+ end
353
+ end
354
+
355
+ context 'destructive version' do
356
+ it 'affects the object' do
357
+ word = 'ağapaşa ağa'
358
+
359
+ expect { word.sub!(/\w+/, 'bey') }.to(change { word }.from('ağapaşa ağa').to('bey ağa'))
360
+ end
361
+ end
362
+ end
363
+
364
+ describe '#gsub' do
365
+ context 'non-destructive version' do
366
+ it 'does not affect the object' do
367
+ word = 'ağapaşa ağa'
368
+
369
+ expect { word.gsub(/\w+/, 'bey') }.to_not(change { word })
370
+ end
371
+
372
+ it 'matches Turkish characters, and replaces them' do
373
+ expect('ağapaşa ağa'.gsub(/\w+/, 'bey')).to(eq('bey bey'))
374
+ expect('ağapaşa ağa şapka'.gsub(/\W+/, 'bey')).to(eq('ağapaşabeyağabeyşapka'))
375
+ expect('ağapaşaağa'.gsub(/[a-h]+/, 'bey')).to(eq('beypbeyşbey'))
376
+ end
377
+ end
378
+
379
+ context 'destructive version' do
380
+ it 'affects the object' do
381
+ word = 'ağapaşa ağa'
382
+
383
+ expect { word.gsub!(/\w+/, 'bey') }.to(change { word }.from('ağapaşa ağa').to('bey bey'))
384
+ end
385
+ end
386
+ end
387
+
388
+ describe '#>' do
389
+ it 'should compares turkish cars correctly' do
390
+ expect('d' > 'ç').to be true
391
+ expect('ağa' > 'aga').to be true
392
+ expect('ğ' > 'h').to be false
393
+ end
394
+ end
395
+
396
+ describe '#>=' do
397
+ it 'should compares turkish cars correctly' do
398
+ expect('d' >= 'ç').to be true
399
+ expect('aha' >= 'ağa').to be true
400
+ expect('ğ.' >= 'ğ').to be true
401
+ end
402
+ end
403
+
404
+ describe '#<' do
405
+ it 'should compares turkish cars correctly' do
406
+ expect('d' < 'ç').to be false
407
+ expect('ağa' < 'aga').to be false
408
+ expect('ğ' < 'h').to be true
409
+ end
410
+ end
411
+
412
+ describe '#<=' do
413
+ it 'should compares turkish cars correctly' do
414
+ expect('d' <= 'ç').to be false
415
+ expect('aha' <= 'ağa').to be false
416
+ expect('ğ.' <= 'ğ').to be false
417
+ end
418
+ end
419
+
420
+ describe '#<=>' do
421
+ let(:sorted_equal_length_strings) { %w[Cahit Çağla Ömer Sıtkı Şakir] }
422
+ let(:sorted_different_length_strings) { %w[c ca falan om saki sıt] }
423
+ context 'with equal length strings' do
424
+ it 'works for smaller test' do
425
+ 0.upto(sorted_equal_length_strings.length - 2) do |i|
426
+ expect(sorted_equal_length_strings[i] <=> sorted_equal_length_strings[i + 1]).to(eq(-1))
427
+ end
428
+ end
429
+
430
+ it 'works for bigger test' do
431
+ (sorted_equal_length_strings.length - 1).downto(1) do |i|
432
+ expect(sorted_equal_length_strings[i] <=> sorted_equal_length_strings[i - 1]).to(eq(1))
433
+ end
434
+ end
435
+
436
+ it 'works for equals test' do
437
+ sorted_equal_length_strings.each do |str|
438
+ expect(str <=> str).to eq(0) # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands
439
+ end
440
+ end
441
+ end
442
+
443
+ context 'with different length strings' do
444
+ it 'works for smaller test' do
445
+ 0.upto(sorted_different_length_strings.length - 2) do |i|
446
+ expect(sorted_different_length_strings[i] <=> sorted_different_length_strings[i + 1]).to eq(-1)
447
+ end
448
+ end
449
+
450
+ it 'works for bigger test' do
451
+ (sorted_different_length_strings.length - 1).downto(1) do |i|
452
+ expect(sorted_different_length_strings[i] <=> sorted_different_length_strings[i - 1]).to eq(1)
453
+ end
454
+ end
455
+ end
456
+
457
+ context 'invalid comparisons' do
458
+ it 'returns nil' do
459
+ expect('a' <=> 3.5).to be nil
460
+ expect('a' <=> true).to be nil
461
+ expect('a' <=> Object.new).to be nil
462
+ expect('a' <=> 1).to be nil
463
+ end
464
+ end
465
+ end
466
+ end
467
+ end