barby 0.6.2 → 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 (52) 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 +108 -0
  6. data/Rakefile +15 -0
  7. data/barby.gemspec +31 -0
  8. data/lib/barby/barcode.rb +3 -3
  9. data/lib/barby/barcode/bookland.rb +0 -1
  10. data/lib/barby/barcode/codabar.rb +82 -0
  11. data/lib/barby/barcode/code_128.rb +22 -20
  12. data/lib/barby/barcode/code_25.rb +6 -3
  13. data/lib/barby/barcode/code_25_interleaved.rb +2 -2
  14. data/lib/barby/barcode/code_39.rb +2 -1
  15. data/lib/barby/barcode/data_matrix.rb +1 -1
  16. data/lib/barby/barcode/ean_13.rb +1 -1
  17. data/lib/barby/barcode/gs1_128.rb +5 -1
  18. data/lib/barby/barcode/qr_code.rb +2 -1
  19. data/lib/barby/outputter.rb +1 -1
  20. data/lib/barby/outputter/cairo_outputter.rb +16 -3
  21. data/lib/barby/outputter/png_outputter.rb +43 -7
  22. data/lib/barby/outputter/prawn_outputter.rb +12 -4
  23. data/lib/barby/outputter/rmagick_outputter.rb +43 -11
  24. data/lib/barby/outputter/svg_outputter.rb +11 -13
  25. data/lib/barby/version.rb +2 -2
  26. data/test/barcodes.rb +20 -0
  27. data/test/bookland_test.rb +54 -0
  28. data/test/codabar_test.rb +58 -0
  29. data/test/code_128_test.rb +470 -0
  30. data/test/code_25_iata_test.rb +19 -0
  31. data/test/code_25_interleaved_test.rb +116 -0
  32. data/test/code_25_test.rb +110 -0
  33. data/test/code_39_test.rb +210 -0
  34. data/test/code_93_test.rb +144 -0
  35. data/test/data_matrix_test.rb +30 -0
  36. data/test/ean13_test.rb +169 -0
  37. data/test/ean8_test.rb +100 -0
  38. data/test/outputter/cairo_outputter_test.rb +129 -0
  39. data/test/outputter/html_outputter_test.rb +68 -0
  40. data/test/outputter/pdfwriter_outputter_test.rb +37 -0
  41. data/test/outputter/png_outputter_test.rb +49 -0
  42. data/test/outputter/prawn_outputter_test.rb +79 -0
  43. data/test/outputter/rmagick_outputter_test.rb +83 -0
  44. data/test/outputter/svg_outputter_test.rb +89 -0
  45. data/test/outputter_test.rb +134 -0
  46. data/test/pdf_417_test.rb +45 -0
  47. data/test/qr_code_test.rb +78 -0
  48. data/test/test_helper.rb +24 -0
  49. data/test/upc_supplemental_test.rb +109 -0
  50. metadata +160 -19
  51. data/README +0 -93
  52. data/lib/barby/outputter/point_matrix.rb +0 -211
@@ -0,0 +1,54 @@
1
+ require 'test_helper'
2
+ require 'barby/barcode/bookland'
3
+
4
+ class BooklandTest < Barby::TestCase
5
+
6
+ before do
7
+ # Gr Publ Tit Checksum
8
+ @isbn = '96-8261-240-3'
9
+ @code = Bookland.new(@isbn)
10
+ end
11
+
12
+ it "should have the expected data" do
13
+ @code.data.must_equal '978968261240'
14
+ end
15
+
16
+ it "should have the expected numbers" do
17
+ @code.numbers.must_equal [9,7,8,9,6,8,2,6,1,2,4,0]
18
+ end
19
+
20
+ it "should have the expected checksum" do
21
+ @code.checksum.must_equal 4
22
+ end
23
+
24
+ it "should raise an error when data not valid" do
25
+ lambda{ Bookland.new('1234') }.must_raise ArgumentError
26
+ end
27
+
28
+ describe 'ISBN conversion' do
29
+
30
+ it "should accept ISBN with number system and check digit" do
31
+ code = Bookland.new('978-82-92526-14-9')
32
+ assert code.valid?
33
+ code.data.must_equal '978829252614'
34
+ code = Bookland.new('979-82-92526-14-9')
35
+ assert code.valid?
36
+ code.data.must_equal '979829252614'
37
+ end
38
+
39
+ it "should accept ISBN without number system but with check digit" do
40
+ code = Bookland.new('82-92526-14-9')
41
+ assert code.valid?
42
+ code.data.must_equal '978829252614' #978 is the default prefix
43
+ end
44
+
45
+ it "should accept ISBN without number system or check digit" do
46
+ code = Bookland.new('82-92526-14')
47
+ assert code.valid?
48
+ code.data.must_equal '978829252614'
49
+ end
50
+
51
+ end
52
+
53
+ end
54
+
@@ -0,0 +1,58 @@
1
+ require 'test_helper'
2
+ require 'barby/barcode/codabar'
3
+
4
+ class CodabarTest < Barby::TestCase
5
+
6
+ describe 'validations' do
7
+
8
+ before do
9
+ @valid = Codabar.new('A12345D')
10
+ end
11
+
12
+ it "should be valid with alphabet rounded numbers" do
13
+ assert @valid.valid?
14
+ end
15
+
16
+ it "should not be valid with unsupported characters" do
17
+ @valid.data = "A12345E"
18
+ refute @valid.valid?
19
+ end
20
+
21
+ it "should raise an exception when data is invalid" do
22
+ lambda{ Codabar.new('A12345E') }.must_raise(ArgumentError)
23
+ end
24
+ end
25
+
26
+ describe 'data' do
27
+
28
+ before do
29
+ @data = 'A12345D'
30
+ @code = Codabar.new(@data)
31
+ end
32
+
33
+ it "should have the same data as was passed to it" do
34
+ @code.data.must_equal @data
35
+ end
36
+ end
37
+
38
+ describe 'encoding' do
39
+
40
+ before do
41
+ @code = Codabar.new('A01D')
42
+ @code.white_narrow_width = 1
43
+ @code.black_narrow_width = 1
44
+ @code.wide_width_rate = 2
45
+ @code.spacing = 2
46
+ end
47
+
48
+ it "should have the expected encoding" do
49
+ @code.encoding.must_equal [
50
+ "1011001001", # A
51
+ "101010011", # 0
52
+ "101011001", # 1
53
+ "1010011001", # D
54
+ ].join("00")
55
+ end
56
+ end
57
+ end
58
+
@@ -0,0 +1,470 @@
1
+ # encoding: UTF-8
2
+ require 'test_helper'
3
+ require 'barby/barcode/code_128'
4
+
5
+ class Code128Test < Barby::TestCase
6
+
7
+ %w[CODEA CODEB CODEC FNC1 FNC2 FNC3 FNC4 SHIFT].each do |const|
8
+ const_set const, Code128.const_get(const)
9
+ end
10
+
11
+ before do
12
+ @data = 'ABC123'
13
+ @code = Code128A.new(@data)
14
+ end
15
+
16
+ it "should have the expected stop encoding (including termination bar 11)" do
17
+ @code.send(:stop_encoding).must_equal '1100011101011'
18
+ end
19
+
20
+ it "should find the right class for a character A, B or C" do
21
+ @code.send(:class_for, 'A').must_equal Code128A
22
+ @code.send(:class_for, 'B').must_equal Code128B
23
+ @code.send(:class_for, 'C').must_equal Code128C
24
+ end
25
+
26
+ it "should find the right change code for a class" do
27
+ @code.send(:change_code_for_class, Code128A).must_equal Code128::CODEA
28
+ @code.send(:change_code_for_class, Code128B).must_equal Code128::CODEB
29
+ @code.send(:change_code_for_class, Code128C).must_equal Code128::CODEC
30
+ end
31
+
32
+ it "should not allow empty data" do
33
+ lambda{ Code128B.new("") }.must_raise(ArgumentError)
34
+ end
35
+
36
+ describe "single encoding" do
37
+
38
+ before do
39
+ @data = 'ABC123'
40
+ @code = Code128A.new(@data)
41
+ end
42
+
43
+ it "should have the same data as when initialized" do
44
+ @code.data.must_equal @data
45
+ end
46
+
47
+ it "should be able to change its data" do
48
+ @code.data = '123ABC'
49
+ @code.data.must_equal '123ABC'
50
+ @code.data.wont_equal @data
51
+ end
52
+
53
+ it "should not have an extra" do
54
+ assert @code.extra.nil?
55
+ end
56
+
57
+ it "should have empty extra encoding" do
58
+ @code.extra_encoding.must_equal ''
59
+ end
60
+
61
+ it "should have the correct checksum" do
62
+ @code.checksum.must_equal 66
63
+ end
64
+
65
+ it "should return all data for to_s" do
66
+ @code.to_s.must_equal @data
67
+ end
68
+
69
+ end
70
+
71
+ describe "multiple encodings" do
72
+
73
+ before do
74
+ @data = binary_encode("ABC123\306def\3074567")
75
+ @code = Code128A.new(@data)
76
+ end
77
+
78
+ it "should be able to return full_data which includes the entire extra chain excluding charset change characters" do
79
+ @code.full_data.must_equal "ABC123def4567"
80
+ end
81
+
82
+ it "should be able to return full_data_with_change_codes which includes the entire extra chain including charset change characters" do
83
+ @code.full_data_with_change_codes.must_equal @data
84
+ end
85
+
86
+ it "should not matter if extras were added separately" do
87
+ code = Code128B.new("ABC")
88
+ code.extra = binary_encode("\3071234")
89
+ code.full_data.must_equal "ABC1234"
90
+ code.full_data_with_change_codes.must_equal binary_encode("ABC\3071234")
91
+ code.extra.extra = binary_encode("\306abc")
92
+ code.full_data.must_equal "ABC1234abc"
93
+ code.full_data_with_change_codes.must_equal binary_encode("ABC\3071234\306abc")
94
+ code.extra.extra.data = binary_encode("abc\305DEF")
95
+ code.full_data.must_equal "ABC1234abcDEF"
96
+ code.full_data_with_change_codes.must_equal binary_encode("ABC\3071234\306abc\305DEF")
97
+ code.extra.extra.full_data.must_equal "abcDEF"
98
+ code.extra.extra.full_data_with_change_codes.must_equal binary_encode("abc\305DEF")
99
+ code.extra.full_data.must_equal "1234abcDEF"
100
+ code.extra.full_data_with_change_codes.must_equal binary_encode("1234\306abc\305DEF")
101
+ end
102
+
103
+ it "should have a Code B extra" do
104
+ @code.extra.must_be_instance_of(Code128B)
105
+ end
106
+
107
+ it "should have a valid extra" do
108
+ assert @code.extra.valid?
109
+ end
110
+
111
+ it "the extra should also have an extra of type C" do
112
+ @code.extra.extra.must_be_instance_of(Code128C)
113
+ end
114
+
115
+ it "the extra's extra should be valid" do
116
+ assert @code.extra.extra.valid?
117
+ end
118
+
119
+ it "should not have more than two extras" do
120
+ assert @code.extra.extra.extra.nil?
121
+ end
122
+
123
+ it "should split extra data from string on data assignment" do
124
+ @code.data = binary_encode("123\306abc")
125
+ @code.data.must_equal '123'
126
+ @code.extra.must_be_instance_of(Code128B)
127
+ @code.extra.data.must_equal 'abc'
128
+ end
129
+
130
+ it "should be be able to change its extra" do
131
+ @code.extra = binary_encode("\3071234")
132
+ @code.extra.must_be_instance_of(Code128C)
133
+ @code.extra.data.must_equal '1234'
134
+ end
135
+
136
+ it "should split extra data from string on extra assignment" do
137
+ @code.extra = binary_encode("\306123\3074567")
138
+ @code.extra.must_be_instance_of(Code128B)
139
+ @code.extra.data.must_equal '123'
140
+ @code.extra.extra.must_be_instance_of(Code128C)
141
+ @code.extra.extra.data.must_equal '4567'
142
+ end
143
+
144
+ it "should not fail on newlines in extras" do
145
+ code = Code128B.new(binary_encode("ABC\305\n"))
146
+ code.data.must_equal "ABC"
147
+ code.extra.must_be_instance_of(Code128A)
148
+ code.extra.data.must_equal "\n"
149
+ code.extra.extra = binary_encode("\305\n\n\n\n\n\nVALID")
150
+ code.extra.extra.data.must_equal "\n\n\n\n\n\nVALID"
151
+ end
152
+
153
+ it "should raise an exception when extra string doesn't start with the special code character" do
154
+ lambda{ @code.extra = '123' }.must_raise ArgumentError
155
+ end
156
+
157
+ it "should have the correct checksum" do
158
+ @code.checksum.must_equal 84
159
+ end
160
+
161
+ it "should have the expected encoding" do
162
+ #STARTA A B C 1 2 3
163
+ @code.encoding.must_equal '11010000100101000110001000101100010001000110100111001101100111001011001011100'+
164
+ #CODEB d e f
165
+ '10111101110100001001101011001000010110000100'+
166
+ #CODEC 45 67
167
+ '101110111101011101100010000101100'+
168
+ #CHECK=84 STOP
169
+ '100111101001100011101011'
170
+ end
171
+
172
+ it "should return all data including extras, except change codes for to_s" do
173
+ @code.to_s.must_equal "ABC123def4567"
174
+ end
175
+
176
+ end
177
+
178
+ describe "128A" do
179
+
180
+ before do
181
+ @data = 'ABC123'
182
+ @code = Code128A.new(@data)
183
+ end
184
+
185
+ it "should be valid when given valid data" do
186
+ assert @code.valid?
187
+ end
188
+
189
+ it "should not be valid when given invalid data" do
190
+ @code.data = 'abc123'
191
+ refute @code.valid?
192
+ end
193
+
194
+ it "should have the expected characters" do
195
+ @code.characters.must_equal %w(A B C 1 2 3)
196
+ end
197
+
198
+ it "should have the expected start encoding" do
199
+ @code.start_encoding.must_equal '11010000100'
200
+ end
201
+
202
+ it "should have the expected data encoding" do
203
+ @code.data_encoding.must_equal '101000110001000101100010001000110100111001101100111001011001011100'
204
+ end
205
+
206
+ it "should have the expected encoding" do
207
+ @code.encoding.must_equal '11010000100101000110001000101100010001000110100111001101100111001011001011100100100001101100011101011'
208
+ end
209
+
210
+ it "should have the expected checksum encoding" do
211
+ @code.checksum_encoding.must_equal '10010000110'
212
+ end
213
+
214
+ end
215
+
216
+ describe "128B" do
217
+
218
+ before do
219
+ @data = 'abc123'
220
+ @code = Code128B.new(@data)
221
+ end
222
+
223
+ it "should be valid when given valid data" do
224
+ assert @code.valid?
225
+ end
226
+
227
+ it "should not be valid when given invalid data" do
228
+ @code.data = binary_encode("abc£123")
229
+ refute @code.valid?
230
+ end
231
+
232
+ it "should have the expected characters" do
233
+ @code.characters.must_equal %w(a b c 1 2 3)
234
+ end
235
+
236
+ it "should have the expected start encoding" do
237
+ @code.start_encoding.must_equal '11010010000'
238
+ end
239
+
240
+ it "should have the expected data encoding" do
241
+ @code.data_encoding.must_equal '100101100001001000011010000101100100111001101100111001011001011100'
242
+ end
243
+
244
+ it "should have the expected encoding" do
245
+ @code.encoding.must_equal '11010010000100101100001001000011010000101100100111001101100111001011001011100110111011101100011101011'
246
+ end
247
+
248
+ it "should have the expected checksum encoding" do
249
+ @code.checksum_encoding.must_equal '11011101110'
250
+ end
251
+
252
+ end
253
+
254
+ describe "128C" do
255
+
256
+ before do
257
+ @data = '123456'
258
+ @code = Code128C.new(@data)
259
+ end
260
+
261
+ it "should be valid when given valid data" do
262
+ assert @code.valid?
263
+ end
264
+
265
+ it "should not be valid when given invalid data" do
266
+ @code.data = '123'
267
+ refute @code.valid?
268
+ @code.data = 'abc'
269
+ refute @code.valid?
270
+ end
271
+
272
+ it "should have the expected characters" do
273
+ @code.characters.must_equal %w(12 34 56)
274
+ end
275
+
276
+ it "should have the expected start encoding" do
277
+ @code.start_encoding.must_equal '11010011100'
278
+ end
279
+
280
+ it "should have the expected data encoding" do
281
+ @code.data_encoding.must_equal '101100111001000101100011100010110'
282
+ end
283
+
284
+ it "should have the expected encoding" do
285
+ @code.encoding.must_equal '11010011100101100111001000101100011100010110100011011101100011101011'
286
+ end
287
+
288
+ it "should have the expected checksum encoding" do
289
+ @code.checksum_encoding.must_equal '10001101110'
290
+ end
291
+
292
+ end
293
+
294
+ describe "Function characters" do
295
+
296
+ it "should retain the special symbols in the data accessor" do
297
+ Code128A.new(binary_encode("\301ABC\301DEF")).data.must_equal binary_encode("\301ABC\301DEF")
298
+ Code128B.new(binary_encode("\301ABC\302DEF")).data.must_equal binary_encode("\301ABC\302DEF")
299
+ Code128C.new(binary_encode("\301123456")).data.must_equal binary_encode("\301123456")
300
+ Code128C.new(binary_encode("12\30134\30156")).data.must_equal binary_encode("12\30134\30156")
301
+ end
302
+
303
+ it "should keep the special symbols as characters" do
304
+ Code128A.new(binary_encode("\301ABC\301DEF")).characters.must_equal binary_encode_array(%W(\301 A B C \301 D E F))
305
+ Code128B.new(binary_encode("\301ABC\302DEF")).characters.must_equal binary_encode_array(%W(\301 A B C \302 D E F))
306
+ Code128C.new(binary_encode("\301123456")).characters.must_equal binary_encode_array(%W(\301 12 34 56))
307
+ Code128C.new(binary_encode("12\30134\30156")).characters.must_equal binary_encode_array(%W(12 \301 34 \301 56))
308
+ end
309
+
310
+ it "should not allow FNC > 1 for Code C" do
311
+ lambda{ Code128C.new("12\302") }.must_raise ArgumentError
312
+ lambda{ Code128C.new("\30312") }.must_raise ArgumentError
313
+ lambda{ Code128C.new("12\304") }.must_raise ArgumentError
314
+ end
315
+
316
+ it "should be included in the encoding" do
317
+ a = Code128A.new(binary_encode("\301AB"))
318
+ a.data_encoding.must_equal '111101011101010001100010001011000'
319
+ a.encoding.must_equal '11010000100111101011101010001100010001011000101000011001100011101011'
320
+ end
321
+
322
+ end
323
+
324
+ describe "Code128 with type" do
325
+
326
+ #it "should raise an exception when not given a type" do
327
+ # lambda{ Code128.new('abc') }.must_raise(ArgumentError)
328
+ #end
329
+
330
+ it "should raise an exception when given a non-existent type" do
331
+ lambda{ Code128.new('abc', 'F') }.must_raise(ArgumentError)
332
+ end
333
+
334
+ it "should not fail on frozen type" do
335
+ Code128.new('123456', 'C'.freeze) # not failing
336
+ Code128.new('123456', 'c'.freeze) # not failing even when upcasing
337
+ end
338
+
339
+ it "should give the right encoding for type A" do
340
+ code = Code128.new('ABC123', 'A')
341
+ code.encoding.must_equal '11010000100101000110001000101100010001000110100111001101100111001011001011100100100001101100011101011'
342
+ end
343
+
344
+ it "should give the right encoding for type B" do
345
+ code = Code128.new('abc123', 'B')
346
+ code.encoding.must_equal '11010010000100101100001001000011010000101100100111001101100111001011001011100110111011101100011101011'
347
+ end
348
+
349
+ it "should give the right encoding for type B" do
350
+ code = Code128.new('123456', 'C')
351
+ code.encoding.must_equal '11010011100101100111001000101100011100010110100011011101100011101011'
352
+ end
353
+
354
+ end
355
+
356
+
357
+
358
+ describe "Code128 automatic charset" do
359
+ =begin
360
+ 5.4.7.7. Use of Start, Code Set, and Shift Characters to Minimize Symbol Length (Informative)
361
+
362
+ The same data may be represented by different GS1-128 barcodes through the use of different combinations of Start, code set, and shift characters.
363
+
364
+ The following rules should normally be implemented in printer control software to minimise the number of symbol characters needed to represent a given data string (and, therefore, reduce the overall symbol length).
365
+
366
+ * Determine the Start Character:
367
+ - If the data consists of two digits, use Start Character C.
368
+ - If the data begins with four or more numeric data characters, use Start Character C.
369
+ - If an ASCII symbology element (e.g., NUL) occurs in the data before any lowercase character, use Start Character A.
370
+ - Otherwise, use Start Character B.
371
+ * If Start Character C is used and the data begins with an odd number of numeric data characters, insert a code set A or code set B character before the last digit, following rules 1c and 1d to determine between code sets A and B.
372
+ * If four or more numeric data characters occur together when in code sets A or B and:
373
+ - If there is an even number of numeric data characters, then insert a code set C character before the first numeric digit to change to code set C.
374
+ - If there is an odd number of numeric data characters, then insert a code set C character immediately after the first numeric digit to change to code set C.
375
+ * When in code set B and an ASCII symbology element occurs in the data:
376
+ - If following that character, a lowercase character occurs in the data before the occurrence of another symbology element, then insert a shift character before the symbology element.
377
+ - Otherwise, insert a code set A character before the symbology element to change to code set A.
378
+ * When in code set A and a lowercase character occurs in the data:
379
+ - If following that character, a symbology element occurs in the data before the occurrence of another lowercase character, then insert a shift character before the lowercase character.
380
+ - Otherwise, insert a code set B character before the lowercase character to change to code set B.
381
+ When in code set C and a non-numeric character occurs in the data, insert a code set A or code set B character before that character, and follow rules 1c and 1d to determine between code sets A and B.
382
+
383
+ Note: In these rules, the term “lowercase” is used for convenience to mean any code set B character with Code 128 Symbol character values 64 to 95 (ASCII values 96 to 127) (e.g., all lowercase alphanumeric characters plus `{|}~DEL). The term “symbology element” means any code set A character with Code 128 Symbol character values 64 to 95 (ASCII values 00 to 31).
384
+ Note 2: If the Function 1 Symbol Character (FNC1) occurs in the first position following the Start Character, or in an odd-numbered position in a numeric field, it should be treated as two digits for the purpose of determining the appropriate code set.
385
+ =end
386
+ it "should minimize symbol length according to GS1-128 guidelines" do
387
+ # Determine the Start Character.
388
+ Code128.apply_shortest_encoding_for_data("#{FNC1}10").must_equal "#{CODEC}#{FNC1}10"
389
+ Code128.apply_shortest_encoding_for_data("#{FNC1}101234").must_equal "#{CODEC}#{FNC1}101234"
390
+ Code128.apply_shortest_encoding_for_data("10\001LOT").must_equal "#{CODEA}10\001LOT"
391
+ Code128.apply_shortest_encoding_for_data("lot1").must_equal "#{CODEB}lot1"
392
+
393
+ # Switching to codeset B from codeset C
394
+ Code128.apply_shortest_encoding_for_data("#{FNC1}101").must_equal "#{CODEC}#{FNC1}10#{CODEB}1"
395
+ # Switching to codeset A from codeset C
396
+ Code128.apply_shortest_encoding_for_data("#{FNC1}10\001a").must_equal "#{CODEC}#{FNC1}10#{CODEA}\001#{CODEB}a"
397
+
398
+ # Switching to codeset C from codeset A
399
+ Code128.apply_shortest_encoding_for_data("#{FNC1}10\001LOT1234").must_equal "#{CODEC}#{FNC1}10#{CODEA}\001LOT#{CODEC}1234"
400
+ Code128.apply_shortest_encoding_for_data("#{FNC1}10\001LOT12345").must_equal "#{CODEC}#{FNC1}10#{CODEA}\001LOT1#{CODEC}2345"
401
+
402
+ # Switching to codeset C from codeset B
403
+ Code128.apply_shortest_encoding_for_data("#{FNC1}10LOT1234").must_equal "#{CODEC}#{FNC1}10#{CODEB}LOT#{CODEC}1234"
404
+ Code128.apply_shortest_encoding_for_data("#{FNC1}10LOT12345").must_equal "#{CODEC}#{FNC1}10#{CODEB}LOT1#{CODEC}2345"
405
+
406
+ # Switching to codeset A from codeset B
407
+ Code128.apply_shortest_encoding_for_data("#{FNC1}10lot\001a").must_equal "#{CODEC}#{FNC1}10#{CODEB}lot#{SHIFT}\001a"
408
+ Code128.apply_shortest_encoding_for_data("#{FNC1}10lot\001\001").must_equal "#{CODEC}#{FNC1}10#{CODEB}lot#{CODEA}\001\001"
409
+
410
+ # Switching to codeset B from codeset A
411
+ Code128.apply_shortest_encoding_for_data("#{FNC1}10\001l\001").must_equal "#{CODEC}#{FNC1}10#{CODEA}\001#{SHIFT}l\001"
412
+ Code128.apply_shortest_encoding_for_data("#{FNC1}10\001ll").must_equal "#{CODEC}#{FNC1}10#{CODEA}\001#{CODEB}ll"
413
+
414
+ # testing "Note 2" from the GS1 specification
415
+ Code128.apply_shortest_encoding_for_data("#{FNC1}10LOT#{FNC1}0101").must_equal "#{CODEC}#{FNC1}10#{CODEB}LOT#{CODEC}#{FNC1}0101"
416
+ Code128.apply_shortest_encoding_for_data("#{FNC1}10LOT#{FNC1}01010").must_equal "#{CODEC}#{FNC1}10#{CODEB}LOT#{FNC1}0#{CODEC}1010"
417
+ Code128.apply_shortest_encoding_for_data("#{FNC1}10LOT01#{FNC1}0101").must_equal "#{CODEC}#{FNC1}10#{CODEB}LOT#{CODEC}01#{FNC1}0101"
418
+ end
419
+
420
+ it "should know how to extract CODEC segments properly from a data string" do
421
+ Code128.send(:extract_codec, "1234abcd5678\r\n\r\n").must_equal ["1234", "abcd", "5678", "\r\n\r\n"]
422
+ Code128.send(:extract_codec, "12345abc6").must_equal ["1234", "5abc6"]
423
+ Code128.send(:extract_codec, "abcdef").must_equal ["abcdef"]
424
+ Code128.send(:extract_codec, "123abcdef45678").must_equal ["123abcdef4", "5678"]
425
+ Code128.send(:extract_codec, "abcd12345").must_equal ["abcd1", "2345"]
426
+ Code128.send(:extract_codec, "abcd12345efg").must_equal ["abcd1", "2345", "efg"]
427
+ Code128.send(:extract_codec, "12345").must_equal ["1234", "5"]
428
+ Code128.send(:extract_codec, "12345abc").must_equal ["1234", "5abc"]
429
+ Code128.send(:extract_codec, "abcdef1234567").must_equal ["abcdef1", "234567"]
430
+ end
431
+
432
+ it "should know how to most efficiently apply different encodings to a data string" do
433
+ Code128.apply_shortest_encoding_for_data("123456").must_equal "#{CODEC}123456"
434
+ Code128.apply_shortest_encoding_for_data("abcdef").must_equal "#{CODEB}abcdef"
435
+ Code128.apply_shortest_encoding_for_data("ABCDEF").must_equal "#{CODEB}ABCDEF"
436
+ Code128.apply_shortest_encoding_for_data("\n\t\r").must_equal "#{CODEA}\n\t\r"
437
+ Code128.apply_shortest_encoding_for_data("123456abcdef").must_equal "#{CODEC}123456#{CODEB}abcdef"
438
+ Code128.apply_shortest_encoding_for_data("abcdef123456").must_equal "#{CODEB}abcdef#{CODEC}123456"
439
+ Code128.apply_shortest_encoding_for_data("1234567").must_equal "#{CODEC}123456#{CODEB}7"
440
+ Code128.apply_shortest_encoding_for_data("123b456").must_equal "#{CODEB}123b456"
441
+ Code128.apply_shortest_encoding_for_data("abc123def45678gh").must_equal "#{CODEB}abc123def4#{CODEC}5678#{CODEB}gh"
442
+ Code128.apply_shortest_encoding_for_data("12345AB\nEEasdgr12EE\r\n").must_equal "#{CODEC}1234#{CODEA}5AB\nEE#{CODEB}asdgr12EE#{CODEA}\r\n"
443
+ Code128.apply_shortest_encoding_for_data("123456QWERTY\r\n\tAAbbcc12XX34567").must_equal "#{CODEC}123456#{CODEA}QWERTY\r\n\tAA#{CODEB}bbcc12XX3#{CODEC}4567"
444
+
445
+ Code128.apply_shortest_encoding_for_data("ABCdef\rGHIjkl").must_equal "#{CODEB}ABCdef#{SHIFT}\rGHIjkl"
446
+ Code128.apply_shortest_encoding_for_data("ABC\rb\nDEF12gHI3456").must_equal "#{CODEA}ABC\r#{SHIFT}b\nDEF12#{CODEB}gHI#{CODEC}3456"
447
+ Code128.apply_shortest_encoding_for_data("ABCdef\rGHIjkl\tMNop\nqRs").must_equal "#{CODEB}ABCdef#{SHIFT}\rGHIjkl#{SHIFT}\tMNop#{SHIFT}\nqRs"
448
+ end
449
+
450
+ it "should apply automatic charset when no charset is given" do
451
+ b = Code128.new("123456QWERTY\r\n\tAAbbcc12XX34567")
452
+ b.type.must_equal 'C'
453
+ b.full_data_with_change_codes.must_equal "123456#{CODEA}QWERTY\r\n\tAA#{CODEB}bbcc12XX3#{CODEC}4567"
454
+ end
455
+
456
+ end
457
+
458
+
459
+
460
+ private
461
+
462
+ def binary_encode_array(datas)
463
+ datas.each { |data| binary_encode(data) }
464
+ end
465
+
466
+ def binary_encode(data)
467
+ ruby_19_or_greater? ? data.force_encoding('BINARY') : data
468
+ end
469
+
470
+ end