Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

models/person_spec passes

  • Loading branch information...
commit c1612f7d40fb0065b1ef5b1f4f12356856b52cf6 1 parent 534cbdf
@linojon authored
View
2  Gemfile
@@ -12,6 +12,7 @@ end
gem 'jquery-rails'
gem 'haml-rails'
gem 'simple_form'
+gem 'hebruby'
# official unofficial ruby-debug19 fix
# with the same gems as mentioned in
@@ -29,6 +30,7 @@ group :test, :development do
gem "rspec-rails"
gem 'rspec-instafail'
gem 'factory_girl_rails'
+ gem 'faker'
gem 'database_cleaner'
gem "capybara"
end
View
5 Gemfile.lock
@@ -63,6 +63,8 @@ GEM
factory_girl_rails (1.7.0)
factory_girl (~> 2.6.0)
railties (>= 3.0.0)
+ faker (1.0.1)
+ i18n (~> 0.4)
ffi (1.0.11)
haml (3.1.4)
haml-rails (0.3.4)
@@ -70,6 +72,7 @@ GEM
activesupport (~> 3.0)
haml (~> 3.0)
railties (~> 3.0)
+ hebruby (2.0.4)
heroku (2.21.3)
launchy (>= 0.3.2)
netrc (~> 0.7.1)
@@ -191,7 +194,9 @@ DEPENDENCIES
coffee-rails (~> 3.2.1)
database_cleaner
factory_girl_rails
+ faker
haml-rails
+ hebruby
heroku
jquery-rails
linecache19 (>= 0.5.13)
View
94 app/models/person.rb
@@ -1,2 +1,96 @@
+require 'capitalize_name'
+require 'hebrew_date'
+require 'proper_name_validator'
+
class Person < ActiveRecord::Base
+ #extend ActiveSupport::Memoizable
+
+ def full_name
+ [ prefix, first_name, middle_name, last_name, suffix ].join(' ')
+ end
+
+ composed_of :death_hebrew_date,
+ :class_name => 'Hebruby::HebrewDate',
+ :mapping =>
+ [ # database # HebrewDate
+ [:death_hebrew_date_day, :day],
+ [:death_hebrew_date_month, :month],
+ [:death_hebrew_date_year, :year]
+ ],
+ :allow_nil => true
+
+ GENDERS = %w{ male female }
+ validates :gender, :inclusion => { :in => GENDERS }, :allow_blank => true
+
+ PREFIXES = %w{ Ms Miss Mrs Mr Dr Atty Prof Hon Gov Ofc Rabbi Cantor }
+ validates :prefix, :inclusion => { :in => PREFIXES }, :allow_blank => true
+
+ validates :last_name, :presence => true,
+ :length => { :minimum => 2 },
+ :proper_name => true
+
+ validates :first_name, :presence => true,
+ :proper_name => true
+
+ validates :maiden, :proper_name => true,
+ :allow_blank => true
+
+ validates :middle_name, :proper_name => true,
+ :allow_blank => true
+
+ validate :death_date_cannot_be_before_birth_date
+
+
+ def death_date_cannot_be_before_birth_date
+ if !death_date.blank? and !birth_date.blank? and death_date < birth_date
+ errors.add(:death_date, "can't be before birth date")
+ end
+ end
+
+ before_save :strip_and_capitalize_names
+ before_save :set_death_dates
+
+ # get next yahrzeit date on or after "from" date
+ def next_yahrzeit_date(from=Date.today)
+ return unless death_date
+ # TODO: use Marlena rules
+ h_from = Hebruby::HebrewDate.new(from)
+ h_death = Hebruby::HebrewDate.new(death_date)
+ # yahrzeit date from year
+ h_yahrzeit = Hebruby::HebrewDate.new(h_death.day, h_death.month, h_from.year)
+ date = Date.jd(h_yahrzeit.jd)
+ if date < from
+ h_yahrzeit = Hebruby::HebrewDate.new(h_death.day, h_death.month, h_from.year+1)
+ date = Date.jd(h_yahrzeit.jd)
+ end
+ date
+ end
+
+ ### callbacks
+
+ def strip_and_capitalize_names
+ self.last_name.strip! unless last_name.nil?
+ self.first_name.strip! unless first_name.nil?
+ self.middle_name.strip! unless middle_name.nil?
+ self.maiden.strip! unless maiden.nil?
+
+ self.last_name.capitalize_name! if last_name.present?
+ self.first_name.capitalize_name! if first_name.present?
+ self.middle_name.capitalize_name! if middle_name.present?
+ self.maiden.capitalize_name! if maiden.present?
+ end
+
+ def set_death_dates
+ if death_hebrew_date.nil? && death_date.present?
+ date = death_date
+ date += 1.day if death_after_sunset
+ self.death_hebrew_date = Hebruby::HebrewDate.new(date)
+ end
+ if death_date.nil? && death_hebrew_date.present?
+ jd = death_hebrew_date.jd
+ jd -= 1 if death_after_sunset
+ self.death_date = Date.jd(jd)
+ end
+ end
+
end
View
2  app/views/people/_form.html.haml
@@ -5,7 +5,7 @@
= f.input :last_name
= f.input :first_name
= f.input :middle_name
- = f.input :maden
+ = f.input :maiden
= f.input :prefix
= f.input :suffix
= f.input :gender
View
4 app/views/people/index.html.haml
@@ -5,7 +5,7 @@
%th Last name
%th First name
%th Middle name
- %th Maden
+ %th Maiden
%th Prefix
%th Suffix
%th Gender
@@ -24,7 +24,7 @@
%td= person.last_name
%td= person.first_name
%td= person.middle_name
- %td= person.maden
+ %td= person.maiden
%td= person.prefix
%td= person.suffix
%td= person.gender
View
4 app/views/people/show.html.haml
@@ -10,8 +10,8 @@
%b Middle name:
= @person.middle_name
%p
- %b Maden:
- = @person.maden
+ %b Maiden:
+ = @person.maiden
%p
%b Prefix:
= @person.prefix
View
2  db/migrate/20120318022557_create_people.rb
@@ -4,7 +4,7 @@ def change
t.string :last_name
t.string :first_name
t.string :middle_name
- t.string :maden
+ t.string :maiden
t.string :prefix
t.string :suffix
t.string :gender
View
2  db/schema.rb
@@ -17,7 +17,7 @@
t.string "last_name"
t.string "first_name"
t.string "middle_name"
- t.string "maden"
+ t.string "maiden"
t.string "prefix"
t.string "suffix"
t.string "gender"
View
11 doc/step by step.txt
@@ -237,11 +237,20 @@ re-deploy
## ---------------
## people
-$ rails g scaffold person last_name first_name middle_name maden prefix suffix gender birth_date:date death_date:date death_hebrew_date_day:integer death_hebrew_date_month:integer death_hebrew_date_year:integer death_after_sunset:boolean --skip-stylesheets
+$ rails g scaffold person last_name first_name middle_name maiden prefix suffix gender birth_date:date death_date:date death_hebrew_date_day:integer death_hebrew_date_month:integer death_hebrew_date_year:integer death_after_sunset:boolean --skip-stylesheets
$ rake db:migrate
$ rails s
+$ rake spec
+specs for people
+ Gemfile
+ gem 'faker'
+ spec/factories/people.rb
+ app/models/person.rb
+ spec/support/random_date.rb
+ spec/support/shared_examples.rb
+
## ---------------
##
View
13 lib/extras/capitalize_name.rb
@@ -0,0 +1,13 @@
+class String
+ def capitalize_name
+ if self.downcase==self || self.upcase==self
+ self.capitalize
+ else
+ self
+ end
+ end
+ def capitalize_name!
+ self.replace self.capitalize_name
+ end
+
+end
View
40 lib/extras/hebrew_date.rb
@@ -0,0 +1,40 @@
+class Hebruby::HebrewDate
+ include Comparable
+
+ def to_s(format = :day_month_year)
+ case format
+ when :day_month
+ "#{day} #{month_name}"
+ else # :day_month_year
+ "#{day} #{month_name} #{year}"
+ end
+ end
+
+ def ==(other_date)
+ jd == other_date.jd if other_date.is_a? Hebruby::HebrewDate
+ end
+
+ def <=>(other_date)
+ jd <=> other_date.jd if other_date.is_a? Hebruby::HebrewDate
+ end
+
+ # new object from string "dd month yyyy"
+ def self.parse(hebstr)
+ if hebstr.include? 'Sheni'
+ day, month, sheni, year = hebstr.split(' ')
+ hm = 13
+ else
+ day, month, year = hebstr.split(' ')
+ hm = MONTH_NAMES.find_index {|m| m==month}
+ end
+ self.new( day.to_i, hm, year.to_i)
+ end
+
+ def self.today
+ @today ||= Hebruby::HebrewDate.new(Date.today.jd)
+ end
+
+ def self.months_for_select
+ 1.upto(13).map {|i| [Hebruby::HebrewDate::MONTH_NAMES[i], i] }
+ end
+end
View
7 lib/extras/proper_name_validator.rb
@@ -0,0 +1,7 @@
+class ProperNameValidator < ActiveModel::EachValidator
+ def validate_each(record, attribute, value)
+ unless value =~ /\A[a-zA-Z\'\-\x20]+\z/
+ record.errors[attribute] << (options[:message] || "is not a proper name format")
+ end
+ end
+end
View
29 spec/factories/people.rb
@@ -2,18 +2,21 @@
FactoryGirl.define do
factory :person do
- last_name "MyString"
- first_name "MyString"
- middle_name "MyString"
- maden "MyString"
- prefix "MyString"
- suffix "MyString"
- gender "MyString"
- birth_date "2012-03-17"
- death_date "2012-03-17"
- death_hebrew_date_day 1
- death_hebrew_date_month 1
- death_hebrew_date_year 1
- death_after_sunset false
+ last_name { Faker::Name.last_name }
+ first_name { Faker::Name.first_name }
+ middle_name { Faker::Name.first_name }
+ # prefix "MyString"
+ # suffix "MyString"
+ gender { Person::GENDERS[rand 2] }
+ ignore do
+ bdate { randomDate(:year_range => 60, :year_latest => 22).to_date }
+ end
+ maiden { Faker::Name.last_name if gender=='female' }
+ birth_date { bdate }
+ death_date { bdate + rand(Date.today - bdate) }
+ # death_hebrew_date_day 1
+ # death_hebrew_date_month 1
+ # death_hebrew_date_year 1
+ # death_after_sunset false
end
end
View
102 spec/models/person_spec.rb
@@ -1,5 +1,105 @@
require 'spec_helper'
describe Person do
- pending "add some examples to (or delete) #{__FILE__}"
+ describe "last_name" do
+ it "must be > 1 character" do
+ Factory.build(:person, :last_name => 'A').should_not be_valid
+ end
+ it_should_behave_like "a proper name", Factory.build(:person), :last_name
+ end
+ describe "first_name" do
+ it_should_behave_like "a proper name", Factory.build(:person), :first_name
+ end
+ describe "middle_name" do
+ it_should_behave_like "a proper name", Factory.build(:person), :middle_name
+ end
+ describe "maiden" do
+ it_should_behave_like "a proper name", Factory.build(:person), :maiden
+ end
+ describe "gender" do
+ it "only allows 'male' and 'female'" do
+ Factory.build(:person, :gender => 'male').should be_valid
+ Factory.build(:person, :gender => 'female').should be_valid
+ Factory.build(:person, :gender => 'foo').should_not be_valid
+ end
+ it "is not required" do
+ Factory.build(:person, :gender => '').should be_valid
+ Factory.build(:person, :gender => nil).should be_valid
+ end
+ end
+ describe "prefix" do
+ it "only allows stanard prefixes" do
+ %w{ Ms Miss Mrs Mr Dr Atty Prof Hon Gov Ofc Rabbi Cantor }.each do |prefix|
+ Factory.build(:person, :prefix => prefix).should be_valid
+ end
+ end
+ it "is not required" do
+ Factory.build(:person, :prefix => '').should be_valid
+ Factory.build(:person, :prefix => nil).should be_valid
+ end
+ end
+
+ describe "death date" do
+ it "cannot be before birth date" do
+ person = Factory.build(:person)
+ person.death_date = person.birth_date - 1.day
+ person.should_not be_valid
+ person.errors[:death_date].should include("can't be before birth date")
+ end
+ it "calculates death_hebrew_date on save" do
+ person = Factory.build(:person, :death_date => "2000/08/17")
+ person.death_hebrew_date_day.should be_nil
+ person.death_hebrew_date_month.should be_nil
+ person.death_hebrew_date_year.should be_nil
+
+ person.save
+ person.death_hebrew_date_day.should == 16
+ person.death_hebrew_date_month.should == 5
+ person.death_hebrew_date_year.should == 5760
+ end
+ it "calculates death_hebrew_date as next day if after sunset" do
+ person = Factory.build(:person, :death_date => "2000/08/17", :death_after_sunset => true )
+ person.save
+ person.death_hebrew_date_day.should == 17
+ person.death_hebrew_date_month.should == 5
+ person.death_hebrew_date_year.should == 5760
+
+ end
+ end
+
+ describe "death_hebrew_date" do
+ it "calculates western death_date on save" do
+ person = Factory.build(:person, :death_date => nil, :death_hebrew_date_day => 16, :death_hebrew_date_month => 5, :death_hebrew_date_year => 5760)
+ person.death_date.should be_nil
+ person.save
+ person.death_date.should == Date.parse("2000/08/17")
+ end
+ it "calculates western death_date as day before if after sunset" do
+ person = Factory.build(:person, :death_date => nil, :death_hebrew_date_day => 16, :death_hebrew_date_month => 5, :death_hebrew_date_year => 5760, :death_after_sunset => true)
+ person.save
+ person.death_date.should == Date.parse("2000/08/16")
+ end
+ # ref: http://www.hebcal.com/converter
+ it "is a hebdate" do
+ person = Factory.create(:person, :death_date => "2000/08/17")
+ person.death_hebrew_date.jd.should == Hebruby::HebrewDate.new(16,5,5760).jd
+ end
+ it "can find by hebrew month" do
+ person = Factory.create(:person, :death_date => "2000/08/17")
+ Person.where(:death_hebrew_date_month => 5).should == [person]
+ end
+ end
+
+ describe "next_yahrzeit_date" do
+ it "calculates yahrzeit within the next year" do
+ person = Factory.create(:person, :death_date => "2000/08/17")
+ Date.stub(:today).and_return(Date.parse("2011/11/6"))
+ person.next_yahrzeit_date.should == Date.parse("2012/8/4")
+ end
+ it "calculates yahrzeit from a date" do
+ person = Factory.create(:person, :death_date => "2000/08/17")
+ from = Date.parse("2010/11/6")
+ person.next_yahrzeit_date(from).should == Date.parse("2011/8/16")
+ end
+ end
end
View
17 spec/support/random_date.rb
@@ -0,0 +1,17 @@
+# ref: http://www.idolhands.com/ruby-on-rails/rails-gems-plugins-and-engines/using-faker-to-pre-populate-a-dev-database
+
+def randomDate(params={})
+ years_back = params[:year_range] || 5
+ latest_year = params [:year_latest] || 0
+ year = (rand * (years_back)).ceil + (Time.now.year - latest_year - years_back)
+ month = (rand * 12).ceil
+ day = (rand * 31).ceil
+ series = [date = Time.local(year, month, day)]
+ if params[:series]
+ params[:series].each do |some_time_after|
+ series << series.last + (rand * some_time_after).ceil
+ end
+ return series
+ end
+ date
+end
View
30 spec/support/shared_examples.rb
@@ -0,0 +1,30 @@
+shared_examples_for "a proper name" do |obj, atr|
+ it "must be alphabetic" do
+ %w{ 1 $ % + }.each do |ch|
+ obj.send("#{atr}=", ch)
+ obj.should_not be_valid
+ end
+ end
+ it "allows hyphenation, apostrophe, spaces" do
+ obj.send("#{atr}=", "O'a-b c")
+ obj.should be_valid
+ end
+ it "before save, corrects capitalization when all upper or all lower, otherwise leaves it alone" do
+ obj.send("#{atr}=", 'cohen')
+ obj.save
+ obj.send(atr).should == 'Cohen'
+
+ obj.send("#{atr}=", 'COHEN')
+ obj.save
+ obj.send(atr).should == 'Cohen'
+
+ obj.send("#{atr}=", 'mcCohen')
+ obj.save
+ obj.send(atr).should == 'mcCohen'
+ end
+ it "before save, strips blanks" do
+ obj.send("#{atr}=", ' Co hen ')
+ obj.save
+ obj.send(atr).should == 'Co hen'
+ end
+end
View
4 spec/views/people/edit.html.haml_spec.rb
@@ -6,7 +6,7 @@
:last_name => "MyString",
:first_name => "MyString",
:middle_name => "MyString",
- :maden => "MyString",
+ :maiden => "MyString",
:prefix => "MyString",
:suffix => "MyString",
:gender => "MyString",
@@ -25,7 +25,7 @@
assert_select "input#person_last_name", :name => "person[last_name]"
assert_select "input#person_first_name", :name => "person[first_name]"
assert_select "input#person_middle_name", :name => "person[middle_name]"
- assert_select "input#person_maden", :name => "person[maden]"
+ assert_select "input#person_maiden", :name => "person[maiden]"
assert_select "input#person_prefix", :name => "person[prefix]"
assert_select "input#person_suffix", :name => "person[suffix]"
assert_select "input#person_gender", :name => "person[gender]"
View
6 spec/views/people/index.html.haml_spec.rb
@@ -7,7 +7,7 @@
:last_name => "Last Name",
:first_name => "First Name",
:middle_name => "Middle Name",
- :maden => "Maden",
+ :maiden => "Maiden",
:prefix => "Prefix",
:suffix => "Suffix",
:gender => "Gender",
@@ -20,7 +20,7 @@
:last_name => "Last Name",
:first_name => "First Name",
:middle_name => "Middle Name",
- :maden => "Maden",
+ :maiden => "Maiden",
:prefix => "Prefix",
:suffix => "Suffix",
:gender => "Gender",
@@ -38,7 +38,7 @@
assert_select "tr>td", :text => "Last Name".to_s, :count => 2
assert_select "tr>td", :text => "First Name".to_s, :count => 2
assert_select "tr>td", :text => "Middle Name".to_s, :count => 2
- assert_select "tr>td", :text => "Maden".to_s, :count => 2
+ assert_select "tr>td", :text => "Maiden".to_s, :count => 2
assert_select "tr>td", :text => "Prefix".to_s, :count => 2
assert_select "tr>td", :text => "Suffix".to_s, :count => 2
assert_select "tr>td", :text => "Gender".to_s, :count => 2
View
4 spec/views/people/new.html.haml_spec.rb
@@ -6,7 +6,7 @@
:last_name => "MyString",
:first_name => "MyString",
:middle_name => "MyString",
- :maden => "MyString",
+ :maiden => "MyString",
:prefix => "MyString",
:suffix => "MyString",
:gender => "MyString",
@@ -25,7 +25,7 @@
assert_select "input#person_last_name", :name => "person[last_name]"
assert_select "input#person_first_name", :name => "person[first_name]"
assert_select "input#person_middle_name", :name => "person[middle_name]"
- assert_select "input#person_maden", :name => "person[maden]"
+ assert_select "input#person_maiden", :name => "person[maiden]"
assert_select "input#person_prefix", :name => "person[prefix]"
assert_select "input#person_suffix", :name => "person[suffix]"
assert_select "input#person_gender", :name => "person[gender]"
View
4 spec/views/people/show.html.haml_spec.rb
@@ -6,7 +6,7 @@
:last_name => "Last Name",
:first_name => "First Name",
:middle_name => "Middle Name",
- :maden => "Maden",
+ :maiden => "Maiden",
:prefix => "Prefix",
:suffix => "Suffix",
:gender => "Gender",
@@ -23,7 +23,7 @@
rendered.should match(/Last Name/)
rendered.should match(/First Name/)
rendered.should match(/Middle Name/)
- rendered.should match(/Maden/)
+ rendered.should match(/Maiden/)
rendered.should match(/Prefix/)
rendered.should match(/Suffix/)
rendered.should match(/Gender/)
Please sign in to comment.
Something went wrong with that request. Please try again.