regional 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 +7 -0
- data/.gitignore +17 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +28 -0
- data/Rakefile +1 -0
- data/features/determine_inclusion.feature +34 -0
- data/features/postal_codes.feature +51 -0
- data/features/step_definitions/postcode_steps.rb +8 -0
- data/features/step_definitions/steps.rb +19 -0
- data/features/step_definitions/zone_steps.rb +14 -0
- data/features/support/env.rb +4 -0
- data/lib/regional/postcode.rb +45 -0
- data/lib/regional/version.rb +3 -0
- data/lib/regional/zone.rb +31 -0
- data/lib/regional.rb +5 -0
- data/regional.gemspec +26 -0
- metadata +137 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 92ca6c0a9ea4d63e6c7997fcf9ffc947395082ad
|
4
|
+
data.tar.gz: ae05934e3d9ffaf5e1b51c158c96061e5e66b01b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8ef941e925059cf5ffb7a2b732972c8c5721f3b1bff10934d428ae730fcd208efbf46cf2e94ea556be285e40d6723dcb7587bb0265e54687b43ee8c00fef5360
|
7
|
+
data.tar.gz: 5947eb692989ebf6dee865b2e77947a94cf8c5cd63c10a1696fea8580985bb882380b9fde8d13b806e6717001dd5527c3fd56a68651f8bce1e032307635fa379
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Jonathan Allard
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# Regional
|
2
|
+
**Regional** tells you if a certain location is within a given
|
3
|
+
territory.
|
4
|
+
|
5
|
+
For now, territories are defined with Canadian postal codes only.
|
6
|
+
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
gem 'regional'
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
|
16
|
+
$ bundle
|
17
|
+
|
18
|
+
Or install it yourself as:
|
19
|
+
|
20
|
+
$ gem install regional
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
```rb
|
25
|
+
plateau = Regional::Zone.new "H2H, H2J, H2T"
|
26
|
+
plateau.cover? "H2J 1L8" #=> true
|
27
|
+
plateau.cover? "H3A 1A1" #=> false
|
28
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,34 @@
|
|
1
|
+
Feature: Determine whether postal code is in range
|
2
|
+
|
3
|
+
Scenario: One FSA
|
4
|
+
Given the zone is J7Y
|
5
|
+
Then J7Y 4B1 should be included
|
6
|
+
But J7Z 1A1 shouldn't be included
|
7
|
+
|
8
|
+
Scenario: One letter
|
9
|
+
Given the zone is H
|
10
|
+
Then H2J 1B1 should be included
|
11
|
+
But J4C 1P3 shouldn't be included
|
12
|
+
|
13
|
+
Scenario: Hyphen range
|
14
|
+
Given the zone is G5U-G5X
|
15
|
+
Then G5V 1S1 should be included
|
16
|
+
But G5Z 0A0 shouldn't be included
|
17
|
+
|
18
|
+
Scenario: Multiple ranges
|
19
|
+
Given the zone is "H2, H3A-H3C"
|
20
|
+
Then H2J 1X1 should be included
|
21
|
+
And H3A 1B7 should be included
|
22
|
+
And H3B 2B9 should be included
|
23
|
+
And H3C 3B6 should be included
|
24
|
+
But H3D 5A5 should not be included
|
25
|
+
|
26
|
+
Scenario: Three ranges
|
27
|
+
Given the zone is "H2H, H2J, H2T"
|
28
|
+
Then H2J 1B9 should be included
|
29
|
+
But H2K 0A3 should not be included
|
30
|
+
|
31
|
+
Scenario: No range
|
32
|
+
Given the zone is ""
|
33
|
+
Then H0H 0H0 should be included
|
34
|
+
Then V1A 0B3 should be included
|
@@ -0,0 +1,51 @@
|
|
1
|
+
Feature: Understand Canadian postal codes
|
2
|
+
|
3
|
+
Scenario: Typical postal code
|
4
|
+
When I enter postal code J5L 1A8
|
5
|
+
Then it is valid
|
6
|
+
|
7
|
+
Scenario Outline: LDL DLD
|
8
|
+
When I enter postal code <input>
|
9
|
+
Then it's an error
|
10
|
+
|
11
|
+
Examples:
|
12
|
+
| input |
|
13
|
+
| 11A 1A1 |
|
14
|
+
| AAA 1A1 |
|
15
|
+
| A11 1A1 |
|
16
|
+
| A1A AA1 |
|
17
|
+
| A1A 111 |
|
18
|
+
| A1A 1AA |
|
19
|
+
| 1A1 A1A |
|
20
|
+
|
21
|
+
Scenario: Gibberish
|
22
|
+
When I enter postal code BOB LOBLAW
|
23
|
+
Then it is an error
|
24
|
+
|
25
|
+
Scenario Outline: Forbidden letters
|
26
|
+
When I enter postal code <input>
|
27
|
+
Then it is softly invalid
|
28
|
+
|
29
|
+
Examples:
|
30
|
+
| input |
|
31
|
+
| D1A 1A1 |
|
32
|
+
| F1A 1A1 |
|
33
|
+
| I1A 1A1 |
|
34
|
+
| O1A 1A1 |
|
35
|
+
| Q1A 1A1 |
|
36
|
+
| U1A 1A1 |
|
37
|
+
| W1A 1A1 |
|
38
|
+
| A1W 1A1 |
|
39
|
+
| A1A 1Q1 |
|
40
|
+
|
41
|
+
Scenario Outline: Spaces don't matter
|
42
|
+
When I enter postal code <input>
|
43
|
+
Then the canonical representation is "J7Y 6B1"
|
44
|
+
|
45
|
+
Examples:
|
46
|
+
| input |
|
47
|
+
| J7Y 6B1 |
|
48
|
+
| J7Y6B1 |
|
49
|
+
| J7Y-6B1 |
|
50
|
+
|
51
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
Then(/^it is valid$/) do
|
2
|
+
@it.should be_valid
|
3
|
+
end
|
4
|
+
|
5
|
+
Then(/^it is \S* ?invalid$/) do
|
6
|
+
@it.should_not be_valid
|
7
|
+
end
|
8
|
+
|
9
|
+
Then(/^(?:it does ?n.t work|it ?[i']s an error)$/) do
|
10
|
+
@error.should_not be_nil
|
11
|
+
end
|
12
|
+
|
13
|
+
Then('the canonical representation is "$s"') do |s|
|
14
|
+
@it.to_s.should == s
|
15
|
+
end
|
16
|
+
|
17
|
+
Then(/^pry$/i) do
|
18
|
+
binding.pry
|
19
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Given(/^the zone is "?([^"]*)"?$/) do |zone|
|
2
|
+
@zone = Regional::Zone.new(zone)
|
3
|
+
end
|
4
|
+
|
5
|
+
Then(/^(.+) should be included$/) do |place|
|
6
|
+
place = Regional::Postcode.new(place)
|
7
|
+
@zone.should cover(place)
|
8
|
+
end
|
9
|
+
|
10
|
+
Then(/^(.+) should.?n.t be included$/) do |place|
|
11
|
+
place = Regional::Postcode.new(place)
|
12
|
+
@zone.should_not cover(place)
|
13
|
+
end
|
14
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
|
2
|
+
module Regional
|
3
|
+
# Canadian postal code
|
4
|
+
class Postcode
|
5
|
+
@@pattern = /[a-z][0-9][a-z][0-9][a-z][0-9]/i
|
6
|
+
|
7
|
+
# returns `nil` if string is not a postal code
|
8
|
+
def initialize(string)
|
9
|
+
string = string.scan(/[a-z0-9]+/i).join.upcase
|
10
|
+
string = string.match(@@pattern).to_s
|
11
|
+
raise FormatDoesntMatch if string.empty?
|
12
|
+
|
13
|
+
@fsa = string[0..2]
|
14
|
+
@ldu = string[3..5]
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
@fsa + ' ' + @ldu
|
19
|
+
end
|
20
|
+
|
21
|
+
def pp
|
22
|
+
@fsa + ' ' + @ldu
|
23
|
+
end
|
24
|
+
|
25
|
+
def squeeze
|
26
|
+
@fsa + @ldu
|
27
|
+
end
|
28
|
+
|
29
|
+
def valid?
|
30
|
+
!false && !illegal_characters?
|
31
|
+
end
|
32
|
+
|
33
|
+
def illegal_characters?
|
34
|
+
to_s =~ /[DFIOQUW]/
|
35
|
+
end
|
36
|
+
|
37
|
+
def inspect
|
38
|
+
"#<#{self.class.name} #{to_s}>"
|
39
|
+
end
|
40
|
+
|
41
|
+
class ParseError < StandardError; end
|
42
|
+
|
43
|
+
class FormatDoesntMatch < ParseError; end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Regional
|
2
|
+
class Zone
|
3
|
+
attr_reader :components
|
4
|
+
|
5
|
+
def initialize(zone)
|
6
|
+
@components = zone.split(/,\s*/).map do |str|
|
7
|
+
array = str.split("-")
|
8
|
+
|
9
|
+
if array.count == 1
|
10
|
+
array.first...array.first.succ
|
11
|
+
elsif array.count == 2
|
12
|
+
array.first...array.last.succ
|
13
|
+
else
|
14
|
+
raise ArgumentError, "Range can only have one hyphen"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
@components[0] ||= "0".."ZZZZZZ"
|
19
|
+
end
|
20
|
+
|
21
|
+
def cover?(area)
|
22
|
+
@components.map{ |c| c.cover?(area.squeeze) }.inject do |m,o|
|
23
|
+
m || o
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def inspect
|
28
|
+
"#<#{self.class.name} #{@components.join(", ")}>"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/regional.rb
ADDED
data/regional.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'regional/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "regional"
|
8
|
+
spec.version = Regional::VERSION
|
9
|
+
spec.authors = ["Jonathan Allard"]
|
10
|
+
spec.email = ["jonathan@allard.io"]
|
11
|
+
spec.description = %q{Regional allows defining regions and testing what's inside it.}
|
12
|
+
spec.summary = spec.description
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "cucumber"
|
23
|
+
spec.add_development_dependency "rake"
|
24
|
+
spec.add_development_dependency "pry"
|
25
|
+
spec.add_development_dependency "rspec-expectations"
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: regional
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jonathan Allard
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-06-25 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: cucumber
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec-expectations
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: Regional allows defining regions and testing what's inside it.
|
84
|
+
email:
|
85
|
+
- jonathan@allard.io
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- .gitignore
|
91
|
+
- Gemfile
|
92
|
+
- LICENSE.txt
|
93
|
+
- README.md
|
94
|
+
- Rakefile
|
95
|
+
- features/determine_inclusion.feature
|
96
|
+
- features/postal_codes.feature
|
97
|
+
- features/step_definitions/postcode_steps.rb
|
98
|
+
- features/step_definitions/steps.rb
|
99
|
+
- features/step_definitions/zone_steps.rb
|
100
|
+
- features/support/env.rb
|
101
|
+
- lib/regional.rb
|
102
|
+
- lib/regional/postcode.rb
|
103
|
+
- lib/regional/version.rb
|
104
|
+
- lib/regional/zone.rb
|
105
|
+
- regional.gemspec
|
106
|
+
homepage: ''
|
107
|
+
licenses:
|
108
|
+
- MIT
|
109
|
+
metadata: {}
|
110
|
+
post_install_message:
|
111
|
+
rdoc_options: []
|
112
|
+
require_paths:
|
113
|
+
- lib
|
114
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - '>='
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - '>='
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
requirements: []
|
125
|
+
rubyforge_project:
|
126
|
+
rubygems_version: 2.0.3
|
127
|
+
signing_key:
|
128
|
+
specification_version: 4
|
129
|
+
summary: Regional allows defining regions and testing what's inside it.
|
130
|
+
test_files:
|
131
|
+
- features/determine_inclusion.feature
|
132
|
+
- features/postal_codes.feature
|
133
|
+
- features/step_definitions/postcode_steps.rb
|
134
|
+
- features/step_definitions/steps.rb
|
135
|
+
- features/step_definitions/zone_steps.rb
|
136
|
+
- features/support/env.rb
|
137
|
+
has_rdoc:
|