pinpoint 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,20 +2,28 @@ require 'pinpoint/formatter'
2
2
 
3
3
  module Pinpoint
4
4
  class Address
5
- attr_accessor :name,
6
- :street,
7
- :city,
8
- :state,
9
- :county,
10
- :zip_code,
11
- :country,
12
- :latitude,
13
- :longitude
5
+ ATTRIBUTE_NAMES = [
6
+ :name,
7
+ :street_and_premises,
8
+ :city,
9
+ :state,
10
+ :county,
11
+ :postal_code,
12
+ :country,
13
+ :latitude,
14
+ :longitude
15
+ ]
16
+
17
+ attr_accessor *ATTRIBUTE_NAMES
14
18
 
15
19
  # City Aliases
16
20
  alias :locality :city
17
21
  alias :locality= :city=
18
22
 
23
+ # Street Aliases
24
+ alias :street :street_and_premises
25
+ alias :street= :street_and_premises=
26
+
19
27
  # State Aliases
20
28
  alias :region :state
21
29
  alias :region= :state=
@@ -23,12 +31,10 @@ module Pinpoint
23
31
  alias :province= :state=
24
32
 
25
33
  # Zip Code Aliases
26
- alias :postal_code :zip_code
27
- alias :postal_code= :zip_code=
28
- alias :postalcode :zip_code
29
- alias :postalcode= :zip_code=
30
- alias :zip :zip_code
31
- alias :zip= :zip_code=
34
+ alias :zip_code :postal_code
35
+ alias :zip_code= :postal_code=
36
+ alias :zip :postal_code
37
+ alias :zip= :postal_code=
32
38
 
33
39
  # County Aliases
34
40
  alias :district :county
@@ -41,10 +47,10 @@ module Pinpoint
41
47
  end
42
48
 
43
49
  def complete?
44
- present?(street) &&
45
- present?(city) &&
46
- present?(state) &&
47
- present?(zip_code)
50
+ present?(street_and_premises) &&
51
+ present?(city) &&
52
+ present?(state) &&
53
+ present?(postal_code)
48
54
  end
49
55
 
50
56
  def incomplete?
@@ -52,10 +58,10 @@ module Pinpoint
52
58
  end
53
59
 
54
60
  def empty?
55
- blank?(street) &&
56
- blank?(city) &&
57
- blank?(state) &&
58
- blank?(zip_code)
61
+ blank?(street_and_premises) &&
62
+ blank?(city) &&
63
+ blank?(state) &&
64
+ blank?(postal_code)
59
65
  end
60
66
 
61
67
  def to_s(options = { :country => :us, :format => :one_line })
@@ -0,0 +1,48 @@
1
+ require 'pinpoint/model_support'
2
+ require 'pinpoint/validations'
3
+
4
+ module Pinpoint
5
+ module Composable
6
+ ##
7
+ # Public: Allows fields on a class to be composed/decomposed to
8
+ # Pinpoint::Addresses.
9
+ #
10
+ # field_name - The object to apply the accessors to
11
+ # options - A Hash of options to apply to the method call
12
+ #
13
+ # :validate - A Boolean describing whether to include
14
+ # ActiveModel::Validations into the class for the
15
+ # address fields.
16
+ # :prefix - If set, then all fields which make up the Address
17
+ # will be prefixed with that string (eg: #venue_city
18
+ # instead of just #city) If you do not want field
19
+ # names to be prefixed simply set it to false.
20
+ # (defaults to the field name).
21
+ #
22
+ # Example
23
+ #
24
+ # # Implicit Prefix (will look for fields such as 'address_city')
25
+ # pinpoint :address
26
+ #
27
+ # # Explicit Prefix (will look for fields such as 'venue_city')
28
+ # pinpoint :location, :prefix => :venue
29
+ #
30
+ # # No Prefix (will look for fields such as 'city')
31
+ # pinpoint :location, :prefix => false
32
+ #
33
+ # # Include field validations
34
+ # pinpoint :address, :validate => true
35
+ #
36
+ # Returns nothing
37
+ #
38
+ def pinpoint(field_name, options = {})
39
+ options[:field_field_name] = field_name
40
+
41
+ if options[:validate]
42
+ Pinpoint::Validations.define(self, options)
43
+ end
44
+
45
+ Pinpoint::ModelSupport.define_address_accessors(self, options)
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,157 @@
1
+ require 'active_support/core_ext/object/blank'
2
+ require 'pinpoint/address'
3
+
4
+ module Pinpoint
5
+ module ModelSupport
6
+ ##
7
+ # Private: Defines address accessors for a given object.
8
+ #
9
+ # object - The object to apply the accessors to
10
+ # options - A Hash of options to apply to the method call
11
+ #
12
+ # :field_name - The String or Symbol representing the name of the
13
+ # field pair to create (eg: #venue and #venue=).
14
+ # :prefix - If set, then all fields which make up the Address
15
+ # will be prefixed with that string (eg: #venue_city
16
+ # instead of just #city) If you do not want field
17
+ # names to be prefixed simply set it to false.
18
+ # (defaults to the field name).
19
+ #
20
+ # Example
21
+ #
22
+ # # Without a Prefix
23
+ # define_address_accessors my_object, field_name: :venue
24
+ #
25
+ # # With a Prefix
26
+ # define_address_accessors my_object, field_name: :address,
27
+ # prefix: :venue
28
+ #
29
+ # Returns nothing
30
+ #
31
+ def self.define_address_accessors(object, options = {})
32
+ field_name = options.fetch(:field_name)
33
+ options[:prefix] = options.fetch(:prefix, field_name)
34
+ options[:address_fields] ||= find_address_fields(object, options)
35
+
36
+ define_address_reader(object, options)
37
+ define_address_setter(object, options)
38
+ define_address_predicates(object, options)
39
+ end
40
+
41
+ private
42
+
43
+ ##
44
+ # Private: Defines the reader for the composed Address field.
45
+ #
46
+ # The defined method will collect all of the disparate pieces of information
47
+ # from the model and create a Pinpoint::Address that represents that
48
+ # information.
49
+ #
50
+ # object - (See .define_address_accessors object parameter)
51
+ # options - (See .define_address_accessors options parameter)
52
+ #
53
+ # Returns nothing
54
+ #
55
+ def self.define_address_reader(object, options)
56
+ field_name = options.fetch(:field_name)
57
+ attribute_fields = options.fetch(:address_fields).fetch(:base_fields)
58
+ reader_fields = options.fetch(:address_fields).fetch(:reader_fields)
59
+ field_pairs = attribute_fields.zip reader_fields
60
+
61
+ # TODO: Memoize
62
+ object.send(:define_method, field_name) do
63
+ address_fields_and_values = field_pairs.map do |field_pair|
64
+ [field_pair[0], send(field_pair[1])]
65
+ end
66
+ address_fields_and_values = Hash[address_fields_and_values]
67
+
68
+ Pinpoint::Address.new(address_fields_and_values)
69
+ end
70
+ end
71
+
72
+ ##
73
+ # Private: Defines the writer for the composed Address field.
74
+ #
75
+ # The defined method will read all of the pieces of the address from the
76
+ # Address that is passed in and set that information on the model's address
77
+ # fields.
78
+ #
79
+ # object - (See .define_address_accessors object parameter)
80
+ # options - (See .define_address_accessors options parameter)
81
+ #
82
+ # Returns nothing
83
+ #
84
+ def self.define_address_setter(object, options)
85
+ name = options.fetch(:field_name)
86
+ reader_fields = options.fetch(:address_fields).fetch(:base_fields)
87
+ writer_fields = options.fetch(:address_fields).fetch(:writer_fields)
88
+ field_pairs = reader_fields.zip writer_fields
89
+
90
+ object.send(:define_method, "#{name}=") do |address|
91
+ field_pairs.each do |field_pair|
92
+ send(field_pair[1], address.send(field_pair[0]))
93
+ end
94
+ end
95
+ end
96
+
97
+ ##
98
+ # Private: Defines a method which checks to see if the composed address
99
+ # field is incomplete.
100
+ #
101
+ # This is used mainly to remove the need to 'reach into' the Address itself.
102
+ #
103
+ # object - (See .define_address_accessors object parameter)
104
+ # options - (See .define_address_accessors options parameter)
105
+ #
106
+ # Returns nothing
107
+ #
108
+ def self.define_address_predicates(object, options)
109
+ name = options.fetch(:field_name)
110
+
111
+ object.send(:define_method, "#{name}_incomplete?") do
112
+ send(:"#{name}").incomplete?
113
+ end
114
+ end
115
+
116
+ ##
117
+ # Private: Finds the writer and reader methods that will be used whenever
118
+ # the composed address field is read from or written to.
119
+ #
120
+ # Additionally it maps writer fields back to the field that must be read
121
+ # from on the Address to get the proper value.
122
+ #
123
+ # Returns a Hash of 'base', 'reader' and 'writer' fields.
124
+ #
125
+ def self.find_address_fields(object, options)
126
+ prefix = options[:prefix].blank? ? '' : "#{options[:prefix]}_"
127
+ address_attrs = Pinpoint::Address::ATTRIBUTE_NAMES
128
+ reader_field_names = address_attrs.map { |field| :"#{prefix}#{field}" }
129
+ writer_field_names = address_attrs.map { |field| :"#{prefix}#{field}=" }
130
+
131
+ reader_fields = find_existing_methods(object, reader_field_names)
132
+ writer_fields = find_existing_methods(object, writer_field_names)
133
+ base_fields = writer_fields.map do |field|
134
+ field.to_s.
135
+ gsub(/\A#{prefix}/, '').
136
+ gsub(/=\z/, '').
137
+ to_sym
138
+ end
139
+
140
+ {
141
+ base_fields: base_fields,
142
+ reader_fields: reader_fields,
143
+ writer_fields: writer_fields
144
+ }
145
+ end
146
+
147
+ ##
148
+ # Private: Finds the items that are common between the fields being passed
149
+ # in and the public instance methods on the object.
150
+ #
151
+ # Returns an Array of common methods
152
+ #
153
+ def self.find_existing_methods(object, fields)
154
+ fields & object.public_instance_methods
155
+ end
156
+ end
157
+ end
@@ -3,32 +3,35 @@ require 'pinpoint/config/patterns'
3
3
 
4
4
  module Pinpoint
5
5
  module Validations
6
- def install_validations(name)
7
- instance_eval <<-VALIDATIONIZATION
8
- validates :#{name}_name,
6
+ def self.define(object, options)
7
+ name = options.fetch(:field_name)
8
+ prefix = options.fetch(:prefix, name).blank? ? '' : "#{options[:prefix]}_"
9
+
10
+ object.instance_eval <<-VALIDATIONIZATION
11
+ validates :#{prefix}name,
9
12
  :length => {
10
13
  :maximum => 140 }
11
14
 
12
- validates :#{name}_street_and_premises,
15
+ validates :#{prefix}street_and_premises,
13
16
  :presence => {
14
17
  :if => :#{name}_incomplete? },
15
18
  :length => {
16
19
  :maximum => 255 }
17
20
 
18
- validates :#{name}_city,
21
+ validates :#{prefix}city,
19
22
  :presence => {
20
23
  :if => :#{name}_incomplete? },
21
24
  :length => {
22
25
  :maximum => 60 }
23
26
 
24
- validates :#{name}_state_or_province,
27
+ validates :#{prefix}state,
25
28
  :presence => {
26
29
  :if => :#{name}_incomplete? },
27
30
  :inclusion => {
28
31
  :in => Pinpoint::US_STATES,
29
32
  :allow_blank => true }
30
33
 
31
- validates :#{name}_postal_code,
34
+ validates :#{prefix}postal_code,
32
35
  :presence => {
33
36
  :if => :#{name}_incomplete? },
34
37
  :format => {
@@ -1,3 +1,3 @@
1
1
  module Pinpoint
2
- VERSION = '0.1.0'
2
+ VERSION = '0.2.0'
3
3
  end
data/lib/pinpoint.rb CHANGED
@@ -1,48 +1,6 @@
1
1
  require 'pinpoint/version'
2
- require 'pinpoint/validations'
2
+ require 'pinpoint/composable'
3
3
  require 'pinpoint/address'
4
4
 
5
5
  module Pinpoint
6
- module ClassMethods
7
- include Validations
8
-
9
- def pinpoint(name, options = {})
10
- if options[:validate]
11
- install_validations(name)
12
- end
13
-
14
- define_method name do
15
- # TODO: Memoize
16
-
17
- Pinpoint::Address.new(
18
- :name => respond_to?(:"#{name}_name") ? send(:"#{name}_name") : '',
19
- :street => respond_to?(:"#{name}_street_and_premises") ? send(:"#{name}_street_and_premises") : '',
20
- :city => respond_to?(:"#{name}_city") ? send(:"#{name}_city") : '',
21
- :state => respond_to?(:"#{name}_state_or_province") ? send(:"#{name}_state_or_province") : '',
22
- :county => respond_to?(:"#{name}_district_or_county") ? send(:"#{name}_district_or_county") : '',
23
- :postal_code => respond_to?(:"#{name}_postal_code") ? send(:"#{name}_postal_code") : '',
24
- :country => respond_to?(:"#{name}_country") ? send(:"#{name}_country") : '',
25
- :latitude => respond_to?(:"#{name}_latitude") ? send(:"#{name}_latitude") : '',
26
- :longitude => respond_to?(:"#{name}_longitude") ? send(:"#{name}_longitude") : ''
27
- )
28
- end
29
-
30
- define_method "#{name}=" do |address|
31
- send(:"#{name}_name=", address.name)
32
- send(:"#{name}_street_and_premises=", address.street)
33
- send(:"#{name}_city=", address.city)
34
- send(:"#{name}_state_or_province=", address.state)
35
- send(:"#{name}_postal_code=", address.zip_code)
36
- send(:"#{name}_country=", address.country)
37
- end
38
-
39
- define_method "#{name}_incomplete?" do
40
- send(:"#{name}").incomplete?
41
- end
42
- end
43
- end
44
-
45
- def self.included(base)
46
- base.extend ClassMethods
47
- end
48
6
  end
data/spec/address_spec.rb CHANGED
@@ -12,8 +12,6 @@ describe 'Pinpoint::Address' do
12
12
  it { address.respond_to?(:locality=).should be_true }
13
13
  it { address.respond_to?(:postal_code).should be_true }
14
14
  it { address.respond_to?(:postal_code=).should be_true }
15
- it { address.respond_to?(:postalcode).should be_true }
16
- it { address.respond_to?(:postalcode=).should be_true }
17
15
  it { address.respond_to?(:zip).should be_true }
18
16
  it { address.respond_to?(:zip=).should be_true }
19
17
  it { address.respond_to?(:district).should be_true }
@@ -0,0 +1,234 @@
1
+ require 'rspectacular'
2
+ require 'pinpoint/model_support'
3
+
4
+ class PinpointableAccessorClass
5
+ def initialize(options = {})
6
+ options.each do |key, value|
7
+ send("#{key}=", value)
8
+ end
9
+ end
10
+ end
11
+
12
+ class PinpointableAccessorClassWithNoPrefixedFields < PinpointableAccessorClass
13
+ attr_accessor :name,
14
+ :street_and_premises,
15
+ :city,
16
+ :state,
17
+ :county,
18
+ :postal_code,
19
+ :country,
20
+ :latitude,
21
+ :longitude
22
+ end
23
+
24
+ class PinpointableAccessorClassWithPrefixedFields < PinpointableAccessorClass
25
+ attr_accessor :my_address_name,
26
+ :my_address_street_and_premises,
27
+ :my_address_city,
28
+ :my_address_state,
29
+ :my_address_county,
30
+ :my_address_postal_code,
31
+ :my_address_country,
32
+ :my_address_latitude,
33
+ :my_address_longitude
34
+ end
35
+
36
+ class PinpointableAccessorClassWithIncompleteFields < PinpointableAccessorClass
37
+ attr_accessor :name,
38
+ :street_and_premises,
39
+ :city,
40
+ :state
41
+ end
42
+
43
+ describe Pinpoint::ModelSupport do
44
+ let(:model_support_module) { Pinpoint::ModelSupport }
45
+
46
+ context 'when only a composed name is passed in' do
47
+ let(:pinpointable_class) { PinpointableAccessorClassWithPrefixedFields }
48
+ let(:pinpointable) { pinpointable_class.new(
49
+ my_address_name: 'name',
50
+ my_address_street_and_premises: 'street',
51
+ my_address_city: 'city',
52
+ my_address_state: 'state',
53
+ my_address_county: 'county',
54
+ my_address_postal_code: 'postal_code',
55
+ my_address_country: 'country',
56
+ my_address_latitude: 'latitude',
57
+ my_address_longitude: 'longitude' ) }
58
+
59
+ it 'can add a reader to a class' do
60
+ model_support_module.define_address_accessors(pinpointable_class,
61
+ field_name: :my_address)
62
+
63
+ pinpointable.should respond_to :my_address
64
+ end
65
+
66
+ it 'can compose an Address with the proper values from the model' do
67
+ model_support_module.define_address_accessors(pinpointable_class,
68
+ field_name: :my_address)
69
+
70
+ Pinpoint::Address.should_receive(:new).with(
71
+ name: 'name',
72
+ street_and_premises: 'street',
73
+ city: 'city',
74
+ state: 'state',
75
+ county: 'county',
76
+ postal_code: 'postal_code',
77
+ country: 'country',
78
+ latitude: 'latitude',
79
+ longitude: 'longitude'
80
+ )
81
+
82
+ pinpointable.my_address
83
+ end
84
+
85
+ it 'can deconstruct an Address into its component pieces' do
86
+ model_support_module.define_address_accessors(pinpointable_class,
87
+ field_name: :my_address)
88
+
89
+ address = Pinpoint::Address.new(name: 'name',
90
+ street_and_premises: 'street',
91
+ city: 'city',
92
+ state: 'state',
93
+ county: 'county',
94
+ postal_code: 'postal_code',
95
+ country: 'country',
96
+ latitude: 'latitude',
97
+ longitude: 'longitude')
98
+
99
+ pinpointable.should_receive :my_address_name=, :with => 'name'
100
+ pinpointable.should_receive :my_address_street_and_premises=, :with => 'street'
101
+ pinpointable.should_receive :my_address_city=, :with => 'city'
102
+ pinpointable.should_receive :my_address_state=, :with => 'state'
103
+ pinpointable.should_receive :my_address_county=, :with => 'county'
104
+ pinpointable.should_receive :my_address_postal_code=, :with => 'postal_code'
105
+ pinpointable.should_receive :my_address_country=, :with => 'country'
106
+ pinpointable.should_receive :my_address_latitude=, :with => 'latitude'
107
+ pinpointable.should_receive :my_address_longitude=, :with => 'longitude'
108
+
109
+ pinpointable.my_address = address
110
+ end
111
+ end
112
+
113
+ context 'when a composed name is passed in along with a prefix' do
114
+ let(:pinpointable_class) { PinpointableAccessorClassWithPrefixedFields }
115
+ let(:pinpointable) { pinpointable_class.new( my_address_name: 'name',
116
+ my_address_street_and_premises: 'street',
117
+ my_address_city: 'city',
118
+ my_address_state: 'state',
119
+ my_address_county: 'county',
120
+ my_address_postal_code: 'postal_code',
121
+ my_address_country: 'country',
122
+ my_address_latitude: 'latitude',
123
+ my_address_longitude: 'longitude' ) }
124
+
125
+ it 'can add a reader to a class' do
126
+ model_support_module.define_address_accessors(pinpointable_class,
127
+ field_name: :address,
128
+ prefix: :my_address)
129
+
130
+ pinpointable.should respond_to :address
131
+ end
132
+
133
+ it 'can compose an Address with the proper values from the model' do
134
+ model_support_module.define_address_accessors(pinpointable_class,
135
+ field_name: :address,
136
+ prefix: :my_address)
137
+
138
+ Pinpoint::Address.should_receive(:new).with(
139
+ name: 'name',
140
+ street_and_premises: 'street',
141
+ city: 'city',
142
+ state: 'state',
143
+ county: 'county',
144
+ postal_code: 'postal_code',
145
+ country: 'country',
146
+ latitude: 'latitude',
147
+ longitude: 'longitude'
148
+ )
149
+
150
+ pinpointable.address
151
+ end
152
+
153
+ it 'can deconstruct an Address into its component pieces' do
154
+ model_support_module.define_address_accessors(pinpointable_class,
155
+ field_name: :address,
156
+ prefix: :my_address)
157
+
158
+ address = Pinpoint::Address.new(name: 'name',
159
+ street_and_premises: 'street',
160
+ city: 'city',
161
+ state: 'state',
162
+ county: 'county',
163
+ postal_code: 'postal_code',
164
+ country: 'country',
165
+ latitude: 'latitude',
166
+ longitude: 'longitude')
167
+
168
+ pinpointable.should_receive :my_address_name=, :with => 'name'
169
+ pinpointable.should_receive :my_address_street_and_premises=, :with => 'street'
170
+ pinpointable.should_receive :my_address_city=, :with => 'city'
171
+ pinpointable.should_receive :my_address_state=, :with => 'state'
172
+ pinpointable.should_receive :my_address_county=, :with => 'county'
173
+ pinpointable.should_receive :my_address_postal_code=, :with => 'postal_code'
174
+ pinpointable.should_receive :my_address_country=, :with => 'country'
175
+ pinpointable.should_receive :my_address_latitude=, :with => 'latitude'
176
+ pinpointable.should_receive :my_address_longitude=, :with => 'longitude'
177
+
178
+ pinpointable.address = address
179
+ end
180
+ end
181
+
182
+ context 'when an object is referenced which does not implement all of the fields' do
183
+ let(:pinpointable_class) { PinpointableAccessorClassWithIncompleteFields }
184
+ let(:pinpointable) { pinpointable_class.new( name: 'name',
185
+ street_and_premises: 'street',
186
+ city: 'city',
187
+ state: 'state' ) }
188
+
189
+ it 'can compose an Address with the proper values from the model' do
190
+ model_support_module.define_address_accessors(pinpointable_class,
191
+ field_name: :address,
192
+ prefix: false)
193
+
194
+ Pinpoint::Address.should_receive(:new).with(
195
+ name: 'name',
196
+ street_and_premises: 'street',
197
+ city: 'city',
198
+ state: 'state'
199
+ )
200
+
201
+ pinpointable.address
202
+ end
203
+
204
+ it 'can deconstruct an Address into its component pieces' do
205
+ model_support_module.define_address_accessors(pinpointable_class,
206
+ field_name: :address,
207
+ prefix: false)
208
+
209
+ address = Pinpoint::Address.new(name: 'name',
210
+ street_and_premises: 'street',
211
+ city: 'city',
212
+ state: 'state',
213
+ county: 'county',
214
+ postal_code: 'postal_code',
215
+ country: 'country',
216
+ latitude: 'latitude',
217
+ longitude: 'longitude')
218
+
219
+ pinpointable.should_receive :name=, :with => 'name'
220
+ pinpointable.should_receive :street_and_premises=, :with => 'street'
221
+ pinpointable.should_receive :city=, :with => 'city'
222
+ pinpointable.should_receive :state=, :with => 'state'
223
+
224
+ pinpointable.address = address
225
+ end
226
+ end
227
+
228
+ context 'when a composed name is not passed in' do
229
+ it 'throws an error' do
230
+ expect { model_support_module.define_address_accessors(pinpointable_class) }.to(
231
+ raise_error)
232
+ end
233
+ end
234
+ end
@@ -5,30 +5,31 @@ require 'pinpoint'
5
5
 
6
6
  class ValidatablePinpointable
7
7
  include ActiveModel::Validations
8
- include Pinpoint
8
+ extend Pinpoint::Composable
9
9
 
10
- attr_accessor :address_name,
11
- :address_street_and_premises,
12
- :address_city,
13
- :address_state_or_province,
14
- :address_postal_code,
15
- :address_country
10
+ attr_accessor :name,
11
+ :street_and_premises,
12
+ :city,
13
+ :state,
14
+ :postal_code,
15
+ :country
16
16
 
17
- pinpoint :address, :validate => true
17
+ pinpoint :address, prefix: false,
18
+ validate: true
18
19
  end
19
20
 
20
21
  class UnvalidatablePinpointable
21
22
  include ActiveModel::Validations
22
- include Pinpoint
23
+ extend Pinpoint::Composable
23
24
 
24
25
  attr_accessor :address_name,
25
26
  :address_street_and_premises,
26
27
  :address_city,
27
- :address_state_or_province,
28
+ :address_state,
28
29
  :address_postal_code,
29
30
  :address_country
30
31
 
31
- pinpoint :address
32
+ pinpoint :address, :prefix => :address
32
33
  end
33
34
 
34
35
  describe 'Pinpoint::Validations' do
@@ -36,60 +37,60 @@ describe 'Pinpoint::Validations' do
36
37
  subject { ValidatablePinpointable.new }
37
38
 
38
39
  describe '#address_name' do
39
- it { should have_valid(:address_name).when nil, ('*' * 140) }
40
- it { should_not have_valid(:address_name).when ('*' * 141) }
40
+ it { should have_valid(:name).when nil, ('*' * 140) }
41
+ it { should_not have_valid(:name).when ('*' * 141) }
41
42
  end
42
43
 
43
- describe '#address_state_or_province' do
44
- it { should have_valid(:address_street_and_premises).when nil, ('*' * 255) }
45
- it { should_not have_valid(:address_street_and_premises).when ('*' * 256) }
44
+ describe '#address_state' do
45
+ it { should have_valid(:street_and_premises).when nil, ('*' * 255) }
46
+ it { should_not have_valid(:street_and_premises).when ('*' * 256) }
46
47
  end
47
48
 
48
49
  describe '#address_city' do
49
- it { should have_valid(:address_city).when nil, ('*' * 60) }
50
- it { should_not have_valid(:address_city).when ('*' * 61) }
50
+ it { should have_valid(:city).when nil, ('*' * 60) }
51
+ it { should_not have_valid(:city).when ('*' * 61) }
51
52
  end
52
53
 
53
54
  describe '#address_street_and_premises' do
54
- it { should have_valid(:address_state_or_province).when nil, '', 'NY', 'MO' }
55
- it { should_not have_valid(:address_state_or_province).when 'WP', 'NI', 'PO' }
55
+ it { should have_valid(:state).when nil, '', 'NY', 'MO' }
56
+ it { should_not have_valid(:state).when 'WP', 'NI', 'PO' }
56
57
  end
57
58
 
58
59
  describe '#address_postal_code' do
59
- it { should have_valid(:address_postal_code).when nil, '', 12345, 12345-1234 }
60
- it { should_not have_valid(:address_postal_code).when 'asdf', '123456' }
60
+ it { should have_valid(:postal_code).when nil, '', 12345, 12345-1234 }
61
+ it { should_not have_valid(:postal_code).when 'asdf', '123456' }
61
62
  end
62
63
 
63
64
  context "when the street address is set" do
64
- before { subject.address_street_and_premises = "foo" }
65
+ before { subject.street_and_premises = "foo" }
65
66
 
66
- it('the city should not be valid when blank') { should_not have_valid(:address_city).when nil, '' }
67
- it('the state should not be valid when blank') { should_not have_valid(:address_state_or_province).when nil, '' }
68
- it('the zip code should not be valid when blank') { should_not have_valid(:address_postal_code).when nil, '' }
67
+ it('the city should not be valid when blank') { should_not have_valid(:city).when nil, '' }
68
+ it('the state should not be valid when blank') { should_not have_valid(:state).when nil, '' }
69
+ it('the zip code should not be valid when blank') { should_not have_valid(:postal_code).when nil, '' }
69
70
  end
70
71
 
71
72
  context "when the city is set" do
72
- before { subject.address_city = "foo" }
73
+ before { subject.city = "foo" }
73
74
 
74
- it('the street should not be valid when blank') { should_not have_valid(:address_street_and_premises).when nil, '' }
75
- it('the state should not be valid when blank') { should_not have_valid(:address_state_or_province).when nil, '' }
76
- it('the zip code should not be valid when blank') { should_not have_valid(:address_postal_code).when nil, '' }
75
+ it('the street should not be valid when blank') { should_not have_valid(:street_and_premises).when nil, '' }
76
+ it('the state should not be valid when blank') { should_not have_valid(:state).when nil, '' }
77
+ it('the zip code should not be valid when blank') { should_not have_valid(:postal_code).when nil, '' }
77
78
  end
78
79
 
79
80
  context "when the state is set" do
80
- before { subject.address_state_or_province= "FO" }
81
+ before { subject.state = "FO" }
81
82
 
82
- it('the street should not be valid when blank') { should_not have_valid(:address_street_and_premises).when nil, '' }
83
- it('the city should not be valid when blank') { should_not have_valid(:address_city).when nil, '' }
84
- it('the zip code should not be valid when blank') { should_not have_valid(:address_postal_code).when nil, '' }
83
+ it('the street should not be valid when blank') { should_not have_valid(:street_and_premises).when nil, '' }
84
+ it('the city should not be valid when blank') { should_not have_valid(:city).when nil, '' }
85
+ it('the zip code should not be valid when blank') { should_not have_valid(:postal_code).when nil, '' }
85
86
  end
86
87
 
87
88
  context "when the zip is set" do
88
- before { subject.address_postal_code = "12345" }
89
+ before { subject.postal_code = "12345" }
89
90
 
90
- it('the street should not be valid when blank') { should_not have_valid(:address_street_and_premises).when nil, '' }
91
- it('the city should not be valid when blank') { should_not have_valid(:address_city).when nil, '' }
92
- it('the state should not be valid when blank') { should_not have_valid(:address_state_or_province).when nil, '' }
91
+ it('the street should not be valid when blank') { should_not have_valid(:street_and_premises).when nil, '' }
92
+ it('the city should not be valid when blank') { should_not have_valid(:city).when nil, '' }
93
+ it('the state should not be valid when blank') { should_not have_valid(:state).when nil, '' }
93
94
  end
94
95
  end
95
96
 
@@ -97,55 +98,55 @@ describe 'Pinpoint::Validations' do
97
98
  subject { UnvalidatablePinpointable.new }
98
99
 
99
100
  describe '#address_name' do
100
- it { should have_valid(:address_name).when ('*' * 141) }
101
+ it { should have_valid(:address_name).when ('*' * 141) }
101
102
  end
102
103
 
103
- describe '#address_state_or_province' do
104
- it { should have_valid(:address_street_and_premises).when ('*' * 256) }
104
+ describe '#address_state' do
105
+ it { should have_valid(:address_street_and_premises).when ('*' * 256) }
105
106
  end
106
107
 
107
108
  describe '#address_city' do
108
- it { should have_valid(:address_city).when ('*' * 61) }
109
+ it { should have_valid(:address_city).when ('*' * 61) }
109
110
  end
110
111
 
111
112
  describe '#address_street_and_premises' do
112
- it { should have_valid(:address_state_or_province).when 'WP', 'NI', 'PO' }
113
+ it { should have_valid(:address_state).when 'WP', 'NI', 'PO' }
113
114
  end
114
115
 
115
116
  describe '#address_postal_code' do
116
- it { should have_valid(:address_postal_code).when 'asdf', '123456' }
117
+ it { should have_valid(:address_postal_code).when 'asdf', '123456' }
117
118
  end
118
119
 
119
120
  context "when the street address is set" do
120
121
  before { subject.address_street_and_premises = "foo" }
121
122
 
122
- it('the city should not be valid when blank') { should have_valid(:address_city).when nil, '' }
123
- it('the state should not be valid when blank') { should have_valid(:address_state_or_province).when nil, '' }
124
- it('the zip code should not be valid when blank') { should have_valid(:address_postal_code).when nil, '' }
123
+ it('the city should not be valid when blank') { should have_valid(:address_city).when nil, '' }
124
+ it('the state should not be valid when blank') { should have_valid(:address_state).when nil, '' }
125
+ it('the zip code should not be valid when blank') { should have_valid(:address_postal_code).when nil, '' }
125
126
  end
126
127
 
127
128
  context "when the city is set" do
128
129
  before { subject.address_city = "foo" }
129
130
 
130
- it('the street should not be valid when blank') { should have_valid(:address_street_and_premises).when nil, '' }
131
- it('the state should not be valid when blank') { should have_valid(:address_state_or_province).when nil, '' }
132
- it('the zip code should not be valid when blank') { should have_valid(:address_postal_code).when nil, '' }
131
+ it('the street should not be valid when blank') { should have_valid(:address_street_and_premises).when nil, '' }
132
+ it('the state should not be valid when blank') { should have_valid(:address_state).when nil, '' }
133
+ it('the zip code should not be valid when blank') { should have_valid(:address_postal_code).when nil, '' }
133
134
  end
134
135
 
135
136
  context "when the state is set" do
136
- before { subject.address_state_or_province= "FO" }
137
+ before { subject.address_state = "FO" }
137
138
 
138
- it('the street should not be valid when blank') { should have_valid(:address_street_and_premises).when nil, '' }
139
- it('the city should not be valid when blank') { should have_valid(:address_city).when nil, '' }
140
- it('the zip code should not be valid when blank') { should have_valid(:address_postal_code).when nil, '' }
139
+ it('the street should not be valid when blank') { should have_valid(:address_street_and_premises).when nil, '' }
140
+ it('the city should not be valid when blank') { should have_valid(:address_city).when nil, '' }
141
+ it('the zip code should not be valid when blank') { should have_valid(:address_postal_code).when nil, '' }
141
142
  end
142
143
 
143
144
  context "when the zip is set" do
144
145
  before { subject.address_postal_code = "12345" }
145
146
 
146
- it('the street should not be valid when blank') { should have_valid(:address_street_and_premises).when nil, '' }
147
- it('the city should not be valid when blank') { should have_valid(:address_city).when nil, '' }
148
- it('the state should not be valid when blank') { should have_valid(:address_state_or_province).when nil, '' }
147
+ it('the street should not be valid when blank') { should have_valid(:address_street_and_premises).when nil, '' }
148
+ it('the city should not be valid when blank') { should have_valid(:address_city).when nil, '' }
149
+ it('the state should not be valid when blank') { should have_valid(:address_state).when nil, '' }
149
150
  end
150
151
  end
151
152
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pinpoint
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-02-18 00:00:00.000000000 Z
13
+ date: 2013-02-19 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rspec
@@ -86,6 +86,7 @@ extra_rdoc_files:
86
86
  - LICENSE
87
87
  files:
88
88
  - lib/pinpoint/address.rb
89
+ - lib/pinpoint/composable.rb
89
90
  - lib/pinpoint/config/formats/us.yml
90
91
  - lib/pinpoint/config/patterns.rb
91
92
  - lib/pinpoint/config/us_states.rb
@@ -99,6 +100,7 @@ files:
99
100
  - lib/pinpoint/format/tokenizer.rb
100
101
  - lib/pinpoint/format.rb
101
102
  - lib/pinpoint/formatter.rb
103
+ - lib/pinpoint/model_support.rb
102
104
  - lib/pinpoint/validations.rb
103
105
  - lib/pinpoint/version.rb
104
106
  - lib/pinpoint.rb
@@ -115,7 +117,7 @@ files:
115
117
  - spec/format/tokenizer_spec.rb
116
118
  - spec/format_spec.rb
117
119
  - spec/formatter_spec.rb
118
- - spec/pinpoint_spec.rb
120
+ - spec/model_support_spec.rb
119
121
  - spec/spec_helper.rb
120
122
  - spec/support/focused.rb
121
123
  - spec/support/pending.rb
@@ -156,7 +158,7 @@ test_files:
156
158
  - spec/format/tokenizer_spec.rb
157
159
  - spec/format_spec.rb
158
160
  - spec/formatter_spec.rb
159
- - spec/pinpoint_spec.rb
161
+ - spec/model_support_spec.rb
160
162
  - spec/spec_helper.rb
161
163
  - spec/support/focused.rb
162
164
  - spec/support/pending.rb
@@ -1,86 +0,0 @@
1
- require 'rspectacular'
2
- require 'pinpoint'
3
-
4
- class Pinpointable
5
- include Pinpoint
6
-
7
- attr_accessor :address_name,
8
- :address_street_and_premises,
9
- :address_city,
10
- :address_state_or_province,
11
- :address_postal_code,
12
- :address_country
13
-
14
- pinpoint :address
15
- end
16
-
17
- describe 'Pinpoint' do
18
- let(:pinpointable) { Pinpointable.new }
19
-
20
- describe '.pinpoint' do
21
- it 'creates a method to access the address' do
22
- pinpointable.respond_to?(:address).should be_true
23
- end
24
-
25
- it 'creates a method to set the address' do
26
- pinpointable.respond_to?(:address=).should be_true
27
- end
28
- end
29
-
30
- describe '#address' do
31
- it 'is a Pinpoint::Address' do
32
- pinpointable.address.should be_a Pinpoint::Address
33
- end
34
-
35
- context 'when the object has address information set' do
36
- before do
37
- pinpointable.address_name = 'The TARDIS'
38
- pinpointable.address_street_and_premises = '413 Citadel Drive'
39
- pinpointable.address_city = 'Panopticon'
40
- pinpointable.address_state_or_province = 'Eye of Harmony'
41
- pinpointable.address_postal_code = '12345'
42
- end
43
-
44
- it 'has the correct address components' do
45
- pinpointable.address.name.should eql 'The TARDIS'
46
- pinpointable.address.street.should eql '413 Citadel Drive'
47
- pinpointable.address.city.should eql 'Panopticon'
48
- pinpointable.address.state.should eql 'Eye of Harmony'
49
- pinpointable.address.county.should eql ''
50
- pinpointable.address.zip_code.should eql '12345'
51
- pinpointable.address.latitude.should eql ''
52
- pinpointable.address.longitude.should eql ''
53
- end
54
- end
55
- end
56
-
57
- describe '#address=' do
58
- context 'when the object has address information set' do
59
- before do
60
- pinpointable.address_name = 'The TARDIS'
61
- pinpointable.address_street_and_premises = '413 Citadel Drive'
62
- pinpointable.address_city = 'Panopticon'
63
- pinpointable.address_state_or_province = 'Eye of Harmony'
64
- pinpointable.address_postal_code = '12345'
65
- end
66
-
67
- it 'overrides the current address information with that stored in the Pinpoint::Address' do
68
- pinpointable.address = Pinpoint::Address.new(
69
- name: 'Buckingham Palace',
70
- street: '',
71
- city: 'City of Westminster',
72
- state: 'London',
73
- zip_code: 'SW1A',
74
- country: 'United Kingdom'
75
- )
76
-
77
- pinpointable.address_name.should eql 'Buckingham Palace'
78
- pinpointable.address_street_and_premises.should eql ''
79
- pinpointable.address_city.should eql 'City of Westminster'
80
- pinpointable.address_state_or_province.should eql 'London'
81
- pinpointable.address_postal_code.should eql 'SW1A'
82
- pinpointable.address_country.should eql 'United Kingdom'
83
- end
84
- end
85
- end
86
- end