axon 0.0.2 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.rdoc +9 -3
- data/README.rdoc +29 -36
- data/Rakefile +26 -21
- data/TODO.rdoc +1 -6
- data/ext/axon/axon.c +6 -15
- data/ext/axon/extconf.rb +19 -9
- data/ext/axon/interpolation.c +147 -0
- data/ext/axon/jpeg.c +1207 -0
- data/ext/axon/png.c +542 -0
- data/lib/axon.rb +235 -32
- data/lib/axon/cropper.rb +80 -18
- data/lib/axon/fit.rb +69 -19
- data/lib/axon/generators.rb +109 -0
- data/lib/axon/scalers.rb +160 -0
- data/test/helper.rb +151 -6
- data/test/reader_tests.rb +37 -82
- data/test/scaler_tests.rb +102 -0
- data/test/stress_helper.rb +58 -0
- data/test/stress_tests.rb +8 -5
- data/test/test_bilinear_scaler.rb +60 -2
- data/test/test_cropper.rb +68 -1
- data/test/test_fit.rb +35 -0
- data/test/test_generators.rb +21 -0
- data/test/test_image.rb +61 -0
- data/test/test_jpeg_reader.rb +96 -94
- data/test/test_jpeg_writer.rb +95 -8
- data/test/test_nearest_neighbor_scaler.rb +28 -4
- data/test/test_png_reader.rb +12 -8
- data/test/test_png_writer.rb +8 -6
- data/test/writer_tests.rb +129 -111
- metadata +71 -128
- data/.gemtest +0 -0
- data/ext/axon/bilinear_interpolation.c +0 -115
- data/ext/axon/interpolation.h +0 -7
- data/ext/axon/jpeg_common.c +0 -118
- data/ext/axon/jpeg_common.h +0 -37
- data/ext/axon/jpeg_native_writer.c +0 -248
- data/ext/axon/jpeg_reader.c +0 -774
- data/ext/axon/nearest_neighbor_interpolation.c +0 -50
- data/ext/axon/png_common.c +0 -21
- data/ext/axon/png_common.h +0 -18
- data/ext/axon/png_native_writer.c +0 -166
- data/ext/axon/png_reader.c +0 -381
- data/lib/axon/axon.so +0 -0
- data/lib/axon/bilinear_scaler.rb +0 -60
- data/lib/axon/jpeg_writer.rb +0 -41
- data/lib/axon/nearest_neighbor_scaler.rb +0 -39
- data/lib/axon/png_writer.rb +0 -35
- data/lib/axon/scaler.rb +0 -41
- data/lib/axon/solid.rb +0 -23
- data/test/_test_readme.rb +0 -34
- data/test/test_exif.rb +0 -39
- data/test/test_generator.rb +0 -10
- data/test/test_icc.rb +0 -18
- data/test/test_jpeg.rb +0 -9
- data/test/test_png.rb +0 -9
data/test/test_jpeg_reader.rb
CHANGED
@@ -1,108 +1,110 @@
|
|
1
1
|
require 'helper'
|
2
|
+
require 'reader_tests'
|
2
3
|
|
3
4
|
module Axon
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
def setup
|
8
|
-
super
|
9
|
-
@readerclass = JPEGReader
|
10
|
-
@data = @image.to_jpeg.data
|
11
|
-
@io_in = StringIO.new @data
|
12
|
-
@reader = @readerclass.new(@io_in)
|
13
|
-
end
|
5
|
+
module JPEG
|
6
|
+
class TestJPEGReader < AxonTestCase
|
7
|
+
include ReaderTests
|
14
8
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
assert_raises(RuntimeError){ @reader.in_color_model = "foobar" }
|
24
|
-
end
|
25
|
-
|
26
|
-
def test_set_out_color_model
|
27
|
-
@reader.color_model = :YCbCr
|
28
|
-
assert_equal :YCbCr, @reader.color_model
|
29
|
-
|
30
|
-
assert_raises(RuntimeError){ @reader.color_model = "foobar" }
|
31
|
-
end
|
32
|
-
|
33
|
-
def test_scale_num
|
34
|
-
assert @reader.scale_num > 0
|
35
|
-
end
|
36
|
-
|
37
|
-
def test_set_scale_num
|
38
|
-
@reader.scale_num = 5
|
39
|
-
assert_equal 5, @reader.scale_num
|
40
|
-
end
|
41
|
-
|
42
|
-
def test_scale_denom
|
43
|
-
assert @reader.scale_denom > 0
|
44
|
-
end
|
45
|
-
|
46
|
-
def test_set_scale_denom
|
47
|
-
@reader.scale_denom = 8
|
48
|
-
|
49
|
-
assert_equal 8, @reader.scale_denom
|
50
|
-
end
|
51
|
-
|
52
|
-
def test_scale_denom_affects_image_size
|
53
|
-
pre_width = @reader.width
|
54
|
-
pre_height = @reader.height
|
55
|
-
|
56
|
-
@reader.scale_denom = 2
|
57
|
-
|
58
|
-
assert @reader.width < pre_width
|
59
|
-
assert @reader.height < pre_height
|
60
|
-
end
|
9
|
+
def setup
|
10
|
+
super
|
11
|
+
io = StringIO.new
|
12
|
+
JPEG.write(@image, io)
|
13
|
+
@data = io.string
|
14
|
+
@readerclass = Reader
|
15
|
+
@reader = Reader.new(StringIO.new(@data))
|
16
|
+
end
|
61
17
|
|
62
|
-
|
63
|
-
|
64
|
-
|
18
|
+
def test_in_color_model
|
19
|
+
assert_equal :YCbCr, @reader.in_color_model
|
20
|
+
end
|
65
21
|
|
66
|
-
|
67
|
-
|
22
|
+
def test_set_in_color_model
|
23
|
+
@reader.in_color_model = :RGB
|
24
|
+
assert_equal :RGB, @reader.in_color_model
|
68
25
|
|
69
|
-
|
26
|
+
assert_raises(RuntimeError){ @reader.in_color_model = "foobar" }
|
27
|
+
end
|
70
28
|
|
71
|
-
|
29
|
+
def test_set_out_color_model
|
30
|
+
@reader.color_model = :YCbCr
|
31
|
+
assert_equal :YCbCr, @reader.color_model
|
72
32
|
|
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
|
-
|
33
|
+
assert_raises(RuntimeError){ @reader.color_model = "foobar" }
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_scale_num
|
37
|
+
assert @reader.scale_num > 0
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_set_scale_num
|
41
|
+
@reader.scale_num = 5
|
42
|
+
assert_equal 5, @reader.scale_num
|
43
|
+
end
|
44
|
+
|
45
|
+
unless LIB_TURBO
|
46
|
+
def test_scale_denom
|
47
|
+
assert @reader.scale_denom > 0
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_set_scale_denom
|
51
|
+
@reader.scale_denom = 8
|
52
|
+
assert_equal 8, @reader.scale_denom
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_scale_denom_affects_image_size
|
56
|
+
pre_width = @reader.width
|
57
|
+
pre_height = @reader.height
|
58
|
+
|
59
|
+
@reader.scale_denom = 2
|
60
|
+
|
61
|
+
assert @reader.width < pre_width
|
62
|
+
assert @reader.height < pre_height
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_scale_denom_affects_written_image
|
66
|
+
pre_width = @reader.width
|
67
|
+
pre_height = @reader.height
|
68
|
+
|
69
|
+
@reader.scale_denom = 2
|
70
|
+
|
71
|
+
io_out = StringIO.new
|
72
|
+
JPEG.write(@reader, io_out)
|
73
|
+
io_out.rewind
|
74
|
+
|
75
|
+
new_velvet_reader = Reader.new(io_out)
|
76
|
+
|
77
|
+
assert new_velvet_reader.width < pre_width
|
78
|
+
assert new_velvet_reader.height < pre_height
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_dct_method
|
83
|
+
assert_equal Reader::DEFAULT_DCT, @reader.dct_method
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_set_dct_method
|
87
|
+
@reader.dct_method = :IFAST
|
88
|
+
assert_equal :IFAST, @reader.dct_method
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_markers_read_by_default
|
92
|
+
refute_empty @reader[:APP0]
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_empty_marker_prevents_reads
|
96
|
+
r = Reader.new StringIO.new(@data), []
|
97
|
+
assert_empty r[:APP0]
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_marker_content
|
101
|
+
assert_match(/^JFIF/, @reader[:APP0].first)
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_no_configuration_after_initiated
|
105
|
+
@reader.gets
|
103
106
|
assert_raises(RuntimeError) { @reader.dct_method = :IFAST }
|
104
107
|
assert_raises(RuntimeError) { @reader.scale_denom = 4 }
|
105
|
-
break
|
106
108
|
end
|
107
109
|
end
|
108
110
|
end
|
data/test/test_jpeg_writer.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'helper'
|
2
|
+
require 'writer_tests'
|
2
3
|
|
3
4
|
module Axon
|
4
5
|
class TestJPEGWriter < AxonTestCase
|
@@ -6,21 +7,107 @@ module Axon
|
|
6
7
|
|
7
8
|
def setup
|
8
9
|
super
|
9
|
-
@
|
10
|
-
@writer = @image.to_jpeg
|
10
|
+
@mod = JPEG
|
11
11
|
end
|
12
12
|
|
13
13
|
def test_output_has_jpeg_header
|
14
|
-
|
15
|
-
|
16
|
-
assert_equal "\
|
17
|
-
assert_equal "JFIF\x00", string[6..10]
|
14
|
+
JPEG.write(@image, @io_out)
|
15
|
+
assert_equal "\xFF\xD8\xFF\xE0", @io_out.string[0..3]
|
16
|
+
assert_equal "JFIF\x00", @io_out.string[6..10]
|
18
17
|
end
|
19
18
|
|
20
|
-
def
|
19
|
+
def test_invalid_bufsize
|
21
20
|
assert_raises RuntimeError do
|
22
|
-
|
21
|
+
JPEG.write(@image, @io_out, :bufsize => 0)
|
22
|
+
end
|
23
|
+
|
24
|
+
assert_raises RuntimeError do
|
25
|
+
JPEG.write(@image, @io_out, :bufsize => -5)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_symbol_bufsize
|
30
|
+
assert_raises TypeError do
|
31
|
+
JPEG.write(@image, @io_out, :bufsize => :foo)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_quality_filesize
|
36
|
+
file_sizes = {}
|
37
|
+
[-10, 0, 1, 50, 100, 130].each do |q|
|
38
|
+
im = Solid.new(100, 200)
|
39
|
+
io = StringIO.new
|
40
|
+
JPEG.write(im, io, :quality => q)
|
41
|
+
file_sizes[q] = io.size
|
23
42
|
end
|
43
|
+
|
44
|
+
assert file_sizes[-10] > 1
|
45
|
+
|
46
|
+
# libjpeg treats values under 1 as 1
|
47
|
+
assert_equal file_sizes[-10], file_sizes[0]
|
48
|
+
assert_equal file_sizes[0], file_sizes[1]
|
49
|
+
|
50
|
+
assert file_sizes[50] > file_sizes[1]
|
51
|
+
assert file_sizes[100] > file_sizes[50]
|
52
|
+
|
53
|
+
# libjpeg treats values over 100 as 100
|
54
|
+
assert_equal file_sizes[130], file_sizes[100]
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_symbol_quality
|
58
|
+
assert_raises TypeError do
|
59
|
+
JPEG.write(@image, @io_out, :quality => :foo)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_exif_roundtrip
|
64
|
+
random_data = ""
|
65
|
+
(100).times do
|
66
|
+
random_data << [rand].pack('d') # 800 bytes random data
|
67
|
+
end
|
68
|
+
|
69
|
+
io_out = StringIO.new
|
70
|
+
JPEG.write(@image, io_out, :exif => random_data)
|
71
|
+
io_out.rewind
|
72
|
+
|
73
|
+
image_with_exif = JPEG::Reader.new(io_out)
|
74
|
+
assert_equal random_data, image_with_exif.exif
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_exif_with_icc_roundtrip
|
78
|
+
random_icc_data = ""
|
79
|
+
(2**16).times do # a little larger than one jpeg segment
|
80
|
+
random_icc_data << [rand].pack('d') # 8 bytes random data
|
81
|
+
end
|
82
|
+
|
83
|
+
random_exif_data = ""
|
84
|
+
(100).times do
|
85
|
+
random_exif_data << [rand].pack('d') # 800 bytes random data
|
86
|
+
end
|
87
|
+
|
88
|
+
io_out = StringIO.new
|
89
|
+
JPEG.write(@image, io_out, :icc_profile => random_icc_data,
|
90
|
+
:exif => random_exif_data)
|
91
|
+
io_out.rewind
|
92
|
+
|
93
|
+
image_with_exif_and_icc = JPEG::Reader.new(io_out)
|
94
|
+
|
95
|
+
assert_equal random_exif_data, image_with_exif_and_icc.exif
|
96
|
+
assert_equal random_icc_data, image_with_exif_and_icc.icc_profile
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_large_icc_roundtrip
|
100
|
+
random_data = ""
|
101
|
+
(2**16).times do # a little larger than one jpeg segment
|
102
|
+
random_data << [rand].pack('d') # 8 bytes random data
|
103
|
+
end
|
104
|
+
|
105
|
+
io_out = StringIO.new
|
106
|
+
JPEG.write(@image, io_out, :icc_profile => random_data)
|
107
|
+
io_out.rewind
|
108
|
+
|
109
|
+
image_with_icc = JPEG::Reader.new(io_out)
|
110
|
+
assert_equal random_data, image_with_icc.icc_profile
|
24
111
|
end
|
25
112
|
end
|
26
113
|
end
|
@@ -1,13 +1,37 @@
|
|
1
1
|
require 'helper'
|
2
|
+
require 'scaler_tests'
|
2
3
|
|
3
4
|
module Axon
|
4
5
|
class TestNearestNeighborScaler < AxonTestCase
|
5
|
-
|
6
|
-
|
6
|
+
include ScalerTests
|
7
|
+
|
8
|
+
def setup
|
9
|
+
super
|
10
|
+
@scalerclass = NearestNeighborScaler
|
11
|
+
@scalertestclass = TestNearestNeighborScaler
|
7
12
|
end
|
8
13
|
|
9
|
-
|
10
|
-
|
14
|
+
class TestNearestNeighborScaler
|
15
|
+
def initialize(original, width, height)
|
16
|
+
@original = original
|
17
|
+
@scale_x_inv = original.width / width.to_f
|
18
|
+
@scale_y_inv = original.height / height.to_f
|
19
|
+
@data = []
|
20
|
+
@original.height.times do
|
21
|
+
sl = @original.gets
|
22
|
+
@data << sl + sl[-@original.components, @original.components]
|
23
|
+
end
|
24
|
+
@data << @data.last
|
25
|
+
end
|
26
|
+
|
27
|
+
def calc(x, y)
|
28
|
+
smp_x = (x * @scale_x_inv).floor
|
29
|
+
smp_y = (y * @scale_y_inv).floor
|
30
|
+
cmp = @original.components
|
31
|
+
@data[smp_y][smp_x * cmp, cmp].chars.map do |c|
|
32
|
+
c.respond_to?(:ord) ? c.ord : c[0]
|
33
|
+
end
|
34
|
+
end
|
11
35
|
end
|
12
36
|
end
|
13
37
|
end
|
data/test/test_png_reader.rb
CHANGED
@@ -1,15 +1,19 @@
|
|
1
1
|
require 'helper'
|
2
|
+
require 'reader_tests'
|
2
3
|
|
3
4
|
module Axon
|
4
|
-
|
5
|
-
|
5
|
+
module PNG
|
6
|
+
class TestPNGReader < AxonTestCase
|
7
|
+
include ReaderTests
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
def setup
|
10
|
+
super
|
11
|
+
io = StringIO.new
|
12
|
+
PNG.write(@image, io)
|
13
|
+
@data = io.string
|
14
|
+
@readerclass = Reader
|
15
|
+
@reader = Reader.new(StringIO.new(@data))
|
16
|
+
end
|
13
17
|
end
|
14
18
|
end
|
15
19
|
end
|
data/test/test_png_writer.rb
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
require 'helper'
|
2
|
+
require 'writer_tests'
|
2
3
|
|
3
4
|
module Axon
|
4
|
-
|
5
|
-
|
5
|
+
module PNG
|
6
|
+
class TestPNGWriter < AxonTestCase
|
7
|
+
include WriterTests
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
def setup
|
10
|
+
super
|
11
|
+
@mod = PNG
|
12
|
+
end
|
11
13
|
end
|
12
14
|
end
|
13
15
|
end
|
data/test/writer_tests.rb
CHANGED
@@ -1,178 +1,196 @@
|
|
1
1
|
module Axon
|
2
2
|
module WriterTests
|
3
3
|
def test_writes_something
|
4
|
-
@
|
4
|
+
@mod.write(@image, @io_out)
|
5
5
|
refute @io_out.string.empty?
|
6
6
|
end
|
7
7
|
|
8
|
-
|
9
|
-
|
8
|
+
def test_returns_bytes_written
|
9
|
+
ret = @mod.write(@image, @io_out)
|
10
|
+
assert_equal @io_out.size, ret
|
10
11
|
end
|
11
12
|
|
12
|
-
|
13
|
-
|
13
|
+
def test_invalid_numeric_height
|
14
|
+
[0, -100, 0.0001].each do |h|
|
15
|
+
assert_raises RuntimeError do
|
16
|
+
@mod.write(CustomHeightImage.new(h), @io_out)
|
17
|
+
end
|
18
|
+
end
|
14
19
|
end
|
15
20
|
|
16
|
-
|
17
|
-
|
21
|
+
def test_invalid_height_type
|
22
|
+
[nil, :foo].each do |h|
|
23
|
+
assert_raises TypeError, "should throw a TypeError when given a #{h.class} for height." do
|
24
|
+
@mod.write(CustomHeightImage.new(h), @io_out)
|
25
|
+
end
|
26
|
+
end
|
18
27
|
end
|
19
28
|
|
20
|
-
def
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
assert_raises RuntimeError do
|
25
|
-
writer.write(@io_out)
|
29
|
+
def test_height_raises_exception
|
30
|
+
im = CustomHeightImage.new(Proc.new{ raise CustomError })
|
31
|
+
assert_raises CustomError do
|
32
|
+
@mod.write(im, @io_out)
|
26
33
|
end
|
27
|
-
|
28
|
-
i = NegativeHeightImage.new 10, 15, @velvet
|
29
|
-
writer = @writerclass.new(i)
|
34
|
+
end
|
30
35
|
|
31
|
-
|
32
|
-
|
36
|
+
def test_invalid_numeric_width
|
37
|
+
[0, -100, 0.0001].each do |w|
|
38
|
+
assert_raises RuntimeError do
|
39
|
+
@mod.write(CustomWidthImage.new(w), @io_out)
|
40
|
+
end
|
33
41
|
end
|
42
|
+
end
|
34
43
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
44
|
+
def test_invalid_width_type
|
45
|
+
[nil, :foo].each do |w|
|
46
|
+
assert_raises TypeError, "should throw a TypeError when given a #{w.class} for width." do
|
47
|
+
@mod.write(CustomWidthImage.new(w), @io_out)
|
48
|
+
end
|
40
49
|
end
|
41
50
|
end
|
42
51
|
|
43
|
-
|
44
|
-
|
52
|
+
def test_width_raises_exception
|
53
|
+
im = CustomWidthImage.new(Proc.new{ raise CustomError })
|
54
|
+
assert_raises CustomError do
|
55
|
+
@mod.write(im, @io_out)
|
56
|
+
end
|
45
57
|
end
|
46
58
|
|
47
|
-
def
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
assert_raises RuntimeError do
|
52
|
-
writer.write(@io_out)
|
59
|
+
def test_nil_image_color_model
|
60
|
+
assert_raises TypeError do
|
61
|
+
@mod.write(CustomColorModelImage.new(nil), @io_out)
|
53
62
|
end
|
54
63
|
end
|
55
64
|
|
56
|
-
|
57
|
-
|
65
|
+
def test_invalid_color_model
|
66
|
+
assert_raises RuntimeError do
|
67
|
+
@mod.write(CustomColorModelImage.new(:foo), @io_out)
|
68
|
+
end
|
58
69
|
end
|
59
70
|
|
60
|
-
|
61
|
-
|
71
|
+
def test_color_model_raises_exception
|
72
|
+
im = CustomColorModelImage.new(Proc.new{ raise CustomError })
|
73
|
+
assert_raises CustomError do
|
74
|
+
@mod.write(im, @io_out)
|
75
|
+
end
|
62
76
|
end
|
63
77
|
|
64
|
-
|
65
|
-
|
78
|
+
def test_invalid_image_components
|
79
|
+
[0, -100, 0.0001, 15].each do |w|
|
80
|
+
assert_raises RuntimeError do
|
81
|
+
@mod.write(CustomComponentsImage.new(w), @io_out)
|
82
|
+
end
|
83
|
+
end
|
66
84
|
end
|
67
85
|
|
68
|
-
def
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
writer.write(@io_out)
|
86
|
+
def test_invalid_components_type
|
87
|
+
[nil, :foo].each do |w|
|
88
|
+
assert_raises TypeError do
|
89
|
+
@mod.write(CustomComponentsImage.new(w), @io_out)
|
90
|
+
end
|
74
91
|
end
|
92
|
+
end
|
75
93
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
94
|
+
def test_invalid_components_type
|
95
|
+
[nil, :foo].each do |w|
|
96
|
+
assert_raises TypeError, "should throw a TypeError when given a #{w.class} for components." do
|
97
|
+
@mod.write(CustomComponentsImage.new(w), @io_out)
|
98
|
+
end
|
81
99
|
end
|
100
|
+
end
|
82
101
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
writer.write(@io_out)
|
102
|
+
def test_components_raises_exception
|
103
|
+
im = CustomComponentsImage.new(Proc.new{ raise CustomError })
|
104
|
+
assert_raises CustomError do
|
105
|
+
@mod.write(im, @io_out)
|
88
106
|
end
|
89
107
|
end
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
108
|
+
|
109
|
+
def test_invalid_lineno_type
|
110
|
+
[-1, nil, :foo].each do |l|
|
111
|
+
# we don't know if the writer will care but test anyways to detect
|
112
|
+
# interpreter crashes and mem leaks.
|
113
|
+
@mod.write(CustomLinenoImage.new(l), @io_out)
|
94
114
|
end
|
95
115
|
end
|
96
|
-
|
97
|
-
def
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
116
|
+
|
117
|
+
def test_odd_gets_type
|
118
|
+
[nil, :foo, 1234].each do |l|
|
119
|
+
assert_raises RuntimeError do
|
120
|
+
@mod.write(CustomGetsImage.new(l), @io_out)
|
121
|
+
end
|
102
122
|
end
|
103
123
|
end
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
124
|
+
|
125
|
+
def test_gets_raises_exception_immediately
|
126
|
+
im = CustomGetsImage.new(Proc.new{ raise CustomError })
|
127
|
+
assert_raises CustomError do
|
128
|
+
@mod.write(im, @io_out)
|
108
129
|
end
|
109
130
|
end
|
110
131
|
|
111
|
-
def
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
writer.write(@io_out)
|
132
|
+
def test_gets_raises_exception_later
|
133
|
+
proc = Proc.new{ |im| im.lineno > 3 ? raise(CustomError) : im.gets }
|
134
|
+
i = CustomGetsImage.new(proc)
|
135
|
+
assert_raises CustomError do
|
136
|
+
@mod.write(i, @io_out)
|
117
137
|
end
|
138
|
+
assert_equal 4, i.lineno
|
118
139
|
end
|
119
140
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
141
|
+
def test_gets_return_is_too_short_immediately
|
142
|
+
proc = Proc.new{ |im| im.gets[2, -1] }
|
143
|
+
assert_raises RuntimeError do
|
144
|
+
@mod.write(CustomGetsImage.new(proc), @io_out)
|
124
145
|
end
|
125
146
|
end
|
126
147
|
|
127
|
-
def
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
class TooFewScanLinesImage < Solid
|
134
|
-
def each
|
135
|
-
yield(@color * width)
|
148
|
+
def test_gets_return_is_too_short_later
|
149
|
+
proc = Proc.new{ |im| im.lineno > 3 ? im.gets[2, -1] : im.gets }
|
150
|
+
i = CustomGetsImage.new(proc)
|
151
|
+
assert_raises RuntimeError do
|
152
|
+
@mod.write(i, @io_out)
|
136
153
|
end
|
154
|
+
assert_equal 5, i.lineno
|
137
155
|
end
|
138
156
|
|
139
|
-
def
|
140
|
-
|
141
|
-
writer = @writerclass.new(image)
|
142
|
-
|
157
|
+
def test_gets_return_is_too_long_immediately
|
158
|
+
proc = Proc.new{ |im| im.gets * 2 }
|
143
159
|
assert_raises RuntimeError do
|
144
|
-
|
160
|
+
@mod.write(CustomGetsImage.new(proc), @io_out)
|
145
161
|
end
|
146
162
|
end
|
147
163
|
|
148
|
-
|
149
|
-
|
150
|
-
|
164
|
+
def test_gets_return_is_too_long_later
|
165
|
+
proc = Proc.new{ |im| im.lineno > 3 ? im.gets * 2 : im.gets }
|
166
|
+
i = CustomGetsImage.new(proc)
|
167
|
+
assert_raises RuntimeError do
|
168
|
+
@mod.write(i, @io_out)
|
151
169
|
end
|
170
|
+
assert_equal 5, i.lineno
|
152
171
|
end
|
153
|
-
|
154
|
-
def test_image_scanlines_raises_exception
|
155
|
-
image = RaisingImage.new(10, 15, @velvet)
|
156
|
-
writer = @writerclass.new(image)
|
157
172
|
|
158
|
-
|
159
|
-
|
173
|
+
def test_io_raises_exception_immediately
|
174
|
+
io = CustomIO.new(Proc.new{ raise CustomError })
|
175
|
+
assert_raises CustomError do
|
176
|
+
@mod.write(@image, io)
|
160
177
|
end
|
161
178
|
end
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
179
|
+
|
180
|
+
def test_io_returns_invalid_type
|
181
|
+
[nil, :foo, "bar"].each do |r|
|
182
|
+
im = Solid.new(200, 100)
|
183
|
+
assert_raises TypeError, "should get a TypeError when IO#write returns a #{r.class}." do
|
184
|
+
@mod.write(im, CustomIO.new(r))
|
185
|
+
end
|
167
186
|
end
|
168
187
|
end
|
169
|
-
|
170
|
-
def test_image_scanlines_returns_too_much
|
171
|
-
image = BigWidthImage.new(10, 15, @velvet)
|
172
|
-
writer = @writerclass.new(image)
|
173
188
|
|
174
|
-
|
175
|
-
|
189
|
+
def test_io_returns_invalid_length
|
190
|
+
[0, -1, -100, 2000, 1].each do |r|
|
191
|
+
assert_raises RuntimeError do
|
192
|
+
@mod.write(@image, CustomIO.new(r))
|
193
|
+
end
|
176
194
|
end
|
177
195
|
end
|
178
196
|
end
|