pnm 0.4.1 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +25 -20
- data/Rakefile +11 -10
- data/benchmark/bm_converter.rb +21 -17
- data/lib/pnm.rb +54 -54
- data/lib/pnm/converter.rb +44 -47
- data/lib/pnm/exceptions.rb +2 -0
- data/lib/pnm/image.rb +81 -54
- data/lib/pnm/parser.rb +48 -39
- data/lib/pnm/version.rb +4 -2
- data/pnm.gemspec +23 -19
- data/test/backports.rb +19 -0
- data/test/test_converter.rb +85 -80
- data/test/test_exceptions.rb +124 -120
- data/test/test_image.rb +198 -122
- data/test/test_parser.rb +57 -53
- data/test/test_pnm.rb +58 -54
- metadata +17 -16
data/test/test_image.rb
CHANGED
@@ -1,9 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# test_image.rb: Unit tests for the PNM library.
|
2
4
|
#
|
3
|
-
# Copyright (C) 2013-
|
5
|
+
# Copyright (C) 2013-2020 Marcus Stollsteimer
|
6
|
+
|
7
|
+
require "minitest/autorun"
|
8
|
+
require "pnm"
|
4
9
|
|
5
|
-
|
6
|
-
require 'pnm'
|
10
|
+
require_relative "backports"
|
7
11
|
|
8
12
|
|
9
13
|
describe PNM::Image do
|
@@ -12,190 +16,262 @@ describe PNM::Image do
|
|
12
16
|
@srcpath = File.dirname(__FILE__)
|
13
17
|
@temp_path = File.expand_path("#{@srcpath}/temp.pnm")
|
14
18
|
|
15
|
-
pixels = [[0,0,0,0,0],
|
16
|
-
[0,1,1,1,0],
|
17
|
-
[0,0,1,0,0],
|
18
|
-
[0,0,1,0,0],
|
19
|
-
[0,0,1,0,0],
|
20
|
-
[0,0,0,0,0]]
|
21
|
-
comment =
|
22
|
-
@bilevel = PNM.create(pixels,
|
23
|
-
|
24
|
-
pixels = [[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
25
|
-
[0,1,1,1,0,1,1,1,1,0,1,1,1,1,1,0],
|
26
|
-
[0,0,1,0,0,1,0,0,1,0,1,0,1,0,1,0],
|
27
|
-
[0,0,1,0,0,1,0,0,1,0,1,0,1,0,1,0],
|
28
|
-
[0,0,1,0,0,1,1,1,1,0,1,0,1,0,1,0],
|
29
|
-
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]]
|
30
|
-
@
|
31
|
-
|
32
|
-
pixels = [[ 0,
|
33
|
-
[ 50,100,150,200],
|
34
|
-
[100,150,200,250]]
|
19
|
+
pixels = [[0, 0, 0, 0, 0],
|
20
|
+
[0, 1, 1, 1, 0],
|
21
|
+
[0, 0, 1, 0, 0],
|
22
|
+
[0, 0, 1, 0, 0],
|
23
|
+
[0, 0, 1, 0, 0],
|
24
|
+
[0, 0, 0, 0, 0]]
|
25
|
+
comment = "Bilevel"
|
26
|
+
@bilevel = PNM.create(pixels, comment: comment)
|
27
|
+
|
28
|
+
pixels = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
29
|
+
[0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0],
|
30
|
+
[0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0],
|
31
|
+
[0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0],
|
32
|
+
[0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0],
|
33
|
+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
|
34
|
+
@bilevel2 = PNM.create(pixels)
|
35
|
+
|
36
|
+
pixels = [[ 0, 50, 100, 150],
|
37
|
+
[ 50, 100, 150, 200],
|
38
|
+
[100, 150, 200, 250]]
|
35
39
|
comment = "Grayscale\n(with multiline comment)"
|
36
|
-
@grayscale = PNM.create(pixels,
|
40
|
+
@grayscale = PNM.create(pixels, maxgray: 250, comment: comment)
|
37
41
|
|
38
|
-
pixels = [[65,66], [13,10], [65,66]]
|
42
|
+
pixels = [[65, 66], [13, 10], [65, 66]]
|
39
43
|
@grayscale_crlf = PNM.create(pixels)
|
40
44
|
|
41
|
-
pixels = [[[0,6,0], [1,5,1], [2,4,2], [3,3,4], [4,2,6]],
|
42
|
-
[[1,5,2], [2,4,2], [3,3,2], [4,2,2], [5,1,2]],
|
43
|
-
[[2,4,6], [3,3,4], [4,2,2], [5,1,1], [6,0,0]]]
|
44
|
-
@color = PNM.create(pixels,
|
45
|
+
pixels = [[[0, 6, 0], [1, 5, 1], [2, 4, 2], [3, 3, 4], [4, 2, 6]],
|
46
|
+
[[1, 5, 2], [2, 4, 2], [3, 3, 2], [4, 2, 2], [5, 1, 2]],
|
47
|
+
[[2, 4, 6], [3, 3, 4], [4, 2, 2], [5, 1, 1], [6, 0, 0]]]
|
48
|
+
@color = PNM.create(pixels, maxgray: 6)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "freezes pixel data" do
|
52
|
+
_ { @bilevel.pixels << [1, 1, 0, 1, 1] }.must_raise RuntimeError
|
45
53
|
end
|
46
54
|
|
47
|
-
it
|
48
|
-
|
49
|
-
image.type.must_equal :pbm
|
50
|
-
image.maxgray.must_equal 1
|
55
|
+
it "freezes comment string" do
|
56
|
+
_ { @bilevel.comment << "string" }.must_raise RuntimeError
|
51
57
|
end
|
52
58
|
|
53
|
-
it
|
54
|
-
image = PNM.create([[0,
|
55
|
-
image.type.must_equal :
|
56
|
-
image.maxgray.must_equal
|
59
|
+
it "sets maxgray to 1 for bilevel images" do
|
60
|
+
image = PNM.create([[0, 1, 0], [1, 0, 1]])
|
61
|
+
_(image.type).must_equal :pbm
|
62
|
+
_(image.maxgray).must_equal 1
|
57
63
|
end
|
58
64
|
|
59
|
-
it
|
60
|
-
image = PNM.create([[
|
61
|
-
image.type.must_equal :
|
62
|
-
image.maxgray.must_equal 255
|
65
|
+
it "sets maxgray by default to 255 for grayscale images" do
|
66
|
+
image = PNM.create([[0, 10, 20], [10, 20, 30]])
|
67
|
+
_(image.type).must_equal :pgm
|
68
|
+
_(image.maxgray).must_equal 255
|
63
69
|
end
|
64
70
|
|
65
|
-
it
|
66
|
-
image = PNM.create([[0,
|
67
|
-
image.type.must_equal :
|
68
|
-
image.maxgray.must_equal
|
71
|
+
it "sets maxgray by default to 255 for color images" do
|
72
|
+
image = PNM.create([[[0, 0, 0], [10, 10, 10]], [[10, 10, 10], [20, 20, 20]]])
|
73
|
+
_(image.type).must_equal :ppm
|
74
|
+
_(image.maxgray).must_equal 255
|
69
75
|
end
|
70
76
|
|
71
|
-
it
|
72
|
-
image = PNM.create([[0,1,0], [1,0,1]],
|
73
|
-
image.type.must_equal :pbm
|
74
|
-
image.maxgray.must_equal 1
|
77
|
+
it "accepts setting of maxgray to 1 for bilevel images" do
|
78
|
+
image = PNM.create([[0, 1, 0], [1, 0, 1]], maxgray: 1)
|
79
|
+
_(image.type).must_equal :pbm
|
80
|
+
_(image.maxgray).must_equal 1
|
75
81
|
end
|
76
82
|
|
77
|
-
it
|
78
|
-
image = PNM.create([[0,1,0], [1,0,1]],
|
79
|
-
image.type.must_equal :
|
80
|
-
image.
|
81
|
-
image.maxgray.must_equal 255
|
83
|
+
it "ignores invalid maxgray for bilevel images and sets it to 1" do
|
84
|
+
image = PNM.create([[0, 1, 0], [1, 0, 1]], type: :pbm, maxgray: 255)
|
85
|
+
_(image.type).must_equal :pbm
|
86
|
+
_(image.maxgray).must_equal 1
|
82
87
|
end
|
83
88
|
|
84
|
-
it
|
85
|
-
image = PNM.create([[0,1,0], [1,0,1]],
|
86
|
-
image.type.must_equal :pgm
|
89
|
+
it "can create a grayscale image from bilevel values (using type)" do
|
90
|
+
image = PNM.create([[0, 1, 0], [1, 0, 1]], type: :pgm)
|
91
|
+
_(image.type).must_equal :pgm
|
92
|
+
_(image.pixels).must_equal [[0, 1, 0], [1, 0, 1]]
|
93
|
+
_(image.maxgray).must_equal 255
|
87
94
|
end
|
88
95
|
|
89
|
-
it
|
90
|
-
image = PNM.create([[0,1,0], [1,0,1]],
|
91
|
-
image.type.must_equal :pgm
|
92
|
-
image.pixels.must_equal [[0,1,0], [1,0,1]]
|
93
|
-
image.maxgray.must_equal 2
|
96
|
+
it "also accepts types given as string instead of symbol" do
|
97
|
+
image = PNM.create([[0, 1, 0], [1, 0, 1]], type: "pgm")
|
98
|
+
_(image.type).must_equal :pgm
|
94
99
|
end
|
95
100
|
|
96
|
-
it
|
97
|
-
image = PNM.create([[0,1,0], [1,0,1]],
|
98
|
-
image.
|
99
|
-
image.pixels.must_equal [[
|
100
|
-
image.maxgray.must_equal
|
101
|
+
it "can create a grayscale image from bilevel values (using maxgray)" do
|
102
|
+
image = PNM.create([[0, 1, 0], [1, 0, 1]], maxgray: 2)
|
103
|
+
_(image.type).must_equal :pgm
|
104
|
+
_(image.pixels).must_equal [[0, 1, 0], [1, 0, 1]]
|
105
|
+
_(image.maxgray).must_equal 2
|
101
106
|
end
|
102
107
|
|
103
|
-
it
|
104
|
-
image = PNM.create([[0,1,0], [1,0,1]],
|
105
|
-
image.info.
|
106
|
-
image.pixels.must_equal [[[0,0,0], [1,1,1], [0,0,0]], [[1,1,1], [0,0,0], [1,1,1]]]
|
107
|
-
image.maxgray.must_equal
|
108
|
+
it "can create a color image from bilevel values" do
|
109
|
+
image = PNM.create([[0, 1, 0], [1, 0, 1]], type: :ppm)
|
110
|
+
_(image.info).must_equal "PPM 3x2 Color"
|
111
|
+
_(image.pixels).must_equal [[[0, 0, 0], [1, 1, 1], [0, 0, 0]], [[1, 1, 1], [0, 0, 0], [1, 1, 1]]]
|
112
|
+
_(image.maxgray).must_equal 255
|
108
113
|
end
|
109
114
|
|
110
|
-
it
|
111
|
-
image = PNM.create([[0,
|
112
|
-
image.info.
|
113
|
-
image.pixels.must_equal [[[0,0,0], [
|
115
|
+
it "can create a color image from bilevel values with a given maxgray" do
|
116
|
+
image = PNM.create([[0, 1, 0], [1, 0, 1]], type: :ppm, maxgray: 2)
|
117
|
+
_(image.info).must_equal "PPM 3x2 Color"
|
118
|
+
_(image.pixels).must_equal [[[0, 0, 0], [1, 1, 1], [0, 0, 0]], [[1, 1, 1], [0, 0, 0], [1, 1, 1]]]
|
119
|
+
_(image.maxgray).must_equal 2
|
114
120
|
end
|
115
121
|
|
116
|
-
it
|
117
|
-
|
118
|
-
|
119
|
-
|
122
|
+
it "can create a color image from gray values" do
|
123
|
+
image = PNM.create([[0, 3, 6], [3, 6, 9]], type: :ppm)
|
124
|
+
_(image.info).must_equal "PPM 3x2 Color"
|
125
|
+
_(image.pixels).must_equal [[[0, 0, 0], [3, 3, 3], [6, 6, 6]], [[3, 3, 3], [6, 6, 6], [9, 9, 9]]]
|
120
126
|
end
|
121
127
|
|
122
|
-
it
|
123
|
-
|
124
|
-
|
128
|
+
it "does not modify the input data for color images created from gray values" do
|
129
|
+
data = [[0, 3, 6], [3, 6, 9]]
|
130
|
+
PNM.create(data, type: :ppm)
|
131
|
+
_(data).must_equal [[0, 3, 6], [3, 6, 9]]
|
132
|
+
end
|
133
|
+
|
134
|
+
it "can write a bilevel image to an ASCII encoded file" do
|
135
|
+
@bilevel.write(@temp_path, encoding: :ascii)
|
136
|
+
_(File.binread(@temp_path)).must_equal File.binread("#{@srcpath}/bilevel_ascii.pbm")
|
125
137
|
File.delete(@temp_path)
|
126
138
|
end
|
127
139
|
|
128
|
-
it
|
129
|
-
@bilevel.write(@temp_path, :binary)
|
130
|
-
File.binread(@temp_path).must_equal File.binread("#{@srcpath}/bilevel_binary.pbm")
|
140
|
+
it "can write a bilevel image (width 5) to a binary encoded file" do
|
141
|
+
@bilevel.write(@temp_path, encoding: :binary)
|
142
|
+
_(File.binread(@temp_path)).must_equal File.binread("#{@srcpath}/bilevel_binary.pbm")
|
131
143
|
File.delete(@temp_path)
|
132
144
|
end
|
133
145
|
|
134
|
-
it
|
135
|
-
@
|
136
|
-
File.binread(@temp_path).must_equal File.binread("#{@srcpath}/bilevel_2_binary.pbm")
|
146
|
+
it "can write a bilevel image (width 16) to a binary encoded file" do
|
147
|
+
@bilevel2.write(@temp_path, encoding: :binary)
|
148
|
+
_(File.binread(@temp_path)).must_equal File.binread("#{@srcpath}/bilevel_2_binary.pbm")
|
137
149
|
File.delete(@temp_path)
|
138
150
|
end
|
139
151
|
|
140
|
-
it
|
141
|
-
@grayscale.write(@temp_path, :ascii)
|
142
|
-
File.binread(@temp_path).must_equal File.binread("#{@srcpath}/grayscale_ascii.pgm")
|
152
|
+
it "can write a grayscale image to an ASCII encoded file" do
|
153
|
+
@grayscale.write(@temp_path, encoding: :ascii)
|
154
|
+
_(File.binread(@temp_path)).must_equal File.binread("#{@srcpath}/grayscale_ascii.pgm")
|
143
155
|
File.delete(@temp_path)
|
144
156
|
end
|
145
157
|
|
146
|
-
it
|
147
|
-
@grayscale.write(@temp_path, :binary)
|
148
|
-
File.binread(@temp_path).must_equal File.binread("#{@srcpath}/grayscale_binary.pgm")
|
158
|
+
it "can write a grayscale image to a binary encoded file" do
|
159
|
+
@grayscale.write(@temp_path, encoding: :binary)
|
160
|
+
_(File.binread(@temp_path)).must_equal File.binread("#{@srcpath}/grayscale_binary.pgm")
|
149
161
|
File.delete(@temp_path)
|
150
162
|
end
|
151
163
|
|
152
|
-
it
|
153
|
-
@color.write(@temp_path, :ascii)
|
154
|
-
File.binread(@temp_path).must_equal File.binread("#{@srcpath}/color_ascii.ppm")
|
164
|
+
it "can write a color image to an ASCII encoded file" do
|
165
|
+
@color.write(@temp_path, encoding: :ascii)
|
166
|
+
_(File.binread(@temp_path)).must_equal File.binread("#{@srcpath}/color_ascii.ppm")
|
155
167
|
File.delete(@temp_path)
|
156
168
|
end
|
157
169
|
|
158
|
-
it
|
159
|
-
@color.write(@temp_path, :binary)
|
160
|
-
File.binread(@temp_path).must_equal File.binread("#{@srcpath}/color_binary.ppm")
|
170
|
+
it "can write a color image to a binary encoded file" do
|
171
|
+
@color.write(@temp_path, encoding: :binary)
|
172
|
+
_(File.binread(@temp_path)).must_equal File.binread("#{@srcpath}/color_binary.ppm")
|
161
173
|
File.delete(@temp_path)
|
162
174
|
end
|
163
175
|
|
164
|
-
it
|
165
|
-
@bilevel.
|
166
|
-
@
|
167
|
-
@
|
176
|
+
it "can write a bilevel image to a file, adding the extension" do
|
177
|
+
@bilevel.write(@temp_path, add_extension: true)
|
178
|
+
_(File.binread("#{@temp_path}.pbm")).must_equal File.binread("#{@srcpath}/bilevel_binary.pbm")
|
179
|
+
File.delete("#{@temp_path}.pbm")
|
180
|
+
end
|
181
|
+
|
182
|
+
it "can write a grayscale image to a file, adding the extension" do
|
183
|
+
@grayscale.write(@temp_path, add_extension: true, encoding: :ascii)
|
184
|
+
_(File.binread("#{@temp_path}.pgm")).must_equal File.binread("#{@srcpath}/grayscale_ascii.pgm")
|
185
|
+
File.delete("#{@temp_path}.pgm")
|
168
186
|
end
|
169
187
|
|
170
|
-
it
|
171
|
-
@
|
172
|
-
@
|
173
|
-
|
188
|
+
it "can write a color image to a file, adding the extension" do
|
189
|
+
@color.write(@temp_path, add_extension: true, encoding: :binary)
|
190
|
+
_(File.binread("#{@temp_path}.ppm")).must_equal File.binread("#{@srcpath}/color_binary.ppm")
|
191
|
+
File.delete("#{@temp_path}.ppm")
|
174
192
|
end
|
175
193
|
|
176
|
-
it
|
177
|
-
@
|
178
|
-
|
194
|
+
it "can return image information" do
|
195
|
+
_(@bilevel.info).must_equal "PBM 5x6 Bilevel"
|
196
|
+
_(@grayscale.info).must_equal "PGM 4x3 Grayscale"
|
197
|
+
_(@color.info).must_equal "PPM 5x3 Color"
|
198
|
+
end
|
199
|
+
|
200
|
+
it "can return meaningful debugging information" do
|
201
|
+
_(@bilevel.inspect).must_match %r{\A#<PNM::PBMImage:0x\h+ PBM 5x6 Bilevel>\z}
|
202
|
+
_(@grayscale.inspect).must_match %r{\A#<PNM::PGMImage:0x\h+ PGM 4x3 Grayscale, maxgray=250>\z}
|
203
|
+
_(@color.inspect).must_match %r{\A#<PNM::PPMImage:0x\h+ PPM 5x3 Color, maxgray=6>\z}
|
204
|
+
end
|
205
|
+
|
206
|
+
it "can write binary data containing CRLF" do
|
207
|
+
@grayscale_crlf.write(@temp_path, encoding: :binary)
|
208
|
+
_(File.binread(@temp_path)).must_equal File.binread("#{@srcpath}/grayscale_binary_crlf.pgm")
|
179
209
|
File.delete(@temp_path)
|
180
210
|
end
|
181
211
|
|
182
|
-
it
|
183
|
-
File.open(@temp_path,
|
184
|
-
File.binread(@temp_path).must_equal File.binread("#{@srcpath}/grayscale_binary_crlf.pgm")
|
212
|
+
it "can write binary data containing CRLF to an I/O stream" do
|
213
|
+
File.open(@temp_path, "w") {|f| @grayscale_crlf.write(f, encoding: :binary) }
|
214
|
+
_(File.binread(@temp_path)).must_equal File.binread("#{@srcpath}/grayscale_binary_crlf.pgm")
|
185
215
|
File.delete(@temp_path)
|
186
216
|
end
|
187
217
|
|
188
|
-
it
|
189
|
-
comment =
|
190
|
-
PNM.create([[0,0]], :
|
191
|
-
File.binread(@temp_path).must_equal "P1\n#\n2 1\n0 0\n"
|
218
|
+
it "can write zero-length comments" do
|
219
|
+
comment = ""
|
220
|
+
PNM.create([[0, 0]], comment: comment).write(@temp_path, encoding: :ascii)
|
221
|
+
_(File.binread(@temp_path)).must_equal "P1\n#\n2 1\n0 0\n"
|
192
222
|
File.delete(@temp_path)
|
193
223
|
end
|
194
224
|
|
195
|
-
it
|
225
|
+
it "can write comments with trailing zero-length line" do
|
196
226
|
comment = "An empty line:\n"
|
197
|
-
PNM.create([[0,0]], :
|
198
|
-
File.binread(@temp_path).must_equal "P1\n# An empty line:\n#\n2 1\n0 0\n"
|
227
|
+
PNM.create([[0, 0]], comment: comment).write(@temp_path, encoding: :ascii)
|
228
|
+
_(File.binread(@temp_path)).must_equal "P1\n# An empty line:\n#\n2 1\n0 0\n"
|
199
229
|
File.delete(@temp_path)
|
200
230
|
end
|
231
|
+
|
232
|
+
it "can check equality of images (1)" do
|
233
|
+
pixels = [[0, 1, 0], [1, 0, 1]]
|
234
|
+
bilevel1 = PNM.create(pixels, comment: "image")
|
235
|
+
bilevel2 = PNM.create(pixels, comment: "image")
|
236
|
+
|
237
|
+
_(bilevel2 == bilevel1).must_equal true
|
238
|
+
end
|
239
|
+
|
240
|
+
it "can check equality of images (2)" do
|
241
|
+
pixels = [[0, 1, 0], [1, 0, 1]]
|
242
|
+
bilevel1 = PNM.create(pixels, comment: "image")
|
243
|
+
bilevel2 = PNM.create(pixels, comment: "other image")
|
244
|
+
|
245
|
+
_(bilevel2 == bilevel1).must_equal false
|
246
|
+
end
|
247
|
+
|
248
|
+
it "can check equality of images (3)" do
|
249
|
+
pixels = [[0, 1, 0], [1, 0, 1]]
|
250
|
+
bilevel1 = PNM.create(pixels)
|
251
|
+
bilevel2 = PNM.create(pixels.reverse)
|
252
|
+
|
253
|
+
_(bilevel2 == bilevel1).must_equal false
|
254
|
+
end
|
255
|
+
|
256
|
+
it "can check equality of images (4)" do
|
257
|
+
pixels = [[0, 1, 0], [1, 0, 1]]
|
258
|
+
bilevel = PNM.create(pixels, type: :pbm)
|
259
|
+
graylevel = PNM.create(pixels, type: :pgm)
|
260
|
+
|
261
|
+
_(graylevel == bilevel).must_equal false
|
262
|
+
end
|
263
|
+
|
264
|
+
it "can check equality of images (5)" do
|
265
|
+
pixels = [[0, 1, 2], [3, 4, 5]]
|
266
|
+
graylevel1 = PNM.create(pixels, maxgray: 10)
|
267
|
+
graylevel2 = PNM.create(pixels, maxgray: 255)
|
268
|
+
|
269
|
+
_(graylevel2 == graylevel1).must_equal false
|
270
|
+
end
|
271
|
+
|
272
|
+
it "can check equality of images (6)" do
|
273
|
+
image = PNM.create([[0, 1, 2], [3, 4, 5]])
|
274
|
+
|
275
|
+
_(image == "a string").must_equal false
|
276
|
+
end
|
201
277
|
end
|
data/test/test_parser.rb
CHANGED
@@ -1,9 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# test_parser.rb: Unit tests for the PNM library.
|
2
4
|
#
|
3
|
-
# Copyright (C) 2013-
|
5
|
+
# Copyright (C) 2013-2020 Marcus Stollsteimer
|
6
|
+
|
7
|
+
require "minitest/autorun"
|
8
|
+
require "pnm/parser"
|
4
9
|
|
5
|
-
|
6
|
-
require 'pnm/parser'
|
10
|
+
require_relative "backports"
|
7
11
|
|
8
12
|
|
9
13
|
describe PNM::Parser do
|
@@ -12,89 +16,89 @@ describe PNM::Parser do
|
|
12
16
|
@parser = PNM::Parser
|
13
17
|
end
|
14
18
|
|
15
|
-
it
|
16
|
-
content
|
19
|
+
it "can parse ASCII encoded PBM data" do
|
20
|
+
content = <<-PBM.chomp.gsub(/^ */, "")
|
17
21
|
P1 6 2
|
18
22
|
0 1 0 0 1 1
|
19
23
|
0 0 0 1 1 1
|
20
|
-
|
24
|
+
PBM
|
21
25
|
expected = {
|
22
|
-
:
|
23
|
-
:
|
24
|
-
:
|
25
|
-
:
|
26
|
+
magic_number: "P1",
|
27
|
+
width: 6,
|
28
|
+
height: 2,
|
29
|
+
data: "0 1 0 0 1 1\n0 0 0 1 1 1"
|
26
30
|
}
|
27
31
|
|
28
|
-
@parser.parse(content).must_equal expected
|
32
|
+
_(@parser.parse(content)).must_equal expected
|
29
33
|
end
|
30
34
|
|
31
|
-
it
|
32
|
-
content
|
35
|
+
it "can parse ASCII encoded PGM data" do
|
36
|
+
content = <<-PGM.chomp.gsub(/^ */, "")
|
33
37
|
P2 4 2 100
|
34
38
|
10 20 30 40
|
35
39
|
50 60 70 80
|
36
|
-
|
40
|
+
PGM
|
37
41
|
expected = {
|
38
|
-
:
|
39
|
-
:
|
40
|
-
:
|
41
|
-
:
|
42
|
-
:
|
42
|
+
magic_number: "P2",
|
43
|
+
width: 4,
|
44
|
+
height: 2,
|
45
|
+
maxgray: 100,
|
46
|
+
data: "10 20 30 40\n50 60 70 80"
|
43
47
|
}
|
44
48
|
|
45
|
-
@parser.parse(content).must_equal expected
|
49
|
+
_(@parser.parse(content)).must_equal expected
|
46
50
|
end
|
47
51
|
|
48
|
-
it
|
49
|
-
content =
|
52
|
+
it "can parse binary encoded data" do
|
53
|
+
content = "P4 8 2 ".dup << ["05AF"].pack("H*")
|
50
54
|
expected = {
|
51
|
-
:
|
52
|
-
:
|
53
|
-
:
|
54
|
-
:
|
55
|
+
magic_number: "P4",
|
56
|
+
width: 8,
|
57
|
+
height: 2,
|
58
|
+
data: ["05AF"].pack("H*")
|
55
59
|
}
|
56
60
|
|
57
|
-
@parser.parse(content).must_equal expected
|
61
|
+
_(@parser.parse(content)).must_equal expected
|
58
62
|
end
|
59
63
|
|
60
|
-
it
|
61
|
-
content =
|
64
|
+
it "does not change the passed data" do
|
65
|
+
content = "P1 3 2 0 1 0 0 1 1"
|
62
66
|
original_content = content.dup
|
63
67
|
@parser.parse(content)
|
64
68
|
|
65
|
-
content.must_equal original_content
|
69
|
+
_(content).must_equal original_content
|
66
70
|
end
|
67
71
|
|
68
|
-
it
|
72
|
+
it "does accept multiple whitespace as delimiter" do
|
69
73
|
content = "P1 \n\t 3 \r \n2 0 1 0 0 1 1"
|
70
74
|
expected = {
|
71
|
-
:
|
72
|
-
:
|
73
|
-
:
|
74
|
-
:
|
75
|
+
magic_number: "P1",
|
76
|
+
width: 3,
|
77
|
+
height: 2,
|
78
|
+
data: "0 1 0 0 1 1"
|
75
79
|
}
|
76
80
|
|
77
|
-
@parser.parse(content).must_equal expected
|
81
|
+
_(@parser.parse(content)).must_equal expected
|
78
82
|
end
|
79
83
|
|
80
|
-
it
|
81
|
-
@parser.parse("P4 16 4 A\nB\rC D\t")[:data].must_equal "A\nB\rC D\t"
|
84
|
+
it "can parse binary encoded data including whitespace" do
|
85
|
+
_(@parser.parse("P4 16 4 A\nB\rC D\t")[:data]).must_equal "A\nB\rC D\t"
|
82
86
|
end
|
83
87
|
|
84
|
-
it
|
85
|
-
@parser.parse("P4 8 2 \nA")[:data].must_equal "\nA"
|
88
|
+
it "can parse binary encoded data starting with whitespace" do
|
89
|
+
_(@parser.parse("P4 8 2 \nA")[:data]).must_equal "\nA"
|
86
90
|
end
|
87
91
|
|
88
|
-
it
|
89
|
-
@parser.parse("P4 8 2 #A")[:data].must_equal "#A"
|
92
|
+
it "can parse binary encoded data starting with comment character" do
|
93
|
+
_(@parser.parse("P4 8 2 #A")[:data]).must_equal "#A"
|
90
94
|
end
|
91
95
|
|
92
|
-
it
|
93
|
-
@parser.parse("P4 8 2 AB\n")[:data].must_equal "AB\n"
|
96
|
+
it "does not chomp newlines from parsed binary encoded data" do
|
97
|
+
_(@parser.parse("P4 8 2 AB\n")[:data]).must_equal "AB\n"
|
94
98
|
end
|
95
99
|
|
96
|
-
it
|
97
|
-
content
|
100
|
+
it "can parse comments" do
|
101
|
+
content = <<-PBM.chomp.gsub(/^ */, "")
|
98
102
|
# Comment 1
|
99
103
|
P1 # Comment 2
|
100
104
|
6# Comment 3
|
@@ -104,15 +108,15 @@ describe PNM::Parser do
|
|
104
108
|
2
|
105
109
|
0 1 0 0 1 1
|
106
110
|
0 0 0 1 1 1
|
107
|
-
|
111
|
+
PBM
|
108
112
|
expected = {
|
109
|
-
:
|
110
|
-
:
|
111
|
-
:
|
112
|
-
:
|
113
|
-
:
|
113
|
+
magic_number: "P1",
|
114
|
+
width: 6,
|
115
|
+
height: 2,
|
116
|
+
comments: ["Comment 1", "Comment 2", "Comment 3", "Comment 4", "", "Comment 6"],
|
117
|
+
data: "0 1 0 0 1 1\n0 0 0 1 1 1"
|
114
118
|
}
|
115
119
|
|
116
|
-
@parser.parse(content).must_equal expected
|
120
|
+
_(@parser.parse(content)).must_equal expected
|
117
121
|
end
|
118
122
|
end
|