usps_intelligent_barcode 0.3.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.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/.travis.yml +8 -0
  3. data/CHANGELOG.markdown +67 -0
  4. data/Gemfile +13 -0
  5. data/Gemfile.lock +90 -0
  6. data/LICENSE.md +11 -0
  7. data/README.markdown +64 -0
  8. data/Rakefile +40 -0
  9. data/VERSION +1 -0
  10. data/examples/example.rb +17 -0
  11. data/lib/USPS-intelligent-barcode.rb +17 -0
  12. data/lib/USPS-intelligent-barcode/bar_map.rb +52 -0
  13. data/lib/USPS-intelligent-barcode/bar_position.rb +40 -0
  14. data/lib/USPS-intelligent-barcode/bar_symbol.rb +49 -0
  15. data/lib/USPS-intelligent-barcode/bar_to_character_mapping.yml +66 -0
  16. data/lib/USPS-intelligent-barcode/barcode.rb +152 -0
  17. data/lib/USPS-intelligent-barcode/barcode_id.rb +98 -0
  18. data/lib/USPS-intelligent-barcode/character_position.rb +28 -0
  19. data/lib/USPS-intelligent-barcode/codeword_map.rb +38 -0
  20. data/lib/USPS-intelligent-barcode/codeword_to_character_mapping.yml +1366 -0
  21. data/lib/USPS-intelligent-barcode/crc.rb +52 -0
  22. data/lib/USPS-intelligent-barcode/mailer_id.rb +105 -0
  23. data/lib/USPS-intelligent-barcode/numeric_conversions.rb +22 -0
  24. data/lib/USPS-intelligent-barcode/routing_code.rb +134 -0
  25. data/lib/USPS-intelligent-barcode/serial_number.rb +88 -0
  26. data/lib/USPS-intelligent-barcode/service_type.rb +79 -0
  27. data/lib/usps_intelligent_barcode.rb +17 -0
  28. data/lib/usps_intelligent_barcode/bar_map.rb +52 -0
  29. data/lib/usps_intelligent_barcode/bar_position.rb +40 -0
  30. data/lib/usps_intelligent_barcode/bar_symbol.rb +49 -0
  31. data/lib/usps_intelligent_barcode/bar_to_character_mapping.yml +66 -0
  32. data/lib/usps_intelligent_barcode/barcode.rb +152 -0
  33. data/lib/usps_intelligent_barcode/barcode_id.rb +98 -0
  34. data/lib/usps_intelligent_barcode/character_position.rb +28 -0
  35. data/lib/usps_intelligent_barcode/codeword_map.rb +38 -0
  36. data/lib/usps_intelligent_barcode/codeword_to_character_mapping.yml +1366 -0
  37. data/lib/usps_intelligent_barcode/crc.rb +52 -0
  38. data/lib/usps_intelligent_barcode/mailer_id.rb +105 -0
  39. data/lib/usps_intelligent_barcode/numeric_conversions.rb +22 -0
  40. data/lib/usps_intelligent_barcode/routing_code.rb +134 -0
  41. data/lib/usps_intelligent_barcode/serial_number.rb +88 -0
  42. data/lib/usps_intelligent_barcode/service_type.rb +79 -0
  43. data/spec/bar_map_spec.rb +30 -0
  44. data/spec/bar_position_spec.rb +40 -0
  45. data/spec/bar_symbol_spec.rb +39 -0
  46. data/spec/barcode_id_spec.rb +106 -0
  47. data/spec/barcode_spec.rb +213 -0
  48. data/spec/character_position_spec.rb +25 -0
  49. data/spec/codeword_map_spec.rb +22 -0
  50. data/spec/crc_spec.rb +21 -0
  51. data/spec/mailer_id_spec.rb +124 -0
  52. data/spec/numeric_conversions_spec.rb +23 -0
  53. data/spec/routing_code_spec.rb +180 -0
  54. data/spec/serial_number_spec.rb +117 -0
  55. data/spec/service_type_spec.rb +93 -0
  56. data/spec/spec_helper.rb +8 -0
  57. data/usps_intelligent_barcode.gemspec +117 -0
  58. metadata +216 -0
@@ -0,0 +1,30 @@
1
+ require File.expand_path('spec_helper', File.dirname(__FILE__))
2
+
3
+ module Imb
4
+
5
+ describe BarMap do
6
+
7
+ let(:characters) do
8
+ [
9
+ 0x1FE0, 0x001F, 0x001F, 0x001F, 0x0ADB,
10
+ 0x01A3, 0x1BC3, 0x1838, 0x012B, 0x0076,
11
+ ]
12
+ end
13
+ let(:codes) do
14
+ [
15
+ 2, 0, 0, 3, 2, 0, 0, 1, 0, 0, 2, 1, 0,
16
+ 2, 2, 0, 0, 1, 0, 1, 0, 2, 0, 0, 1, 2,
17
+ 3, 1, 1, 3, 2, 1, 3, 1, 3, 0, 3, 3, 3,
18
+ 3, 3, 0, 2, 0, 3, 2, 2, 2, 2, 0, 1, 3,
19
+ 3, 0, 1, 2, 2, 1, 3, 0, 3, 1, 0, 1, 0,
20
+ ]
21
+ end
22
+ let(:bar_map) {BarMap.new}
23
+
24
+ specify do
25
+ expect(bar_map.symbols(characters).map(&:code)).to eq(codes)
26
+ end
27
+
28
+ end
29
+
30
+ end
@@ -0,0 +1,40 @@
1
+ require File.expand_path('spec_helper', File.dirname(__FILE__))
2
+
3
+ module Imb
4
+
5
+ describe BarPosition do
6
+
7
+ describe '#map' do
8
+
9
+ let(:ascender_bit) {double 'ascender bit'}
10
+ let(:descender_bit) {double 'descender bit'}
11
+ let(:characters) {double 'array of characters'}
12
+ let(:descender_character_position) {double CharacterPosition}
13
+ let(:ascender_character_position) {double CharacterPosition}
14
+ let(:bar_position) do
15
+ BarPosition.new(descender_character_position,
16
+ ascender_character_position)
17
+ end
18
+ let(:bar_symbol) {double BarSymbol}
19
+
20
+ before(:each) do
21
+ allow(descender_character_position).to receive(:extract_bit_from_characters)\
22
+ .with(characters)\
23
+ .and_return(descender_bit)
24
+ allow(ascender_character_position).to receive(:extract_bit_from_characters)\
25
+ .with(characters)\
26
+ .and_return(ascender_bit)
27
+ allow(BarSymbol).to receive(:make)\
28
+ .with(ascender_bit, descender_bit)\
29
+ .and_return(bar_symbol)
30
+ end
31
+
32
+ specify do
33
+ expect(bar_position.map(characters)).to eq(bar_symbol)
34
+ end
35
+
36
+ end
37
+
38
+ end
39
+
40
+ end
@@ -0,0 +1,39 @@
1
+ require File.expand_path('spec_helper', File.dirname(__FILE__))
2
+
3
+ module Imb
4
+
5
+ describe BarSymbol do
6
+
7
+ subject {BarSymbol.make(ascender_bit, descender_bit)}
8
+
9
+ context 'tracker' do
10
+ let(:ascender_bit) {0}
11
+ let(:descender_bit) {0}
12
+ its(:code) {should eq 0}
13
+ its(:letter) {should eq 'T'}
14
+ end
15
+
16
+ context 'descender' do
17
+ let(:ascender_bit) {0}
18
+ let(:descender_bit) {1}
19
+ its(:code) {should eq 1}
20
+ its(:letter) {should eq 'D'}
21
+ end
22
+
23
+ context 'ascender' do
24
+ let(:ascender_bit) {1}
25
+ let(:descender_bit) {0}
26
+ its(:code) {should eq 2}
27
+ its(:letter) {should eq 'A'}
28
+ end
29
+
30
+ context 'full' do
31
+ let(:ascender_bit) {1}
32
+ let(:descender_bit) {1}
33
+ its(:code) {should eq 3}
34
+ its(:letter) {should eq 'F'}
35
+ end
36
+
37
+ end
38
+
39
+ end
@@ -0,0 +1,106 @@
1
+ require File.expand_path('spec_helper', File.dirname(__FILE__))
2
+
3
+ module Imb
4
+
5
+ describe BarcodeId do
6
+
7
+ describe '::coerce' do
8
+
9
+ subject {BarcodeId.coerce(o)}
10
+
11
+ context 'BarcodeId' do
12
+ let(:o) {BarcodeId.new(12)}
13
+ its(:to_i) {should == 12}
14
+ end
15
+
16
+ context 'String' do
17
+ let(:o) {'12'}
18
+ its(:to_i) {should == 12}
19
+ end
20
+
21
+ context 'Integer' do
22
+ let(:o) {12}
23
+ its(:to_i) {should == 12}
24
+ end
25
+
26
+ context 'unknown' do
27
+ let(:o) {Object.new}
28
+ specify do
29
+ expect {
30
+ BarcodeId.coerce(o)
31
+ }.to raise_error ArgumentError, 'Cannot coerce to BarcodeId'
32
+ end
33
+ end
34
+
35
+ end
36
+
37
+ describe '#to_i' do
38
+ let(:value) {23}
39
+ subject {BarcodeId.new(value)}
40
+ its(:to_i) {should == value}
41
+ end
42
+
43
+ describe '#=' do
44
+ def o1 ; BarcodeId.new(1) ; end
45
+ def o2 ; 1 ; end
46
+ def o3 ; BarcodeId.new(2) ; end
47
+ def o4 ; Object.new ; end
48
+ specify {expect(o1).to eq(o1)}
49
+ specify {expect(o1).to eq(o2)}
50
+ specify {expect(o1).not_to eq(o3)}
51
+ specify {expect(o1).not_to eq(o4)}
52
+ end
53
+
54
+ describe '#validate' do
55
+
56
+ let(:long_mailer_id?) {double 'long_mailer_id?'}
57
+
58
+ def validate(value)
59
+ BarcodeId.new(value).validate(long_mailer_id?)
60
+ end
61
+
62
+ def self.is_valid(value)
63
+ context "#{value}" do
64
+ specify {validate(value)}
65
+ end
66
+ end
67
+
68
+ def self.is_out_of_range(value)
69
+ context "#{value}" do
70
+ specify do
71
+ expect {
72
+ validate(value)
73
+ }.to raise_error ArgumentError, 'Must be 0..94'
74
+ end
75
+ end
76
+ end
77
+
78
+ def self.has_bad_least_significant_digit(value)
79
+ context "#{value}" do
80
+ specify do
81
+ expect {
82
+ validate(value)
83
+ }.to raise_error(ArgumentError,
84
+ 'Least significant digit must be 0..4')
85
+ end
86
+ end
87
+ end
88
+
89
+ is_out_of_range -1
90
+ is_valid 0
91
+ is_valid 4
92
+ has_bad_least_significant_digit 5
93
+ is_valid 94
94
+ is_out_of_range 95
95
+
96
+ end
97
+
98
+ describe '#shift_and_add_to' do
99
+ let(:barcode_id) {BarcodeId.new(12)}
100
+ let(:long_mailer_id?) {double 'long mailer id'}
101
+ specify {expect(barcode_id.shift_and_add_to(1, long_mailer_id?)).to eq(57)}
102
+ end
103
+
104
+ end
105
+
106
+ end
@@ -0,0 +1,213 @@
1
+ require File.expand_path('spec_helper', File.dirname(__FILE__))
2
+
3
+ module Imb
4
+
5
+ describe Barcode do
6
+
7
+ let(:barcode) do
8
+ Barcode.new(barcode_id,
9
+ service_type,
10
+ mailer_id,
11
+ serial_number,
12
+ routing_code)
13
+ end
14
+ subject {barcode}
15
+
16
+ describe 'Examples from USPS-B-3200 rev. G, Appendix B' do
17
+
18
+ describe '#1' do
19
+
20
+ let(:barcode_id) {'01'}
21
+ let(:service_type) {'234'}
22
+ let(:mailer_id) {'567094'}
23
+ let(:serial_number) {'987654321'}
24
+ let(:routing_code) {nil}
25
+
26
+ its(:binary_data) {should == 0x00000000001122103B5C2004B1}
27
+ its(:frame_check_sequence) {should == 0x051}
28
+ its(:codewords) do
29
+ should == [0, 0, 0, 0, 559, 202, 508, 451, 124, 17]
30
+ end
31
+ its(:codewords_with_orientation_in_character_j) do
32
+ should == [0, 0, 0, 0, 559, 202, 508, 451, 124, 34]
33
+ end
34
+ its(:codewords_with_fcs_bit_in_character_a) do
35
+ should == [0, 0, 0, 0, 559, 202, 508, 451, 124, 34]
36
+ end
37
+ its(:characters) do
38
+ should == [
39
+ 0x001F, 0x001F, 0x001F, 0x001F, 0x1524,
40
+ 0x01A3, 0x043C, 0x1838, 0x012B, 0x0076,
41
+ ]
42
+ end
43
+ its(:characters_with_fcs_bits_0_through_9) do
44
+ should == [
45
+ 0x1FE0, 0x001F, 0x001F, 0x001F, 0x0ADB,
46
+ 0x01A3, 0x1BC3, 0x1838, 0x012B, 0x0076,
47
+ ]
48
+ end
49
+ its(:barcode_letters) do
50
+ should == ('ATTFATTDTTADTAATTDTDTATTDAFDDFADF'\
51
+ 'DFTFFFFFTATFAAAATDFFTDAADFTFDTDT')
52
+ end
53
+
54
+ end
55
+
56
+ describe '#2' do
57
+
58
+ let(:barcode_id) {'01'}
59
+ let(:service_type) {'234'}
60
+ let(:mailer_id) {'567094'}
61
+ let(:serial_number) {'987654321'}
62
+ let(:routing_code) {'01234'}
63
+
64
+ its(:binary_data) {should == 0x0000000D138A87BAB5CF3804B1}
65
+ its(:frame_check_sequence) {should == 0x065}
66
+ its(:codewords) do
67
+ should == [0, 0, 15, 14, 290, 567, 385, 48, 388, 333]
68
+ end
69
+ its(:codewords_with_orientation_in_character_j) do
70
+ should == [0, 0, 15, 14, 290, 567, 385, 48, 388, 666]
71
+ end
72
+ its(:codewords_with_fcs_bit_in_character_a) do
73
+ should == [0, 0, 15, 14, 290, 567, 385, 48, 388, 666]
74
+ end
75
+ its(:characters) do
76
+ should == [
77
+ 0x001F, 0x001F, 0x1D40, 0x0057, 0x0255,
78
+ 0x0724, 0x04E8, 0x009D, 0x030B, 0x0583,
79
+ ]
80
+ end
81
+ its(:characters_with_fcs_bits_0_through_9) do
82
+ should == [
83
+ 0x1FE0, 0x001F, 0x02BF, 0x0057, 0x0255,
84
+ 0x18DB, 0x1B17, 0x009D, 0x030B, 0x0583,
85
+ ]
86
+ end
87
+ its(:barcode_letters) do
88
+ should == ('DTTAFADDTTFTDTFTFDTDDADADAFADFATD'\
89
+ 'DFTAAAFDTTADFAAATDFDTDFADDDTDFFT')
90
+ end
91
+
92
+ end
93
+
94
+ describe '#3' do
95
+
96
+ let(:barcode_id) {'01'}
97
+ let(:service_type) {'234'}
98
+ let(:mailer_id) {'567094'}
99
+ let(:serial_number) {'987654321'}
100
+ let(:routing_code) {'012345678'}
101
+
102
+ its(:binary_data) {should == 0x000202BDC097711204D21804B1}
103
+ its(:frame_check_sequence) {should == 0x606}
104
+ its(:codewords) do
105
+ should == [0, 110, 1113, 1363, 198, 413, 470, 468, 1333, 513]
106
+ end
107
+ its(:codewords_with_orientation_in_character_j) do
108
+ should == [0, 110, 1113, 1363, 198, 413, 470, 468, 1333, 1026]
109
+ end
110
+ its(:codewords_with_fcs_bit_in_character_a) do
111
+ should == [659, 110, 1113, 1363, 198, 413, 470, 468, 1333, 1026]
112
+ end
113
+ its(:characters) do
114
+ should == [
115
+ 0x1154, 0x00F8, 0x1E01, 0x0110, 0x019A,
116
+ 0x1298, 0x03A2, 0x03A1, 0x0084, 0x0B11,
117
+ ]
118
+ end
119
+ its(:characters_with_fcs_bits_0_through_9) do
120
+ should == [
121
+ 0x1154, 0x1F07, 0x01FE, 0x0110, 0x019A,
122
+ 0x1298, 0x03A2, 0x03A1, 0x0084, 0x14EE,
123
+ ]
124
+ end
125
+ its(:barcode_letters) do
126
+ should == ('ADFTTAFDTTTTFATTADTAAATFTFTATDAAA'\
127
+ 'FDDADATATDTDTTDFDTDATADADTDFFTFA')
128
+ end
129
+
130
+ end
131
+
132
+ describe '#4' do
133
+
134
+ let(:barcode_id) {'01'}
135
+ let(:service_type) {'234'}
136
+ let(:mailer_id) {'567094'}
137
+ let(:serial_number) {'987654321'}
138
+ let(:routing_code) {'01234567891'}
139
+
140
+ its(:binary_data) {should == 0x016907B2A24ABC16A2E5C004B1}
141
+ its(:frame_check_sequence) {should == 0x751}
142
+ its(:codewords) do
143
+ should == [14, 787, 607, 1022, 861, 19, 816, 1294, 35, 301]
144
+ end
145
+ its(:codewords_with_orientation_in_character_j) do
146
+ should == [14, 787, 607, 1022, 861, 19, 816, 1294, 35, 602]
147
+ end
148
+ its(:codewords_with_fcs_bit_in_character_a) do
149
+ should == [673, 787, 607, 1022, 861, 19, 816, 1294, 35, 602]
150
+ end
151
+ its(:characters) do
152
+ should == [
153
+ 0x1234, 0x085C, 0x08E4, 0x0B06, 0x1922,
154
+ 0x1740, 0x0839, 0x1200, 0x0DC0, 0x04D4,
155
+ ]
156
+ end
157
+ its(:characters_with_fcs_bits_0_through_9) do
158
+ should == [
159
+ 0x0DCB, 0x085C, 0x08E4, 0x0B06, 0x06DD,
160
+ 0x1740, 0x17C6, 0x1200, 0x123F, 0x1B2B,
161
+ ]
162
+ end
163
+ its(:barcode_letters) do
164
+ should == ('AADTFFDFTDADTAADAATFDTDDAAADDTDTT'\
165
+ 'DAFADADDDTFFFDDTTTADFAAADFTDAADA')
166
+ end
167
+
168
+ end
169
+
170
+ end
171
+
172
+ describe '#accessors' do
173
+
174
+ let(:barcode) do
175
+ Barcode.new(barcode_id,
176
+ service_type,
177
+ mailer_id,
178
+ serial_number,
179
+ routing_code)
180
+ end
181
+ subject {barcode}
182
+
183
+ context 'when constructed with strings' do
184
+ let(:barcode_id) {'01'}
185
+ let(:service_type) {'234'}
186
+ let(:mailer_id) {'567094'}
187
+ let(:serial_number) {'987654321'}
188
+ let(:routing_code) {'98765432109'}
189
+ its(:barcode_id) {should == 1}
190
+ its(:service_type) {should == 234}
191
+ its(:mailer_id) {should == 567094}
192
+ its(:serial_number) {should == 987654321}
193
+ its(:routing_code) {should == RoutingCode.new(98765, 4321, 9)}
194
+ end
195
+
196
+ context 'when constructed with integers' do
197
+ let(:barcode_id) {01}
198
+ let(:service_type) {234}
199
+ let(:mailer_id) {567094}
200
+ let(:serial_number) {987654321}
201
+ let(:routing_code) {[98765, 4321, 9]}
202
+ its(:barcode_id) {should == 1}
203
+ its(:service_type) {should == 234}
204
+ its(:mailer_id) {should == 567094}
205
+ its(:serial_number) {should == 987654321}
206
+ its(:routing_code) {should == RoutingCode.new(98765, 4321, 9)}
207
+ end
208
+
209
+ end
210
+
211
+ end
212
+
213
+ end
@@ -0,0 +1,25 @@
1
+ require File.expand_path('spec_helper', File.dirname(__FILE__))
2
+
3
+ module Imb
4
+
5
+ describe CharacterPosition do
6
+
7
+ describe '#extract_bit_from_characters' do
8
+
9
+ let(:characters) {[1, 2]}
10
+
11
+ def extract(character_index, bit_number)
12
+ CharacterPosition.new(character_index, bit_number)\
13
+ .extract_bit_from_characters(characters)
14
+ end
15
+
16
+ specify {expect(extract(0, 0)).to eq(1)}
17
+ specify {expect(extract(0, 1)).to eq(0)}
18
+ specify {expect(extract(1, 0)).to eq(0)}
19
+ specify {expect(extract(1, 1)).to eq(1)}
20
+
21
+ end
22
+
23
+ end
24
+
25
+ end