Skip to content

Commit db9b0ed

Browse files
authored
Add more tests (#171)
1 parent 92adcd8 commit db9b0ed

File tree

7 files changed

+262
-11
lines changed

7 files changed

+262
-11
lines changed

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
1+
#Mac OS X
2+
*.DS_Store
3+
4+
#VS Code
5+
/.vscode/
6+
17
*.jl.cov
28
*.jl.*.cov
39
*.jl.mem
10+
/test/Manifest.toml
411
/Manifest.toml
512
/docs/build/
613
/docs/Manifest.toml

Project.toml

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,3 @@ TestExt = ["Test", "Random"]
1919
Random = "1"
2020
Test = "1"
2121
julia = "1.6"
22-
23-
[extras]
24-
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
25-
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
26-
27-
[targets]
28-
test = ["Test", "Random"]

test/Project.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[deps]
2+
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
3+
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
4+
TranscodingStreams = "3bb67fe8-82b1-5028-8e26-92a6c54297fa"

test/REQUIRE

Lines changed: 0 additions & 4 deletions
This file was deleted.

test/codecdoubleframe.jl

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
using TranscodingStreams
2+
using Random
3+
using Test
4+
using TranscodingStreams:
5+
TranscodingStreams,
6+
TranscodingStream,
7+
test_roundtrip_read,
8+
test_roundtrip_write,
9+
test_roundtrip_lines,
10+
test_roundtrip_transcode,
11+
test_roundtrip_fileio,
12+
test_chunked_read,
13+
test_chunked_write,
14+
Error
15+
16+
# An insane codec for testing the codec APIs.
17+
struct DoubleFrameEncoder <: TranscodingStreams.Codec
18+
opened::Base.RefValue{Bool}
19+
stopped::Base.RefValue{Bool}
20+
got_stop_msg::Base.RefValue{Bool}
21+
end
22+
23+
DoubleFrameEncoder() = DoubleFrameEncoder(Ref(false), Ref(false), Ref(false))
24+
25+
function TranscodingStreams.process(
26+
codec :: DoubleFrameEncoder,
27+
input :: TranscodingStreams.Memory,
28+
output :: TranscodingStreams.Memory,
29+
error :: TranscodingStreams.Error,
30+
)
31+
if input.size == 0
32+
codec.got_stop_msg[] = true
33+
end
34+
35+
if output.size < 2
36+
error[] = ErrorException("requires a minimum of 2 bytes of output space")
37+
return 0, 0, :error
38+
elseif codec.stopped[]
39+
error[] = ErrorException("cannot process after stopped")
40+
return 0, 0, :error
41+
elseif codec.got_stop_msg[] && input.size != 0
42+
error[] = ErrorException("cannot accept more input after getting stop message")
43+
return 0, 0, :error
44+
elseif !codec.opened[]
45+
output[1] = UInt8('[')
46+
output[2] = UInt8(' ')
47+
codec.opened[] = true
48+
return 0, 2, :ok
49+
elseif codec.got_stop_msg[]
50+
output[1] = UInt8(' ')
51+
output[2] = UInt8(']')
52+
codec.stopped[] = true
53+
return 0, 2, :end
54+
else
55+
i = j = 0
56+
while i + 1 lastindex(input) && j + 2 lastindex(output)
57+
b = input[i+1]
58+
i += 1
59+
output[j+1] = output[j+2] = b
60+
j += 2
61+
end
62+
return i, j, :ok
63+
end
64+
end
65+
66+
function TranscodingStreams.expectedsize(
67+
:: DoubleFrameEncoder,
68+
input :: TranscodingStreams.Memory)
69+
return input.size * 2 + 2 + 2
70+
end
71+
72+
function TranscodingStreams.minoutsize(
73+
:: DoubleFrameEncoder,
74+
:: TranscodingStreams.Memory)
75+
return 2
76+
end
77+
78+
function TranscodingStreams.startproc(codec::DoubleFrameEncoder, ::Symbol, error::Error)
79+
codec.opened[] = false
80+
codec.got_stop_msg[] = false
81+
codec.stopped[] = false
82+
return :ok
83+
end
84+
85+
# An insane codec for testing the codec APIs.
86+
struct DoubleFrameDecoder <: TranscodingStreams.Codec
87+
state::Base.RefValue{Int}
88+
a::Base.RefValue{UInt8}
89+
b::Base.RefValue{UInt8}
90+
end
91+
92+
DoubleFrameDecoder() = DoubleFrameDecoder(Ref(1), Ref(0x00), Ref(0x00))
93+
94+
function TranscodingStreams.process(
95+
codec :: DoubleFrameDecoder,
96+
input :: TranscodingStreams.Memory,
97+
output :: TranscodingStreams.Memory,
98+
error :: TranscodingStreams.Error,
99+
)
100+
Δin::Int = 0
101+
Δout::Int = 0
102+
103+
function do_read(ref)
104+
iszero(input.size) && error("expected byte")
105+
if Δin + 1 lastindex(input)
106+
Δin += 1
107+
ref[] = input[Δin]
108+
true
109+
else
110+
false
111+
end
112+
end
113+
114+
function do_write(x::UInt8)
115+
if Δout + 1 lastindex(output)
116+
Δout += 1
117+
output[Δout] = x
118+
true
119+
else
120+
false
121+
end
122+
end
123+
124+
try
125+
# hacky resumable function using goto, just for fun.
126+
oldstate = codec.state[]
127+
if oldstate == 1
128+
@goto state1
129+
elseif oldstate == 2
130+
@goto state2
131+
elseif oldstate == 3
132+
@goto state3
133+
elseif oldstate == 4
134+
@goto state4
135+
elseif oldstate == 5
136+
@goto state5
137+
elseif oldstate == 6
138+
error("cannot process after ending")
139+
elseif oldstate == 7
140+
error("cannot process after erroring")
141+
else
142+
error("unexpected state $(oldstate)")
143+
end
144+
145+
@label state1
146+
do_read(codec.a) || return (codec.state[]=1; (Δin, Δout, :ok))
147+
codec.a[] != UInt8('[') && error("expected [")
148+
@label state2
149+
do_read(codec.a) || return (codec.state[]=2; (Δin, Δout, :ok))
150+
codec.a[] != UInt8(' ') && error("expected space")
151+
while true
152+
@label state3
153+
do_read(codec.a) || return (codec.state[]=3; (Δin, Δout, :ok))
154+
@label state4
155+
do_read(codec.b) || return (codec.state[]=4; (Δin, Δout, :ok))
156+
if codec.a[] == codec.b[]
157+
@label state5
158+
do_write(codec.a[]) || return (codec.state[]=5; (Δin, Δout, :ok))
159+
elseif codec.a[] == UInt8(' ') && codec.b[] == UInt8(']')
160+
break
161+
else
162+
error("expected matching bytes or space and ]")
163+
end
164+
end
165+
codec.state[]=6
166+
return Δin, Δout, :end
167+
catch e
168+
codec.state[]=7
169+
e isa ErrorException || rethrow()
170+
error[] = e
171+
return Δin, Δout, :error
172+
end
173+
end
174+
175+
function TranscodingStreams.startproc(codec::DoubleFrameDecoder, ::Symbol, error::Error)
176+
codec.state[] = 1
177+
codec.a[] = 0x00
178+
codec.b[] = 0x00
179+
return :ok
180+
end
181+
182+
const DoubleFrameEncoderStream{S} = TranscodingStream{DoubleFrameEncoder,S} where S<:IO
183+
DoubleFrameEncoderStream(stream::IO; kwargs...) = TranscodingStream(DoubleFrameEncoder(), stream; kwargs...)
184+
185+
const DoubleFrameDecoderStream{S} = TranscodingStream{DoubleFrameDecoder,S} where S<:IO
186+
DoubleFrameDecoderStream(stream::IO; kwargs...) = TranscodingStream(DoubleFrameDecoder(), stream; kwargs...)
187+
188+
189+
@testset "DoubleFrame Codecs" begin
190+
@test transcode(DoubleFrameEncoder, b"") == b"[ ]"
191+
@test transcode(DoubleFrameEncoder, b"a") == b"[ aa ]"
192+
@test transcode(DoubleFrameEncoder, b"ab") == b"[ aabb ]"
193+
@test transcode(DoubleFrameEncoder(), b"") == b"[ ]"
194+
@test transcode(DoubleFrameEncoder(), b"a") == b"[ aa ]"
195+
@test transcode(DoubleFrameEncoder(), b"ab") == b"[ aabb ]"
196+
197+
@test_throws Exception transcode(DoubleFrameDecoder, b"")
198+
@test_throws Exception transcode(DoubleFrameDecoder, b" [")
199+
@test_throws Exception transcode(DoubleFrameDecoder, b" ]")
200+
@test_throws Exception transcode(DoubleFrameDecoder, b"[]")
201+
@test_throws Exception transcode(DoubleFrameDecoder, b" ")
202+
@test_throws Exception transcode(DoubleFrameDecoder, b" ")
203+
@test_throws Exception transcode(DoubleFrameDecoder, b"aabb")
204+
@test_throws Exception transcode(DoubleFrameDecoder, b"[ ab ]")
205+
@test transcode(DoubleFrameDecoder, b"[ ]") == b""
206+
@test transcode(DoubleFrameDecoder, b"[ aa ]") == b"a"
207+
@test transcode(DoubleFrameDecoder, b"[ aabb ]") == b"ab"
208+
@test transcode(DoubleFrameDecoder, b"[ aaaa ]") == b"aa"
209+
@test transcode(DoubleFrameDecoder, b"[ ]") == b" "
210+
@test transcode(DoubleFrameDecoder, b"[ ]] ]") == b" ]"
211+
@test transcode(DoubleFrameDecoder, b"[ aa ][ bb ]") == b"ab"
212+
213+
@testset "eof is true after write stops" begin
214+
sink = IOBuffer()
215+
stream = TranscodingStream(DoubleFrameDecoder(), sink, stop_on_end=true)
216+
write(stream, "[ yy ]sdfsadfasdfdf")
217+
flush(stream)
218+
@test_broken eof(stream)
219+
# TODO This is broken.
220+
# @test_throws ArgumentError read(stream, UInt8)
221+
@test take!(sink) == b"y"
222+
close(stream)
223+
end
224+
225+
test_roundtrip_read(DoubleFrameEncoderStream, DoubleFrameDecoderStream)
226+
test_roundtrip_write(DoubleFrameEncoderStream, DoubleFrameDecoderStream)
227+
test_roundtrip_lines(DoubleFrameEncoderStream, DoubleFrameDecoderStream)
228+
test_roundtrip_transcode(DoubleFrameEncoder, DoubleFrameDecoder)
229+
test_roundtrip_fileio(DoubleFrameEncoder, DoubleFrameDecoder)
230+
test_chunked_read(DoubleFrameEncoder, DoubleFrameDecoder)
231+
test_chunked_write(DoubleFrameEncoder, DoubleFrameDecoder)
232+
end

test/codecquadruple.jl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,4 +134,22 @@ end
134134
@test take!(sink) == b"xxxx"
135135
close(stream)
136136
end
137+
138+
@testset "eof is true after write" begin
139+
sink = IOBuffer()
140+
stream = TranscodingStream(QuadrupleCodec(), sink, bufsize=16)
141+
write(stream, "x")
142+
@test eof(stream)
143+
@test_throws ArgumentError read(stream, UInt8)
144+
@test eof(stream)
145+
write(stream, "y")
146+
@test eof(stream)
147+
write(stream, TranscodingStreams.TOKEN_END)
148+
@test eof(stream)
149+
flush(stream)
150+
@test eof(stream)
151+
@test take!(sink) == b"xxxxyyyy"
152+
close(stream)
153+
@test eof(stream)
154+
end
137155
end

test/runtests.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,4 @@ end
126126
include("codecnoop.jl")
127127
include("codecinvalid.jl")
128128
include("codecquadruple.jl")
129+
include("codecdoubleframe.jl")

0 commit comments

Comments
 (0)