File: writable.rb

package info (click to toggle)
ruby-protocol-http 0.55.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 840 kB
  • sloc: ruby: 6,904; makefile: 4
file content (199 lines) | stat: -rw-r--r-- 4,102 bytes parent folder | download
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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# frozen_string_literal: true

# Released under the MIT License.
# Copyright, 2024, by Samuel Williams.

require "protocol/http/body/writable"
require "protocol/http/body/deflate"
require "protocol/http/body/a_writable_body"

describe Protocol::HTTP::Body::Writable do
	let(:body) {subject.new}
	
	it_behaves_like Protocol::HTTP::Body::AWritableBody
	
	with "#length" do
		it "should be unspecified by default" do
			expect(body.length).to be_nil
		end
	end
	
	with "#closed?" do
		it "should not be closed by default" do
			expect(body).not.to be(:closed?)
		end
	end
	
	with "#ready?" do
		it "should be ready if chunks are available" do
			expect(body).not.to be(:ready?)
			
			body.write("Hello")
			
			expect(body).to be(:ready?)
		end
		
		it "should be ready if closed" do
			body.close
			
			expect(body).to be(:ready?)
		end
	end
	
	with "#empty?" do
		it "should be empty if closed with no pending chunks" do
			expect(body).not.to be(:empty?)
			
			body.close_write
			
			expect(body).to be(:empty?)
		end
		
		it "should become empty when pending chunks are read" do
			body.write("Hello")
			
			body.close_write
			
			expect(body).not.to be(:empty?)
			body.read
			expect(body).to be(:empty?)
		end
		
		it "should not be empty if chunks are available" do
			body.write("Hello")
			expect(body).not.to be(:empty?)
		end
	end
	
	with "#write" do
		it "should write chunks" do
			body.write("Hello")
			body.write("World")
			
			expect(body.read).to be == "Hello"
			expect(body.read).to be == "World"
		end
		
		it "can't write to closed body" do
			body.close
			
			expect do
				body.write("Hello")
			end.to raise_exception(Protocol::HTTP::Body::Writable::Closed)
		end
		
		it "can write and read data" do
			3.times do |i|
				body.write("Hello World #{i}")
				expect(body.read).to be == "Hello World #{i}"
			end
		end
		
		it "can buffer data in order" do
			3.times do |i|
				body.write("Hello World #{i}")
			end
			
			3.times do |i|
				expect(body.read).to be == "Hello World #{i}"
			end
		end
	end
	
	with "#join" do
		it "can join chunks" do
			3.times do |i|
				body.write("#{i}")
			end
			
			body.close_write
			
			expect(body.join).to be == "012"
		end
	end
	
	with "#each" do
		it "can read all data in order" do
			3.times do |i|
				body.write("Hello World #{i}")
			end
			
			body.close_write
			
			3.times do |i|
				chunk = body.read
				expect(chunk).to be == "Hello World #{i}"
			end
		end
		
		it "can propagate failures" do
			body.write("Beep boop") # This will cause a failure.
			
			expect do
				body.each do |chunk|
					raise RuntimeError.new("It was too big!")
				end
			end.to raise_exception(RuntimeError, message: be =~ /big/)
			
			expect do
				body.write("Beep boop") # This will fail.
			end.to raise_exception(RuntimeError, message: be =~ /big/)
		end
		
		it "can propagate failures in nested bodies" do
			nested = ::Protocol::HTTP::Body::Deflate.for(body)
			
			body.write("Beep boop") # This will cause a failure.
			
			expect do
				nested.each do |chunk|
					raise RuntimeError.new("It was too big!")
				end
			end.to raise_exception(RuntimeError, message: be =~ /big/)
			
			expect do
				body.write("Beep boop") # This will fail.
			end.to raise_exception(RuntimeError, message: be =~ /big/)
		end
		
		it "will stop after finishing" do
			body.write("Hello World!")
			body.close_write
			
			expect(body).not.to be(:empty?)
			
			body.each do |chunk|
				expect(chunk).to be == "Hello World!"
			end
			
			expect(body).to be(:empty?)
		end
	end
	
	with "#output" do
		it "can be used to write data" do
			body.output do |output|
				output.write("Hello World!")
			end
			
			expect(body.output).to be(:closed?)
			
			expect(body.read).to be == "Hello World!"
			expect(body.read).to be_nil
		end
		
		it "can propagate errors" do
			expect do
				body.output do |output|
					raise "Oops!"
				end
			end.to raise_exception(RuntimeError, message: be =~ /Oops/)
			
			expect(body).to be(:closed?)
			
			expect do
				body.read
			end.to raise_exception(RuntimeError, message: be =~ /Oops/)
		end
	end
end