USPS-intelligent-barcode 0.1.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.
- data/Gemfile +9 -0
- data/Gemfile.lock +33 -0
- data/LICENSE.md +11 -0
- data/README.md +56 -0
- data/Rakefile +46 -0
- data/VERSION +1 -0
- data/examples/example.rb +17 -0
- data/lib/USPS-intelligent-barcode.rb +5 -0
- data/lib/USPS-intelligent-barcode/BarMap.rb +40 -0
- data/lib/USPS-intelligent-barcode/BarPosition.rb +26 -0
- data/lib/USPS-intelligent-barcode/Barcode.rb +110 -0
- data/lib/USPS-intelligent-barcode/BarcodeId.rb +66 -0
- data/lib/USPS-intelligent-barcode/CharacterPosition.rb +16 -0
- data/lib/USPS-intelligent-barcode/CodewordMap.rb +28 -0
- data/lib/USPS-intelligent-barcode/Crc.rb +42 -0
- data/lib/USPS-intelligent-barcode/MailerId.rb +70 -0
- data/lib/USPS-intelligent-barcode/NumericConversions.rb +13 -0
- data/lib/USPS-intelligent-barcode/RoutingCode.rb +77 -0
- data/lib/USPS-intelligent-barcode/SerialNumber.rb +61 -0
- data/lib/USPS-intelligent-barcode/ServiceType.rb +51 -0
- data/lib/USPS-intelligent-barcode/autoload.rb +61 -0
- data/lib/USPS-intelligent-barcode/bar_to_character_mapping.yml +66 -0
- data/lib/USPS-intelligent-barcode/codeword_to_character_mapping.yml +1366 -0
- data/spec/BarMap_spec.rb +30 -0
- data/spec/BarPosition_spec.rb +52 -0
- data/spec/BarcodeId_spec.rb +118 -0
- data/spec/Barcode_spec.rb +213 -0
- data/spec/CharacterPosition_spec.rb +25 -0
- data/spec/CodewordMap_spec.rb +22 -0
- data/spec/Crc_spec.rb +21 -0
- data/spec/MailerId_spec.rb +114 -0
- data/spec/NumericConversions_spec.rb +23 -0
- data/spec/RoutingCode_spec.rb +180 -0
- data/spec/SerialNumber_spec.rb +117 -0
- data/spec/ServiceType_spec.rb +93 -0
- data/spec/spec_helper.rb +1 -0
- metadata +160 -0
data/spec/Crc_spec.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
2
|
+
|
3
|
+
module Imb
|
4
|
+
|
5
|
+
describe Crc do
|
6
|
+
|
7
|
+
describe '#crc' do
|
8
|
+
|
9
|
+
specify do
|
10
|
+
Crc.crc(0x016907B2A24ABC16A2E5C004B1).should == 0x751
|
11
|
+
end
|
12
|
+
|
13
|
+
specify do
|
14
|
+
Crc.crc(0).should == 0x6e0
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
2
|
+
|
3
|
+
module Imb
|
4
|
+
|
5
|
+
describe MailerId do
|
6
|
+
|
7
|
+
describe '::coerce' do
|
8
|
+
|
9
|
+
subject {MailerId.coerce(o)}
|
10
|
+
|
11
|
+
context 'MailerId' do
|
12
|
+
let(:o) {MailerId.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
|
+
MailerId.coerce(o)
|
31
|
+
}.to raise_error ArgumentError, 'Cannot coerce to MailerId'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#to_i' do
|
38
|
+
let(:value) {23}
|
39
|
+
subject {MailerId.new(value)}
|
40
|
+
its(:to_i) {should == value}
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '#=' do
|
44
|
+
def o1 ; MailerId.new(1) ; end
|
45
|
+
def o2 ; 1 ; end
|
46
|
+
def o3 ; MailerId.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 '#validate' do
|
55
|
+
|
56
|
+
let(:long_mailer_id?) {mock 'long_mailer_id?'}
|
57
|
+
|
58
|
+
def validate(value)
|
59
|
+
MailerId.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,
|
74
|
+
'Must be 0..899999 or 900000000..999999999')
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
is_out_of_range -1
|
80
|
+
is_valid 0
|
81
|
+
is_valid 899_999
|
82
|
+
is_out_of_range 1_000_000
|
83
|
+
is_out_of_range 899_999_999
|
84
|
+
is_valid 900_000_000
|
85
|
+
is_valid 999_999_999
|
86
|
+
is_out_of_range 1_000_000_000
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
describe '#long?' do
|
91
|
+
|
92
|
+
subject {MailerId.new(value)}
|
93
|
+
|
94
|
+
context 'short' do
|
95
|
+
let(:value) {0}
|
96
|
+
its(:long?) {should be_false}
|
97
|
+
end
|
98
|
+
|
99
|
+
context 'long' do
|
100
|
+
let(:value) {900_000_000}
|
101
|
+
its(:long?) {should be_true}
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
describe '#shift_and_add_to' do
|
107
|
+
let(:mailer_id) {MailerId.new(999999)}
|
108
|
+
let(:long_mailer_id?) {mock 'long mailer id'}
|
109
|
+
specify {mailer_id.shift_and_add_to(1, long_mailer_id?).should == 1999999}
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
2
|
+
|
3
|
+
module Imb
|
4
|
+
|
5
|
+
describe NumericConversions do
|
6
|
+
|
7
|
+
include NumericConversions
|
8
|
+
|
9
|
+
describe '#numeric_to_bytes' do
|
10
|
+
|
11
|
+
specify do
|
12
|
+
numeric_to_bytes(0x1234).should == [0x12, 0x34]
|
13
|
+
end
|
14
|
+
|
15
|
+
specify do
|
16
|
+
numeric_to_bytes(0x1234, 3).should == [0, 0x12, 0x34]
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,180 @@
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
2
|
+
|
3
|
+
module Imb
|
4
|
+
|
5
|
+
describe RoutingCode do
|
6
|
+
|
7
|
+
describe '::coerce' do
|
8
|
+
|
9
|
+
let(:zip) {85308}
|
10
|
+
let(:plus4) {1465}
|
11
|
+
let(:delivery_point) {12}
|
12
|
+
|
13
|
+
subject {RoutingCode.coerce(o)}
|
14
|
+
|
15
|
+
shared_examples 'coerces' do
|
16
|
+
its(:zip) {should == zip}
|
17
|
+
its(:plus4) {should == plus4}
|
18
|
+
its(:delivery_point) {should == delivery_point}
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'RoutingCode' do
|
22
|
+
let(:o) {RoutingCode.new(zip, plus4, delivery_point)}
|
23
|
+
it_behaves_like 'coerces'
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'nil' do
|
27
|
+
let(:o) {nil}
|
28
|
+
let(:zip) {nil}
|
29
|
+
let(:plus4) {nil}
|
30
|
+
let(:delivery_point) {nil}
|
31
|
+
it_behaves_like 'coerces'
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'string' do
|
35
|
+
|
36
|
+
let(:o) {"#{zip}#{plus4}#{delivery_point}"}
|
37
|
+
|
38
|
+
context 'empty' do
|
39
|
+
let(:zip) {nil}
|
40
|
+
let(:plus4) {nil}
|
41
|
+
let(:delivery_point) {nil}
|
42
|
+
it_behaves_like 'coerces'
|
43
|
+
end
|
44
|
+
|
45
|
+
context "zip, plu4, delivery_point" do
|
46
|
+
it_behaves_like 'coerces'
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'array' do
|
52
|
+
let(:o) {[zip, plus4, delivery_point]}
|
53
|
+
it_behaves_like 'coerces'
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'unrecognized' do
|
57
|
+
let(:o) {Object.new}
|
58
|
+
specify do
|
59
|
+
expect {
|
60
|
+
RoutingCode.coerce(o)
|
61
|
+
}.to raise_error ArgumentError, 'Cannot coerce to RoutingCode'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
describe '#string_to_array' do
|
68
|
+
|
69
|
+
subject(:array) {RoutingCode.string_to_array(s)}
|
70
|
+
|
71
|
+
context 'empty' do
|
72
|
+
let(:s) {''}
|
73
|
+
it {should == [nil, nil, nil]}
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'zip' do
|
77
|
+
let(:s) {'85308'}
|
78
|
+
it {should == ['85308', nil, nil]}
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'zip, plus4' do
|
82
|
+
let(:s) {'853081465'}
|
83
|
+
it {should == ['85308', '1465', nil]}
|
84
|
+
end
|
85
|
+
|
86
|
+
context 'zip, plu4, delivery_point' do
|
87
|
+
let(:s) {'85308146502'}
|
88
|
+
it {should == ['85308', '1465', '02']}
|
89
|
+
end
|
90
|
+
|
91
|
+
context 'non-digits' do
|
92
|
+
let(:s) {'(85308 1465 02)'}
|
93
|
+
it {should == ['85308', '1465', '02']}
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'incorrect length' do
|
97
|
+
let(:s) {'1'}
|
98
|
+
specify do
|
99
|
+
expect {
|
100
|
+
array
|
101
|
+
}.to raise_error ArgumentError, 'Bad routing code: "1"'
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
describe '#convert' do
|
108
|
+
|
109
|
+
subject do
|
110
|
+
RoutingCode.new(zip, plus4, delivery_point)
|
111
|
+
end
|
112
|
+
|
113
|
+
context 'empty' do
|
114
|
+
let(:zip) {nil}
|
115
|
+
let(:plus4) {nil}
|
116
|
+
let(:delivery_point) {nil}
|
117
|
+
its(:convert) {should == 0}
|
118
|
+
end
|
119
|
+
|
120
|
+
context 'zip' do
|
121
|
+
let(:zip) {85308}
|
122
|
+
let(:plus4) {nil}
|
123
|
+
let(:delivery_point) {nil}
|
124
|
+
its(:convert) {should == 85309}
|
125
|
+
end
|
126
|
+
|
127
|
+
context 'zip, plus4' do
|
128
|
+
let(:zip) {85308}
|
129
|
+
let(:plus4) {1465}
|
130
|
+
let(:delivery_point) {nil}
|
131
|
+
its(:convert) {should == 853181466}
|
132
|
+
end
|
133
|
+
|
134
|
+
context 'zip, plus4, delivery_point' do
|
135
|
+
let(:zip) {85308}
|
136
|
+
let(:plus4) {1465}
|
137
|
+
let(:delivery_point) {2}
|
138
|
+
its(:convert) {should == 86308246503}
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
142
|
+
|
143
|
+
describe '#to_a' do
|
144
|
+
let(:zip) {85308}
|
145
|
+
let(:plus4) {1465}
|
146
|
+
let(:delivery_point) {2}
|
147
|
+
subject {RoutingCode.new(zip, plus4, delivery_point)}
|
148
|
+
its(:to_a) {should == [zip, plus4, delivery_point]}
|
149
|
+
end
|
150
|
+
|
151
|
+
describe '#==' do
|
152
|
+
def o1 ; RoutingCode.new(85308, 1465, 1) ; end
|
153
|
+
def o2 ; [85308, 1465, 1] ; end
|
154
|
+
def o3 ; RoutingCode.new(85308, 1465, 2) ; end
|
155
|
+
def o4 ; RoutingCode.new(85308, 1466, 1) ; end
|
156
|
+
def o5 ; RoutingCode.new(85309, 1465, 1) ; end
|
157
|
+
def o6 ; Object.new ; end
|
158
|
+
specify {o1.should == o1}
|
159
|
+
specify {o1.should == o2}
|
160
|
+
specify {o1.should_not == o3}
|
161
|
+
specify {o1.should_not == o4}
|
162
|
+
specify {o1.should_not == o5}
|
163
|
+
specify {o1.should_not == o6}
|
164
|
+
end
|
165
|
+
|
166
|
+
describe '#validate' do
|
167
|
+
let(:routing_code) {RoutingCode.new(nil, nil, nil)}
|
168
|
+
let(:long_mailer_id?) {mock 'long_mailer_id?'}
|
169
|
+
specify {routing_code.validate(long_mailer_id?)}
|
170
|
+
end
|
171
|
+
|
172
|
+
describe '#shift_and_add_to' do
|
173
|
+
let(:routing_code) {RoutingCode.new(85308, 1465, 2)}
|
174
|
+
let(:long_mailer_id?) {mock 'long mailer id'}
|
175
|
+
specify {routing_code.shift_and_add_to(1, long_mailer_id?).should == 186308246503}
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
179
|
+
|
180
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
2
|
+
|
3
|
+
module Imb
|
4
|
+
|
5
|
+
describe SerialNumber do
|
6
|
+
|
7
|
+
describe '::coerce' do
|
8
|
+
|
9
|
+
subject {SerialNumber.coerce(o)}
|
10
|
+
|
11
|
+
context 'SerialNumber' do
|
12
|
+
let(:o) {SerialNumber.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
|
+
SerialNumber.coerce(o)
|
31
|
+
}.to raise_error ArgumentError, 'Cannot coerce to SerialNumber'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#to_i' do
|
38
|
+
let(:value) {23}
|
39
|
+
subject {SerialNumber.new(value)}
|
40
|
+
its(:to_i) {should == value}
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '#=' do
|
44
|
+
def o1 ; SerialNumber.new(1) ; end
|
45
|
+
def o2 ; 1 ; end
|
46
|
+
def o3 ; SerialNumber.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 '#validate' do
|
55
|
+
|
56
|
+
def self.is_valid(value)
|
57
|
+
context "#{value}" do
|
58
|
+
let(:serial_number) {SerialNumber.new(value)}
|
59
|
+
specify {serial_number.validate(long_mailer_id?)}
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.is_out_of_range(value)
|
64
|
+
context "#{value}" do
|
65
|
+
let(:serial_number) {SerialNumber.new(value)}
|
66
|
+
specify do
|
67
|
+
expect {
|
68
|
+
serial_number.validate(long_mailer_id?)
|
69
|
+
}.to raise_error ArgumentError, message
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'when long mailer id' do
|
75
|
+
let(:long_mailer_id?) {true}
|
76
|
+
let(:message) {'Must be 0..999999'}
|
77
|
+
is_out_of_range -1
|
78
|
+
is_valid 0
|
79
|
+
is_valid 999_999
|
80
|
+
is_out_of_range 1_000_000
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'when short mailer id' do
|
84
|
+
let(:long_mailer_id?) {false}
|
85
|
+
let(:message) {'Must be 0..999999999'}
|
86
|
+
is_out_of_range -1
|
87
|
+
is_valid 0
|
88
|
+
is_valid 999_999_999
|
89
|
+
is_out_of_range 1_000_000_000
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
describe '#shift_and_add_to' do
|
95
|
+
|
96
|
+
let(:serial_number) {SerialNumber.new(value)}
|
97
|
+
|
98
|
+
def shift_and_add_to
|
99
|
+
serial_number.shift_and_add_to(1, long_mailer_id?)
|
100
|
+
end
|
101
|
+
|
102
|
+
context 'long mailer id' do
|
103
|
+
let(:value) {999_999}
|
104
|
+
let(:long_mailer_id?) {true}
|
105
|
+
specify {shift_and_add_to.should == 1_999_999}
|
106
|
+
end
|
107
|
+
|
108
|
+
context 'short mailer id' do
|
109
|
+
let(:value) {999_999_999}
|
110
|
+
let(:long_mailer_id?) {false}
|
111
|
+
specify {shift_and_add_to.should == 1_999_999_999}
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|