validates_zipcode 0.2.1 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 28749acf8368d0467f685cee92bb54476c3b49ebe5b4bd95c347ee9f3ba28bcd
4
- data.tar.gz: 724fc6dace5e4d37f81ad0183c373533e938fe8c2f67ded5b4ba31626ef55c2e
3
+ metadata.gz: ad8c2f2c935a1571e8824200d9494c7d8d95ed6292eec99ddd135b8df5389f11
4
+ data.tar.gz: ad38314b05f03aac01b7ef9800e135eb99afe70dc03610609fb9aa67b5c26a88
5
5
  SHA512:
6
- metadata.gz: d11fe3c378ec82922b225758b5dccc5616c84fea88a46cdec2bd13cbedc8d730565b4e616cd9e727d92dec62cddf362c505c503e23dcb88f8c5293db20634dc0
7
- data.tar.gz: de90359182f4c55a9e188160a6d4f2035b3808e76472529ec300a4aa6d2a5ab844596a303001126c6b22069dd5c5507f40b4795edb2f7fc8625a84cec6d81d96
6
+ metadata.gz: 34b5cf552795e382cf3a17f60898a4124bac5c4bc643f7c8996bbd2df9b442f62f8bae4ccb024f5332dd26698bfd3413f3f1d8b930a68225e388d17497c38ddb
7
+ data.tar.gz: c1cdd89cccb0966f28c1dd27c166097529873ac0a5662ebbf11f15f18a1d04ded857857a2ef858b88403b20988fa6f160d89a2409723ab82b8b29f4ff6866295
@@ -5,9 +5,12 @@ inherit_from:
5
5
  # - enabled.yml
6
6
  # - disabled.yml
7
7
 
8
+ require:
9
+ - rubocop-rails
10
+
8
11
  # Common configuration.
9
12
  AllCops:
10
- TargetRubyVersion: 2.3
13
+ TargetRubyVersion: 2.4
11
14
 
12
15
  TargetRailsVersion: 4.2
13
16
 
@@ -58,7 +61,7 @@ Layout/AccessModifierIndentation:
58
61
  - indent
59
62
 
60
63
  # Align the elements of a hash literal if they span more than one line.
61
- Layout/AlignHash:
64
+ Layout/HashAlignment:
62
65
  # Alignment of entries using hash rocket as separator. Valid values are:
63
66
  #
64
67
  # key - left alignment of keys
@@ -126,7 +129,7 @@ Layout/AlignHash:
126
129
  Style/Alias:
127
130
  Enabled: false
128
131
 
129
- Layout/AlignParameters:
132
+ Layout/ParameterAlignment:
130
133
  # Alignment of parameters in multi-line method calls.
131
134
  #
132
135
  # The `with_first_parameter` style aligns the following lines along the same
@@ -227,20 +230,6 @@ Style/BlockDelimiters:
227
230
  - proc
228
231
  - it
229
232
 
230
- Style/BracesAroundHashParameters:
231
- EnforcedStyle: no_braces
232
- SupportedStyles:
233
- # The `braces` style enforces braces around all method parameters that are
234
- # hashes.
235
- - braces
236
- # The `no_braces` style checks that the last parameter doesn't have braces
237
- # around it.
238
- - no_braces
239
- # The `context_dependent` style checks that the last parameter doesn't have
240
- # braces around it, but requires braces if the second to last parameter is
241
- # also a hash literal.
242
- - context_dependent
243
-
244
233
  # Indentation of `when`.
245
234
  Layout/CaseIndentation:
246
235
  SupportedStyles:
@@ -387,25 +376,18 @@ Layout/EmptyLinesAroundModuleBody:
387
376
  - empty_lines
388
377
  - no_empty_lines
389
378
 
390
- Style/FileName:
379
+ Naming/FileName:
391
380
  # File names listed in AllCops:Include are excluded by default. Add extra
392
381
  # excludes here.
393
382
  Exclude: []
394
383
 
395
384
  Layout/FirstParameterIndentation:
396
- EnforcedStyle: special_for_inner_method_call_in_parentheses
385
+ EnforcedStyle: consistent
397
386
  SupportedStyles:
398
387
  # The first parameter should always be indented one step more than the
399
388
  # preceding line.
400
389
  - consistent
401
- # The first parameter should normally be indented one step more than the
402
- # preceding line, but if it's a parameter for a method call that is itself
403
- # a parameter in a method call, then the inner parameter should be indented
404
- # relative to the inner method.
405
- - special_for_inner_method_call
406
- # Same as special_for_inner_method_call except that the special rule only
407
- # applies if the outer method call encloses its arguments in parentheses.
408
- - special_for_inner_method_call_in_parentheses
390
+ - align_parentheses
409
391
 
410
392
  Style/EmptyMethod:
411
393
  EnforcedStyle: expanded
@@ -439,11 +421,9 @@ Style/FormatStringToken:
439
421
  - template
440
422
 
441
423
  Style/FrozenStringLiteralComment:
442
- EnforcedStyle: when_needed
424
+ EnforcedStyle: always
443
425
  SupportedStyles:
444
- # `when_needed` will add the frozen string literal comment to files
445
- # only when the `TargetRubyVersion` is set to 2.3+.
446
- - when_needed
426
+ - always_true
447
427
  # `always` will always add the frozen string literal comment to a file
448
428
  # regardless of the Ruby version or if `freeze` or `<<` are called on a
449
429
  # string literal. If you run code against multiple versions of Ruby, it is
@@ -483,7 +463,7 @@ Layout/IndentationWidth:
483
463
  Width: 2
484
464
 
485
465
  # Checks the indentation of the first key in a hash literal.
486
- Layout/IndentHash:
466
+ Layout/FirstHashElementIndentation:
487
467
  # The value `special_inside_parentheses` means that hash literals with braces
488
468
  # that have their opening brace on the same line as a surrounding opening
489
469
  # round parenthesis, shall have their first key indented relative to the
@@ -532,7 +512,7 @@ Style/MethodDefParentheses:
532
512
  - require_parentheses
533
513
  - require_no_parentheses
534
514
 
535
- Style/MethodName:
515
+ Naming/MethodName:
536
516
  EnforcedStyle: snake_case
537
517
  SupportedStyles:
538
518
  - snake_case
@@ -569,14 +549,14 @@ Style/PercentQLiterals:
569
549
  - lower_case_q # Use %q when possible, %Q when necessary
570
550
  - upper_case_q # Always use %Q
571
551
 
572
- Style/PredicateName:
552
+ Naming/PredicateName:
573
553
  # Predicate name prefices.
574
554
  NamePrefix:
575
555
  - is_
576
556
  - has_
577
557
  - have_
578
558
  # Predicate name prefices that should be removed.
579
- NamePrefixBlacklist:
559
+ ForbiddenPrefixes:
580
560
  - is_
581
561
  - has_
582
562
  - have_
@@ -694,7 +674,7 @@ Style/SymbolProc:
694
674
  IgnoredMethods:
695
675
  - respond_to
696
676
 
697
- Layout/TrailingBlankLines:
677
+ Layout/TrailingEmptyLines:
698
678
  EnforcedStyle: final_newline
699
679
  SupportedStyles:
700
680
  - final_newline
@@ -756,7 +736,7 @@ Style/TrivialAccessors:
756
736
  # Commonly used in DSLs
757
737
  AllowDSLWriters: false
758
738
  IgnoreClassMethods: false
759
- Whitelist:
739
+ AllowedMethods:
760
740
  - to_ary
761
741
  - to_a
762
742
  - to_c
@@ -775,7 +755,7 @@ Style/TrivialAccessors:
775
755
  - to_s
776
756
  - to_sym
777
757
 
778
- Style/VariableName:
758
+ Naming/VariableName:
779
759
  EnforcedStyle: snake_case
780
760
  SupportedStyles:
781
761
  - snake_case
@@ -825,7 +805,7 @@ Metrics/CyclomaticComplexity:
825
805
  Max: 6
826
806
 
827
807
  # Second-wave metric. Disabled now to prevent noise.
828
- Metrics/LineLength:
808
+ Layout/LineLength:
829
809
  Enabled: false
830
810
  Max: 120
831
811
  # To make it possible to copy or click on URIs in the code, we allow lines
@@ -856,7 +836,7 @@ Lint/AssignmentInCondition:
856
836
  AllowSafeAssignment: true
857
837
 
858
838
  # Align ends correctly.
859
- Lint/EndAlignment:
839
+ Layout/EndAlignment:
860
840
  # The value `keyword` means that `end` should be aligned with the matching
861
841
  # keyword (if, while, etc.).
862
842
  # The value `variable` means that in assignments, `end` should be aligned
@@ -869,7 +849,7 @@ Lint/EndAlignment:
869
849
  - start_of_line
870
850
  AutoCorrect: false
871
851
 
872
- Lint/DefEndAlignment:
852
+ Layout/DefEndAlignment:
873
853
  # The value `def` means that `end` should be aligned with the def keyword.
874
854
  # The value `start_of_line` means that `end` should be aligned with method
875
855
  # calls like `private`, `public`, etc, if present in front of the `def`
@@ -7,21 +7,23 @@ cache: bundler
7
7
  bundler_args: --jobs 3 --retry 3
8
8
 
9
9
  before_install:
10
- - "travis_retry gem update --system"
11
- - "travis_retry gem install bundler"
10
+ - 'travis_retry gem update --system'
11
+ - 'travis_retry gem install bundler'
12
12
 
13
- script: "bundle exec rake"
13
+ script: 'bundle exec rake'
14
14
 
15
15
  rvm:
16
- - 2.3.7
17
- - 2.4.4
18
- - 2.5.3
19
- - 2.6.0
16
+ - 2.4.9
17
+ - 2.5.7
18
+ - 2.6.5
19
+ - 2.7.0
20
20
  - ruby-head
21
+ - truffleruby
21
22
 
22
23
  gemfile:
23
24
  - gemfiles/rails_4.2.gemfile
24
25
  - gemfiles/rails_5.2.gemfile
26
+ - gemfiles/rails_6.0.gemfile
25
27
  - gemfiles/rails_edge.gemfile
26
28
 
27
29
  matrix:
@@ -29,11 +31,7 @@ matrix:
29
31
  allow_failures:
30
32
  - rvm: ruby-head
31
33
  exclude:
32
- - rvm: 2.2.10
33
- gemfile: gemfiles/rails_5.2.gemfile
34
- - rvm: 2.2.10
35
- gemfile: gemfiles/rails_edge.gemfile
36
- - rvm: 2.3.7
37
- gemfile: gemfiles/rails_edge.gemfile
38
- - rvm: 2.4.4
34
+ - rvm: 2.4.9
35
+ gemfile: gemfiles/rails_6.gemfile
36
+ - rvm: 2.4.9
39
37
  gemfile: gemfiles/rails_edge.gemfile
data/Appraisals CHANGED
@@ -8,6 +8,10 @@ appraise 'rails-5.2' do
8
8
  gem 'activemodel', '~> 5.2.0'
9
9
  end
10
10
 
11
+ appraise 'rails-6.0' do
12
+ gem 'activemodel', '~> 5.2.0'
13
+ end
14
+
11
15
  appraise 'rails_edge' do
12
16
  gem 'activemodel', github: 'rails/rails'
13
17
  end
@@ -2,6 +2,31 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## 0.3.1
6
+
7
+ - Removes forbidden combinations in the Netherlands ~ @gerard76
8
+
9
+ ## 0.3.0
10
+
11
+ - Adds zipcode formatting feature ~ @aiomaster
12
+ - Drops support for EoL Rails < 4.2 and Ruby < 2.4. ~ @dgilperez
13
+
14
+ ## 0.2.5
15
+
16
+ - Allows for a custom message passed to the validator ~ @andychongyz
17
+
18
+ ## 0.2.4
19
+
20
+ - Fixes LV postal code format
21
+
22
+ ## 0.2.3
23
+
24
+ - Fixes MU postal code format ~ @thrasherDGK
25
+
26
+ ## 0.2.2
27
+
28
+ - Fixes LT postal code format ~ @tmeckhoff
29
+
5
30
  ## 0.2.1
6
31
 
7
32
  - Fixes NI postal code format ~ Daniel Olivares
data/README.md CHANGED
@@ -4,13 +4,14 @@ Adds zipcode / postal code validation support to Rails (ActiveModel), considerin
4
4
 
5
5
  ``ValidatesZipcode`` currently support **233 country codes**. Regex data taken from several sources, being the main source the [CLDR](http://unicode.org/cldr/trac/browser/tags/release-27-d05/common/supplemental/postalCodeData.xml) database (release 27, around 159). Any other country's postal code will validate without errors.
6
6
 
7
- ``ValidatesZipcode`` works for Rails >= 3.2 and Ruby >= 1.9.3.
7
+ ``ValidatesZipcode`` supports Rails >= 4.2 and Ruby >= 2.4. This gem could work in Rails 3.2 and Ruby 1.9.3 as well, yet unsupported; try v0.2 series if having trouble with later versions. Truffleruby is also tested, but no reports of working in production apps for now.
8
8
 
9
9
  ## Installation
10
10
 
11
11
  Add this line to your application's Gemfile:
12
-
13
- gem 'validates_zipcode'
12
+ ```ruby
13
+ gem 'validates_zipcode'
14
+ ```
14
15
 
15
16
  And then execute:
16
17
 
@@ -22,23 +23,64 @@ Or install it yourself as:
22
23
 
23
24
  ## Usage
24
25
 
25
- validates_zipcode :zipcode
26
+ ### With ActiveModel::Validations
27
+
28
+ ```ruby
29
+ validates_zipcode :zipcode
26
30
 
27
- validates :zipcode, zipcode: true
31
+ validates :zipcode, zipcode: true
32
+ ```
28
33
 
29
34
  ``ValidatesZipcode`` expects the model to have an attribute called ``country_alpha2`` to contain the country code.
30
35
  You can provide your own country_code using ``:country_code`` option, or specify which attribute contains this information
31
36
  using ``:country_code_attribute`` option.
32
37
 
33
- validates :zipcode, zipcode: { country_code: :es }
38
+ ```ruby
39
+ validates :zipcode, zipcode: { country_code: :es }
34
40
 
35
- validates :zipcode, zipcode: { country_code_attribute: :my_country_code_column }
41
+ validates :zipcode, zipcode: { country_code_attribute: :my_country_code_column }
42
+ ```
43
+
44
+ #### Error Messaging
36
45
 
37
46
  If you need to localize the error message, just add this to your I18n locale file:
38
47
 
39
- errors:
40
- messages:
41
- invalid_zipcode: Your zipcode error message.
48
+ ```yaml
49
+ errors:
50
+ messages:
51
+ invalid_zipcode: Your zipcode error message.
52
+ ```
53
+
54
+ You can override this on a per-model basis by passing in a ``:message`` key with the validation:
55
+
56
+ ```ruby
57
+ validates :zipcode, zipcode: { message: 'Your per-model zipcode error message.' }
58
+ ```
59
+
60
+ ### Without ActiveModel::Validations
61
+
62
+ ```ruby
63
+ ValidatesZipcode.valid?('93108', 'ES')
64
+ # => true
65
+ ```
66
+
67
+ ### Formatting
68
+
69
+ This gem can also be used for formatting zipcodes according to country specific rules.
70
+
71
+ ```ruby
72
+ ValidatesZipcode.format('Sw1A 2aA', 'UK')
73
+ # => 'SW1A 2AA'
74
+ ```
75
+
76
+ If the zipcode is not valid an exception is raised.
77
+
78
+ ```ruby
79
+ ValidatesZipcode.format('Sw1A 2aA', 'FR')
80
+ # => raises ValidatesZipcode::InvalidZipcodeError
81
+ ```
82
+
83
+ At the moment not every country is supported. See [lib/validates_zipcode/formatter.rb](lib/validates_zipcode/formatter.rb) to find all available countries.
42
84
 
43
85
  ## Contributing
44
86
 
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
1
2
  # This file was generated by Appraisal
2
3
 
3
- source "https://rubygems.org"
4
+ source 'https://rubygems.org'
4
5
 
5
- gem "activemodel", "~> 4.2.0"
6
+ gem 'activemodel', '~> 4.2.0'
6
7
 
7
- gemspec path: "../"
8
+ gemspec path: '../'
@@ -1,8 +1,8 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- validates_zipcode (0.2.1)
5
- activemodel (>= 3.2.0)
4
+ validates_zipcode (0.3.1)
5
+ activemodel (>= 4.2.0)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
@@ -19,13 +19,20 @@ GEM
19
19
  bundler
20
20
  rake
21
21
  thor (>= 0.14.0)
22
+ ast (2.4.0)
22
23
  builder (3.2.3)
23
24
  concurrent-ruby (1.1.4)
24
25
  diff-lcs (1.3)
25
26
  i18n (0.9.5)
26
27
  concurrent-ruby (~> 1.0)
27
28
  minitest (5.11.3)
28
- rake (12.2.1)
29
+ parallel (1.19.1)
30
+ parser (2.7.1.2)
31
+ ast (~> 2.4.0)
32
+ rack (2.2.2)
33
+ rainbow (3.0.0)
34
+ rake (13.0.1)
35
+ rexml (3.2.4)
29
36
  rspec (3.8.0)
30
37
  rspec-core (~> 3.8.0)
31
38
  rspec-expectations (~> 3.8.0)
@@ -39,10 +46,26 @@ GEM
39
46
  diff-lcs (>= 1.2.0, < 2.0)
40
47
  rspec-support (~> 3.8.0)
41
48
  rspec-support (3.8.0)
49
+ rubocop (0.84.0)
50
+ parallel (~> 1.10)
51
+ parser (>= 2.7.0.1)
52
+ rainbow (>= 2.2.2, < 4.0)
53
+ rexml
54
+ rubocop-ast (>= 0.0.3)
55
+ ruby-progressbar (~> 1.7)
56
+ unicode-display_width (>= 1.4.0, < 2.0)
57
+ rubocop-ast (0.0.3)
58
+ parser (>= 2.7.0.1)
59
+ rubocop-rails (2.5.2)
60
+ activesupport
61
+ rack (>= 1.1)
62
+ rubocop (>= 0.72.0)
63
+ ruby-progressbar (1.10.1)
42
64
  thor (0.20.3)
43
65
  thread_safe (0.3.6)
44
66
  tzinfo (1.2.5)
45
67
  thread_safe (~> 0.1)
68
+ unicode-display_width (1.7.0)
46
69
 
47
70
  PLATFORMS
48
71
  ruby
@@ -51,9 +74,11 @@ DEPENDENCIES
51
74
  activemodel (~> 4.2.0)
52
75
  appraisal
53
76
  bundler
54
- rake (~> 12.2.1)
77
+ rake (>= 12.3.3)
55
78
  rspec
79
+ rubocop
80
+ rubocop-rails
56
81
  validates_zipcode!
57
82
 
58
83
  BUNDLED WITH
59
- 2.0.1
84
+ 2.1.4
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
1
2
  # This file was generated by Appraisal
2
3
 
3
- source "https://rubygems.org"
4
+ source 'https://rubygems.org'
4
5
 
5
- gem "activemodel", "~> 5.2.0"
6
+ gem 'activemodel', '~> 5.2.0'
6
7
 
7
- gemspec path: "../"
8
+ gemspec path: '../'
@@ -1,8 +1,8 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- validates_zipcode (0.2.1)
5
- activemodel (>= 3.2.0)
4
+ validates_zipcode (0.3.1)
5
+ activemodel (>= 4.2.0)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
@@ -18,12 +18,19 @@ GEM
18
18
  bundler
19
19
  rake
20
20
  thor (>= 0.14.0)
21
+ ast (2.4.0)
21
22
  concurrent-ruby (1.1.4)
22
23
  diff-lcs (1.3)
23
24
  i18n (1.5.3)
24
25
  concurrent-ruby (~> 1.0)
25
26
  minitest (5.11.3)
26
- rake (12.2.1)
27
+ parallel (1.19.1)
28
+ parser (2.7.1.2)
29
+ ast (~> 2.4.0)
30
+ rack (2.2.2)
31
+ rainbow (3.0.0)
32
+ rake (13.0.1)
33
+ rexml (3.2.4)
27
34
  rspec (3.8.0)
28
35
  rspec-core (~> 3.8.0)
29
36
  rspec-expectations (~> 3.8.0)
@@ -37,10 +44,26 @@ GEM
37
44
  diff-lcs (>= 1.2.0, < 2.0)
38
45
  rspec-support (~> 3.8.0)
39
46
  rspec-support (3.8.0)
47
+ rubocop (0.84.0)
48
+ parallel (~> 1.10)
49
+ parser (>= 2.7.0.1)
50
+ rainbow (>= 2.2.2, < 4.0)
51
+ rexml
52
+ rubocop-ast (>= 0.0.3)
53
+ ruby-progressbar (~> 1.7)
54
+ unicode-display_width (>= 1.4.0, < 2.0)
55
+ rubocop-ast (0.0.3)
56
+ parser (>= 2.7.0.1)
57
+ rubocop-rails (2.5.2)
58
+ activesupport
59
+ rack (>= 1.1)
60
+ rubocop (>= 0.72.0)
61
+ ruby-progressbar (1.10.1)
40
62
  thor (0.20.3)
41
63
  thread_safe (0.3.6)
42
64
  tzinfo (1.2.5)
43
65
  thread_safe (~> 0.1)
66
+ unicode-display_width (1.7.0)
44
67
 
45
68
  PLATFORMS
46
69
  ruby
@@ -49,9 +72,11 @@ DEPENDENCIES
49
72
  activemodel (~> 5.2.0)
50
73
  appraisal
51
74
  bundler
52
- rake (~> 12.2.1)
75
+ rake (>= 12.3.3)
53
76
  rspec
77
+ rubocop
78
+ rubocop-rails
54
79
  validates_zipcode!
55
80
 
56
81
  BUNDLED WITH
57
- 2.0.1
82
+ 2.1.4
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+ # This file was generated by Appraisal
3
+
4
+ source 'https://rubygems.org'
5
+
6
+ gem 'activemodel', '~> 5.2.0'
7
+
8
+ gemspec path: '../'
@@ -0,0 +1,82 @@
1
+ PATH
2
+ remote: ..
3
+ specs:
4
+ validates_zipcode (0.3.1)
5
+ activemodel (>= 4.2.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activemodel (5.2.3)
11
+ activesupport (= 5.2.3)
12
+ activesupport (5.2.3)
13
+ concurrent-ruby (~> 1.0, >= 1.0.2)
14
+ i18n (>= 0.7, < 2)
15
+ minitest (~> 5.1)
16
+ tzinfo (~> 1.1)
17
+ appraisal (2.2.0)
18
+ bundler
19
+ rake
20
+ thor (>= 0.14.0)
21
+ ast (2.4.0)
22
+ concurrent-ruby (1.1.5)
23
+ diff-lcs (1.3)
24
+ i18n (1.6.0)
25
+ concurrent-ruby (~> 1.0)
26
+ minitest (5.11.3)
27
+ parallel (1.19.1)
28
+ parser (2.7.1.2)
29
+ ast (~> 2.4.0)
30
+ rack (2.2.2)
31
+ rainbow (3.0.0)
32
+ rake (13.0.1)
33
+ rexml (3.2.4)
34
+ rspec (3.8.0)
35
+ rspec-core (~> 3.8.0)
36
+ rspec-expectations (~> 3.8.0)
37
+ rspec-mocks (~> 3.8.0)
38
+ rspec-core (3.8.0)
39
+ rspec-support (~> 3.8.0)
40
+ rspec-expectations (3.8.3)
41
+ diff-lcs (>= 1.2.0, < 2.0)
42
+ rspec-support (~> 3.8.0)
43
+ rspec-mocks (3.8.0)
44
+ diff-lcs (>= 1.2.0, < 2.0)
45
+ rspec-support (~> 3.8.0)
46
+ rspec-support (3.8.0)
47
+ rubocop (0.84.0)
48
+ parallel (~> 1.10)
49
+ parser (>= 2.7.0.1)
50
+ rainbow (>= 2.2.2, < 4.0)
51
+ rexml
52
+ rubocop-ast (>= 0.0.3)
53
+ ruby-progressbar (~> 1.7)
54
+ unicode-display_width (>= 1.4.0, < 2.0)
55
+ rubocop-ast (0.0.3)
56
+ parser (>= 2.7.0.1)
57
+ rubocop-rails (2.5.2)
58
+ activesupport
59
+ rack (>= 1.1)
60
+ rubocop (>= 0.72.0)
61
+ ruby-progressbar (1.10.1)
62
+ thor (0.20.3)
63
+ thread_safe (0.3.6)
64
+ tzinfo (1.2.5)
65
+ thread_safe (~> 0.1)
66
+ unicode-display_width (1.7.0)
67
+
68
+ PLATFORMS
69
+ ruby
70
+
71
+ DEPENDENCIES
72
+ activemodel (~> 5.2.0)
73
+ appraisal
74
+ bundler
75
+ rake (>= 12.3.3)
76
+ rspec
77
+ rubocop
78
+ rubocop-rails
79
+ validates_zipcode!
80
+
81
+ BUNDLED WITH
82
+ 2.1.4
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
1
2
  # This file was generated by Appraisal
2
3
 
3
- source "https://rubygems.org"
4
+ source 'https://rubygems.org'
4
5
 
5
- gem "activemodel", github: "rails/rails"
6
+ gem 'activemodel', github: 'rails/rails'
6
7
 
7
- gemspec path: "../"
8
+ gemspec path: '../'
@@ -14,8 +14,8 @@ GIT
14
14
  PATH
15
15
  remote: ..
16
16
  specs:
17
- validates_zipcode (0.2.1)
18
- activemodel (>= 3.2.0)
17
+ validates_zipcode (0.3.1)
18
+ activemodel (>= 4.2.0)
19
19
 
20
20
  GEM
21
21
  remote: https://rubygems.org/
@@ -24,12 +24,19 @@ GEM
24
24
  bundler
25
25
  rake
26
26
  thor (>= 0.14.0)
27
+ ast (2.4.0)
27
28
  concurrent-ruby (1.1.5)
28
29
  diff-lcs (1.3)
29
30
  i18n (1.6.0)
30
31
  concurrent-ruby (~> 1.0)
31
32
  minitest (5.11.3)
32
- rake (12.2.1)
33
+ parallel (1.19.1)
34
+ parser (2.7.1.2)
35
+ ast (~> 2.4.0)
36
+ rack (2.2.2)
37
+ rainbow (3.0.0)
38
+ rake (13.0.1)
39
+ rexml (3.2.4)
33
40
  rspec (3.8.0)
34
41
  rspec-core (~> 3.8.0)
35
42
  rspec-expectations (~> 3.8.0)
@@ -43,10 +50,26 @@ GEM
43
50
  diff-lcs (>= 1.2.0, < 2.0)
44
51
  rspec-support (~> 3.8.0)
45
52
  rspec-support (3.8.0)
53
+ rubocop (0.84.0)
54
+ parallel (~> 1.10)
55
+ parser (>= 2.7.0.1)
56
+ rainbow (>= 2.2.2, < 4.0)
57
+ rexml
58
+ rubocop-ast (>= 0.0.3)
59
+ ruby-progressbar (~> 1.7)
60
+ unicode-display_width (>= 1.4.0, < 2.0)
61
+ rubocop-ast (0.0.3)
62
+ parser (>= 2.7.0.1)
63
+ rubocop-rails (2.5.2)
64
+ activesupport
65
+ rack (>= 1.1)
66
+ rubocop (>= 0.72.0)
67
+ ruby-progressbar (1.10.1)
46
68
  thor (0.20.3)
47
69
  thread_safe (0.3.6)
48
70
  tzinfo (1.2.5)
49
71
  thread_safe (~> 0.1)
72
+ unicode-display_width (1.7.0)
50
73
  zeitwerk (2.1.6)
51
74
 
52
75
  PLATFORMS
@@ -56,9 +79,11 @@ DEPENDENCIES
56
79
  activemodel!
57
80
  appraisal
58
81
  bundler
59
- rake (~> 12.2.1)
82
+ rake (>= 12.3.3)
60
83
  rspec
84
+ rubocop
85
+ rubocop-rails
61
86
  validates_zipcode!
62
87
 
63
88
  BUNDLED WITH
64
- 2.0.1
89
+ 2.1.4
@@ -1,13 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
  require 'validates_zipcode/railtie' if defined?(Rails)
3
3
  require 'validates_zipcode/cldr_regex_collection'
4
+ require 'validates_zipcode/invalid_zipcode_error'
4
5
  require 'validates_zipcode/validator'
5
6
  require 'validates_zipcode/helper_methods'
6
7
  require 'validates_zipcode/version'
7
8
  require 'validates_zipcode/zipcode'
9
+ require 'validates_zipcode/formatter'
8
10
 
9
11
  module ValidatesZipcode
10
- def self.valid?(zipcode, country_alpha2, options = {})
11
- ValidatesZipcode::Zipcode.new(options.merge(zipcode: zipcode, country_alpha2: country_alpha2)).valid?
12
+ def self.valid?(*args)
13
+ build_zipcode(*args).valid?
14
+ end
15
+
16
+ def self.format(*args)
17
+ build_zipcode(*args).format
18
+ end
19
+
20
+ def self.build_zipcode(zipcode, country_alpha2, options = {})
21
+ ValidatesZipcode::Zipcode.new(options.merge(zipcode: zipcode, country_alpha2: country_alpha2))
12
22
  end
13
23
  end
@@ -21,7 +21,7 @@ module ValidatesZipcode
21
21
  CH: /\A\d{4}\z/,
22
22
  AT: /\A\d{4}\z/,
23
23
  ES: /\A\d{5}\z/,
24
- NL: /\A\d{4}[ ]?[A-Z]{2}\z/,
24
+ NL: /\A[1-9]\d{3}[ ]?(?!SA|SD|SS)[A-Z]{2}\z/,
25
25
  BE: /\A\d{4}\z/,
26
26
  DK: /\A\d{4}\z/,
27
27
  NO: /\A\d{4}\z/,
@@ -73,7 +73,7 @@ module ValidatesZipcode
73
73
  MY: /\A\d{5}\z/,
74
74
  MV: /\A\d{5}\z/,
75
75
  MT: /\A[A-Z]{3}[ ]?\d{2,4}\z/,
76
- MU: /\A(\d{3}[A-Z]{2}\d{3})?\z/,
76
+ MU: /\A[ARar1-9]\d{4}\z/,
77
77
  MX: /\A\d{5}\z/,
78
78
  MA: /\A\d{5}\z/,
79
79
  NZ: /\A\d{4}\z/,
@@ -194,9 +194,9 @@ module ValidatesZipcode
194
194
  KN: /\A([a-zA-Z\d\s]){3,8}\z/,
195
195
  KP: /\A([a-zA-Z\d\s]){3,8}\z/,
196
196
  LI: /\A\d{4}\z/,
197
- LV: /\A([a-zA-Z]|\d){3,8}\z/,
197
+ LV: /\A(LV)?\-?\d{4}\z/,
198
198
  LY: /\A\d{5}\z/,
199
- LT: /\A([a-zA-Z]){2}(-)\d{4,5}\z/,
199
+ LT: /\A(LT-)?\d{5}\z/,
200
200
  LC: /\A([a-zA-Z\d\s]){3,}\z/,
201
201
  MC: /\A\d{5}\z/,
202
202
  MD: /\A(([a-zA-Z]){2})(|\s)\d{4}\z/,
@@ -0,0 +1,38 @@
1
+ module ValidatesZipcode
2
+ class Formatter
3
+
4
+ ZIPCODES_TRANSFORMATIONS = {
5
+ AT: ->(z) { z.scan(/\d/).join },
6
+ CZ: ->(z) { z.scan(/\d/).insert(3, ' ').join },
7
+ DE: ->(z) { z.scan(/\d/).join.rjust(5, "0") },
8
+ GB: ->(z) { z.upcase.scan(/[A-Z0-9]/).insert(-4, ' ').join },
9
+ NL: ->(z) { z.upcase.scan(/[A-Z0-9]/).insert(4, ' ').join },
10
+ PL: ->(z) { z.scan(/\d/).insert(2, '-').join },
11
+ SK: :CZ,
12
+ UK: :GB,
13
+ US: ->(z) {
14
+ digits = z.scan(/\d/)
15
+ digits.insert(5, '-') if digits.count > 5
16
+ digits.join
17
+ }
18
+ }
19
+
20
+ def initialize(args = {})
21
+ @zipcode = args.fetch(:zipcode).to_s
22
+ @country_alpha2 = args.fetch(:country_alpha2).to_s.upcase.to_sym
23
+ end
24
+
25
+ def format
26
+ transformation = ZIPCODES_TRANSFORMATIONS[@country_alpha2]
27
+ case transformation
28
+ when Proc
29
+ transformation.call(@zipcode)
30
+ when Symbol
31
+ ZIPCODES_TRANSFORMATIONS[transformation].call(@zipcode)
32
+ else
33
+ @zipcode.strip
34
+ end
35
+ end
36
+
37
+ end
38
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+ module ValidatesZipcode
3
+ class InvalidZipcodeError < RuntimeError
4
+ end
5
+ end
@@ -21,7 +21,7 @@ module ValidatesZipcode
21
21
  @country_code = options.fetch(:country_code, nil)
22
22
  @country_code_attribute = options.fetch(:country_code_attribute, :country_alpha2)
23
23
  @excluded_country_codes = options.fetch(:excluded_country_codes, [])
24
-
24
+ @message = options.fetch(:message, nil)
25
25
  super
26
26
  end
27
27
 
@@ -32,9 +32,8 @@ module ValidatesZipcode
32
32
  excluded_country_codes: @excluded_country_codes }
33
33
 
34
34
  unless ValidatesZipcode::Zipcode.new(options).valid?
35
- record.errors.add(attribute, :invalid_zipcode, message: I18n.t('errors.messages.invalid_zipcode',
36
- value: value,
37
- default: 'Zipcode is invalid'))
35
+ message = @message || I18n.t('errors.messages.invalid_zipcode', value: value, default: 'Zipcode is invalid')
36
+ record.errors.add(attribute, :invalid_zipcode, message: message)
38
37
  end
39
38
  end
40
39
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module ValidatesZipcode
3
- VERSION = '0.2.1'
3
+ VERSION = '0.3.1'
4
4
  end
@@ -16,6 +16,11 @@ module ValidatesZipcode
16
16
  end
17
17
  alias_method :validate, :valid?
18
18
 
19
+ def format
20
+ raise InvalidZipcodeError, "invalid zipcode #{@zipcode} for country #{@country_alpha2.to_s.upcase}" unless valid?
21
+ Formatter.new(zipcode: @zipcode, country_alpha2: @country_alpha2).format
22
+ end
23
+
19
24
  private
20
25
 
21
26
  def regexp
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+ require 'spec_helper'
3
+
4
+ describe ValidatesZipcode::Formatter, '#format' do
5
+ context 'Czech' do
6
+ it { check_format('CZ', '12000' => '120 00') }
7
+ it { check_format(:cz, '721 00' => '721 00') }
8
+ end
9
+
10
+ context 'Germany' do
11
+ it { check_format('DE', 1309 => '01309') }
12
+ end
13
+
14
+ context 'Netherlands' do
15
+ it { check_format('NL', '1000ap' => '1000 AP') }
16
+ it { check_format('nl', '9104-BR' => '9104 BR') }
17
+ it { check_format(:nl, '6832_AM' => '6832 AM') }
18
+ end
19
+
20
+ context 'UK' do
21
+ it { check_format('UK', 'CB224RG' => 'CB22 4RG') }
22
+ it { check_format('UK', 'Sw1A 2aA' => 'SW1A 2AA') }
23
+ it { check_format('GB', 'id11qd' => 'ID1 1QD') }
24
+ end
25
+
26
+ context 'US' do
27
+ it { check_format('US', '221 62 – 10 10' => '22162-1010') }
28
+ it { check_format('US', '22162' => '22162') }
29
+ it { check_format('US', '22162 1010' => '22162-1010') }
30
+ end
31
+
32
+ def check_format(country, formatting)
33
+ from_zip, to_zip = formatting.first
34
+ expect(::ValidatesZipcode::Formatter.new(zipcode: from_zip, country_alpha2: country).format).to eq(to_zip)
35
+ end
36
+ end
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
  require 'spec_helper'
3
3
 
4
+ # NOTE: Spain has the full case specs.
5
+ # Do not apply all checks to all countries for suite speed.
4
6
  describe ValidatesZipcode, '#validate_each' do
5
7
  context 'Argentina' do
6
8
  it 'does not add errors with a valid zipcode' do
@@ -139,15 +141,19 @@ describe ValidatesZipcode, '#validate_each' do
139
141
 
140
142
  context 'Lithuania' do
141
143
  it 'validates with a valid zipcode' do
142
- record = build_record('LT-0110', 'LT')
143
- zipcode_should_be_valid(record)
144
144
  record = build_record('LT-00110', 'LT')
145
145
  zipcode_should_be_valid(record)
146
+ record = build_record('00110', 'LT')
147
+ zipcode_should_be_valid(record)
146
148
  end
147
149
 
148
150
  it 'does not validate with an invalid zipcode' do
149
- record = build_record('21006', 'LT')
150
- zipcode_should_be_invalid(record, '21006')
151
+ record = build_record('2100', 'LT')
152
+ zipcode_should_be_invalid(record, '2100')
153
+ record = build_record('LT-2100', 'LT')
154
+ zipcode_should_be_invalid(record, 'LT-2100')
155
+ record = build_record('LT21006', 'LT')
156
+ zipcode_should_be_invalid(record, 'LT21006')
151
157
  end
152
158
  end
153
159
 
@@ -167,6 +173,22 @@ describe ValidatesZipcode, '#validate_each' do
167
173
  end
168
174
  end
169
175
 
176
+ context 'Mauritius' do
177
+ it 'validates with a valid zipcode' do
178
+ %w[42602 A2101 r6414].each do |zipcode|
179
+ record = build_record(zipcode, 'MU')
180
+ zipcode_should_be_valid(record)
181
+ end
182
+ end
183
+
184
+ it 'does not validate with an invalid zipcode' do
185
+ %w[05678 B4242].each do |zipcode|
186
+ record = build_record(zipcode, 'MU')
187
+ zipcode_should_be_invalid(record, zipcode)
188
+ end
189
+ end
190
+ end
191
+
170
192
  context 'Moldova' do
171
193
  it 'validates with a valid zipcode' do
172
194
  record = build_record('MD2001', 'MD')
@@ -179,6 +201,19 @@ describe ValidatesZipcode, '#validate_each' do
179
201
  end
180
202
  end
181
203
 
204
+ context 'Netherlands' do
205
+ it 'does not add errors with a valid zipcode' do
206
+ record = build_record('1001 AA', 'NL')
207
+ zipcode_should_be_valid(record)
208
+ end
209
+
210
+ it 'adds errors with an invalid Zipcode' do
211
+ ['0100 AA', '1001 SS', 'invalid_zip'].each do |zipcode|
212
+ record = build_record(zipcode, 'NL')
213
+ zipcode_should_be_invalid(record, zipcode)
214
+ end
215
+ end
216
+ end
182
217
  context 'Panama' do
183
218
  it 'validates with a valid zipcode' do
184
219
  %w[0800 6369].each do |zipcode|
@@ -245,6 +280,8 @@ describe ValidatesZipcode, '#validate_each' do
245
280
  ['1234', '12345-12345', 'D0D0D0', 'invalid_zip'].each do |zipcode|
246
281
  record = build_record(zipcode, 'ES')
247
282
  zipcode_should_be_invalid(record, zipcode)
283
+ record.errors.clear
284
+ zipcode_should_be_invalid_with_custom_message(record, zipcode)
248
285
  end
249
286
  end
250
287
  end
@@ -389,6 +426,16 @@ describe ValidatesZipcode, '.valid?' do
389
426
  end
390
427
  end
391
428
 
429
+ describe ValidatesZipcode, '.format' do
430
+ it "formats valid zipcodes" do
431
+ expect(ValidatesZipcode.format('Ka9 2dj', 'UK')).to eq('KA9 2DJ')
432
+ end
433
+
434
+ it "raises for invalid zipcodes" do
435
+ expect { ValidatesZipcode.format('KA9 1tr', 'DE') }.to raise_error(ValidatesZipcode::InvalidZipcodeError)
436
+ end
437
+ end
438
+
392
439
  def zipcode_should_be_valid(record, options = {})
393
440
  ValidatesZipcode::Validator.new(options.merge(attributes: :zipcode)).validate(record)
394
441
 
@@ -402,6 +449,14 @@ def zipcode_should_be_invalid(record, _zipcode, options = {})
402
449
  expect(record.errors.messages[:zipcode]).to include 'Zipcode is invalid'
403
450
  end
404
451
 
452
+ def zipcode_should_be_invalid_with_custom_message(record, _zipcode, options = {})
453
+ custom_message = 'is really wrong'
454
+ ValidatesZipcode::Validator.new(options.merge(attributes: :zipcode, message: custom_message)).validate(record)
455
+
456
+ expect(record.errors.size).to eq 1
457
+ expect(record.errors.messages[:zipcode]).to include custom_message
458
+ end
459
+
405
460
  def build_record(zipcode, country_alpha2)
406
461
  ValidationDummyClass.new.tap do |object|
407
462
  object.country_alpha2 = country_alpha2
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- lib = File.expand_path('../lib', __FILE__)
3
+ lib = File.expand_path('lib', __dir__)
4
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
  require 'validates_zipcode/version'
6
6
 
@@ -17,14 +17,16 @@ Gem::Specification.new do |s|
17
17
  s.files = `git ls-files -z`.split("\x0")
18
18
  s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
19
  s.test_files = s.files.grep(%r{^(test|spec|features)/})
20
- s.require_paths = ['lib']
20
+ s.require_paths = %w[lib]
21
21
 
22
- s.required_ruby_version = '>= 1.9.3'
22
+ s.required_ruby_version = '>= 2.4'
23
23
 
24
- s.add_dependency 'activemodel', '>= 3.2.0'
24
+ s.add_dependency 'activemodel', '>= 4.2.0'
25
25
 
26
26
  s.add_development_dependency 'appraisal'
27
27
  s.add_development_dependency 'bundler'
28
- s.add_development_dependency 'rake', '~> 12.2.1'
28
+ s.add_development_dependency 'rake', '>= 12.3.3'
29
29
  s.add_development_dependency 'rspec'
30
+ s.add_development_dependency 'rubocop'
31
+ s.add_development_dependency 'rubocop-rails'
30
32
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: validates_zipcode
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Gil
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-14 00:00:00.000000000 Z
11
+ date: 2020-08-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 3.2.0
19
+ version: 4.2.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 3.2.0
26
+ version: 4.2.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: appraisal
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -56,16 +56,16 @@ dependencies:
56
56
  name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: 12.2.1
61
+ version: 12.3.3
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: 12.2.1
68
+ version: 12.3.3
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +80,34 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop-rails
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'
83
111
  description: Adds zipcode validation methods to ActiveModel considering different
84
112
  country zipcode formats.
85
113
  email:
@@ -104,15 +132,20 @@ files:
104
132
  - gemfiles/rails_4.2.gemfile.lock
105
133
  - gemfiles/rails_5.2.gemfile
106
134
  - gemfiles/rails_5.2.gemfile.lock
135
+ - gemfiles/rails_6.0.gemfile
136
+ - gemfiles/rails_6.0.gemfile.lock
107
137
  - gemfiles/rails_edge.gemfile
108
138
  - gemfiles/rails_edge.gemfile.lock
109
139
  - lib/validates_zipcode.rb
110
140
  - lib/validates_zipcode/cldr_regex_collection.rb
141
+ - lib/validates_zipcode/formatter.rb
111
142
  - lib/validates_zipcode/helper_methods.rb
143
+ - lib/validates_zipcode/invalid_zipcode_error.rb
112
144
  - lib/validates_zipcode/railtie.rb
113
145
  - lib/validates_zipcode/validator.rb
114
146
  - lib/validates_zipcode/version.rb
115
147
  - lib/validates_zipcode/zipcode.rb
148
+ - spec/format_zipcode_spec.rb
116
149
  - spec/spec_helper.rb
117
150
  - spec/validates_zipcode_spec.rb
118
151
  - validates_zipcode.gemspec
@@ -120,7 +153,7 @@ homepage: http://github.com/dgilperez/validates_zipcode
120
153
  licenses:
121
154
  - MIT
122
155
  metadata: {}
123
- post_install_message:
156
+ post_install_message:
124
157
  rdoc_options: []
125
158
  require_paths:
126
159
  - lib
@@ -128,17 +161,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
128
161
  requirements:
129
162
  - - ">="
130
163
  - !ruby/object:Gem::Version
131
- version: 1.9.3
164
+ version: '2.4'
132
165
  required_rubygems_version: !ruby/object:Gem::Requirement
133
166
  requirements:
134
167
  - - ">="
135
168
  - !ruby/object:Gem::Version
136
169
  version: '0'
137
170
  requirements: []
138
- rubygems_version: 3.0.3
139
- signing_key:
171
+ rubygems_version: 3.0.8
172
+ signing_key:
140
173
  specification_version: 4
141
174
  summary: Localizable zipcode validation for Rails.
142
175
  test_files:
176
+ - spec/format_zipcode_spec.rb
143
177
  - spec/spec_helper.rb
144
178
  - spec/validates_zipcode_spec.rb