barby 0.6.5 → 0.6.8
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.
- checksums.yaml +5 -5
- data/.gitignore +2 -0
- data/CHANGELOG +8 -0
- data/Gemfile +5 -0
- data/README.md +21 -20
- data/Rakefile +15 -0
- data/barby.gemspec +31 -0
- data/lib/barby/barcode/codabar.rb +82 -0
- data/lib/barby/barcode.rb +3 -3
- data/lib/barby/outputter/cairo_outputter.rb +11 -3
- data/lib/barby/outputter/png_outputter.rb +43 -11
- data/lib/barby/outputter/prawn_outputter.rb +12 -9
- data/lib/barby/outputter/rmagick_outputter.rb +38 -11
- data/lib/barby/outputter/svg_outputter.rb +11 -18
- data/lib/barby/outputter.rb +1 -1
- data/lib/barby/version.rb +2 -2
- data/test/barcodes.rb +20 -0
- data/test/bookland_test.rb +54 -0
- data/test/codabar_test.rb +58 -0
- data/test/code_128_test.rb +470 -0
- data/test/code_25_iata_test.rb +19 -0
- data/test/code_25_interleaved_test.rb +116 -0
- data/test/code_25_test.rb +110 -0
- data/test/code_39_test.rb +210 -0
- data/test/code_93_test.rb +144 -0
- data/test/data_matrix_test.rb +30 -0
- data/test/ean13_test.rb +169 -0
- data/test/ean8_test.rb +100 -0
- data/test/outputter/cairo_outputter_test.rb +129 -0
- data/test/outputter/html_outputter_test.rb +68 -0
- data/test/outputter/pdfwriter_outputter_test.rb +37 -0
- data/test/outputter/png_outputter_test.rb +49 -0
- data/test/outputter/prawn_outputter_test.rb +79 -0
- data/test/outputter/rmagick_outputter_test.rb +83 -0
- data/test/outputter/svg_outputter_test.rb +89 -0
- data/test/outputter_test.rb +134 -0
- data/test/pdf_417_test.rb +45 -0
- data/test/qr_code_test.rb +78 -0
- data/test/test_helper.rb +24 -0
- data/test/upc_supplemental_test.rb +109 -0
- metadata +157 -7
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class RmagickTestBarcode < Barby::Barcode
|
4
|
+
def initialize(data)
|
5
|
+
@data = data
|
6
|
+
end
|
7
|
+
def encoding
|
8
|
+
@data
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class RmagickOutputterTest < Barby::TestCase
|
13
|
+
|
14
|
+
before do
|
15
|
+
load_outputter('rmagick')
|
16
|
+
@barcode = RmagickTestBarcode.new('10110011100011110000')
|
17
|
+
@outputter = RmagickOutputter.new(@barcode)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should register to_png, to_gif, to_jpg, to_image" do
|
21
|
+
Barcode.outputters.must_include(:to_png)
|
22
|
+
Barcode.outputters.must_include(:to_gif)
|
23
|
+
Barcode.outputters.must_include(:to_jpg)
|
24
|
+
Barcode.outputters.must_include(:to_image)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should have defined to_png, to_gif, to_jpg, to_image" do
|
28
|
+
@outputter.must_respond_to(:to_png)
|
29
|
+
@outputter.must_respond_to(:to_gif)
|
30
|
+
@outputter.must_respond_to(:to_jpg)
|
31
|
+
@outputter.must_respond_to(:to_image)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should return a string on to_png and to_gif" do
|
35
|
+
@outputter.to_png.must_be_instance_of(String)
|
36
|
+
@outputter.to_gif.must_be_instance_of(String)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should return a Magick::Image instance on to_image" do
|
40
|
+
@outputter.to_image.must_be_instance_of(Magick::Image)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should have a width equal to the length of the barcode encoding string * x dimension" do
|
44
|
+
@outputter.xdim.must_equal 1#Default
|
45
|
+
@outputter.width.must_equal @outputter.barcode.encoding.length
|
46
|
+
@outputter.xdim = 2
|
47
|
+
@outputter.width.must_equal @outputter.barcode.encoding.length * 2
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should have a full_width equal to the width + left and right margins" do
|
51
|
+
@outputter.xdim.must_equal 1
|
52
|
+
@outputter.margin.must_equal 10
|
53
|
+
@outputter.full_width.must_equal (@outputter.width + 10 + 10)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should have a default height of 100" do
|
57
|
+
@outputter.height.must_equal 100
|
58
|
+
@outputter.height = 200
|
59
|
+
@outputter.height.must_equal 200
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should have a full_height equal to the height + top and bottom margins" do
|
63
|
+
@outputter.full_height.must_equal @outputter.height + (@outputter.margin * 2)
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "#to_image" do
|
67
|
+
|
68
|
+
before do
|
69
|
+
@barcode = RmagickTestBarcode.new('10110011100011110000')
|
70
|
+
@outputter = RmagickOutputter.new(@barcode)
|
71
|
+
@image = @outputter.to_image
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should have a width and height equal to the outputter's full_width and full_height" do
|
75
|
+
@image.columns.must_equal @outputter.full_width
|
76
|
+
@image.rows.must_equal @outputter.full_height
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class SvgBarcode < Barby::Barcode
|
4
|
+
attr_accessor :data, :two_d
|
5
|
+
def initialize(data, two_d=false)
|
6
|
+
self.data, self.two_d = data, two_d
|
7
|
+
end
|
8
|
+
def encoding
|
9
|
+
data
|
10
|
+
end
|
11
|
+
def two_dimensional?
|
12
|
+
two_d
|
13
|
+
end
|
14
|
+
def to_s
|
15
|
+
data
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class SvgOutputterTest < Barby::TestCase
|
20
|
+
|
21
|
+
before do
|
22
|
+
load_outputter('svg')
|
23
|
+
@barcode = SvgBarcode.new('10110011100011110000')
|
24
|
+
@outputter = SvgOutputter.new(@barcode)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should register to_svg, bars_to_rects, and bars_to_path' do
|
28
|
+
Barcode.outputters.must_include :to_svg
|
29
|
+
Barcode.outputters.must_include :bars_to_rects
|
30
|
+
Barcode.outputters.must_include :bars_to_path
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should return a string on to_svg' do
|
34
|
+
@barcode.to_svg.must_be_instance_of String
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should return a string on bars_to_rects' do
|
38
|
+
@barcode.bars_to_rects.must_be_instance_of String
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should return a string on bars_to_path' do
|
42
|
+
@barcode.bars_to_path.must_be_instance_of String
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should produce one rect for each bar' do
|
46
|
+
@barcode.bars_to_rects.scan(/<rect/).size.must_equal @outputter.send(:boolean_groups).select{|bg|bg[0]}.size
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should produce one path stroke for each bar module' do
|
50
|
+
@barcode.bars_to_path.scan(/(M\d+\s+\d+)\s*(V\d+)/).size.must_equal @outputter.send(:booleans).select{|bg|bg}.size
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should return default values for attributes' do
|
54
|
+
@outputter.margin.must_be_instance_of Fixnum
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should use defaults to populate higher level attributes' do
|
58
|
+
@outputter.xmargin.must_equal @outputter.margin
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should return nil for overridden attributes' do
|
62
|
+
@outputter.xmargin = 1
|
63
|
+
@outputter.margin.must_equal nil
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should still use defaults for unspecified attributes' do
|
67
|
+
@outputter.xmargin = 1
|
68
|
+
@outputter.ymargin.must_equal @outputter.send(:_margin)
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'should have a width equal to Xdim * barcode_string.length' do
|
72
|
+
@outputter.width.must_equal @outputter.barcode.encoding.length * @outputter.xdim
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'should have a full_width which is by default the sum of width + (margin*2)' do
|
76
|
+
@outputter.full_width.must_equal @outputter.width + (@outputter.margin*2)
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'should have a full_width which is the sum of width + xmargin + ymargin' do
|
80
|
+
@outputter.full_width.must_equal @outputter.width + @outputter.xmargin + @outputter.ymargin
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'should use Barcode#to_s for title' do
|
84
|
+
@outputter.title.must_equal @barcode.data
|
85
|
+
def @barcode.to_s; "the eastern star"; end
|
86
|
+
@outputter.title.must_equal "the eastern star"
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class OutputterTest < Barby::TestCase
|
4
|
+
|
5
|
+
before do
|
6
|
+
@outputter = Class.new(Outputter)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should be able to register an output method for barcodes" do
|
10
|
+
@outputter.register :foo
|
11
|
+
Barcode.outputters.must_include(:foo)
|
12
|
+
@outputter.register :bar, :baz
|
13
|
+
Barcode.outputters.must_include(:bar)
|
14
|
+
Barcode.outputters.must_include(:baz)
|
15
|
+
@outputter.register :quux => :my_quux
|
16
|
+
Barcode.outputters.must_include(:quux)
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "Outputter instances" do
|
20
|
+
|
21
|
+
before do
|
22
|
+
@barcode = Barcode.new
|
23
|
+
class << @barcode; attr_accessor :encoding; end
|
24
|
+
@barcode.encoding = '101100111000'
|
25
|
+
@outputter = Outputter.new(@barcode)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should have a method 'booleans' which converts the barcode encoding to an array of true,false values" do
|
29
|
+
@outputter.send(:booleans).length.must_equal @barcode.encoding.length
|
30
|
+
t, f = true, false
|
31
|
+
@outputter.send(:booleans).must_equal [t,f,t,t,f,f,t,t,t,f,f,f]
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should convert 2D encodings with 'booleans'" do
|
35
|
+
barcode = Barcode2D.new
|
36
|
+
def barcode.encoding; ['101100','110010']; end
|
37
|
+
outputter = Outputter.new(barcode)
|
38
|
+
outputter.send(:booleans).length.must_equal barcode.encoding.length
|
39
|
+
t, f = true, false
|
40
|
+
outputter.send(:booleans).must_equal [[t,f,t,t,f,f], [t,t,f,f,t,f]]
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should have an 'encoding' attribute" do
|
44
|
+
@outputter.send(:encoding).must_equal @barcode.encoding
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should cache encoding" do
|
48
|
+
@outputter.send(:encoding).must_equal @barcode.encoding
|
49
|
+
previous_encoding = @barcode.encoding
|
50
|
+
@barcode.encoding = '101010'
|
51
|
+
@outputter.send(:encoding).must_equal previous_encoding
|
52
|
+
@outputter.send(:encoding, true).must_equal @barcode.encoding
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should have a boolean_groups attribute which collects continuous bars and spaces" do
|
56
|
+
t, f = true, false
|
57
|
+
# 1 0 11 00 111 000
|
58
|
+
@outputter.send(:boolean_groups).must_equal [[t,1],[f,1],[t,2],[f,2],[t,3],[f,3]]
|
59
|
+
|
60
|
+
barcode = Barcode2D.new
|
61
|
+
def barcode.encoding; ['1100', '111000']; end
|
62
|
+
outputter = Outputter.new(barcode)
|
63
|
+
outputter.send(:boolean_groups).must_equal [[[t,2],[f,2]],[[t,3],[f,3]]]
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should have a with_options method which sets the instance's attributes temporarily while the block gets yielded" do
|
67
|
+
class << @outputter; attr_accessor :foo, :bar; end
|
68
|
+
@outputter.foo, @outputter.bar = 'humbaba', 'scorpion man'
|
69
|
+
@outputter.send(:with_options, :foo => 'horse', :bar => 'donkey') do
|
70
|
+
@outputter.foo.must_equal 'horse'
|
71
|
+
@outputter.bar.must_equal 'donkey'
|
72
|
+
end
|
73
|
+
@outputter.foo.must_equal 'humbaba'
|
74
|
+
@outputter.bar.must_equal 'scorpion man'
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should return the block value on with_options" do
|
78
|
+
@outputter.send(:with_options, {}){ 'donkey' }.must_equal 'donkey'
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should have a two_dimensional? method which returns true if the barcode is 2d" do
|
82
|
+
refute Outputter.new(Barcode1D.new).send(:two_dimensional?)
|
83
|
+
assert Outputter.new(Barcode2D.new).send(:two_dimensional?)
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should not require the barcode object to respond to two_dimensional?" do
|
87
|
+
barcode = Object.new
|
88
|
+
def barcode.encoding; "101100111000"; end
|
89
|
+
outputter = Outputter.new(barcode)
|
90
|
+
assert outputter.send(:booleans)
|
91
|
+
assert outputter.send(:boolean_groups)
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "Barcode instances" do
|
97
|
+
|
98
|
+
before do
|
99
|
+
@outputter = Class.new(Outputter)
|
100
|
+
@outputter.register :foo
|
101
|
+
@outputter.register :bar => :my_bar
|
102
|
+
@outputter.class_eval{ def foo; 'foo'; end; def my_bar; 'bar'; end }
|
103
|
+
@barcode = Barcode.new
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should respond to registered output methods" do
|
107
|
+
@barcode.foo.must_equal 'foo'
|
108
|
+
@barcode.bar.must_equal 'bar'
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should send arguments to registered method on outputter class" do
|
112
|
+
@outputter.class_eval{ def foo(*a); a; end; def my_bar(*a); a; end }
|
113
|
+
@barcode.foo(1,2,3).must_equal [1,2,3]
|
114
|
+
@barcode.bar('humbaba').must_equal ['humbaba']
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should pass block to registered methods" do
|
118
|
+
@outputter.class_eval{ def foo(*a, &b); b.call(*a); end }
|
119
|
+
@barcode.foo(1,2,3){|*a| a }.must_equal [1,2,3]
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should be able to get an instance of a specific outputter" do
|
123
|
+
@barcode.outputter_for(:foo).must_be_instance_of(@outputter)
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should be able to get a specific outputter class" do
|
127
|
+
@barcode.outputter_class_for(:foo).must_equal @outputter
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
if defined? JRUBY_VERSION
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'barby/barcode/pdf_417'
|
5
|
+
|
6
|
+
class Pdf417Test < Barby::TestCase
|
7
|
+
|
8
|
+
it "should produce a nice code" do
|
9
|
+
enc = Pdf417.new('Ereshkigal').encoding
|
10
|
+
enc.must_equal [
|
11
|
+
"111111111101010100101111010110011110100111010110001110100011101101011100100001111111101000110100100",
|
12
|
+
"111111111101010100101111010110000100100110100101110000101011111110101001111001111111101000110100100",
|
13
|
+
"111111111101010100101101010111111000100100011100110011111010101100001111100001111111101000110100100",
|
14
|
+
"111111111101010100101111101101111110110100010100011101111011010111110111111001111111101000110100100",
|
15
|
+
"111111111101010100101101011110000010100110010101110010100011101101110001110001111111101000110100100",
|
16
|
+
"111111111101010100101111101101110000110101101100000011110011110110111110111001111111101000110100100",
|
17
|
+
"111111111101010100101101001111001111100110001101001100100010100111101110100001111111101000110100100",
|
18
|
+
"111111111101010100101111110110010111100111100100101000110010101111111001111001111111101000110100100",
|
19
|
+
"111111111101010100101010011101111100100101111110001110111011111101001110110001111111101000110100100",
|
20
|
+
"111111111101010100101010001111011100100100111110111110111010100101100011100001111111101000110100100",
|
21
|
+
"111111111101010100101101001111000010100110001101110000101011101100111001110001111111101000110100100",
|
22
|
+
"111111111101010100101101000110011111100101111111011101100011111110100011100101111111101000110100100",
|
23
|
+
"111111111101010100101010000101010000100100011100001100101010100100110000111001111111101000110100100",
|
24
|
+
"111111111101010100101111010100100001100100010100111100101011110110001001100001111111101000110100100",
|
25
|
+
"111111111101010100101111010100011110110110011111101001100010100100001001111101111111101000110100100"
|
26
|
+
]
|
27
|
+
enc.length.must_equal 15
|
28
|
+
enc[0].length.must_equal 99
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should produce a 19x135 code with default aspect_ratio" do
|
32
|
+
enc = Pdf417.new('qwertyuiopasdfghjklzxcvbnm'*3).encoding
|
33
|
+
enc.length.must_equal 19
|
34
|
+
enc[0].length.must_equal 135
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should produce a 29x117 code with 0.7 aspect_ratio" do
|
38
|
+
enc = Pdf417.new('qwertyuiopasdfghjklzxcvbnm'*3, :aspect_ratio => 0.7).encoding
|
39
|
+
enc.length.must_equal 29
|
40
|
+
enc[0].length.must_equal 117
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'barby/barcode/qr_code'
|
3
|
+
|
4
|
+
class QrCodeTest < Barby::TestCase
|
5
|
+
|
6
|
+
before do
|
7
|
+
@data = 'Ereshkigal'
|
8
|
+
@code = QrCode.new(@data)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should have the expected data" do
|
12
|
+
@code.data.must_equal @data
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should have the expected encoding" do
|
16
|
+
# Should be an array of strings, where each string represents a "line"
|
17
|
+
@code.encoding.must_equal(rqrcode(@code).modules.map do |line|
|
18
|
+
line.inject(''){|s,m| s << (m ? '1' : '0') }
|
19
|
+
end)
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should be able to change its data and output a different encoding" do
|
24
|
+
@code.data = 'hades'
|
25
|
+
@code.data.must_equal 'hades'
|
26
|
+
@code.encoding.must_equal(rqrcode(@code).modules.map do |line|
|
27
|
+
line.inject(''){|s,m| s << (m ? '1' : '0') }
|
28
|
+
end)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should have a 'level' accessor" do
|
32
|
+
@code.must_respond_to :level
|
33
|
+
@code.must_respond_to :level=
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should set size according to size of data" do
|
37
|
+
QrCode.new('1'*15, :level => :l).size.must_equal 1
|
38
|
+
QrCode.new('1'*15, :level => :m).size.must_equal 2
|
39
|
+
QrCode.new('1'*15, :level => :q).size.must_equal 2
|
40
|
+
QrCode.new('1'*15, :level => :h).size.must_equal 3
|
41
|
+
|
42
|
+
QrCode.new('1'*30, :level => :l).size.must_equal 2
|
43
|
+
QrCode.new('1'*30, :level => :m).size.must_equal 3
|
44
|
+
QrCode.new('1'*30, :level => :q).size.must_equal 3
|
45
|
+
QrCode.new('1'*30, :level => :h).size.must_equal 4
|
46
|
+
|
47
|
+
QrCode.new('1'*270, :level => :l).size.must_equal 10
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should allow size to be set manually" do
|
51
|
+
code = QrCode.new('1'*15, :level => :l, :size => 2)
|
52
|
+
code.size.must_equal 2
|
53
|
+
code.encoding.must_equal(rqrcode(code).modules.map do |line|
|
54
|
+
line.inject(''){|s,m| s << (m ? '1' : '0') }
|
55
|
+
end)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should raise ArgumentError when data too large" do
|
59
|
+
assert QrCode.new('1'*2953, :level => :l)
|
60
|
+
lambda{ QrCode.new('1'*2954, :level => :l) }.must_raise ArgumentError
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should return the original data on to_s" do
|
64
|
+
@code.to_s.must_equal 'Ereshkigal'
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should include at most 20 characters on to_s" do
|
68
|
+
QrCode.new('123456789012345678901234567890').to_s.must_equal '12345678901234567890'
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def rqrcode(code)
|
75
|
+
RQRCode::QRCode.new(code.data, :level => code.level, :size => code.size)
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'barby'
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require 'minitest/spec'
|
5
|
+
|
6
|
+
module Barby
|
7
|
+
class TestCase < MiniTest::Spec
|
8
|
+
|
9
|
+
include Barby
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
# So we can register outputter during an full test suite run.
|
14
|
+
def load_outputter(outputter)
|
15
|
+
@loaded_outputter ||= load "barby/outputter/#{outputter}_outputter.rb"
|
16
|
+
rescue LoadError => e
|
17
|
+
skip "#{outputter} not being installed properly"
|
18
|
+
end
|
19
|
+
|
20
|
+
def ruby_19_or_greater?
|
21
|
+
RUBY_VERSION >= '1.9'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'barby/barcode/upc_supplemental'
|
3
|
+
|
4
|
+
class UpcSupplementalTest < Barby::TestCase
|
5
|
+
|
6
|
+
it 'should be valid with 2 or 5 digits' do
|
7
|
+
assert UPCSupplemental.new('12345').valid?
|
8
|
+
assert UPCSupplemental.new('12').valid?
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should not be valid with any number of digits other than 2 or 5' do
|
12
|
+
refute UPCSupplemental.new('1234').valid?
|
13
|
+
refute UPCSupplemental.new('123').valid?
|
14
|
+
refute UPCSupplemental.new('1').valid?
|
15
|
+
refute UPCSupplemental.new('123456').valid?
|
16
|
+
refute UPCSupplemental.new('123456789012').valid?
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should not be valid with non-digit characters' do
|
20
|
+
refute UPCSupplemental.new('abcde').valid?
|
21
|
+
refute UPCSupplemental.new('ABC').valid?
|
22
|
+
refute UPCSupplemental.new('1234e').valid?
|
23
|
+
refute UPCSupplemental.new('!2345').valid?
|
24
|
+
refute UPCSupplemental.new('ab').valid?
|
25
|
+
refute UPCSupplemental.new('1b').valid?
|
26
|
+
refute UPCSupplemental.new('a1').valid?
|
27
|
+
end
|
28
|
+
|
29
|
+
describe 'checksum for 5 digits' do
|
30
|
+
|
31
|
+
it 'should have the expected odd_digits' do
|
32
|
+
UPCSupplemental.new('51234').odd_digits.must_equal [4,2,5]
|
33
|
+
UPCSupplemental.new('54321').odd_digits.must_equal [1,3,5]
|
34
|
+
UPCSupplemental.new('99990').odd_digits.must_equal [0,9,9]
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should have the expected even_digits' do
|
38
|
+
UPCSupplemental.new('51234').even_digits.must_equal [3,1]
|
39
|
+
UPCSupplemental.new('54321').even_digits.must_equal [2,4]
|
40
|
+
UPCSupplemental.new('99990').even_digits.must_equal [9,9]
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should have the expected odd and even sums' do
|
44
|
+
UPCSupplemental.new('51234').odd_sum.must_equal 33
|
45
|
+
UPCSupplemental.new('54321').odd_sum.must_equal 27
|
46
|
+
UPCSupplemental.new('99990').odd_sum.must_equal 54
|
47
|
+
|
48
|
+
UPCSupplemental.new('51234').even_sum.must_equal 36
|
49
|
+
UPCSupplemental.new('54321').even_sum.must_equal 54
|
50
|
+
UPCSupplemental.new('99990').even_sum.must_equal 162
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should have the expected checksum' do
|
54
|
+
UPCSupplemental.new('51234').checksum.must_equal 9
|
55
|
+
UPCSupplemental.new('54321').checksum.must_equal 1
|
56
|
+
UPCSupplemental.new('99990').checksum.must_equal 6
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
describe 'checksum for 2 digits' do
|
62
|
+
|
63
|
+
it 'should have the expected checksum' do
|
64
|
+
UPCSupplemental.new('51').checksum.must_equal 3
|
65
|
+
UPCSupplemental.new('21').checksum.must_equal 1
|
66
|
+
UPCSupplemental.new('99').checksum.must_equal 3
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
describe 'encoding' do
|
72
|
+
|
73
|
+
before do
|
74
|
+
@data = '51234'
|
75
|
+
@code = UPCSupplemental.new(@data)
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should have the expected encoding' do
|
79
|
+
# START 5 1 2 3 4
|
80
|
+
UPCSupplemental.new('51234').encoding.must_equal '1011 0110001 01 0011001 01 0011011 01 0111101 01 0011101'.tr(' ', '')
|
81
|
+
# 9 9 9 9 0
|
82
|
+
UPCSupplemental.new('99990').encoding.must_equal '1011 0001011 01 0001011 01 0001011 01 0010111 01 0100111'.tr(' ', '')
|
83
|
+
# START 5 1
|
84
|
+
UPCSupplemental.new('51').encoding.must_equal '1011 0111001 01 0110011'.tr(' ', '')
|
85
|
+
# 2 2
|
86
|
+
UPCSupplemental.new('22').encoding.must_equal '1011 0011011 01 0010011'.tr(' ', '')
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should be able to change its data' do
|
90
|
+
prev_encoding = @code.encoding
|
91
|
+
@code.data = '99990'
|
92
|
+
@code.encoding.wont_equal prev_encoding
|
93
|
+
# 9 9 9 9 0
|
94
|
+
@code.encoding.must_equal '1011 0001011 01 0001011 01 0001011 01 0010111 01 0100111'.tr(' ', '')
|
95
|
+
prev_encoding = @code.encoding
|
96
|
+
@code.data = '22'
|
97
|
+
@code.encoding.wont_equal prev_encoding
|
98
|
+
# 2 2
|
99
|
+
@code.encoding.must_equal '1011 0011011 01 0010011'.tr(' ', '')
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
|
108
|
+
|
109
|
+
|