USPS-intelligent-barcode 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. data/Gemfile +9 -0
  2. data/Gemfile.lock +33 -0
  3. data/LICENSE.md +11 -0
  4. data/README.md +56 -0
  5. data/Rakefile +46 -0
  6. data/VERSION +1 -0
  7. data/examples/example.rb +17 -0
  8. data/lib/USPS-intelligent-barcode.rb +5 -0
  9. data/lib/USPS-intelligent-barcode/BarMap.rb +40 -0
  10. data/lib/USPS-intelligent-barcode/BarPosition.rb +26 -0
  11. data/lib/USPS-intelligent-barcode/Barcode.rb +110 -0
  12. data/lib/USPS-intelligent-barcode/BarcodeId.rb +66 -0
  13. data/lib/USPS-intelligent-barcode/CharacterPosition.rb +16 -0
  14. data/lib/USPS-intelligent-barcode/CodewordMap.rb +28 -0
  15. data/lib/USPS-intelligent-barcode/Crc.rb +42 -0
  16. data/lib/USPS-intelligent-barcode/MailerId.rb +70 -0
  17. data/lib/USPS-intelligent-barcode/NumericConversions.rb +13 -0
  18. data/lib/USPS-intelligent-barcode/RoutingCode.rb +77 -0
  19. data/lib/USPS-intelligent-barcode/SerialNumber.rb +61 -0
  20. data/lib/USPS-intelligent-barcode/ServiceType.rb +51 -0
  21. data/lib/USPS-intelligent-barcode/autoload.rb +61 -0
  22. data/lib/USPS-intelligent-barcode/bar_to_character_mapping.yml +66 -0
  23. data/lib/USPS-intelligent-barcode/codeword_to_character_mapping.yml +1366 -0
  24. data/spec/BarMap_spec.rb +30 -0
  25. data/spec/BarPosition_spec.rb +52 -0
  26. data/spec/BarcodeId_spec.rb +118 -0
  27. data/spec/Barcode_spec.rb +213 -0
  28. data/spec/CharacterPosition_spec.rb +25 -0
  29. data/spec/CodewordMap_spec.rb +22 -0
  30. data/spec/Crc_spec.rb +21 -0
  31. data/spec/MailerId_spec.rb +114 -0
  32. data/spec/NumericConversions_spec.rb +23 -0
  33. data/spec/RoutingCode_spec.rb +180 -0
  34. data/spec/SerialNumber_spec.rb +117 -0
  35. data/spec/ServiceType_spec.rb +93 -0
  36. data/spec/spec_helper.rb +1 -0
  37. metadata +160 -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(:barcode) 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
+ bar_map.barcode(characters).should == barcode
26
+ end
27
+
28
+ end
29
+
30
+ end
@@ -0,0 +1,52 @@
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(:characters) {mock 'array of characters'}
10
+ let(:descender_character_position) {mock CharacterPosition}
11
+ let(:ascender_character_position) {mock CharacterPosition}
12
+ let(:bar_position) do
13
+ BarPosition.new(descender_character_position,
14
+ ascender_character_position)
15
+ end
16
+
17
+ before(:each) do
18
+ descender_character_position.stub(:extract_bit_from_characters)\
19
+ .with(characters).and_return(descender_bit)
20
+ ascender_character_position.stub(:extract_bit_from_characters)\
21
+ .with(characters).and_return(ascender_bit)
22
+ end
23
+
24
+ context 'without ascender, without descender' do
25
+ let(:ascender_bit) {0}
26
+ let(:descender_bit) {0}
27
+ specify {bar_position.map(characters).should == 0}
28
+ end
29
+
30
+ context 'without ascender, with descender' do
31
+ let(:ascender_bit) {0}
32
+ let(:descender_bit) {1}
33
+ specify {bar_position.map(characters).should == 1}
34
+ end
35
+
36
+ context 'with ascender, without descender' do
37
+ let(:ascender_bit) {1}
38
+ let(:descender_bit) {0}
39
+ specify {bar_position.map(characters).should == 2}
40
+ end
41
+
42
+ context 'with ascender, with descender' do
43
+ let(:ascender_bit) {1}
44
+ let(:descender_bit) {1}
45
+ specify {bar_position.map(characters).should == 3}
46
+ end
47
+
48
+ end
49
+
50
+ end
51
+
52
+ end
@@ -0,0 +1,118 @@
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 {o1.should == o1}
49
+ specify {o1.should == o2}
50
+ specify {o1.should_not == o3}
51
+ specify {o1.should_not == o4}
52
+ end
53
+
54
+ describe '#most_significant_digit' do
55
+ specify do
56
+ BarcodeId.new(12).most_significant_digit.should == 1
57
+ end
58
+ end
59
+
60
+ describe '#least_significant_digit' do
61
+ specify do
62
+ BarcodeId.new(12).least_significant_digit.should == 2
63
+ end
64
+ end
65
+
66
+ describe '#validate' do
67
+
68
+ let(:long_mailer_id?) {mock 'long_mailer_id?'}
69
+
70
+ def validate(value)
71
+ BarcodeId.new(value).validate(long_mailer_id?)
72
+ end
73
+
74
+ def self.is_valid(value)
75
+ context "#{value}" do
76
+ specify {validate(value)}
77
+ end
78
+ end
79
+
80
+ def self.is_out_of_range(value)
81
+ context "#{value}" do
82
+ specify do
83
+ expect {
84
+ validate(value)
85
+ }.to raise_error ArgumentError, 'Must be 0..94'
86
+ end
87
+ end
88
+ end
89
+
90
+ def self.has_bad_least_significant_digit(value)
91
+ context "#{value}" do
92
+ specify do
93
+ expect {
94
+ validate(value)
95
+ }.to raise_error(ArgumentError,
96
+ 'Least significant digit must be 0..4')
97
+ end
98
+ end
99
+ end
100
+
101
+ is_out_of_range -1
102
+ is_valid 0
103
+ is_valid 4
104
+ has_bad_least_significant_digit 5
105
+ is_valid 94
106
+ is_out_of_range 95
107
+
108
+ end
109
+
110
+ describe '#shift_and_add_to' do
111
+ let(:barcode_id) {BarcodeId.new(12)}
112
+ let(:long_mailer_id?) {mock 'long mailer id'}
113
+ specify {barcode_id.shift_and_add_to(1, long_mailer_id?).should == 57}
114
+ end
115
+
116
+ end
117
+
118
+ 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 {extract(0, 0).should == 1}
17
+ specify {extract(0, 1).should == 0}
18
+ specify {extract(1, 0).should == 0}
19
+ specify {extract(1, 1).should == 1}
20
+
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,22 @@
1
+ require File.expand_path('spec_helper', File.dirname(__FILE__))
2
+
3
+ module Imb
4
+
5
+ describe CodewordMap do
6
+
7
+ let(:characters) do
8
+ [
9
+ 0x001F, 0x001F, 0x001F, 0x001F, 0x1524,
10
+ 0x01A3, 0x043C, 0x1838, 0x012B, 0x0076,
11
+ ]
12
+ end
13
+ let(:codewords) {[0, 0, 0, 0, 559, 202, 508, 451, 124, 34]}
14
+ let(:codeword_map) {CodewordMap.new}
15
+
16
+ specify do
17
+ codeword_map.characters(codewords).should == characters
18
+ end
19
+
20
+ end
21
+
22
+ end