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 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
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
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,8 @@
1
+
2
+ When(/^I enter postal code (.+)$/) do |postcode|
3
+ begin
4
+ @it = Regional::Postcode.new(postcode)
5
+ rescue => @error
6
+ end
7
+ end
8
+
@@ -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,4 @@
1
+
2
+ require File.dirname(__FILE__) + '/../../lib/regional.rb'
3
+ require 'rspec/expectations'
4
+ require 'pry'
@@ -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,3 @@
1
+ module Regional
2
+ VERSION = "0.1.0"
3
+ 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
@@ -0,0 +1,5 @@
1
+ require "regional/version"
2
+ require "regional/postcode"
3
+ require "regional/zone"
4
+
5
+ module Regional; end
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: