uk_postcode 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,34 @@
1
+ uk_postcode
2
+ ===========
3
+
4
+ UK postcode parsing and validation for Ruby.
5
+
6
+ Usage
7
+ -----
8
+
9
+ require "uk_postcode"
10
+
11
+ Validate and extract sections of a full postcode:
12
+
13
+ pc = UKPostcode.new("W1A 1AA")
14
+ pc.valid? #=> true
15
+ pc.full? #=> true
16
+ pc.outcode #=> "W1A"
17
+ pc.incode #=> "1AA"
18
+
19
+ Or of a partial postcode:
20
+
21
+ pc = UKPostcode.new("W1A")
22
+ pc.valid? #=> true
23
+ pc.full? #=> false
24
+ pc.outcode #=> "W1A"
25
+ pc.incode #=> nil
26
+
27
+ Normalise postcodes:
28
+
29
+ UKPostcode.new("w1a1aa").to_str #=> "W1A 1AA"
30
+
31
+ Gem?
32
+ ----
33
+
34
+ gem install uk_postcode
data/Rakefile ADDED
@@ -0,0 +1,44 @@
1
+ require "rubygems"
2
+ require "rake/gempackagetask"
3
+ require "rake/testtask"
4
+
5
+ task :default => [:test]
6
+
7
+ Rake::TestTask.new("test") do |t|
8
+ t.libs << "test"
9
+ t.pattern = "test/**/test_*.rb"
10
+ t.verbose = true
11
+ end
12
+
13
+ task :default => :test
14
+
15
+ require "rake/testtask"
16
+ Rake::TestTask.new do |t|
17
+ t.libs << "test"
18
+ t.test_files = FileList["test/**/*_test.rb"]
19
+ t.verbose = true
20
+ end
21
+
22
+ spec = Gem::Specification.new do |s|
23
+ s.name = "uk_postcode"
24
+ s.version = "0.0.1"
25
+ s.summary = "UK postcode parsing and validation"
26
+ s.author = "Paul Battley"
27
+ s.email = "pbattley@gmail.com"
28
+
29
+ s.has_rdoc = true
30
+
31
+ s.files = %w(Rakefile README.md) + Dir.glob("{bin,test,lib}/**/*")
32
+ s.executables = FileList["bin/**"].map { |f| File.basename(f) }
33
+
34
+ s.require_paths = ["lib"]
35
+
36
+ s.add_development_dependency("thoughtbot-shoulda")
37
+ end
38
+
39
+ Rake::GemPackageTask.new(spec) do |pkg|
40
+ pkg.gem_spec = spec
41
+ end
42
+
43
+ desc 'Clear out generated packages'
44
+ task :clean => [:clobber_package]
@@ -0,0 +1,46 @@
1
+ class UKPostcode
2
+ RE_OUTCODE = /[A-Z]{1,2}[0-9R][0-9A-Z]?/
3
+ RE_INCODE = /[0-9][ABD-HJLNP-UW-Z]{2}/
4
+ RE_OUTCODE_ONLY = /\A(#{RE_OUTCODE})\Z/
5
+ RE_FULL = /\A(#{RE_OUTCODE}) ?(#{RE_INCODE})\Z/
6
+
7
+ attr_reader :raw
8
+
9
+ # Initialise a new UKPostcode instance from the given postcode string
10
+ #
11
+ def initialize(postcode_as_string)
12
+ @raw = postcode_as_string.upcase
13
+ end
14
+
15
+ # Returns true if the postcode is a valid full postcode (e.g. W1A 1AA) or outcode (e.g. W1A)
16
+ #
17
+ def valid?
18
+ raw.match(RE_FULL) || raw.match(RE_OUTCODE_ONLY)
19
+ end
20
+
21
+ # Returns true if the postcode is a valid full postcode (e.g. W1A 1AA)
22
+ #
23
+ def full?
24
+ raw.match(RE_FULL)
25
+ end
26
+
27
+ # The left-hand part of the postcode, e.g. W1A 1AA -> W1A
28
+ #
29
+ def outcode
30
+ raw[RE_FULL, 1] || raw[RE_OUTCODE_ONLY]
31
+ end
32
+
33
+ # The right-hand part of the postcode, e.g. W1A 1AA -> 1AA
34
+ #
35
+ def incode
36
+ raw[RE_FULL, 2]
37
+ end
38
+
39
+ # Render the postcode as a normalised string, i.e. in upper case and with spacing.
40
+ # Returns an empty string if the postcode is not valid.
41
+ #
42
+ def to_str
43
+ [outcode, incode].compact.join(" ")
44
+ end
45
+ alias_method :to_s, :to_str
46
+ end
@@ -0,0 +1,174 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), "..", "lib")
2
+ require "test/unit"
3
+ require "shoulda"
4
+ require "uk_postcode"
5
+
6
+ class UKPostcodeTest < Test::Unit::TestCase
7
+
8
+ VALID_SAMPLES = [ "A9 9AA", "A99 9AA", "AA9 9AA", "AA99 9AA", "A9A 9AA", "AA9A 9AA",
9
+ "SW1A 0AA", "SW1A 0PW", "SW1A 1AA", "SW1A 2HQ", "W1A 1AA", "W1A 1AB",
10
+ "N81 1ER", "EH99 1SP" ]
11
+ VALID_OUTCODES = VALID_SAMPLES.map{ |s| s.split(/\s/).first }
12
+ VALID_INCODES = VALID_SAMPLES.map{ |s| s.split(/\s/).last }
13
+
14
+ context "full samples with spaces" do
15
+ setup do
16
+ @samples = VALID_SAMPLES
17
+ end
18
+
19
+ should "all be valid" do
20
+ @samples.each do |sample|
21
+ assert UKPostcode.new(sample).valid?, "'#{sample}' should be valid"
22
+ end
23
+ end
24
+
25
+ should "all be full" do
26
+ @samples.each do |sample|
27
+ assert UKPostcode.new(sample).full?, "'#{sample}' should be full"
28
+ end
29
+ end
30
+
31
+ should "extract outcodes" do
32
+ @samples.zip(VALID_OUTCODES).each do |sample, outcode|
33
+ assert_equal outcode, UKPostcode.new(sample).outcode
34
+ end
35
+ end
36
+
37
+ should "extract incodes" do
38
+ @samples.zip(VALID_INCODES).each do |sample, incode|
39
+ assert_equal incode, UKPostcode.new(sample).incode
40
+ end
41
+ end
42
+ end
43
+
44
+ context "full samples without spaces" do
45
+ setup do
46
+ @samples = VALID_SAMPLES.map{ |s| s.sub(/\s/, "") }
47
+ end
48
+
49
+ should "all be valid" do
50
+ @samples.each do |sample|
51
+ assert UKPostcode.new(sample).valid?, "'#{sample}' should be valid"
52
+ end
53
+ end
54
+
55
+ should "all be full" do
56
+ @samples.each do |sample|
57
+ assert UKPostcode.new(sample).full?, "'#{sample}' should be full"
58
+ end
59
+ end
60
+
61
+ should "extract outcodes" do
62
+ @samples.zip(VALID_OUTCODES).each do |sample, outcode|
63
+ assert_equal outcode, UKPostcode.new(sample).outcode
64
+ end
65
+ end
66
+
67
+ should "extract incodes" do
68
+ @samples.zip(VALID_INCODES).each do |sample, incode|
69
+ assert_equal incode, UKPostcode.new(sample).incode
70
+ end
71
+ end
72
+ end
73
+
74
+ context "outcode samples" do
75
+ setup do
76
+ @samples = VALID_OUTCODES
77
+ end
78
+
79
+ should "all be valid" do
80
+ @samples.each do |sample|
81
+ assert UKPostcode.new(sample).valid?, "'#{sample}' should be valid"
82
+ end
83
+ end
84
+
85
+ should "not be full" do
86
+ @samples.each do |sample|
87
+ assert !UKPostcode.new(sample).full?, "'#{sample}' should not be full"
88
+ end
89
+ end
90
+
91
+ should "keep outcode unchanged" do
92
+ @samples.each do |sample|
93
+ assert_equal sample, UKPostcode.new(sample).outcode
94
+ end
95
+ end
96
+
97
+ should "have nil incode" do
98
+ @samples.each do |sample|
99
+ assert_nil UKPostcode.new(sample).incode
100
+ end
101
+ end
102
+ end
103
+
104
+ context "when the postcode is supplied in lower case" do
105
+ setup do
106
+ @postcode = UKPostcode.new("w1a 1aa")
107
+ end
108
+
109
+ should "extract outcode in upper case" do
110
+ assert_equal "W1A", @postcode.outcode
111
+ end
112
+
113
+ should "extract incode in upper case" do
114
+ assert_equal "1AA", @postcode.incode
115
+ end
116
+
117
+ should "be valid" do
118
+ assert @postcode.valid?
119
+ end
120
+ end
121
+
122
+ { "when the postcode is blank" => "",
123
+ "when the incode is truncated" => "W1A 1A",
124
+ "when the outcode is truncated" => "W",
125
+ "when the postcode is invalid" => "ABC DEFG"
126
+ }.each do |desc, sample|
127
+ context desc do
128
+ setup do
129
+ @postcode = UKPostcode.new(sample)
130
+ end
131
+
132
+ should "not be valid" do
133
+ assert !@postcode.valid?
134
+ end
135
+
136
+ should "not be full" do
137
+ assert !@postcode.full?
138
+ end
139
+
140
+ should "return an empty string for to_str" do
141
+ assert_equal "", @postcode.to_str
142
+ end
143
+
144
+ should "return nil for outcode" do
145
+ assert_nil @postcode.outcode
146
+ end
147
+
148
+ should "return nil for incode" do
149
+ assert_nil @postcode.incode
150
+ end
151
+ end
152
+ end
153
+
154
+ context "when used as a string" do
155
+ should "normalise spacing" do
156
+ assert_equal "W1A 1AA", UKPostcode.new("W1A1AA").to_str
157
+ end
158
+
159
+ should "convert case" do
160
+ assert_equal "W1A 1AA", UKPostcode.new("w1a 1aa").to_str
161
+ end
162
+
163
+ should "ignore a missing incode" do
164
+ assert_equal "W1A", UKPostcode.new("W1A").to_str
165
+ end
166
+ end
167
+
168
+ should "have same output for to_s and to_str" do
169
+ ["W1A1AA", "w1a 1aa", "W1A"].each do |s|
170
+ postcode = UKPostcode.new(s)
171
+ assert_equal s.to_str, s.to_s
172
+ end
173
+ end
174
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: uk_postcode
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Paul Battley
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-01-06 00:00:00 +00:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: thoughtbot-shoulda
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ description:
26
+ email: pbattley@gmail.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files: []
32
+
33
+ files:
34
+ - Rakefile
35
+ - README.md
36
+ - test/test_uk_postcode.rb
37
+ - lib/uk_postcode.rb
38
+ has_rdoc: true
39
+ homepage:
40
+ licenses: []
41
+
42
+ post_install_message:
43
+ rdoc_options: []
44
+
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ version:
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ version:
59
+ requirements: []
60
+
61
+ rubyforge_project:
62
+ rubygems_version: 1.3.5
63
+ signing_key:
64
+ specification_version: 3
65
+ summary: UK postcode parsing and validation
66
+ test_files: []
67
+