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.
Files changed (41) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +2 -0
  3. data/CHANGELOG +8 -0
  4. data/Gemfile +5 -0
  5. data/README.md +21 -20
  6. data/Rakefile +15 -0
  7. data/barby.gemspec +31 -0
  8. data/lib/barby/barcode/codabar.rb +82 -0
  9. data/lib/barby/barcode.rb +3 -3
  10. data/lib/barby/outputter/cairo_outputter.rb +11 -3
  11. data/lib/barby/outputter/png_outputter.rb +43 -11
  12. data/lib/barby/outputter/prawn_outputter.rb +12 -9
  13. data/lib/barby/outputter/rmagick_outputter.rb +38 -11
  14. data/lib/barby/outputter/svg_outputter.rb +11 -18
  15. data/lib/barby/outputter.rb +1 -1
  16. data/lib/barby/version.rb +2 -2
  17. data/test/barcodes.rb +20 -0
  18. data/test/bookland_test.rb +54 -0
  19. data/test/codabar_test.rb +58 -0
  20. data/test/code_128_test.rb +470 -0
  21. data/test/code_25_iata_test.rb +19 -0
  22. data/test/code_25_interleaved_test.rb +116 -0
  23. data/test/code_25_test.rb +110 -0
  24. data/test/code_39_test.rb +210 -0
  25. data/test/code_93_test.rb +144 -0
  26. data/test/data_matrix_test.rb +30 -0
  27. data/test/ean13_test.rb +169 -0
  28. data/test/ean8_test.rb +100 -0
  29. data/test/outputter/cairo_outputter_test.rb +129 -0
  30. data/test/outputter/html_outputter_test.rb +68 -0
  31. data/test/outputter/pdfwriter_outputter_test.rb +37 -0
  32. data/test/outputter/png_outputter_test.rb +49 -0
  33. data/test/outputter/prawn_outputter_test.rb +79 -0
  34. data/test/outputter/rmagick_outputter_test.rb +83 -0
  35. data/test/outputter/svg_outputter_test.rb +89 -0
  36. data/test/outputter_test.rb +134 -0
  37. data/test/pdf_417_test.rb +45 -0
  38. data/test/qr_code_test.rb +78 -0
  39. data/test/test_helper.rb +24 -0
  40. data/test/upc_supplemental_test.rb +109 -0
  41. metadata +157 -7
@@ -0,0 +1,169 @@
1
+ require 'test_helper'
2
+ require 'barby/barcode/ean_13'
3
+
4
+ class EAN13Test < Barby::TestCase
5
+
6
+ describe 'validations' do
7
+
8
+ before do
9
+ @valid = EAN13.new('123456789012')
10
+ end
11
+
12
+ it "should be valid with 12 digits" do
13
+ assert @valid.valid?
14
+ end
15
+
16
+ it "should not be valid with non-digit characters" do
17
+ @valid.data = "The shit apple doesn't fall far from the shit tree"
18
+ refute @valid.valid?
19
+ end
20
+
21
+ it "should not be valid with less than 12 digits" do
22
+ @valid.data = "12345678901"
23
+ refute @valid.valid?
24
+ end
25
+
26
+ it "should not be valid with more than 12 digits" do
27
+ @valid.data = "1234567890123"
28
+ refute @valid.valid?
29
+ end
30
+
31
+ it "should raise an exception when data is invalid" do
32
+ lambda{ EAN13.new('123') }.must_raise(ArgumentError)
33
+ end
34
+
35
+ end
36
+
37
+ describe 'data' do
38
+
39
+ before do
40
+ @data = '007567816412'
41
+ @code = EAN13.new(@data)
42
+ end
43
+
44
+ it "should have the same data as was passed to it" do
45
+ @code.data.must_equal @data
46
+ end
47
+
48
+ it "should have the expected characters" do
49
+ @code.characters.must_equal @data.split(//)
50
+ end
51
+
52
+ it "should have the expected numbers" do
53
+ @code.numbers.must_equal @data.split(//).map{|s| s.to_i }
54
+ end
55
+
56
+ it "should have the expected odd_and_even_numbers" do
57
+ @code.odd_and_even_numbers.must_equal [[2,4,1,7,5,0], [1,6,8,6,7,0]]
58
+ end
59
+
60
+ it "should have the expected left_numbers" do
61
+ #0=second number in number system code
62
+ @code.left_numbers.must_equal [0,7,5,6,7,8]
63
+ end
64
+
65
+ it "should have the expected right_numbers" do
66
+ @code.right_numbers.must_equal [1,6,4,1,2,5]#5=checksum
67
+ end
68
+
69
+ it "should have the expected numbers_with_checksum" do
70
+ @code.numbers_with_checksum.must_equal @data.split(//).map{|s| s.to_i } + [5]
71
+ end
72
+
73
+ it "should have the expected data_with_checksum" do
74
+ @code.data_with_checksum.must_equal @data+'5'
75
+ end
76
+
77
+ it "should return all digits and the checksum on to_s" do
78
+ @code.to_s.must_equal '0075678164125'
79
+ end
80
+
81
+ end
82
+
83
+ describe 'checksum' do
84
+
85
+ before do
86
+ @code = EAN13.new('007567816412')
87
+ end
88
+
89
+ it "should have the expected weighted_sum" do
90
+ @code.weighted_sum.must_equal 85
91
+ @code.data = '007567816413'
92
+ @code.weighted_sum.must_equal 88
93
+ end
94
+
95
+ it "should have the correct checksum" do
96
+ @code.checksum.must_equal 5
97
+ @code.data = '007567816413'
98
+ @code.checksum.must_equal 2
99
+ end
100
+
101
+ it "should have the correct checksum_encoding" do
102
+ @code.checksum_encoding.must_equal '1001110'
103
+ end
104
+
105
+ end
106
+
107
+ describe 'encoding' do
108
+
109
+ before do
110
+ @code = EAN13.new('750103131130')
111
+ end
112
+
113
+ it "should have the expected checksum" do
114
+ @code.checksum.must_equal 9
115
+ end
116
+
117
+ it "should have the expected checksum_encoding" do
118
+ @code.checksum_encoding.must_equal '1110100'
119
+ end
120
+
121
+ it "should have the expected left_parity_map" do
122
+ @code.left_parity_map.must_equal [:odd, :even, :odd, :even, :odd, :even]
123
+ end
124
+
125
+ it "should have the expected left_encodings" do
126
+ @code.left_encodings.must_equal %w(0110001 0100111 0011001 0100111 0111101 0110011)
127
+ end
128
+
129
+ it "should have the expected right_encodings" do
130
+ @code.right_encodings.must_equal %w(1000010 1100110 1100110 1000010 1110010 1110100)
131
+ end
132
+
133
+ it "should have the expected left_encoding" do
134
+ @code.left_encoding.must_equal '011000101001110011001010011101111010110011'
135
+ end
136
+
137
+ it "should have the expected right_encoding" do
138
+ @code.right_encoding.must_equal '100001011001101100110100001011100101110100'
139
+ end
140
+
141
+ it "should have the expected encoding" do
142
+ #Start Left Center Right Stop
143
+ @code.encoding.must_equal '101' + '011000101001110011001010011101111010110011' + '01010' + '100001011001101100110100001011100101110100' + '101'
144
+ end
145
+
146
+ end
147
+
148
+ describe 'static data' do
149
+
150
+ before :each do
151
+ @code = EAN13.new('123456789012')
152
+ end
153
+
154
+ it "should have the expected start_encoding" do
155
+ @code.start_encoding.must_equal '101'
156
+ end
157
+
158
+ it "should have the expected stop_encoding" do
159
+ @code.stop_encoding.must_equal '101'
160
+ end
161
+
162
+ it "should have the expected center_encoding" do
163
+ @code.center_encoding.must_equal '01010'
164
+ end
165
+
166
+ end
167
+
168
+ end
169
+
data/test/ean8_test.rb ADDED
@@ -0,0 +1,100 @@
1
+ require 'test_helper'
2
+ require 'barby/barcode/ean_8'
3
+
4
+ class EAN8Test < Barby::TestCase
5
+
6
+ describe 'validations' do
7
+
8
+ before do
9
+ @valid = EAN8.new('1234567')
10
+ end
11
+
12
+ it "should be valid with 7 digits" do
13
+ assert @valid.valid?
14
+ end
15
+
16
+ it "should not be valid with less than 7 digits" do
17
+ @valid.data = '123456'
18
+ refute @valid.valid?
19
+ end
20
+
21
+ it "should not be valid with more than 7 digits" do
22
+ @valid.data = '12345678'
23
+ refute @valid.valid?
24
+ end
25
+
26
+ it "should not be valid with non-digits" do
27
+ @valid.data = 'abcdefg'
28
+ refute @valid.valid?
29
+ end
30
+
31
+ end
32
+
33
+ describe 'checksum' do
34
+
35
+ before :each do
36
+ @code = EAN8.new('5512345')
37
+ end
38
+
39
+ it "should have the expected weighted_sum" do
40
+ @code.weighted_sum.must_equal 53
41
+ end
42
+
43
+ it "should have the expected checksum" do
44
+ @code.checksum.must_equal 7
45
+ end
46
+
47
+ end
48
+
49
+ describe 'data' do
50
+
51
+ before :each do
52
+ @data = '5512345'
53
+ @code = EAN8.new(@data)
54
+ end
55
+
56
+ it "should have the expected data" do
57
+ @code.data.must_equal @data
58
+ end
59
+
60
+ it "should have the expected odd_and_even_numbers" do
61
+ @code.odd_and_even_numbers.must_equal [[5,3,1,5],[4,2,5]]
62
+ end
63
+
64
+ it "should have the expected left_numbers" do
65
+ #EAN-8 includes the first character in the left-hand encoding, unlike EAN-13
66
+ @code.left_numbers.must_equal [5,5,1,2]
67
+ end
68
+
69
+ it "should have the expected right_numbers" do
70
+ @code.right_numbers.must_equal [3,4,5,7]
71
+ end
72
+
73
+ it "should return the data with checksum on to_s" do
74
+ @code.to_s.must_equal '55123457'
75
+ end
76
+
77
+ end
78
+
79
+ describe 'encoding' do
80
+
81
+ before :each do
82
+ @code = EAN8.new('5512345')
83
+ end
84
+
85
+ it "should have the expected left_parity_map" do
86
+ @code.left_parity_map.must_equal [:odd, :odd, :odd, :odd]
87
+ end
88
+
89
+ it "should have the expected left_encoding" do
90
+ @code.left_encoding.must_equal '0110001011000100110010010011'
91
+ end
92
+
93
+ it "should have the expected right_encoding" do
94
+ @code.right_encoding.must_equal '1000010101110010011101000100'
95
+ end
96
+
97
+ end
98
+
99
+ end
100
+
@@ -0,0 +1,129 @@
1
+ require 'test_helper'
2
+
3
+ class CairoOutputterTest < Barby::TestCase
4
+
5
+ def ps_available?
6
+ Cairo.const_defined?(:PSSurface)
7
+ end
8
+
9
+ def eps_available?
10
+ ps_available? and Cairo::PSSurface.method_defined?(:eps=)
11
+ end
12
+
13
+ def pdf_available?
14
+ Cairo.const_defined?(:PDFSurface)
15
+ end
16
+
17
+ def svg_available?
18
+ Cairo.const_defined?(:SVGSurface)
19
+ end
20
+
21
+ before do
22
+ load_outputter('cairo')
23
+ @barcode = Barby::Barcode.new
24
+ def @barcode.encoding; '101100111000'; end
25
+ @outputter = Barby::CairoOutputter.new(@barcode)
26
+ @outputters = Barby::Barcode.outputters
27
+ @surface = Cairo::ImageSurface.new(100, 100)
28
+ @context = Cairo::Context.new(@surface)
29
+ end
30
+
31
+ it "should have defined the render_to_cairo_context method" do
32
+ @outputters.must_include(:render_to_cairo_context)
33
+ end
34
+
35
+ it "should have defined the to_png method" do
36
+ @outputters.must_include(:to_png)
37
+ end
38
+
39
+ it "should have defined the to_ps and to_eps method if available" do
40
+ if ps_available?
41
+ @outputters.must_include(:to_ps)
42
+ if eps_available?
43
+ @outputters.must_include(:to_eps)
44
+ else
45
+ @outputters.wont_include(:to_eps)
46
+ end
47
+ else
48
+ @outputters.wont_include(:to_ps)
49
+ @outputters.wont_include(:to_eps)
50
+ end
51
+ end
52
+
53
+ it "should have defined the to_pdf method if available" do
54
+ if pdf_available?
55
+ @outputters.must_include(:to_pdf)
56
+ else
57
+ @outputters.wont_include(:to_pdf)
58
+ end
59
+ end
60
+
61
+ it "should have defined the to_svg method if available" do
62
+ if svg_available?
63
+ @outputters.must_include(:to_svg)
64
+ else
65
+ @outputters.wont_include(:to_svg)
66
+ end
67
+ end
68
+
69
+ it "should return the cairo context object it was given in render_to_cairo_context" do
70
+ @barcode.render_to_cairo_context(@context).object_id.must_equal @context.object_id
71
+ end
72
+
73
+ it "should return PNG image by the to_png method" do
74
+ png = @barcode.to_png
75
+ data = ruby_19_or_greater? ? png.force_encoding('BINARY') : png
76
+ data.must_match(/\A\x89PNG/n)
77
+ end
78
+
79
+ it "should return PS document by the to_ps method" do
80
+ if ps_available?
81
+ @barcode.to_ps.must_match(/\A%!PS-Adobe-[\d.]/)
82
+ end
83
+ end
84
+
85
+ it "should return EPS document by the to_eps method" do
86
+ if eps_available?
87
+ @barcode.to_eps.must_match(/\A%!PS-Adobe-[\d.]+ EPSF-[\d.]+/)
88
+ end
89
+ end
90
+
91
+ it "should return PDF document by the to_pdf method" do
92
+ if pdf_available?
93
+ pdf = @barcode.to_pdf
94
+ data = ruby_19_or_greater? ? pdf.force_encoding('BINARY') : pdf
95
+ data.must_match(/\A%PDF-[\d.]+/n)
96
+ end
97
+ end
98
+
99
+ it "should return SVG document by the to_svg method" do
100
+ if svg_available?
101
+ @barcode.to_svg.must_match(/<\/svg>\s*\Z/m)
102
+ end
103
+ end
104
+
105
+ it "should have x, y, width, height, full_width, full_height, xdim and margin attributes" do
106
+ @outputter.must_respond_to(:x)
107
+ @outputter.must_respond_to(:y)
108
+ @outputter.must_respond_to(:width)
109
+ @outputter.must_respond_to(:height)
110
+ @outputter.must_respond_to(:full_width)
111
+ @outputter.must_respond_to(:full_height)
112
+ @outputter.must_respond_to(:xdim)
113
+ @outputter.must_respond_to(:margin)
114
+ end
115
+
116
+ it "should not change attributes when given an options hash to render" do
117
+ %w(x y height xdim).each do |m|
118
+ @outputter.send("#{m}=", 10)
119
+ @outputter.send(m).must_equal 10
120
+ end
121
+ @outputter.render_to_cairo_context(@context,
122
+ :x => 20,
123
+ :y => 20,
124
+ :height => 20,
125
+ :xdim => 20)
126
+ %w(x y height xdim).each{|m| @outputter.send(m).must_equal 10 }
127
+ end
128
+
129
+ end
@@ -0,0 +1,68 @@
1
+ require 'test_helper'
2
+ require 'barby/barcode/code_128'
3
+ #require 'barby/outputter/html_outputter'
4
+
5
+ class HtmlOutputterTest < Barby::TestCase
6
+
7
+ class MockCode
8
+ attr_reader :encoding
9
+ def initialize(e)
10
+ @encoding = e
11
+ end
12
+ def two_dimensional?
13
+ encoding.is_a? Array
14
+ end
15
+ end
16
+
17
+ before do
18
+ load_outputter('html')
19
+ @barcode = Barby::Code128B.new('BARBY')
20
+ @outputter = HtmlOutputter.new(@barcode)
21
+ end
22
+
23
+ it "should register to_html" do
24
+ Barcode.outputters.must_include(:to_html)
25
+ end
26
+
27
+ it 'should have the expected start HTML' do
28
+ assert_equal '<table class="barby-barcode"><tbody>', @outputter.start
29
+ end
30
+
31
+ it 'should be able to set additional class name' do
32
+ @outputter.class_name = 'humbaba'
33
+ assert_equal '<table class="barby-barcode humbaba"><tbody>', @outputter.start
34
+ end
35
+
36
+ it 'should have the expected stop HTML' do
37
+ assert_equal '</tbody></table>', @outputter.stop
38
+ end
39
+
40
+ it 'should build the expected cells' do
41
+ assert_equal ['<td class="barby-cell on"></td>', '<td class="barby-cell off"></td>', '<td class="barby-cell off"></td>', '<td class="barby-cell on"></td>'],
42
+ @outputter.cells_for([true, false, false, true])
43
+ end
44
+
45
+ it 'should build the expected rows' do
46
+ assert_equal(
47
+ [
48
+ "<tr class=\"barby-row\">#{@outputter.cells_for([true, false]).join}</tr>",
49
+ "<tr class=\"barby-row\">#{@outputter.cells_for([false, true]).join}</tr>",
50
+ ],
51
+ @outputter.rows_for([[true, false],[false, true]])
52
+ )
53
+ end
54
+
55
+ it 'should have the expected rows' do
56
+ barcode = MockCode.new('101100')
57
+ outputter = HtmlOutputter.new(barcode)
58
+ assert_equal outputter.rows_for([[true, false, true, true, false, false]]), outputter.rows
59
+ barcode = MockCode.new(['101', '010'])
60
+ outputter = HtmlOutputter.new(barcode)
61
+ assert_equal outputter.rows_for([[true, false, true], [false, true, false]]), outputter.rows
62
+ end
63
+
64
+ it 'should have the expected html' do
65
+ assert_equal @outputter.start + @outputter.rows.join + @outputter.stop, @outputter.to_html
66
+ end
67
+
68
+ end
@@ -0,0 +1,37 @@
1
+ unless RUBY_VERSION >= '1.9'
2
+
3
+ require 'test_helper'
4
+ require 'pdf/writer'
5
+
6
+ class PDFWriterOutputterTest < Barby::TestCase
7
+
8
+ before do
9
+ load_outputter('pdfwriter')
10
+ @barcode = Barcode.new
11
+ def @barcode.encoding; '101100111000'; end
12
+ @outputter = PDFWriterOutputter.new(@barcode)
13
+ @pdf = PDF::Writer.new
14
+ end
15
+
16
+ it "should have registered annotate_pdf" do
17
+ Barcode.outputters.must_include(:annotate_pdf)
18
+ end
19
+
20
+ it "should have defined the annotate_pdf method" do
21
+ @outputter.must_respond_to(:annotate_pdf)
22
+ end
23
+
24
+ it "should return the pdf object it was given in annotate_pdf" do
25
+ @barcode.annotate_pdf(@pdf).object_id.must_equal @pdf.object_id
26
+ end
27
+
28
+ it "should have x, y, height and xdim attributes" do
29
+ @outputter.must_respond_to(:x)
30
+ @outputter.must_respond_to(:y)
31
+ @outputter.must_respond_to(:height)
32
+ @outputter.must_respond_to(:xdim)
33
+ end
34
+
35
+ end
36
+
37
+ end
@@ -0,0 +1,49 @@
1
+ require 'test_helper'
2
+
3
+ class PngTestBarcode < Barby::Barcode
4
+ def initialize(data)
5
+ @data = data
6
+ end
7
+ def encoding
8
+ @data
9
+ end
10
+ end
11
+
12
+ class PngOutputterTest < Barby::TestCase
13
+
14
+ before do
15
+ load_outputter('png')
16
+ @barcode = PngTestBarcode.new('10110011100011110000')
17
+ @outputter = PngOutputter.new(@barcode)
18
+ end
19
+
20
+ it "should register to_png and to_image" do
21
+ Barcode.outputters.must_include(:to_png)
22
+ Barcode.outputters.must_include(:to_image)
23
+ end
24
+
25
+ it "should return a ChunkyPNG::Datastream on to_datastream" do
26
+ @barcode.to_datastream.must_be_instance_of(ChunkyPNG::Datastream)
27
+ end
28
+
29
+ it "should return a string on to_png" do
30
+ @barcode.to_png.must_be_instance_of(String)
31
+ end
32
+
33
+ it "should return a ChunkyPNG::Image on to_canvas" do
34
+ @barcode.to_image.must_be_instance_of(ChunkyPNG::Image)
35
+ end
36
+
37
+ it "should have a width equal to Xdim * barcode_string.length" do
38
+ @outputter.width.must_equal @outputter.barcode.encoding.length * @outputter.xdim
39
+ end
40
+
41
+ it "should have a full_width which is the sum of width + (margin*2)" do
42
+ @outputter.full_width.must_equal @outputter.width + (@outputter.margin*2)
43
+ end
44
+
45
+ it "should have a full_height which is the sum of height + (margin*2)" do
46
+ @outputter.full_height.must_equal @outputter.height + (@outputter.margin*2)
47
+ end
48
+
49
+ end
@@ -0,0 +1,79 @@
1
+ require 'test_helper'
2
+
3
+ class PrawnOutputterTest < Barby::TestCase
4
+
5
+ before do
6
+ load_outputter('prawn')
7
+ @barcode = Barcode.new
8
+ def @barcode.encoding; '10110011100011110000'; end
9
+ @outputter = PrawnOutputter.new(@barcode)
10
+ end
11
+
12
+ it "should register to_pdf and annotate_pdf" do
13
+ Barcode.outputters.must_include(:to_pdf)
14
+ Barcode.outputters.must_include(:annotate_pdf)
15
+ end
16
+
17
+ it "should have a to_pdf method" do
18
+ @outputter.must_respond_to(:to_pdf)
19
+ end
20
+
21
+ it "should return a PDF document in a string on to_pdf" do
22
+ @barcode.to_pdf.must_be_instance_of(String)
23
+ end
24
+
25
+ it "should return the same Prawn::Document on annotate_pdf" do
26
+ doc = Prawn::Document.new
27
+ @barcode.annotate_pdf(doc).object_id.must_equal doc.object_id
28
+ end
29
+
30
+ it "should default x and y to margin value" do
31
+ @outputter.margin = 123
32
+ @outputter.x.must_equal 123
33
+ @outputter.y.must_equal 123
34
+ end
35
+
36
+ it "should default ydim to xdim value" do
37
+ @outputter.xdim = 321
38
+ @outputter.ydim.must_equal 321
39
+ end
40
+
41
+ it "should be able to calculate width required" do
42
+ @outputter.width.must_equal @barcode.encoding.length
43
+ @outputter.xdim = 2
44
+ @outputter.width.must_equal @barcode.encoding.length * 2
45
+ @outputter.full_width.must_equal @barcode.encoding.length * 2
46
+ @outputter.margin = 5
47
+ @outputter.full_width.must_equal((@barcode.encoding.length * 2) + 10)
48
+
49
+ #2D
50
+ barcode = Barcode2D.new
51
+ def barcode.encoding; ['111', '000', '111'] end
52
+ outputter = PrawnOutputter.new(barcode)
53
+ outputter.width.must_equal 3
54
+ outputter.xdim = 2
55
+ outputter.margin = 5
56
+ outputter.width.must_equal 6
57
+ outputter.full_width.must_equal 16
58
+ end
59
+
60
+ it "should be able to calculate height required" do
61
+ @outputter.full_height.must_equal @outputter.height
62
+ @outputter.margin = 5
63
+ @outputter.full_height.must_equal @outputter.height + 10
64
+
65
+ #2D
66
+ barcode = Barcode2D.new
67
+ def barcode.encoding; ['111', '000', '111'] end
68
+ outputter = PrawnOutputter.new(barcode)
69
+ outputter.height.must_equal 3
70
+ outputter.xdim = 2 #ydim defaults to xdim
71
+ outputter.margin = 5
72
+ outputter.height.must_equal 6
73
+ outputter.full_height.must_equal 16
74
+ outputter.ydim = 3 #ydim overrides xdim when set
75
+ outputter.height.must_equal 9
76
+ outputter.full_height.must_equal 19
77
+ end
78
+
79
+ end