uk_postcode 1.0.1 → 2.0.0.alpha
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/COPYING.txt +25 -0
- data/README.md +105 -55
- data/lib/uk_postcode/country_finder.rb +15 -0
- data/lib/uk_postcode/country_lookup.rb +10 -0
- data/lib/uk_postcode/geographic_postcode.rb +98 -0
- data/lib/uk_postcode/giro_postcode.rb +61 -0
- data/lib/uk_postcode/invalid_postcode.rb +38 -0
- data/lib/uk_postcode/tree.rb +75 -0
- data/lib/uk_postcode/version.rb +2 -2
- data/lib/uk_postcode.rb +13 -106
- data/test/country_finder_test.rb +33 -0
- data/test/full_postcode_test.rb +35 -0
- data/test/geographic_postcode_test.rb +271 -0
- data/test/giro_postcode_test.rb +100 -0
- data/test/invalid_postcode_test.rb +75 -0
- data/test/special_postcode_test.rb +50 -0
- data/test/tree_test.rb +84 -0
- data/test/uk_postcode_test.rb +17 -265
- metadata +20 -9
- data/Rakefile +0 -8
- data/test/samples/wikipedia.list +0 -35
- data/test/samples_test.rb +0 -18
data/lib/uk_postcode.rb
CHANGED
@@ -1,112 +1,19 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
( [A-PR-UWYZ01][A-Z01]? ) # area
|
6
|
-
( [0-9IO][0-9A-HJKMNPR-YIO]? ) # district
|
7
|
-
(?: \s*
|
8
|
-
( [0-9IO] ) # sector
|
9
|
-
( [ABD-HJLNPQ-Z10]{2} ) # unit
|
10
|
-
)?
|
11
|
-
) \s* \Z/x
|
12
|
-
|
13
|
-
attr_reader :raw
|
14
|
-
|
15
|
-
# Initialise a new UKPostcode instance from the given postcode string
|
16
|
-
#
|
17
|
-
def initialize(postcode_as_string)
|
18
|
-
@raw = postcode_as_string
|
19
|
-
end
|
20
|
-
|
21
|
-
# Returns true if the postcode is a valid full postcode (e.g. W1A 1AA) or outcode (e.g. W1A)
|
22
|
-
#
|
23
|
-
def valid?
|
24
|
-
!!outcode
|
25
|
-
end
|
26
|
-
|
27
|
-
# Returns true if the postcode is a valid full postcode (e.g. W1A 1AA)
|
28
|
-
#
|
29
|
-
def full?
|
30
|
-
!!(outcode && incode)
|
31
|
-
end
|
32
|
-
|
33
|
-
# The left-hand part of the postcode, e.g. W1A 1AA -> W1A
|
34
|
-
#
|
35
|
-
def outcode
|
36
|
-
area && district && [area, district].join
|
37
|
-
end
|
38
|
-
|
39
|
-
# The right-hand part of the postcode, e.g. W1A 1AA -> 1AA
|
40
|
-
#
|
41
|
-
def incode
|
42
|
-
sector && unit && [sector, unit].join
|
43
|
-
end
|
44
|
-
|
45
|
-
# The first part of the outcode, e.g. W1A 2AB -> W
|
46
|
-
#
|
47
|
-
def area
|
48
|
-
parts[0]
|
49
|
-
end
|
50
|
-
|
51
|
-
# The second part of the outcode, e.g. W1A 2AB -> 1A
|
52
|
-
#
|
53
|
-
def district
|
54
|
-
parts[1]
|
55
|
-
end
|
56
|
-
|
57
|
-
# The first part of the incode, e.g. W1A 2AB -> 2
|
58
|
-
#
|
59
|
-
def sector
|
60
|
-
parts[2]
|
61
|
-
end
|
1
|
+
require "uk_postcode/version"
|
2
|
+
require "uk_postcode/geographic_postcode"
|
3
|
+
require "uk_postcode/giro_postcode"
|
4
|
+
require "uk_postcode/invalid_postcode"
|
62
5
|
|
63
|
-
|
64
|
-
|
65
|
-
def unit
|
66
|
-
parts[3]
|
67
|
-
end
|
6
|
+
module UKPostcode
|
7
|
+
module_function
|
68
8
|
|
69
|
-
#
|
70
|
-
#
|
9
|
+
# Attempt to parse the string str as a postcode. Returns an object
|
10
|
+
# representing the postcode, or an InvalidPostcode if the string cannot be
|
11
|
+
# parsed.
|
71
12
|
#
|
72
|
-
def
|
73
|
-
[
|
74
|
-
|
75
|
-
|
76
|
-
alias_method :normalize, :norm
|
77
|
-
|
78
|
-
alias_method :to_s, :raw
|
79
|
-
alias_method :to_str, :raw
|
80
|
-
|
81
|
-
def inspect(*args)
|
82
|
-
"<#{self.class.to_s} #{raw}>"
|
83
|
-
end
|
84
|
-
|
85
|
-
private
|
86
|
-
def parts
|
87
|
-
return @parts if @matched
|
88
|
-
|
89
|
-
@matched = true
|
90
|
-
matches = raw.upcase.match(MATCH) || []
|
91
|
-
if matches[1]
|
92
|
-
@parts = %w[ G IR 0 AA ]
|
93
|
-
else
|
94
|
-
a, b, c, d = (2..5).map{ |i| matches[i] }
|
95
|
-
if a =~ /^[A-Z][I1]$/
|
96
|
-
a = a[0, 1]
|
97
|
-
b = "1" + b
|
98
|
-
end
|
99
|
-
@parts = [letters(a), digits(b), digits(c), letters(d)]
|
13
|
+
def parse(str)
|
14
|
+
[GiroPostcode, GeographicPostcode, InvalidPostcode].each do |klass|
|
15
|
+
pc = klass.parse(str)
|
16
|
+
return pc if pc
|
100
17
|
end
|
101
18
|
end
|
102
|
-
|
103
|
-
def letters(s)
|
104
|
-
s && s.tr("10", "IO")
|
105
|
-
end
|
106
|
-
|
107
|
-
def digits(s)
|
108
|
-
s && s.tr("IO", "10")
|
109
|
-
end
|
110
19
|
end
|
111
|
-
|
112
|
-
require "uk_postcode/version"
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require_relative "./test_helper"
|
2
|
+
require "uk_postcode"
|
3
|
+
|
4
|
+
describe UKPostcode do
|
5
|
+
it 'should find the country of a full postcode in England' do
|
6
|
+
UKPostcode.parse('W1A 1AA').country.must_equal :england
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'should find the country of a full postcode in Scotland' do
|
10
|
+
UKPostcode.parse('EH8 8DX').country.must_equal :scotland
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should find the country of a full postcode in Wales' do
|
14
|
+
UKPostcode.parse('CF99 1NA').country.must_equal :wales
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should find the country of a full postcode in Northern Ireland' do
|
18
|
+
UKPostcode.parse('BT4 3XX').country.must_equal :northern_ireland
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should find the country of a postcode in a border region' do
|
22
|
+
UKPostcode.parse('CA6 5HS').country.must_equal :scotland
|
23
|
+
UKPostcode.parse('CA6 5HT').country.must_equal :england
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should find the country of an unambiguous partial postcode' do
|
27
|
+
UKPostcode.parse('BT4').country.must_equal :northern_ireland
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should return :unknown for an ambiguous partial postcode' do
|
31
|
+
UKPostcode.parse('DG16').country.must_equal :unknown
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative "./test_helper"
|
2
|
+
require "csv"
|
3
|
+
require "uk_postcode"
|
4
|
+
|
5
|
+
describe "Full set of postcodes" do
|
6
|
+
CSV_PATH = File.expand_path("../data/postcodes.csv", __FILE__)
|
7
|
+
|
8
|
+
COUNTRIES = {
|
9
|
+
'E92000001' => :england,
|
10
|
+
'N92000002' => :northern_ireland,
|
11
|
+
'S92000003' => :scotland,
|
12
|
+
'W92000004' => :wales,
|
13
|
+
'L93000001' => :channel_islands,
|
14
|
+
'M83000003' => :isle_of_man
|
15
|
+
}
|
16
|
+
|
17
|
+
it "should correctly parse and find the country of every extant postcode" do
|
18
|
+
if File.exist?(CSV_PATH)
|
19
|
+
CSV.foreach(CSV_PATH, headers: [:postcode, :country]) do |row|
|
20
|
+
outcode = row[:postcode][0,4].strip
|
21
|
+
incode = row[:postcode][4,3].strip
|
22
|
+
country = COUNTRIES.fetch(row[:country])
|
23
|
+
|
24
|
+
postcode = UKPostcode.parse(outcode + incode)
|
25
|
+
|
26
|
+
postcode.wont_be_nil
|
27
|
+
postcode.outcode.must_equal outcode
|
28
|
+
postcode.incode.must_equal incode
|
29
|
+
postcode.country.must_equal country
|
30
|
+
end
|
31
|
+
else
|
32
|
+
skip "Skipping because #{CSV_PATH} does not exist"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,271 @@
|
|
1
|
+
require_relative "./test_helper"
|
2
|
+
require "uk_postcode/geographic_postcode"
|
3
|
+
|
4
|
+
describe UKPostcode::GeographicPostcode do
|
5
|
+
described_class = UKPostcode::GeographicPostcode
|
6
|
+
|
7
|
+
describe "parse" do
|
8
|
+
it "should parse a full postcode" do
|
9
|
+
pc = described_class.parse("W1A 1AA")
|
10
|
+
pc.must_be_instance_of described_class
|
11
|
+
pc.area.must_equal "W"
|
12
|
+
pc.district.must_equal "1A"
|
13
|
+
pc.sector.must_equal "1"
|
14
|
+
pc.unit.must_equal "AA"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should parse a postcode with no unit" do
|
18
|
+
pc = described_class.parse("W1A 1")
|
19
|
+
pc.must_be_instance_of described_class
|
20
|
+
pc.area.must_equal "W"
|
21
|
+
pc.district.must_equal "1A"
|
22
|
+
pc.sector.must_equal "1"
|
23
|
+
pc.unit.must_be_nil
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should parse an outcode" do
|
27
|
+
pc = described_class.parse("W1A")
|
28
|
+
pc.must_be_instance_of described_class
|
29
|
+
pc.area.must_equal "W"
|
30
|
+
pc.district.must_equal "1A"
|
31
|
+
pc.sector.must_be_nil
|
32
|
+
pc.unit.must_be_nil
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should parse an area" do
|
36
|
+
pc = described_class.parse("W")
|
37
|
+
pc.must_be_instance_of described_class
|
38
|
+
pc.area.must_equal "W"
|
39
|
+
pc.district.must_be_nil
|
40
|
+
pc.sector.must_be_nil
|
41
|
+
pc.unit.must_be_nil
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should handle extra spaces" do
|
45
|
+
pc = described_class.parse(" W1A 1AA ")
|
46
|
+
pc.must_be_instance_of described_class
|
47
|
+
pc.to_s.must_equal "W1A 1AA"
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should handle no spaces" do
|
51
|
+
pc = described_class.parse("W1A1AA")
|
52
|
+
pc.must_be_instance_of described_class
|
53
|
+
pc.to_s.must_equal "W1A 1AA"
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should be case-insensitive" do
|
57
|
+
pc = described_class.parse("w1a 1aa")
|
58
|
+
pc.must_be_instance_of described_class
|
59
|
+
pc.to_s.must_equal "W1A 1AA"
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should return nil if unable to parse" do
|
63
|
+
pc = described_class.parse("Can't parse this")
|
64
|
+
pc.must_be_nil
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "single-letter area" do
|
68
|
+
it "should extract area without trailing I from outcode" do
|
69
|
+
pc = described_class.parse("B11")
|
70
|
+
pc.area.must_equal "B"
|
71
|
+
pc.district.must_equal "11"
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should extract area without trailing I from full postcode with space" do
|
75
|
+
pc = described_class.parse("E17 1AA")
|
76
|
+
pc.area.must_equal "E"
|
77
|
+
pc.district.must_equal "17"
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should extract area without trailing I from full postcode without space" do
|
81
|
+
pc = described_class.parse("E171AA")
|
82
|
+
pc.area.must_equal "E"
|
83
|
+
pc.district.must_equal "17"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "trailing O in area" do
|
88
|
+
it "should extract area with trailing O from outcode" do
|
89
|
+
pc = described_class.parse("CO1")
|
90
|
+
pc.area.must_equal "CO"
|
91
|
+
pc.district.must_equal "1"
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should extract area with trailing O from full postcode with space" do
|
95
|
+
pc = described_class.parse("CO1 1BT")
|
96
|
+
pc.area.must_equal "CO"
|
97
|
+
pc.district.must_equal "1"
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should extract area with trailing O from full postcode without space" do
|
101
|
+
pc = described_class.parse("CO11BT")
|
102
|
+
pc.area.must_equal "CO"
|
103
|
+
pc.district.must_equal "1"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe "tricky postcodes" do
|
108
|
+
it "should parse B11 1LL" do
|
109
|
+
pc = described_class.parse("B111LL")
|
110
|
+
pc.area.must_equal "B"
|
111
|
+
pc.district.must_equal "11"
|
112
|
+
pc.sector.must_equal "1"
|
113
|
+
pc.unit.must_equal "LL"
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should parse BII ILL" do
|
117
|
+
pc = described_class.parse("BIIILL")
|
118
|
+
pc.area.must_equal "B"
|
119
|
+
pc.district.must_equal "11"
|
120
|
+
pc.sector.must_equal "1"
|
121
|
+
pc.unit.must_equal "LL"
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should parse BB11 1DJ" do
|
125
|
+
pc = described_class.parse("BB111DJ")
|
126
|
+
pc.area.must_equal "BB"
|
127
|
+
pc.district.must_equal "11"
|
128
|
+
pc.sector.must_equal "1"
|
129
|
+
pc.unit.must_equal "DJ"
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should parse BBII IDJ" do
|
133
|
+
pc = described_class.parse("BBIIIDJ")
|
134
|
+
pc.area.must_equal "BB"
|
135
|
+
pc.district.must_equal "11"
|
136
|
+
pc.sector.must_equal "1"
|
137
|
+
pc.unit.must_equal "DJ"
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should parse B10 0JP" do
|
141
|
+
pc = described_class.parse("B100JP")
|
142
|
+
pc.area.must_equal "B"
|
143
|
+
pc.district.must_equal "10"
|
144
|
+
pc.sector.must_equal "0"
|
145
|
+
pc.unit.must_equal "JP"
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should parse BIO OJP" do
|
149
|
+
pc = described_class.parse("BIOOJP")
|
150
|
+
pc.area.must_equal "B"
|
151
|
+
pc.district.must_equal "10"
|
152
|
+
pc.sector.must_equal "0"
|
153
|
+
pc.unit.must_equal "JP"
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
describe "area" do
|
159
|
+
it "should be capitalised" do
|
160
|
+
described_class.new("w", "1a", "1", "aa").area.must_equal "W"
|
161
|
+
end
|
162
|
+
|
163
|
+
it "should correct 0 to O" do
|
164
|
+
described_class.new("0X", "1", "0", "AB").area.must_equal "OX"
|
165
|
+
end
|
166
|
+
|
167
|
+
it "should correct 1 to I" do
|
168
|
+
described_class.new("1G", "1", "1", "AA").area.must_equal "IG"
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
describe "district" do
|
173
|
+
it "should be capitalised" do
|
174
|
+
described_class.new("w", "1a", "1", "aa").district.must_equal "1A"
|
175
|
+
end
|
176
|
+
|
177
|
+
it "should correct O to 0" do
|
178
|
+
described_class.new("B", "2O", "2", "XB").district.must_equal "20"
|
179
|
+
end
|
180
|
+
|
181
|
+
it "should correct I to 1" do
|
182
|
+
described_class.new("B", "I", "I", "DF").district.must_equal "1"
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
describe "sector" do
|
187
|
+
it "should correct O to 0" do
|
188
|
+
described_class.new("AB", "1", "O", "DN").sector.must_equal "0"
|
189
|
+
end
|
190
|
+
|
191
|
+
it "should correct I to 1" do
|
192
|
+
described_class.new("W", "1A", "I", "AA").sector.must_equal "1"
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
describe "unit" do
|
197
|
+
it "should be capitalised" do
|
198
|
+
described_class.new("w", "1a", "1", "aa").unit.must_equal "AA"
|
199
|
+
end
|
200
|
+
|
201
|
+
# Note: neither I nor O appear in units
|
202
|
+
end
|
203
|
+
|
204
|
+
describe "outcode" do
|
205
|
+
it "should be generated from area and district" do
|
206
|
+
described_class.new("W", "1A").outcode.must_equal "W1A"
|
207
|
+
end
|
208
|
+
|
209
|
+
it "should be nil if missing district" do
|
210
|
+
described_class.new("W").outcode.must_be_nil
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
describe "incode" do
|
215
|
+
it "should be generated from sector and unit" do
|
216
|
+
described_class.new("W", "1A", "1", "AA").incode.must_equal "1AA"
|
217
|
+
end
|
218
|
+
|
219
|
+
it "should be nil if missing sector" do
|
220
|
+
described_class.new("W", "1A").incode.must_be_nil
|
221
|
+
end
|
222
|
+
|
223
|
+
it "should be nil if missing unit" do
|
224
|
+
described_class.new("W", "1A", "1").incode.must_be_nil
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
describe "to_s" do
|
229
|
+
it "should generate a full postcode" do
|
230
|
+
described_class.new("W", "1A", "1", "AA").to_s.must_equal "W1A 1AA"
|
231
|
+
end
|
232
|
+
|
233
|
+
it "should generate an outcode" do
|
234
|
+
described_class.new("W", "1A").to_s.must_equal "W1A"
|
235
|
+
end
|
236
|
+
|
237
|
+
it "should generate a postcode with no unit" do
|
238
|
+
described_class.new("W", "1A", "1").to_s.must_equal "W1A 1"
|
239
|
+
end
|
240
|
+
|
241
|
+
it "should generate an area alone" do
|
242
|
+
described_class.new("W").to_s.must_equal "W"
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
describe "full?" do
|
247
|
+
it "should be true if outcode and incode are given" do
|
248
|
+
described_class.new("W", "1A", "1", "AA").must_be :full?
|
249
|
+
end
|
250
|
+
|
251
|
+
it "should not be true if something is missing" do
|
252
|
+
described_class.new("W", "1A", "1").wont_be :full?
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
describe "valid?" do
|
257
|
+
it "should be true" do
|
258
|
+
described_class.new("W", "1A", "1", "AA").must_be :valid?
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
describe "country" do
|
263
|
+
it "should look up the country of a full postcode" do
|
264
|
+
described_class.new("EH", "8", "8", "DX").country.must_equal :scotland
|
265
|
+
end
|
266
|
+
|
267
|
+
it "should look up the country of a partial postcode" do
|
268
|
+
described_class.new("W", "1A").country.must_equal :england
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require_relative "./test_helper"
|
2
|
+
require "uk_postcode/giro_postcode"
|
3
|
+
|
4
|
+
describe UKPostcode::GiroPostcode do
|
5
|
+
described_class = UKPostcode::GiroPostcode
|
6
|
+
|
7
|
+
let(:subject) { described_class.instance }
|
8
|
+
|
9
|
+
describe "parse" do
|
10
|
+
it "should parse the canonical form" do
|
11
|
+
pc = described_class.parse("GIR 0AA")
|
12
|
+
pc.must_be_instance_of described_class
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should parse transcribed 0/O and 1/I" do
|
16
|
+
pc = described_class.parse("G1R OAA")
|
17
|
+
pc.must_be_instance_of described_class
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should handle extra spaces" do
|
21
|
+
pc = described_class.parse(" GIR 0AA ")
|
22
|
+
pc.must_be_instance_of described_class
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should handle no spaces" do
|
26
|
+
pc = described_class.parse("GIR0AA")
|
27
|
+
pc.must_be_instance_of described_class
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should be case-insensitive" do
|
31
|
+
pc = described_class.parse("gir 0aa")
|
32
|
+
pc.must_be_instance_of described_class
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should return nil if unable to parse" do
|
36
|
+
pc = described_class.parse("Can't parse this")
|
37
|
+
pc.must_be_nil
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "area" do
|
42
|
+
it "should be nil" do
|
43
|
+
subject.area.must_be_nil
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "district" do
|
48
|
+
it "should be nil" do
|
49
|
+
subject.district.must_be_nil
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "sector" do
|
54
|
+
it "should be nil" do
|
55
|
+
subject.sector.must_be_nil
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "unit" do
|
60
|
+
it "should be nil" do
|
61
|
+
subject.unit.must_be_nil
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "outcode" do
|
66
|
+
it "should be GIR" do
|
67
|
+
subject.outcode.must_equal("GIR")
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "incode" do
|
72
|
+
it "should be 0AA" do
|
73
|
+
subject.incode.must_equal("0AA")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "to_s" do
|
78
|
+
it "should be the canonical form" do
|
79
|
+
subject.to_s.must_equal "GIR 0AA"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "full?" do
|
84
|
+
it "should be true" do
|
85
|
+
subject.must_be :full?
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "valid?" do
|
90
|
+
it "should be true" do
|
91
|
+
subject.must_be :valid?
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "country" do
|
96
|
+
it "should be England" do
|
97
|
+
subject.country.must_equal :england
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require_relative "./test_helper"
|
2
|
+
require "uk_postcode/invalid_postcode"
|
3
|
+
|
4
|
+
describe UKPostcode::InvalidPostcode do
|
5
|
+
described_class = UKPostcode::InvalidPostcode
|
6
|
+
|
7
|
+
let(:subject) { described_class.new("anything") }
|
8
|
+
|
9
|
+
describe "parse" do
|
10
|
+
it "should parse anything" do
|
11
|
+
pc = described_class.parse("Any old junk")
|
12
|
+
pc.must_be_instance_of described_class
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "area" do
|
17
|
+
it "should be nil" do
|
18
|
+
subject.area.must_be_nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "district" do
|
23
|
+
it "should be nil" do
|
24
|
+
subject.district.must_be_nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "sector" do
|
29
|
+
it "should be nil" do
|
30
|
+
subject.sector.must_be_nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "unit" do
|
35
|
+
it "should be nil" do
|
36
|
+
subject.unit.must_be_nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "outcode" do
|
41
|
+
it "should be nil" do
|
42
|
+
subject.outcode.must_be_nil
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "incode" do
|
47
|
+
it "should be nil" do
|
48
|
+
subject.incode.must_be_nil
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "to_s" do
|
53
|
+
it "should return the initialisation string" do
|
54
|
+
subject.to_s.must_equal "anything"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "full?" do
|
59
|
+
it "should be false" do
|
60
|
+
subject.wont_be :full?
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "valid?" do
|
65
|
+
it "should be false" do
|
66
|
+
subject.wont_be :valid?
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "country" do
|
71
|
+
it "should be unknown" do
|
72
|
+
subject.country.must_equal :unknown
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require_relative "./test_helper"
|
2
|
+
require "uk_postcode"
|
3
|
+
|
4
|
+
describe "Special postcodes" do
|
5
|
+
# Special postcodes listed in http://en.wikipedia.org/wiki/UK_postcode
|
6
|
+
SPECIAL = %w[
|
7
|
+
SW1A 0AA
|
8
|
+
SW1A 1AA
|
9
|
+
SW1A 2AA
|
10
|
+
BS98 1TL
|
11
|
+
BX1 1LT
|
12
|
+
BX5 5AT
|
13
|
+
CF99 1NA
|
14
|
+
DH99 1NS
|
15
|
+
E16 1XL
|
16
|
+
E98 1NW
|
17
|
+
E98 1SN
|
18
|
+
E98 1ST
|
19
|
+
E98 1TT
|
20
|
+
EC4Y 0HQ
|
21
|
+
EH99 1SP
|
22
|
+
EN8 9SL
|
23
|
+
G58 1SB
|
24
|
+
GIR 0AA
|
25
|
+
L30 4GB
|
26
|
+
LS98 1FD
|
27
|
+
M2 5BE
|
28
|
+
N81 1ER
|
29
|
+
S2 4SU
|
30
|
+
S6 1SW
|
31
|
+
SE1 8UJ
|
32
|
+
SE9 2UG
|
33
|
+
SN38 1NW
|
34
|
+
SW1A 0PW
|
35
|
+
SW1A 2HQ
|
36
|
+
SW1W 0DT
|
37
|
+
TS1 3BA
|
38
|
+
W1A 1AA
|
39
|
+
W1F 9DJ
|
40
|
+
]
|
41
|
+
|
42
|
+
SPECIAL.each_slice(2) do |outcode, incode|
|
43
|
+
it "should correctly handle special postcode #{outcode} #{incode}" do
|
44
|
+
postcode = UKPostcode.parse(outcode + incode)
|
45
|
+
postcode.wont_be_nil
|
46
|
+
postcode.outcode.must_equal outcode
|
47
|
+
postcode.incode.must_equal incode
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|