postcode_validator 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 50a88a5da088eaac70d238ecb58e5b71ff66659b
4
+ data.tar.gz: 780447807f194f0935efdd21c2aaf62c8d0a331a
5
+ SHA512:
6
+ metadata.gz: 9439a870c7659fdc4796d92bb3927f1d4cf6d58906d677d072360e9a5451151a0b21ad2114ec5a26a7caba17e09c0b5475bfd534d04d6abbf0a4f453154328b1
7
+ data.tar.gz: 4d9bbbee7d089c8c0545987e694cb5acf409e1a02a68bbb6c0e7b44554d1da67094c511f4b1d2b3d9dc301168d7319bc769599772645c58cf649c1cd742d26e6
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,6 @@
1
+ Metrics/LineLength:
2
+ Max: 150
3
+
4
+ Metrics/BlockLength:
5
+ Exclude:
6
+ - 'spec/**/*_spec.rb'
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+ sudo: false
3
+ script: "bundle exec rake clean spec"
4
+
5
+ rvm:
6
+ - 2.2
7
+ - 2.3
8
+ - 2.4
9
+
10
+ gemfile:
11
+ - Gemfile
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in zipcode_validator.gemspec
6
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,74 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ postcode_validator (0.1.0)
5
+ twitter_cldr (~> 4.4.3)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activemodel (5.1.5)
11
+ activesupport (= 5.1.5)
12
+ activesupport (5.1.5)
13
+ concurrent-ruby (~> 1.0, >= 1.0.2)
14
+ i18n (~> 0.7)
15
+ minitest (~> 5.1)
16
+ tzinfo (~> 1.1)
17
+ ast (2.4.0)
18
+ camertron-eprun (1.1.1)
19
+ cldr-plurals-runtime-rb (1.0.1)
20
+ concurrent-ruby (1.0.5)
21
+ diff-lcs (1.3)
22
+ i18n (0.9.5)
23
+ concurrent-ruby (~> 1.0)
24
+ minitest (5.11.3)
25
+ parallel (1.12.1)
26
+ parser (2.5.0.5)
27
+ ast (~> 2.4.0)
28
+ powerpack (0.1.1)
29
+ rainbow (3.0.0)
30
+ rake (10.5.0)
31
+ rspec (3.7.0)
32
+ rspec-core (~> 3.7.0)
33
+ rspec-expectations (~> 3.7.0)
34
+ rspec-mocks (~> 3.7.0)
35
+ rspec-core (3.7.1)
36
+ rspec-support (~> 3.7.0)
37
+ rspec-expectations (3.7.0)
38
+ diff-lcs (>= 1.2.0, < 2.0)
39
+ rspec-support (~> 3.7.0)
40
+ rspec-mocks (3.7.0)
41
+ diff-lcs (>= 1.2.0, < 2.0)
42
+ rspec-support (~> 3.7.0)
43
+ rspec-support (3.7.1)
44
+ rubocop (0.54.0)
45
+ parallel (~> 1.10)
46
+ parser (>= 2.5)
47
+ powerpack (~> 0.1)
48
+ rainbow (>= 2.2.2, < 4.0)
49
+ ruby-progressbar (~> 1.7)
50
+ unicode-display_width (~> 1.0, >= 1.0.1)
51
+ ruby-progressbar (1.9.0)
52
+ thread_safe (0.3.6)
53
+ twitter_cldr (4.4.3)
54
+ camertron-eprun
55
+ cldr-plurals-runtime-rb (~> 1.0)
56
+ tzinfo
57
+ tzinfo (1.2.5)
58
+ thread_safe (~> 0.1)
59
+ unicode-display_width (1.3.0)
60
+
61
+ PLATFORMS
62
+ ruby
63
+
64
+ DEPENDENCIES
65
+ activemodel (> 3.2.0)
66
+ activesupport (> 3.2.0)
67
+ bundler (~> 1.16)
68
+ postcode_validator!
69
+ rake (~> 10.0)
70
+ rspec (~> 3.7.0)
71
+ rubocop
72
+
73
+ BUNDLED WITH
74
+ 1.16.1
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright 2018 notus.sh
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
data/README.md ADDED
@@ -0,0 +1,55 @@
1
+ # PostcodeValidator
2
+
3
+ A simple postcode validator based on the Unicode CLDR project, with an optional integration with ActiveModel.
4
+
5
+ ## Installation
6
+
7
+ `PostcodeValidator` is distributed as a gem and available on [rubygems.org](https://rubygems.org/gems/postcode_validator) so you can add it to your `Gemfile` or install it manually with:
8
+
9
+ ```ruby
10
+ gem install postcode_validator
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ You can use `PostcodeValidator` either as a stand-alone validator or integrated with ActiveModel.
16
+
17
+ ### Stand-alone
18
+
19
+ ```ruby
20
+ require 'postcode_validator'
21
+
22
+ validator = PostcodeValidator.new
23
+
24
+ validator.valid?('98025', country: 'FR') # True
25
+ validator.valid?('AB21 9BG', country: :GB) # True
26
+ validator.valid?('AB21 9BG', country: :DE) # False
27
+ validator.valid?('', country: 'PA') # True - Panama does not use postcodes.
28
+ ```
29
+
30
+ The `:country` option is **required**. It can be anything that respond to `to_s`.
31
+ If the supplied `:country` is not a valid [ISO-3166 country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2), a `PostcodeValidator::Error` will be raised.
32
+
33
+ ### ActiveModel integration
34
+
35
+ ```ruby
36
+ class Address < ActiveRecord::Base
37
+
38
+ # With a dedicated helper
39
+ validates_as_postcode :zipcode, country: :US
40
+
41
+ # Or through the generic `validates` class method, mixed with other validators
42
+ validates :post_code,
43
+ presence: true,
44
+ postcode: { allow_nil: true, country: -> { |record| record.country_code } }
45
+ end
46
+ ```
47
+
48
+ The ActiveModel validator supports the same common arguments others standard validators do (`:if`, `:unless`, `:on`, `:allow_nil`, `:allow_blank` and `:strict`).
49
+ The `:country` argument is **required**. It can be either a static value (anything that respond to `to_s`) or a lambda. The lambda will be called with the will be validated record as its first argument.
50
+
51
+ If the supplied `:country` is not a valid [ISO-3166 country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2), the postcode validation will be skipped (It's your responsability to validate the value of `:country`).
52
+
53
+ ## Contributing
54
+
55
+ Bug reports and pull requests are welcome on GitHub at https://github.com/notus-sh/postcode_validator.
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+
5
+ require 'rspec/core/rake_task'
6
+ RSpec::Core::RakeTask.new
7
+
8
+ require 'rubocop/rake_task'
9
+ RuboCop::RakeTask.new
10
+
11
+ task default: :spec
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_model/validations'
4
+
5
+ module ActiveModel
6
+ module Validations
7
+ class PostcodeValidator < ActiveModel::EachValidator # :nodoc:
8
+ def validate_each(record, attribute, value)
9
+ country = option_call(record, :country)
10
+ record.errors.add(attribute, :invalid_postcode) unless validator.valid?(value, country: country)
11
+ rescue ::PostcodeValidator::Error # rubocop:disable Lint/HandleExceptions
12
+ # When :country is not a valid country, just skip postcode validation
13
+ # :country validation is developer's responsability
14
+ end
15
+
16
+ def check_validity!
17
+ raise ArgumentError, ':country must be supplied' unless options.include?(:country)
18
+ end
19
+
20
+ private
21
+
22
+ def option_call(record, name)
23
+ option = options[name]
24
+ option.respond_to?(:call) ? option.call(record) : option
25
+ end
26
+
27
+ def validator
28
+ @validator ||= ::PostcodeValidator.new
29
+ end
30
+ end
31
+
32
+ module HelperMethods #:nodoc:
33
+ # Validates whether the value of the specified attribute is a valid zip code
34
+ #
35
+ # class Address < ActiveRecord::Base
36
+ #
37
+ # validates_as_postcode :zipcode, country: :US
38
+ #
39
+ # validates :post_code,
40
+ # presence: true,
41
+ # postcode: { allow_nil: true, country: -> { |record| record.country_code } }
42
+ # end
43
+ #
44
+ # Configuration:
45
+ # * <tt>:country</tt> - The ISO-3166-2 code of the country we will validate
46
+ # the zip code for. Can be a static value or a lambda that may accept the
47
+ # current record as its first argument.
48
+ def validates_as_postcode(*attr_names)
49
+ validates_with PostcodeValidator, _merge_attributes(attr_names)
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'twitter_cldr'
4
+
5
+ begin
6
+ # ActiveModel integration
7
+ require 'active_model'
8
+ require 'active_support/i18n'
9
+ require 'active_model/validations/postcode_validator'
10
+
11
+ ActiveSupport.on_load(:i18n) do
12
+ I18n.load_path << Dir[File.expand_path(File.join(__dir__, '..', 'locales', '*.yml')).to_s]
13
+ end
14
+ rescue LoadError # rubocop:disable Lint/HandleExceptions
15
+ end
16
+
17
+ # A simple postcode validator
18
+ #
19
+ # Can be used to validate a post code, regarding a country specified through the
20
+ # :country option as an ISO-3166-2 code.
21
+ class PostcodeValidator
22
+ # Package specific error class
23
+ class Error < StandardError; end
24
+
25
+ def valid?(postcode, options = {})
26
+ iso = country_as_iso(options)
27
+ postcode = postcode.to_s.strip
28
+ validator = validator_for(iso)
29
+ validator ? validator.valid?(postcode) : postcode.blank?
30
+ end
31
+
32
+ protected
33
+
34
+ def country_as_iso(options)
35
+ raise Error, 'Missing :country option' unless options.key?(:country) && !options[:country].nil?
36
+ iso = TwitterCldr::Shared::Territories.normalize_territory_code(options[:country])
37
+
38
+ # raise ArgumentError if :iso is not a valid territory code
39
+ iso if TwitterCldr::Shared::TerritoriesContainment.contains?('001', iso.to_s.upcase)
40
+ rescue ArgumentError => e
41
+ raise Error, e.message
42
+ end
43
+
44
+ def validator_for(iso)
45
+ TwitterCldr::Shared::PostalCodes.for_territory(iso)
46
+ rescue TwitterCldr::Shared::InvalidTerritoryError
47
+ # No validator exists for :iso_code, this country may not use postcodes at all.
48
+ nil
49
+ end
50
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class PostcodeValidator
4
+ VERSION = '0.1.0'
5
+ end
data/locales/en.yml ADDED
@@ -0,0 +1,5 @@
1
+ ---
2
+ en:
3
+ errors:
4
+ messages:
5
+ invalid_postcode: "is not a valid postcode"
data/locales/fr.yml ADDED
@@ -0,0 +1,5 @@
1
+ ---
2
+ fr:
3
+ errors:
4
+ messages:
5
+ invalid_zipcode: "n'est pas un code postal valide"
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'postcode_validator/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'postcode_validator'
9
+ spec.version = PostcodeValidator::VERSION
10
+ spec.licenses = ['Apache-2.0']
11
+ spec.authors = ['Gaël-Ian Havard']
12
+ spec.email = ['gael-ian@notus.sh']
13
+
14
+ spec.summary = 'A simple postcode validator for Rails.'
15
+ spec.description = 'A simple postcode validator based on ActiveModel and Unicode CLDR.'
16
+ spec.homepage = 'https://github.com/notus-sh/postcode_validator'
17
+
18
+ raise 'RubyGems 2.0 or newer is required.' unless spec.respond_to?(:metadata)
19
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
20
+
21
+ spec.require_paths = ['lib']
22
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
23
+ f.match(%r{^(test|spec|features)/})
24
+ end
25
+
26
+ spec.add_runtime_dependency 'twitter_cldr', '~> 4.4.3'
27
+
28
+ # Optional dependencies, used in tests
29
+ spec.add_development_dependency 'activemodel', '> 3.2.0'
30
+ spec.add_development_dependency 'activesupport', '> 3.2.0'
31
+
32
+ # Development tools
33
+ spec.add_development_dependency 'bundler', '~> 1.16'
34
+ spec.add_development_dependency 'rake', '~> 10.0'
35
+ spec.add_development_dependency 'rspec', '~> 3.7.0'
36
+ spec.add_development_dependency 'rubocop'
37
+ end
metadata ADDED
@@ -0,0 +1,158 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: postcode_validator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Gaël-Ian Havard
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-03-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: twitter_cldr
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 4.4.3
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 4.4.3
27
+ - !ruby/object:Gem::Dependency
28
+ name: activemodel
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">"
32
+ - !ruby/object:Gem::Version
33
+ version: 3.2.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">"
39
+ - !ruby/object:Gem::Version
40
+ version: 3.2.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: activesupport
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">"
46
+ - !ruby/object:Gem::Version
47
+ version: 3.2.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">"
53
+ - !ruby/object:Gem::Version
54
+ version: 3.2.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.16'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.16'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '10.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '10.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 3.7.0
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 3.7.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: A simple postcode validator based on ActiveModel and Unicode CLDR.
112
+ email:
113
+ - gael-ian@notus.sh
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - ".gitignore"
119
+ - ".rspec"
120
+ - ".rubocop.yml"
121
+ - ".travis.yml"
122
+ - Gemfile
123
+ - Gemfile.lock
124
+ - LICENSE
125
+ - README.md
126
+ - Rakefile
127
+ - lib/active_model/validations/postcode_validator.rb
128
+ - lib/postcode_validator.rb
129
+ - lib/postcode_validator/version.rb
130
+ - locales/en.yml
131
+ - locales/fr.yml
132
+ - postcode_validator.gemspec
133
+ homepage: https://github.com/notus-sh/postcode_validator
134
+ licenses:
135
+ - Apache-2.0
136
+ metadata:
137
+ allowed_push_host: https://rubygems.org
138
+ post_install_message:
139
+ rdoc_options: []
140
+ require_paths:
141
+ - lib
142
+ required_ruby_version: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ required_rubygems_version: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ requirements: []
153
+ rubyforge_project:
154
+ rubygems_version: 2.6.14
155
+ signing_key:
156
+ specification_version: 4
157
+ summary: A simple postcode validator for Rails.
158
+ test_files: []