validates_as_uk_postcode 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.mdown ADDED
@@ -0,0 +1,54 @@
1
+ # Validates As UK Postcode (version 2.0)
2
+
3
+ This Ruby on Rails plugin implements an ActiveRecord validation macro to allow validating of UK Postcodes. It is based on the following regular expression.
4
+
5
+ http://www.govtalk.gov.uk/gdsc/html/frames/PostCode.htm
6
+
7
+ ## Installation
8
+
9
+ gem install validates_as_uk_postcode
10
+
11
+ ### Rails 2.x
12
+
13
+ # environment.rb
14
+ config.gem "validates_as_uk_postcode"
15
+
16
+ ### Rails 3
17
+
18
+ # Gemfile
19
+ gem "validates_as_uk_postcode"
20
+
21
+ ## Usage
22
+
23
+
24
+ ### Rails 2.x
25
+
26
+ class MyClass < ActiveRecord::Base
27
+ validates_as_uk_postcode :postcode
28
+ end
29
+
30
+ ### Rails 3
31
+
32
+ class MyClass < ActiveRecord::Base
33
+ validates :postcode, :uk_postcode => true
34
+ end
35
+
36
+ ## Authors
37
+
38
+ **Stephen Rushe** - http://deeden.co.uk
39
+ **Dan Kubb** - http://autopilotmarketing.com
40
+ **David Rice** - http://davidjrice.co.uk
41
+
42
+ ## License
43
+
44
+
45
+ This code is released under a Creative Commons Attribution-Share Alike
46
+ 3.0 Unported License. The license can be seen here:
47
+
48
+ http://creativecommons.org/licenses/by-sa/3.0/
49
+
50
+ The original version of the code (see History) was released under the
51
+ Creative Commons Attribution-Share Alike 2.5 License, which can be seen
52
+ at:
53
+
54
+ http://creativecommons.org/licenses/by-sa/2.5/
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'validates_as_uk_postcode'
data/lib/rails2.rb ADDED
@@ -0,0 +1,27 @@
1
+ module ValidatesAsUKPostcode
2
+ module Postcodes
3
+ UK = begin
4
+ an_naa_or_ann_naa = '^[A-PR-UWYZ]{1}\d{1,2}\s?\d[ABD-HJLNP-UWXYZ]{2}$'
5
+ aan_naa_or_aann_naa = '^[A-PR-UWYZ]{1}[A-HK-Y]{1}\d{1,2}\s?\d[ABD-HJLNP-UWXYZ]{2}$'
6
+ ana_naa = '^[A-PR-UWYZ]{1}\d[A-HJKSTUW]{1}\s?\d[ABD-HJLNP-UWXYZ]{2}$'
7
+ aana_naa = '^[A-PR-UWYZ]{1}[A-HK-Y]{1}\d[ABEHMNPRVWXY]{1}\s?\d[ABD-HJLNP-UWXYZ]{2}$'
8
+ historic_code="GIR\s?0AA"
9
+ postcode_spec = "#{an_naa_or_ann_naa}|#{aan_naa_or_aann_naa}|#{ana_naa}|#{aana_naa}|#{historic_code}"
10
+ pattern = /#{postcode_spec}/i
11
+ end
12
+ end
13
+
14
+ module Rails2
15
+
16
+ def validates_as_uk_postcode(*attr_names)
17
+ configuration = {
18
+ :message => 'is an invalid uk postcode',
19
+ :with => Postcodes::UK,
20
+ :allow_nil => true }
21
+ configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
22
+
23
+ validates_format_of attr_names, configuration
24
+ end
25
+
26
+ end
27
+ end
data/lib/rails3.rb ADDED
@@ -0,0 +1,27 @@
1
+ require 'active_support/concern'
2
+ require 'active_model'
3
+
4
+ module ValidatesAsUKPostcode
5
+ module Postcodes
6
+ UK = begin
7
+ an_naa_or_ann_naa = '^[A-PR-UWYZ]{1}\d{1,2}\s?\d[ABD-HJLNP-UWXYZ]{2}$'
8
+ aan_naa_or_aann_naa = '^[A-PR-UWYZ]{1}[A-HK-Y]{1}\d{1,2}\s?\d[ABD-HJLNP-UWXYZ]{2}$'
9
+ ana_naa = '^[A-PR-UWYZ]{1}\d[A-HJKSTUW]{1}\s?\d[ABD-HJLNP-UWXYZ]{2}$'
10
+ aana_naa = '^[A-PR-UWYZ]{1}[A-HK-Y]{1}\d[ABEHMNPRVWXY]{1}\s?\d[ABD-HJLNP-UWXYZ]{2}$'
11
+ historic_code="GIR\s?0AA"
12
+ postcode_spec = "#{an_naa_or_ann_naa}|#{aan_naa_or_aann_naa}|#{ana_naa}|#{aana_naa}|#{historic_code}"
13
+ pattern = /#{postcode_spec}/i
14
+ end
15
+ end
16
+
17
+ module Rails3
18
+ extend ActiveSupport::Concern
19
+
20
+ class PostcodeValidator < ActiveModel::EachValidator
21
+ def validate_each(object, attribute, value)
22
+ object.errors.add(attribute, "is an invalid UK postcode") unless value =~ Postcodes::UK
23
+ end
24
+ end
25
+ end
26
+
27
+ end
@@ -0,0 +1,7 @@
1
+ if Rails::VERSION::MAJOR >= 3
2
+ require 'rails3'
3
+ ActiveRecord::Base.send(:include, ValidatesAsUKPostcode::Rails3)
4
+ else
5
+ require 'rails2'
6
+ ActiveRecord::Base.send(:extend, ValidatesAsUKPostcode::Rails2)
7
+ end
@@ -0,0 +1,5 @@
1
+ class AbstractModel < ActiveRecord::Base
2
+
3
+ validates_as_uk_postcode :postcode
4
+
5
+ end
@@ -0,0 +1,20 @@
1
+ require 'rubygems'
2
+
3
+ gem 'rails', '2.3.8'
4
+
5
+ require 'sqlite3'
6
+ require 'test/unit'
7
+ require 'active_record'
8
+ require 'active_record/base'
9
+
10
+ ActiveRecord::Migration.verbose = false
11
+ ActiveRecord::Base.establish_connection(
12
+ "adapter" => "sqlite3",
13
+ "database" => ":memory:"
14
+ )
15
+
16
+ require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'rails2.rb')
17
+
18
+ ActiveRecord::Base.send(:extend, ValidatesAsUKPostcode::Rails2)
19
+
20
+ autoload :AbstractModel, File.join(File.dirname(__FILE__), 'models', 'abstract_model.rb')
@@ -0,0 +1,69 @@
1
+ require 'test_helper.rb'
2
+
3
+ class ValidatesAsUkPostcodeTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ ActiveRecord::Schema.define(:version => 1) do
7
+ create_table :abstract_models, :force => true do |t|
8
+ t.string :postcode
9
+ end
10
+ end
11
+ end
12
+
13
+ def teardown
14
+ ActiveRecord::Base.connection.drop_table(:abstract_models)
15
+ end
16
+
17
+ def test_invalid_postcodes
18
+ postcodes = [
19
+ 'Q1 1AA', 'V1 1AA', 'X1 1AA', 'M1 CAA', 'M1 IAA', 'M1 KAA', 'M1 MAA', 'M1 OAA', 'M1 VAA',
20
+
21
+ 'Q60 1NW', 'V60 1NW', 'X60 1NW', 'M60 1CW', 'M60 1IW', 'M60 1KW', 'M60 1MW', 'M60 1OW',
22
+ 'M60 1VW', 'M60 1NC', 'M60 1NI', 'M60 1NK', 'M60 1NM', 'M60 1NO', 'M60 1NV',
23
+
24
+ 'QR2 6XH', 'VR2 6XH', 'XR2 6XH', 'CI2 6XH', 'CJ2 6XH', 'CZ2 6XH', 'CR2 6CH', 'CR2 6IH',
25
+ 'CR2 6KH', 'CR2 6MH', 'CR2 6OH', 'CR2 6VH', 'CR2 6XC', 'CR2 6XI', 'CR2 6XK', 'CR2 6XM',
26
+ 'CR2 6XO', 'CR2 6XV',
27
+
28
+ 'QN55 1PT', 'VN55 1PT', 'XN55 1PT', 'DI55 1PT', 'DJ55 1PT', 'DZ55 1PT', 'DN55 1CT',
29
+ 'DN55 1IT', 'DN55 1KT', 'DN55 1MT', 'DN55 1OT', 'DN55 1VT', 'DN55 1PC', 'DN55 1PI',
30
+ 'DN55 1PK', 'DN55 1PM', 'DN55 1PO', 'DN55 1PV',
31
+
32
+ 'Q1A 1HQ', 'V1A 1HQ', 'X1A 1HQ', 'W1I 1HQ', 'W1L 1HQ', 'W1M 1HQ', 'W1N 1HQ', 'W1O 1HQ',
33
+ 'W1P 1HQ', 'W1Q 1HQ', 'W1R 1HQ', 'W1V 1HQ', 'W1X 1HQ', 'W1Y 1HQ', 'W1Z 1HQ', 'W1A 1CQ',
34
+ 'W1A 1IQ', 'W1A 1KQ', 'W1A 1MQ', 'W1A 1OQ', 'W1A 1VQ', 'W1A 1HC', 'W1A 1HI', 'W1A 1HK',
35
+ 'W1A 1HM', 'W1A 1HO', 'W1A 1HV',
36
+
37
+ 'QC1A 1BB', 'VC1A 1BB', 'XC1A 1BB', 'EI1A 1BB', 'EJ1A 1BB', 'EZ1A 1BB', 'EC1C 1BB',
38
+ 'EC1D 1BB', 'EC1F 1BB', 'EC1G 1BB', 'EC1I 1BB', 'EC1J 1BB', 'EC1K 1BB', 'EC1L 1BB',
39
+ 'EC1O 1BB', 'EC1Q 1BB', 'EC1S 1BB', 'EC1T 1BB', 'EC1U 1BB', 'EC1Z 1BB', 'EC1A 1IB',
40
+ 'EC1A 1MB', 'EC1A 1OB', 'EC1A 1VB', 'EC1A 1BC', 'EC1A 1BI', 'EC1A 1BK', 'EC1A 1BM',
41
+ 'EC1A 1BO', 'EC1A 1BV',
42
+ ]
43
+ postcodes.each do |postcode|
44
+ assert !AbstractModel.new(:postcode => postcode).valid?, "#{postcode} should be illegal."
45
+ assert !AbstractModel.new(:postcode => postcode.downcase).valid?, "#{postcode.downcase} should be illegal."
46
+ assert !AbstractModel.new(:postcode => postcode.gsub(' ', '')).valid?, "#{postcode} (with no spaces) should be illegal."
47
+ assert !AbstractModel.new(:postcode => postcode.downcase.gsub(' ', '')).valid?, "#{postcode.downcase} (with no spaces) should be illegal."
48
+ end
49
+ end
50
+
51
+ def test_valid_postcodes
52
+ postcodes = [
53
+ 'M1 1AA',
54
+ 'M60 1NW',
55
+ 'CR2 6XH',
56
+ 'DN55 1PT',
57
+ 'W1A 1HQ',
58
+ 'EC1A 1BB',
59
+ 'BT9 7JL',
60
+ 'GIR 0AA',
61
+ ]
62
+ postcodes.each do |postcode|
63
+ assert AbstractModel.new(:postcode => postcode).valid?, "#{postcode} should be legal."
64
+ assert AbstractModel.new(:postcode => postcode.downcase).valid?, "#{postcode.downcase} should be legal."
65
+ assert AbstractModel.new(:postcode => postcode.gsub(' ', '')).valid?, "#{postcode} (with no spaces) should be legal."
66
+ assert AbstractModel.new(:postcode => postcode.downcase.gsub(' ', '')).valid?, "#{postcode.downcase} (with no spaces) should be legal."
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,5 @@
1
+ class AbstractModel < ActiveRecord::Base
2
+
3
+ validates :postcode, :postcode => true
4
+
5
+ end
@@ -0,0 +1,20 @@
1
+ require 'rubygems'
2
+
3
+ gem 'rails', '3.0.5'
4
+
5
+ require 'sqlite3'
6
+ require 'test/unit'
7
+ require 'active_record'
8
+ require 'active_record/base'
9
+
10
+ ActiveRecord::Migration.verbose = false
11
+ ActiveRecord::Base.establish_connection(
12
+ "adapter" => "sqlite3",
13
+ "database" => ":memory:"
14
+ )
15
+
16
+ require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'rails3.rb')
17
+
18
+ ActiveRecord::Base.send(:include, ValidatesAsUKPostcode::Rails3)
19
+
20
+ autoload :AbstractModel, File.join(File.dirname(__FILE__), 'models', 'abstract_model.rb')
@@ -0,0 +1,69 @@
1
+ require 'test_helper.rb'
2
+
3
+ class ValidatesAsUkPostcodeTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ ActiveRecord::Schema.define(:version => 1) do
7
+ create_table :abstract_models, :force => true do |t|
8
+ t.string :postcode
9
+ end
10
+ end
11
+ end
12
+
13
+ def teardown
14
+ ActiveRecord::Base.connection.drop_table(:abstract_models)
15
+ end
16
+
17
+ def test_invalid_postcodes
18
+ postcodes = [
19
+ 'Q1 1AA', 'V1 1AA', 'X1 1AA', 'M1 CAA', 'M1 IAA', 'M1 KAA', 'M1 MAA', 'M1 OAA', 'M1 VAA',
20
+
21
+ 'Q60 1NW', 'V60 1NW', 'X60 1NW', 'M60 1CW', 'M60 1IW', 'M60 1KW', 'M60 1MW', 'M60 1OW',
22
+ 'M60 1VW', 'M60 1NC', 'M60 1NI', 'M60 1NK', 'M60 1NM', 'M60 1NO', 'M60 1NV',
23
+
24
+ 'QR2 6XH', 'VR2 6XH', 'XR2 6XH', 'CI2 6XH', 'CJ2 6XH', 'CZ2 6XH', 'CR2 6CH', 'CR2 6IH',
25
+ 'CR2 6KH', 'CR2 6MH', 'CR2 6OH', 'CR2 6VH', 'CR2 6XC', 'CR2 6XI', 'CR2 6XK', 'CR2 6XM',
26
+ 'CR2 6XO', 'CR2 6XV',
27
+
28
+ 'QN55 1PT', 'VN55 1PT', 'XN55 1PT', 'DI55 1PT', 'DJ55 1PT', 'DZ55 1PT', 'DN55 1CT',
29
+ 'DN55 1IT', 'DN55 1KT', 'DN55 1MT', 'DN55 1OT', 'DN55 1VT', 'DN55 1PC', 'DN55 1PI',
30
+ 'DN55 1PK', 'DN55 1PM', 'DN55 1PO', 'DN55 1PV',
31
+
32
+ 'Q1A 1HQ', 'V1A 1HQ', 'X1A 1HQ', 'W1I 1HQ', 'W1L 1HQ', 'W1M 1HQ', 'W1N 1HQ', 'W1O 1HQ',
33
+ 'W1P 1HQ', 'W1Q 1HQ', 'W1R 1HQ', 'W1V 1HQ', 'W1X 1HQ', 'W1Y 1HQ', 'W1Z 1HQ', 'W1A 1CQ',
34
+ 'W1A 1IQ', 'W1A 1KQ', 'W1A 1MQ', 'W1A 1OQ', 'W1A 1VQ', 'W1A 1HC', 'W1A 1HI', 'W1A 1HK',
35
+ 'W1A 1HM', 'W1A 1HO', 'W1A 1HV',
36
+
37
+ 'QC1A 1BB', 'VC1A 1BB', 'XC1A 1BB', 'EI1A 1BB', 'EJ1A 1BB', 'EZ1A 1BB', 'EC1C 1BB',
38
+ 'EC1D 1BB', 'EC1F 1BB', 'EC1G 1BB', 'EC1I 1BB', 'EC1J 1BB', 'EC1K 1BB', 'EC1L 1BB',
39
+ 'EC1O 1BB', 'EC1Q 1BB', 'EC1S 1BB', 'EC1T 1BB', 'EC1U 1BB', 'EC1Z 1BB', 'EC1A 1IB',
40
+ 'EC1A 1MB', 'EC1A 1OB', 'EC1A 1VB', 'EC1A 1BC', 'EC1A 1BI', 'EC1A 1BK', 'EC1A 1BM',
41
+ 'EC1A 1BO', 'EC1A 1BV',
42
+ ]
43
+ postcodes.each do |postcode|
44
+ assert !AbstractModel.new(:postcode => postcode).valid?, "#{postcode} should be illegal."
45
+ assert !AbstractModel.new(:postcode => postcode.downcase).valid?, "#{postcode.downcase} should be illegal."
46
+ assert !AbstractModel.new(:postcode => postcode.gsub(' ', '')).valid?, "#{postcode} (with no spaces) should be illegal."
47
+ assert !AbstractModel.new(:postcode => postcode.downcase.gsub(' ', '')).valid?, "#{postcode.downcase} (with no spaces) should be illegal."
48
+ end
49
+ end
50
+
51
+ def test_valid_postcodes
52
+ postcodes = [
53
+ 'M1 1AA',
54
+ 'M60 1NW',
55
+ 'CR2 6XH',
56
+ 'DN55 1PT',
57
+ 'W1A 1HQ',
58
+ 'EC1A 1BB',
59
+ 'BT9 7JL',
60
+ 'GIR 0AA',
61
+ ]
62
+ postcodes.each do |postcode|
63
+ assert AbstractModel.new(:postcode => postcode).valid?, "#{postcode} should be legal."
64
+ assert AbstractModel.new(:postcode => postcode.downcase).valid?, "#{postcode.downcase} should be legal."
65
+ assert AbstractModel.new(:postcode => postcode.gsub(' ', '')).valid?, "#{postcode} (with no spaces) should be legal."
66
+ assert AbstractModel.new(:postcode => postcode.downcase.gsub(' ', '')).valid?, "#{postcode.downcase} (with no spaces) should be legal."
67
+ end
68
+ end
69
+ end
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: validates_as_uk_postcode
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 2
7
+ - 0
8
+ - 1
9
+ version: 2.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Steven Rushe
13
+ - David Rice
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-04-12 00:00:00 +01:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: A library for validating uk postcodes
23
+ email:
24
+ - me@davidjrice.co.uk
25
+ executables: []
26
+
27
+ extensions: []
28
+
29
+ extra_rdoc_files:
30
+ - README.mdown
31
+ files:
32
+ - init.rb
33
+ - lib/rails2.rb
34
+ - lib/rails3.rb
35
+ - lib/validates_as_uk_postcode.rb
36
+ - README.mdown
37
+ has_rdoc: true
38
+ homepage: http://github.com/davidjrice/validates_as_uk_postcode
39
+ licenses: []
40
+
41
+ post_install_message:
42
+ rdoc_options:
43
+ - --charset=UTF-8
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ segments:
51
+ - 0
52
+ version: "0"
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ segments:
58
+ - 0
59
+ version: "0"
60
+ requirements: []
61
+
62
+ rubyforge_project:
63
+ rubygems_version: 1.3.6
64
+ signing_key:
65
+ specification_version: 3
66
+ summary: Validates a field is a valid UK postcode
67
+ test_files:
68
+ - test/rails2/models/abstract_model.rb
69
+ - test/rails2/test_helper.rb
70
+ - test/rails2/validates_as_uk_postcode_test.rb
71
+ - test/rails3/models/abstract_model.rb
72
+ - test/rails3/test_helper.rb
73
+ - test/rails3/validates_as_uk_postcode_test.rb