]> git.imager.perl.org - imager.git/blob - ICO/t/t60writefail.t
implement limited writes as a closure instead of as an overloaded
[imager.git] / ICO / t / t60writefail.t
1 #!perl -w
2 use strict;
3 use lib '../t';
4 use Test::More tests => 69;
5 use Imager ':handy';
6
7 # this file tries to cover as much of the write error handling cases in 
8 # msicon.c/imicon.c as possible.
9 #
10 # coverage checked with gcc/gcov
11
12 # image too big for format tests, for each entry point
13 {
14   my $im = Imager->new(xsize => 256, ysize => 255);
15   my $data;
16   ok(!$im->write(data => \$data, type=>'ico'),
17      "image too large");
18   is($im->errstr, "image too large for ico file", "check message");
19 }
20
21 {
22   my $im = Imager->new(xsize => 256, ysize => 255);
23   my $data;
24   ok(!Imager->write_multi({ data => \$data, type=>'ico' }, $im, $im),
25      "image too large");
26   is(Imager->errstr, "image too large for ico file", "check message");
27   Imager->_set_error('');
28 }
29
30 {
31   my $im = Imager->new(xsize => 256, ysize => 255);
32   my $data;
33   ok(!$im->write(data => \$data, type=>'cur'),
34      "image too large");
35   is($im->errstr, "image too large for ico file", "check message");
36 }
37
38 {
39   my $im = Imager->new(xsize => 256, ysize => 255);
40   my $data;
41   ok(!Imager->write_multi({ data => \$data, type=>'cur' }, $im),
42      "image too large");
43   is(Imager->errstr, "image too large for ico file", "check message");
44   Imager->_set_error('');
45 }
46
47 # low level write failure tests for each entry point (fail on close)
48 {
49   my $im = Imager->new(xsize => 10, ysize => 10);
50   ok(!$im->write(callback => \&write_failure, type=>'ico'),
51      "low level write failure (ico)");
52   is($im->errstr, "error closing output: synthetic error", "check message");
53 }
54
55 {
56   my $im = Imager->new(xsize => 10, ysize => 10);
57   ok(!$im->write(callback => \&write_failure, type=>'cur'),
58      "low level write failure (cur)");
59   is($im->errstr, "error closing output: synthetic error", "check message");
60 }
61
62 {
63   my $im = Imager->new(xsize => 10, ysize => 10);
64   ok(!Imager->write_multi({ callback => \&write_failure, type=>'ico' }, $im, $im),
65      "low level write_multi failure (ico)");
66   is(Imager->errstr, "error closing output: synthetic error", "check message");
67   Imager->_set_error('');
68 }
69
70 {
71   my $im = Imager->new(xsize => 10, ysize => 10);
72   ok(!Imager->write_multi({ callback => \&write_failure, type=>'cur' }, $im, $im),
73      "low level write_multi failure (cur)");
74   is(Imager->errstr, "error closing output: synthetic error", "check message");
75   Imager->_set_error('');
76 }
77
78 # low level write failure tests for each entry point (fail on write)
79 {
80   my $im = Imager->new(xsize => 10, ysize => 10);
81   ok(!$im->write(callback => \&write_failure, maxbuffer => 1, type=>'ico'),
82      "low level write failure (ico)");
83   is($im->errstr, "Write failure: synthetic error", "check message");
84 }
85
86 {
87   my $im = Imager->new(xsize => 10, ysize => 10);
88   ok(!$im->write(callback => \&write_failure, maxbuffer => 1, type=>'cur'),
89      "low level write failure (cur)");
90   is($im->errstr, "Write failure: synthetic error", "check message");
91 }
92
93 {
94   my $im = Imager->new(xsize => 10, ysize => 10);
95   ok(!Imager->write_multi({ callback => \&write_failure, maxbuffer => 1, type=>'ico' }, $im, $im),
96      "low level write_multi failure (ico)");
97   is(Imager->errstr, "Write failure: synthetic error", "check message");
98   Imager->_set_error('');
99 }
100
101 {
102   my $im = Imager->new(xsize => 10, ysize => 10);
103   ok(!Imager->write_multi({ callback => \&write_failure, maxbuffer => 1, type=>'cur' }, $im, $im),
104      "low level write_multi failure (cur)");
105   is(Imager->errstr, "Write failure: synthetic error", "check message");
106   Imager->_set_error('');
107 }
108
109 {
110   my $im = Imager->new(xsize => 10, ysize => 10);
111   ok(!$im->write(type => 'ico', callback => limited_write(6), maxbuffer => 1),
112      "second write (resource) should fail (ico)");
113   is($im->errstr, "Write failure: limit reached", "check message");
114   $im->_set_error('');
115
116   ok(!$im->write(type => 'cur', callback => limited_write(6), maxbuffer => 1),
117      "second (resource) write should fail (cur)");
118   is($im->errstr, "Write failure: limit reached", "check message");
119   $im->_set_error('');
120
121   ok(!$im->write(type => 'ico', callback => limited_write(22), maxbuffer => 1),
122      "third write (bmi) should fail (32-bit)");
123   is($im->errstr, "Write failure: limit reached", "check message");
124   $im->_set_error('');
125
126   ok(!$im->write(type => 'ico', callback => limited_write(62), maxbuffer => 1),
127      "fourth write (data) should fail (32-bit)");
128   is($im->errstr, "Write failure: limit reached", "check message");
129   $im->_set_error('');
130
131   ok(!$im->write(type => 'ico', callback => limited_write(462), maxbuffer => 1),
132      "mask write should fail (32-bit)");
133   is($im->errstr, "Write failure: limit reached", "check message");
134 }
135
136 { # 1 bit write fails
137   my $im = Imager->new(xsize => 10, ysize => 10, type => 'paletted');
138   my $red = NC(255, 0, 0);
139   my $blue = NC(0, 0, 255);
140   $im->addcolors(colors => [ $red, $blue ]);
141   $im->box(filled => 1, color => $red, ymax => 5);
142   $im->box(filled => 1, color => $blue, ymin => 6);
143   ok(!$im->write(type => 'ico', callback => limited_write(22), maxbuffer => 1),
144      "third write (bmi) should fail (1-bit)");
145   is($im->errstr, "Write failure: limit reached", "check message");
146   
147   ok(!$im->write(type => 'ico', callback => limited_write(66), maxbuffer => 1),
148      "fourth write (palette) should fail (1-bit)");
149   is($im->errstr, "Write failure: limit reached", "check message");
150   ok(!$im->write(type => 'ico', callback => limited_write(74), maxbuffer => 1),
151      "fifth write (image) should fail (1-bit)");
152   is($im->errstr, "Write failure: limit reached", "check message");
153   my $data;
154   ok($im->write(data => \$data, type => 'ico'), "write 1 bit successfully");
155   my $read = Imager->new;
156   ok($read->read(data => $data), "read it back");
157   is($read->type, 'paletted', "check type");
158   is($read->tags(name => 'ico_bits'), 1, "check bits");
159   is(Imager::i_img_diff($read, $im), 0, "check image correct");
160 }
161
162 { # 4 bit write fails
163   my $im = Imager->new(xsize => 10, ysize => 10, type => 'paletted');
164   my $red = NC(255, 0, 0);
165   my $blue = NC(0, 0, 255);
166   $im->addcolors(colors => [ ($red, $blue) x 8 ]);
167   $im->box(filled => 1, color => $red, ymax => 5);
168   $im->box(filled => 1, color => $blue, ymin => 6);
169   ok(!$im->write(type => 'ico', callback => limited_write(22), maxbuffer => 1),
170      "third write (bmi) should fail (4-bit)");
171   is($im->errstr, "Write failure: limit reached", "check message");
172   
173   ok(!$im->write(type => 'ico', callback => limited_write(66), maxbuffer => 1),
174      "fourth write (palette) should fail (4-bit)");
175   is($im->errstr, "Write failure: limit reached", "check message");
176   ok(!$im->write(type => 'ico', callback => limited_write(130), maxbuffer => 1),
177      "fifth write (image) should fail (4-bit)");
178   is($im->errstr, "Write failure: limit reached", "check message");
179   my $data;
180   ok($im->write(data => \$data, type => 'ico'), "write 4 bit successfully");
181   my $read = Imager->new;
182   ok($read->read(data => $data), "read it back");
183   is($read->type, 'paletted', "check type");
184   is($read->tags(name => 'ico_bits'), 4, "check bits");
185   is(Imager::i_img_diff($read, $im), 0, "check image correct");
186 }
187
188 { # 8 bit write fails
189   my $im = Imager->new(xsize => 10, ysize => 10, type => 'paletted');
190   my $red = NC(255, 0, 0);
191   my $blue = NC(0, 0, 255);
192   $im->addcolors(colors => [ ($red, $blue) x 9 ]);
193   $im->box(filled => 1, color => $red, ymax => 5);
194   $im->box(filled => 1, color => $blue, ymin => 6);
195   ok(!$im->write(type => 'ico', callback => limited_write(22), maxbuffer => 1),
196      "third write (bmi) should fail (8-bit)");
197   is($im->errstr, "Write failure: limit reached", "check message");
198   
199   ok(!$im->write(type => 'ico', callback => limited_write(62), maxbuffer => 1),
200      "fourth write (palette) should fail (8-bit)");
201   is($im->errstr, "Write failure: limit reached", "check message");
202   ok(!$im->write(type => 'ico', callback => limited_write(62 + 1024), maxbuffer => 1),
203      "fifth write (image) should fail (8-bit)");
204   is($im->errstr, "Write failure: limit reached", "check message");
205   ok(!$im->write(type => 'ico', callback => limited_write(62 + 1024 + 10), maxbuffer => 1),
206      "sixth write (zeroes) should fail (8-bit)");
207   is($im->errstr, "Write failure: limit reached", "check message");
208   my $data;
209   ok($im->write(data => \$data, type => 'ico'), "write 8 bit successfully");
210   my $read = Imager->new;
211   ok($read->read(data => $data), "read it back");
212   is($read->type, 'paletted', "check type");
213   is($read->tags(name => 'ico_bits'), 8, "check bits");
214   is(Imager::i_img_diff($read, $im), 0, "check image correct");
215 }
216
217 # write callback that fails
218 sub write_failure {
219   print "# synthesized write failure\n";
220   Imager::i_push_error(0, "synthetic error");
221   return;
222 }
223
224 sub limited_write {
225   my ($limit) = @_;
226
227   return
228      sub {
229        my ($data) = @_;
230        $limit -= length $data;
231        if ($limit >= 0) {
232          print "# write of ", length $data, " bytes successful ($limit left)\n";
233          return 1;
234        }
235        else {
236          print "# write of ", length $data, " bytes failed\n";
237          Imager::i_push_error(0, "limit reached");
238          return;
239        }
240      };
241 }