strings 0.1.8 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +0,0 @@
1
- # fronzen_string_literal: true
2
-
3
- RSpec.describe Strings, '#fold' do
4
- it "folds a multiline text into a single line" do
5
- expect(Strings.fold("\tfoo \r\n\n\n bar")).to eq(" foo bar")
6
- end
7
- end
@@ -1,74 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe Strings::Pad, '#pad' do
4
- it "pads content with padding as a single value" do
5
- text = "Ignorance is the parent of fear."
6
- expect(Strings::Pad.pad(text, 1)).to eq([
7
- " ",
8
- " Ignorance is the parent of fear. ",
9
- " ",
10
- ].join("\n"))
11
- end
12
-
13
- it "pads content with specific padding as an array" do
14
- text = "Ignorance is the parent of fear."
15
- expect(Strings::Pad.pad(text, [1,1,1,1])).to eq([
16
- " ",
17
- " Ignorance is the parent of fear. ",
18
- " ",
19
- ].join("\n"))
20
- end
21
-
22
- it "pads with custom character" do
23
- text = "Ignorance is the parent of fear."
24
- expect(Strings::Pad.pad(text, [1, 2], fill: "*")).to eq([
25
- "************************************",
26
- "**Ignorance is the parent of fear.**",
27
- "************************************",
28
- ].join("\n"))
29
- end
30
-
31
- it "pads unicode content" do
32
- text = "ラドクリフ、マラソン"
33
- expect(Strings::Pad.pad(text, [1,1,1,1])).to eq([
34
- " ",
35
- " ラドクリフ、マラソン ",
36
- " "
37
- ].join("\n"))
38
- end
39
-
40
- it "pads multiline content" do
41
- text = "It is the easiest thing\nin the world for a man\nto look as if he had \na great secret in him."
42
- expect(Strings::Pad.pad(text, [1,2])).to eq([
43
- " ",
44
- " It is the easiest thing ",
45
- " in the world for a man ",
46
- " to look as if he had ",
47
- " a great secret in him. ",
48
- " ",
49
- ].join("\n"))
50
- end
51
-
52
- it "pads ANSI codes inside content" do
53
- text = "It is \e[35mthe easiest\e[0m thing\nin the \e[34mworld\e[0m for a man\nto look as if he had \na great \e[33msecret\e[0m in him."
54
- expect(Strings::Pad.pad(text, [1,1,1,1])).to eq([
55
- " ",
56
- " It is \e[35mthe easiest\e[0m thing ",
57
- " in the \e[34mworld\e[0m for a man ",
58
- " to look as if he had ",
59
- " a great \e[33msecret\e[0m in him. ",
60
- " ",
61
- ].join("\n"))
62
- end
63
-
64
- it "handles \r\n line separator" do
65
- text = "Closes #360\r\n\r\nCloses !217"
66
- expect(Strings::Pad.pad(text, [1,1,1,1])).to eq([
67
- " ",
68
- " Closes #360 ",
69
- " ",
70
- " Closes !217 ",
71
- " "
72
- ].join("\r\n"))
73
- end
74
- end
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe Strings, '#pad' do
4
- it "pads text" do
5
- text = 'ラドクリフ、マラソン五輪代表に1万m出場にも含み'
6
- expect(Strings.pad(text, [1,1,1,1])).to eql([
7
- ' ',
8
- ' ラドクリフ、マラソン五輪代表に1万m出場にも含み ',
9
- ' '
10
- ].join("\n"))
11
- end
12
- end
@@ -1,35 +0,0 @@
1
- # frozen_string_literal:true
2
-
3
- RSpec.describe Strings::Padder, '#parse' do
4
- it "parses nil" do
5
- instance = Strings::Padder.parse(nil)
6
- expect(instance.padding).to eq([])
7
- end
8
-
9
- it 'parses self' do
10
- value = Strings::Padder.new([])
11
- instance = Strings::Padder.parse(value)
12
- expect(instance.padding).to eq([])
13
- end
14
-
15
- it "parses digit" do
16
- instance = Strings::Padder.parse(5)
17
- expect(instance.padding).to eq([5,5,5,5])
18
- end
19
-
20
- it "parses 2-element array" do
21
- instance = Strings::Padder.parse([2,3])
22
- expect(instance.padding).to eq([2,3,2,3])
23
- end
24
-
25
- it "parses 4-element array" do
26
- instance = Strings::Padder.parse([1,2,3,4])
27
- expect(instance.padding).to eq([1,2,3,4])
28
- end
29
-
30
- it "fails to parse unknown value" do
31
- expect {
32
- Strings::Padder.parse(:unknown)
33
- }.to raise_error(Strings::Padder::ParseError)
34
- end
35
- end
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe Strings, '#sanitize' do
4
- it "removes ansi codes" do
5
- expect(Strings.sanitize("\e[33mfoo\e[0m")).to eq('foo')
6
- end
7
- end
@@ -1,74 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe Strings::Truncate, '#truncate' do
4
- let(:text) { 'ラドクリフ、マラソン五輪代表に1万m出場にも含み' }
5
-
6
- it "doesn't change text for 0 length" do
7
- expect(Strings::Truncate.truncate(text, 0)).to eq(text)
8
- end
9
-
10
- it "doensn't change text for nil length" do
11
- expect(Strings::Truncate.truncate(text, nil)).to eq(text)
12
- end
13
-
14
- it "truncate length of 1 results in just the trailing character" do
15
- expect(Strings::Truncate.truncate(text, 1)).to eq(Strings::Truncate::DEFAULT_TRAILING)
16
- end
17
-
18
- it "doesn't change text for equal length" do
19
- truncation = Strings::Truncate.truncate(text, text.length * 2)
20
- expect(truncation).to eq(text)
21
- end
22
-
23
- it 'truncates text and displays omission' do
24
- trailing = '…'
25
- expect(Strings::Truncate.truncate(text, 12)).to eq("ラドクリフ#{trailing}")
26
- end
27
-
28
- it "estimates total width correctly " do
29
- text = '太丸ゴシック体'
30
- trailing = '…'
31
- expect(Strings::Truncate.truncate(text, 8)).to eq("太丸ゴ#{trailing}")
32
- end
33
-
34
- it "doesn't truncate text when length exceeds content" do
35
- expect(Strings::Truncate.truncate(text, 100)).to eq(text)
36
- end
37
-
38
- it "doesn't truncate whole words" do
39
- text = "I know not all that may be coming, but be it what it will, I'll go to it laughing."
40
- trailing = '…'
41
- truncation = Strings::Truncate.truncate(text, separator: ' ')
42
- expect(truncation).to eq("I know not all that may be#{trailing}")
43
- end
44
-
45
- it 'truncates text with string separator' do
46
- trailing = '…'
47
- truncation = Strings::Truncate.truncate(text, 12, separator: '')
48
- expect(truncation).to eq("ラドクリフ#{trailing}")
49
- end
50
-
51
- it 'truncates text with regex separator' do
52
- trailing = '…'
53
- truncation = Strings::Truncate.truncate(text, 12, separator: /\s/)
54
- expect(truncation).to eq("ラドクリフ#{trailing}")
55
- end
56
-
57
- it 'truncates text with custom trailing' do
58
- trailing = '... (see more)'
59
- truncation = Strings::Truncate.truncate(text, 20, trailing: trailing)
60
- expect(truncation).to eq("ラド#{trailing}")
61
- end
62
-
63
- it 'correctly truncates with ANSI characters' do
64
- text = "I try \e[34mall things\e[0m, I achieve what I can"
65
- truncation = Strings::Truncate.truncate(text, 18)
66
- expect(truncation).to eq("I try \e[34mall things\e[0m…")
67
- end
68
-
69
- it "finishes on word boundary" do
70
- text = "for there is no folly of the beast of the earth"
71
- truncation = Strings::Truncate.truncate(text, 20, separator: ' ')
72
- expect(truncation).to eq('for there is no…')
73
- end
74
- end
@@ -1,8 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe Strings, '#truncate' do
4
- it "truncates text" do
5
- text = 'ラドクリフ、マラソン五輪代表に1万m出場にも含み'
6
- expect(Strings.truncate(text, 12)).to eq('ラドクリフ…')
7
- end
8
- end
@@ -1,65 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe "#insert_ansi" do
4
- it "doesn't do anything when empty stack" do
5
- text = "Ignorance is the parent of fear."
6
-
7
- val = Strings::Wrap.insert_ansi(text, [])
8
-
9
- expect(val).to eq(text)
10
- end
11
-
12
- it "inserts ANSI strings in a single line" do
13
- text = "Ignorance is the parent of fear."
14
- stack = [["\e[32;44m", 0], ["\e[0m", text.size]]
15
-
16
- val = Strings::Wrap.insert_ansi(text, stack)
17
-
18
- expect(val).to eq("\e[32;44mIgnorance is the parent of fear.\e[0m")
19
- expect(stack).to eq([])
20
- end
21
-
22
- it "inserts ANSI strings with missing reset in a single line" do
23
- text = "Ignorance is the parent of fear."
24
- stack = [["\e[32;44m", 0]]
25
-
26
- val = Strings::Wrap.insert_ansi(text, stack)
27
-
28
- expect(val).to eq("\e[32;44mIgnorance is the parent of fear.\e[0m")
29
- expect(stack).to eq([["\e[32;44m", 0]])
30
- end
31
-
32
- it "inserts 3 ansi strings in a single line" do
33
- text = "Ignorance is the parent of fear."
34
- stack = [
35
- ["\e[32m", 0], ["\e[0m", 9],
36
- ["\e[33m", 13], ["\e[0m", 16],
37
- ["\e[34m", 27], ["\e[0m", 31]
38
- ]
39
-
40
- val = Strings::Wrap.insert_ansi(text, stack)
41
-
42
- expect(val).to eq("\e[32mIgnorance\e[0m is \e[33mthe\e[0m parent of \e[34mfear\e[0m.")
43
- expect(stack).to eq([])
44
- end
45
-
46
- it "inserts nested ANSI strings in a single line" do
47
- text = "Ignorance is the parent of fear."
48
- stack = [["\e[32m", 10], ["\e[33m", 17], ["\e[0m", 23], ["\e[0m", 26]]
49
-
50
- val = Strings::Wrap.insert_ansi(text, stack)
51
-
52
- expect(val).to eq("Ignorance \e[32mis the \e[33mparent\e[0m of\e[0m fear.")
53
- expect(stack).to eq([])
54
- end
55
-
56
- it "removes matching pairs of ANSI codes only" do
57
- text = "one"
58
- stack = [["\e[32m", 0], ["\e[0m", 3], ["\e[33m", 3]]
59
-
60
- val = Strings::Wrap.insert_ansi(text, stack)
61
-
62
- expect(val).to eq("\e[32mone\e[0m")
63
- expect(stack).to eq([["\e[33m", 3]])
64
- end
65
- end
@@ -1,207 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe Strings::Wrap, '.wrap' do
4
- context 'when unicode' do
5
- let(:text) { 'ラドクリフ、マラソン五輪代表に1万m出場にも含み' }
6
-
7
- it "doesn't wrap at zero length" do
8
- expect(Strings::Wrap.wrap(text, 0)).to eq(text)
9
- end
10
-
11
- it "doesn't wrap at nil length" do
12
- expect(Strings::Wrap.wrap(text, nil)).to eq(text)
13
- end
14
-
15
- it "doesn't wrap at length exceeding content length" do
16
- expect(Strings::Wrap.wrap(text, 100)).to eq(text)
17
- end
18
-
19
- it "wraps minimal width" do
20
- str = "#?%"
21
-
22
- val = Strings::Wrap.wrap(str, 1)
23
-
24
- expect(val).to eq([
25
- "#",
26
- "?",
27
- "%"
28
- ].join("\n"))
29
- end
30
-
31
- it "wraps correctly unbreakable words" do
32
- expect(Strings::Wrap.wrap('foobar1', 3)).to eq([
33
- "foo",
34
- "bar",
35
- "1"
36
- ].join("\n"))
37
- end
38
-
39
- it "collapses multiple line breaks " do
40
- text = "some \r\n\n\n\nunbreakable\n\n\n\n \r\r\rcontent \t"
41
- expect(Strings::Wrap.wrap(text, 5)).to eq([
42
- "some ",
43
- "unbre",
44
- "akabl",
45
- "e",
46
- " ",
47
- "conte",
48
- "nt "
49
- ].join("\r\n"))
50
- end
51
-
52
- it "preserves newlines" do
53
- text = "It is not down\n on any map;\n true places never are."
54
- expect(Strings::Wrap.wrap(text, 10)).to eq([
55
- "It is not ",
56
- "down",
57
- " on any ",
58
- "map;",
59
- " true ",
60
- "places ",
61
- "never are."
62
- ].join("\n"))
63
- end
64
-
65
- it "wraps ascii text" do
66
- text = "for there is no folly of the beast of the earth which is not infinitely outdone by the madness of men "
67
- expect(Strings::Wrap.wrap(text, 16)).to eq([
68
- "for there is no ",
69
- "folly of the ",
70
- "beast of the ",
71
- "earth which is ",
72
- "not infinitely ",
73
- "outdone by the ",
74
- "madness of men "
75
- ].join("\n"))
76
- end
77
-
78
- it 'wraps at 8 characters' do
79
- expect(Strings::Wrap.wrap(text, 8)).to eq([
80
- "ラドクリ",
81
- "フ、マラ",
82
- "ソン五輪",
83
- "代表に1",
84
- "万m出場",
85
- "にも含み"
86
- ].join("\n"))
87
- end
88
-
89
- it 'preserves whitespace' do
90
- text = " As for me, I am tormented with an everlasting itch for things remote. "
91
- expect(Strings::Wrap.wrap(text, 10)).to eq([
92
- " As for ",
93
- "me, I ",
94
- "am ",
95
- "tormented ",
96
- "with an ",
97
- "e",
98
- "verlasting",
99
- " itch ",
100
- "for ",
101
- "things ",
102
- "remote. "
103
- ].join("\n"))
104
- end
105
- end
106
-
107
- context 'when long text' do
108
- it "wraps long text at 45 characters" do
109
- text =
110
- "What of it, if some old hunks of a sea-captain orders me to get a broom and sweep down the decks? What does that indignity amount to, weighed, I mean, in the scales of the New Testament? Do you think the archangel Gabriel thinks anything the less of me, because I promptly and respectfully obey that old hunks in that particular instance? Who ain't a slave? Tell me that. Well, then, however the old sea-captains may order me about--however they may thump and punch me about, I have the satisfaction of knowing that it is all right;"
111
- expect(Strings::Wrap.wrap(text, 45)).to eq unindent <<-EOS
112
- What of it, if some old hunks of a \nsea-captain orders me to get a broom and \n sweep down the decks? What does that \nindignity amount to, weighed, I mean, in the \n scales of the New Testament? Do you think \nthe archangel Gabriel thinks anything the \nless of me, because I promptly and \nrespectfully obey that old hunks in that \nparticular instance? Who ain't a slave? Tell \nme that. Well, then, however the old \nsea-captains may order me about--however \nthey may thump and punch me about, I have \nthe satisfaction of knowing that it is all \nright;
113
- EOS
114
- end
115
- end
116
-
117
- context 'with newlines' do
118
- it "preserves newlines for both prefix and postfix" do
119
- text = "\n\nラドクリフ、マラソン五輪代表に1万m出場にも含み\n\n\n"
120
- expect(Strings::Wrap.wrap(text, 10)).to eq([
121
- "\nラドクリフ",
122
- "、マラソン",
123
- "五輪代表に",
124
- "1万m出場に",
125
- "も含み\n"
126
- ].join("\n"))
127
- end
128
-
129
- it "handles \r\n line separator" do
130
- text = "Closes #360\r\n\r\nCloses !217"
131
- expect(Strings::Wrap.wrap(text, 15)).to eq(text)
132
- end
133
- end
134
-
135
- context 'with ANSI codes' do
136
- it "wraps ANSI chars" do
137
- text = "\e[32;44mIgnorance is the parent of fear.\e[0m"
138
- expect(Strings::Wrap.wrap(text, 14)).to eq([
139
- "\e[32;44mIgnorance is \e[0m",
140
- "\e[32;44mthe parent of \e[0m",
141
- "\e[32;44mfear.\e[0m",
142
- ].join("\n"))
143
- end
144
-
145
- it "wraps ANSI in the middle of text" do
146
- text = "Ignorance is the \e[32mparent\e[0m of fear."
147
- expect(Strings::Wrap.wrap(text, 14)).to eq([
148
- "Ignorance is ",
149
- "the \e[32mparent\e[0m of ",
150
- "fear.",
151
- ].join("\n"))
152
- end
153
-
154
- it "wraps multline ANSI codes" do
155
- text = "\e32;44mMulti\nLine\nContent.\e[0m"
156
- expect(Strings::Wrap.wrap(text, 14)).to eq([
157
- "\e32;44mMulti\e[0m",
158
- "\e32;44mLine\e[0m",
159
- "\e32;44mContent.\e[0m",
160
- ].join("\n"))
161
- end
162
-
163
- it "wraps multiple ANSI codes in a single line" do
164
- text = "Talk \e[32mnot\e[0m to me of \e[33mblasphemy\e[0m, man; I'd \e[35mstrike the sun\e[0m if it insulted me."
165
- expect(Strings::Wrap.wrap(text, 30)).to eq([
166
- "Talk \e[32mnot\e[0m to me of \e[33mblasphemy\e[0m, ",
167
- "man; I'd \e[35mstrike the sun\e[0m if it ",
168
- "insulted me."
169
- ].join("\n"))
170
- end
171
-
172
- it "applies ANSI codes when below wrap width" do
173
- str = "\e[32mone\e[0m\e[33mtwo\e[0m"
174
-
175
- val = Strings::Wrap.wrap(str, 6)
176
-
177
- expect(val).to eq("\e[32mone\e[0m\e[33mtwo\e[0m")
178
- end
179
-
180
- xit "splits ANSI codes matching wrap width with space between codes" do
181
- str = "\e[32mone\e[0m \e[33mtwo\e[0m"
182
-
183
- val = Strings::Wrap.wrap(str, 3)
184
-
185
- expect(val).to eq("\e[32mone\e[0m\n\e[33mtwo\e[0m")
186
- end
187
-
188
- xit "splits ANSI codes matching wrap width" do
189
- str = "\e[32mone\e[0m\e[33mtwo\e[0m"
190
-
191
- val = Strings::Wrap.wrap(str, 3)
192
-
193
- expect(val).to eq("\e[32mone\e[0m\n\e[33mtwo\e[0m")
194
- end
195
-
196
- xit "wraps deeply nested ANSI codes correctly" do
197
- str = "\e[32mone\e[33mtwo\e[0m\e[0m"
198
-
199
- val = Strings::Wrap.wrap(str, 3)
200
-
201
- expect(val).to eq([
202
- "\e[32mone\e[0m",
203
- "\e[33mtwo\e[0m",
204
- ].join("\n"))
205
- end
206
- end
207
- end