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