uk_postcode 0.0.1

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/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
+