1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
|
describe :string_each_line, shared: true do
it "splits using default newline separator when none is specified" do
a = []
"one\ntwo\r\nthree".send(@method) { |s| a << s }
a.should == ["one\n", "two\r\n", "three"]
b = []
"hello\n\n\nworld".send(@method) { |s| b << s }
b.should == ["hello\n", "\n", "\n", "world"]
c = []
"\n\n\n\n\n".send(@method) {|s| c << s}
c.should == ["\n", "\n", "\n", "\n", "\n"]
end
it "splits self using the supplied record separator and passes each substring to the block" do
a = []
"one\ntwo\r\nthree".send(@method, "\n") { |s| a << s }
a.should == ["one\n", "two\r\n", "three"]
b = []
"hello\nworld".send(@method, 'l') { |s| b << s }
b.should == [ "hel", "l", "o\nworl", "d" ]
c = []
"hello\n\n\nworld".send(@method, "\n") { |s| c << s }
c.should == ["hello\n", "\n", "\n", "world"]
end
it "splits strings containing multibyte characters" do
s = <<~EOS
foo
🤡🤡🤡🤡🤡🤡🤡
bar
baz
EOS
b = []
s.send(@method) { |part| b << part }
b.should == ["foo\n", "🤡🤡🤡🤡🤡🤡🤡\n", "bar\n", "baz\n"]
end
it "taints substrings that are passed to the block if self is tainted" do
"one\ntwo\r\nthree".taint.send(@method) { |s| s.tainted?.should == true }
"x.y.".send(@method, ".".taint) { |s| s.tainted?.should == false }
end
it "passes self as a whole to the block if the separator is nil" do
a = []
"one\ntwo\r\nthree".send(@method, nil) { |s| a << s }
a.should == ["one\ntwo\r\nthree"]
end
ruby_version_is ''...'2.5' do
it "yields paragraphs (broken by 2 or more successive newlines) when passed ''" do
a = []
"hello\nworld\n\n\nand\nuniverse\n\n\n\n\n".send(@method, '') { |s| a << s }
a.should == ["hello\nworld\n\n\n", "and\nuniverse\n\n\n\n\n"]
a = []
"hello\nworld\n\n\nand\nuniverse\n\n\n\n\ndog".send(@method, '') { |s| a << s }
a.should == ["hello\nworld\n\n\n", "and\nuniverse\n\n\n\n\n", "dog"]
end
end
ruby_version_is '2.5' do
it "yields paragraphs (broken by 2 or more successive newlines) when passed '' and replaces multiple newlines with only two ones" do
a = []
"hello\nworld\n\n\nand\nuniverse\n\n\n\n\n".send(@method, '') { |s| a << s }
a.should == ["hello\nworld\n\n", "and\nuniverse\n\n"]
a = []
"hello\nworld\n\n\nand\nuniverse\n\n\n\n\ndog".send(@method, '') { |s| a << s }
a.should == ["hello\nworld\n\n", "and\nuniverse\n\n", "dog"]
end
end
describe "uses $/" do
before :each do
@before_separator = $/
end
after :each do
$/ = @before_separator
end
it "as the separator when none is given" do
[
"", "x", "x\ny", "x\ry", "x\r\ny", "x\n\r\r\ny",
"hello hullo bello"
].each do |str|
["", "llo", "\n", "\r", nil].each do |sep|
expected = []
str.send(@method, sep) { |x| expected << x }
$/ = sep
actual = []
str.send(@method) { |x| actual << x }
actual.should == expected
end
end
end
end
it "yields subclass instances for subclasses" do
a = []
StringSpecs::MyString.new("hello\nworld").send(@method) { |s| a << s.class }
a.should == [StringSpecs::MyString, StringSpecs::MyString]
end
it "returns self" do
s = "hello\nworld"
(s.send(@method) {}).should equal(s)
end
it "tries to convert the separator to a string using to_str" do
separator = mock('l')
separator.should_receive(:to_str).and_return("l")
a = []
"hello\nworld".send(@method, separator) { |s| a << s }
a.should == [ "hel", "l", "o\nworl", "d" ]
end
it "does not care if the string is modified while substituting" do
str = "hello\nworld."
out = []
str.send(@method){|x| out << x; str[-1] = '!' }.should == "hello\nworld!"
out.should == ["hello\n", "world."]
end
it "raises a TypeError when the separator can't be converted to a string" do
lambda { "hello world".send(@method, false) {} }.should raise_error(TypeError)
lambda { "hello world".send(@method, mock('x')) {} }.should raise_error(TypeError)
end
it "accepts a string separator" do
"hello world".send(@method, ?o).to_a.should == ["hello", " wo", "rld"]
end
it "raises a TypeError when the separator is a symbol" do
lambda { "hello world".send(@method, :o).to_a }.should raise_error(TypeError)
end
ruby_version_is '2.4' do
context "when `chomp` keyword argument is passed" do
it "removes new line characters when separator is not specified" do
a = []
"hello \nworld\n".send(@method, chomp: true) { |s| a << s }
a.should == ["hello ", "world"]
a = []
"hello \r\nworld\r\n".send(@method, chomp: true) { |s| a << s }
a.should == ["hello ", "world"]
end
it "removes only specified separator" do
a = []
"hello world".send(@method, ' ', chomp: true) { |s| a << s }
a.should == ["hello", "world"]
end
# https://bugs.ruby-lang.org/issues/14257
it "ignores new line characters when separator is specified" do
a = []
"hello\n world\n".send(@method, ' ', chomp: true) { |s| a << s }
a.should == ["hello\n", "world\n"]
a = []
"hello\r\n world\r\n".send(@method, ' ', chomp: true) { |s| a << s }
a.should == ["hello\r\n", "world\r\n"]
end
end
end
end
|