Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move Address, State, Country, and QuietNil into plugin. Also improve …
…testing environment for plugin (add Machinist and a bunch of other stuff). [#44]
- Loading branch information
Showing
15 changed files
with
260 additions
and
149 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
91 changes: 91 additions & 0 deletions
91
vendor/plugins/acts_as_addressed/lib/acts/addressed/address.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
# Value object for addresses. | ||
|
||
module Acts::Addressed | ||
class Address | ||
# List of readable attributes. | ||
FIELDS = [:street, :street2, :city, :state, :zip, :coords] | ||
FIELDS.each do |f| | ||
attr_reader f | ||
end | ||
|
||
# Initializes a new #Address object from a #Hash of fields or separate arguments in the order given in FIELDS. | ||
def initialize(*args) | ||
case args.length | ||
when 0 | ||
# do nothing | ||
when 1 | ||
if args[0].kind_of?(Hash) | ||
set_from_hash args[0] | ||
else | ||
raise ArgumentError, "expected Hash, got #{args[0].class.name}" | ||
end | ||
when FIELDS.length | ||
set_from_array args | ||
else | ||
raise ArgumentError, "expected 0, 1, or #{FIELDS.length} arguments, got #{args.length}" | ||
end | ||
if !@state.blank? and !@state.kind_of?(State) | ||
@state = State.find(@state) | ||
end | ||
end | ||
|
||
# Returns the #Country that the address belongs to. | ||
def country | ||
state.country | ||
end | ||
|
||
# Returns the #State that the address belongs to, or a #QuietNil if there is no state. | ||
def state | ||
@state || QuietNil.instance | ||
end | ||
|
||
# Converts #Address to a #String. | ||
# | ||
# Valid values of +format+: | ||
# <tt>:geo</tt>:: Address in comma-separated format for feeding to geocoder. | ||
def to_s(format = :geo) | ||
case format | ||
when :geo | ||
"#{street}, #{city}, #{state.code}, #{zip}, #{country.code}" | ||
else | ||
raise ArgumentError, "unknown format parameter: #{format}" | ||
end | ||
end | ||
|
||
# Compares two Addresses by value. | ||
def ==(other) | ||
if other.kind_of?(Address) | ||
FIELDS.each do |f| | ||
if self.send(f) != other.send(f) | ||
return false | ||
end | ||
end | ||
return true | ||
else | ||
return false | ||
end | ||
end | ||
|
||
protected | ||
|
||
# TODO: set_from_* methods should perhaps become public. | ||
|
||
# Sets instance variables from the supplied #Hash. | ||
def set_from_hash(hash) | ||
FIELDS.each do |f| | ||
if hash.has_key?(f) | ||
eval "@#{f.to_s} = hash[:#{f.to_s}]" | ||
end | ||
end | ||
end | ||
|
||
# Sets instance variables from the supplied #Array, in the same order as #FIELDS. | ||
def set_from_array(array) | ||
hash = {} | ||
FIELDS.each_index do |i| | ||
hash[FIELDS[i]] = array[i] | ||
end | ||
set_from_hash hash | ||
end | ||
end | ||
end |
7 changes: 7 additions & 0 deletions
7
vendor/plugins/acts_as_addressed/lib/acts/addressed/country.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
module Acts::Addressed | ||
class Country < ActiveRecord::Base | ||
has_many :states | ||
validates_length_of :code, :is => 2 | ||
validates_presence_of :name | ||
end | ||
end |
15 changes: 15 additions & 0 deletions
15
vendor/plugins/acts_as_addressed/lib/acts/addressed/quiet_nil.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# This is just like NilClass, but when methods are called on a QuietNil, they just return the QuietNil without raising an exception. | ||
# | ||
# WARNING: This class is easy to abuse. Please resist temptation! | ||
|
||
module Acts::Addressed | ||
class QuietNil < ActiveSupport::BasicObject | ||
# Implementation is yanked from http://coderrr.wordpress.com/2007/09/15/the-ternary-destroyer/ | ||
include Singleton | ||
|
||
def method_missing(method, *args, &b) | ||
return self unless nil.respond_to? method | ||
nil.send(method, *args, &b) rescue self | ||
end | ||
end | ||
end |
12 changes: 12 additions & 0 deletions
12
vendor/plugins/acts_as_addressed/lib/acts/addressed/state.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
module Acts::Addressed | ||
class State < ActiveRecord::Base | ||
belongs_to :country | ||
validates_presence_of :country_id | ||
|
||
validate do |state| | ||
if state.code.blank? ^ state.name.blank? | ||
state.errors.add_to_base("Code and name must both be blank or must both be nonblank.") | ||
end | ||
end | ||
end | ||
end |
File renamed without changes.
15 changes: 12 additions & 3 deletions
15
spec/models/country_spec.rb → ...essed/spec/acts/addressed/country_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
vendor/plugins/acts_as_addressed/spec/acts/addressed/quiet_nil_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') | ||
|
||
module Acts::Addressed | ||
describe QuietNil do | ||
it "should be a valid class" do | ||
QuietNil.class.should == Class | ||
end | ||
|
||
it "should respond as nil to predefined methods" do | ||
qn = QuietNil.instance | ||
qn.should be_nil | ||
pending "can't figure out how to convert to boolean" do | ||
(!!qn).should be_false | ||
end | ||
qn.to_s.should == nil.to_s | ||
qn.to_a.should == nil.to_a | ||
end | ||
|
||
it "should not whine when it receives methods that aren't defined on nil" do | ||
qn = QuietNil.instance | ||
p = lambda {qn.foobarbaz(1, 2, 3)} | ||
p.should_not raise_error | ||
|
||
# We're overriding equality, so we can't do | ||
# (p.call.equal? qn).should be_true | ||
# Instead: | ||
p.call.should be_nil | ||
lambda {p.call.quux(:quuuux)}.should_not raise_error | ||
end | ||
end | ||
end |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# Object blueprints for Machinist. | ||
require 'machinist/active_record' | ||
require 'sham' | ||
require 'faker' | ||
LETTERS = ('A'..'Z').to_a | ||
|
||
module Acts::Addressed | ||
Country.blueprint do | ||
name {Sham.generic_name} | ||
code | ||
end | ||
|
||
State.blueprint do | ||
country | ||
name {Sham.generic_name} | ||
code | ||
end | ||
end | ||
|
||
Sham.define do | ||
generic_name {Faker::Name.last_name} | ||
code {LETTERS.rand + LETTERS.rand} # 2 random letters | ||
end |
Oops, something went wrong.