zodiac 0.1.1 → 0.2.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.
- data/README.md +114 -0
- data/Rakefile +4 -2
- data/lib/generators/zodiac/migration/USAGE +1 -0
- data/lib/generators/zodiac/migration/migration_generator.rb +39 -0
- data/lib/generators/zodiac/migration/templates/migration30.rb.erb +17 -0
- data/lib/generators/zodiac/migration/templates/migration31.rb.erb +12 -0
- data/lib/zodiac.rb +8 -0
- data/lib/zodiac/activerecord.rb +67 -0
- data/lib/zodiac/date.rb +11 -0
- data/lib/zodiac/finder.rb +35 -8
- data/lib/zodiac/version.rb +1 -1
- data/spec/spec_helper.rb +9 -0
- data/spec/support/custom_person.rb +3 -0
- data/spec/support/lite_person.rb +3 -0
- data/spec/support/person.rb +3 -0
- data/spec/support/test.sqlite3 +0 -0
- data/spec/zodiac/activerecord_spec.rb +176 -0
- data/spec/zodiac/date_spec.rb +27 -1
- data/spec/zodiac/finder_spec.rb +14 -6
- data/zodiac.gemspec +13 -8
- metadata +125 -56
- data/README.textile +0 -50
data/README.md
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
# zodiac
|
2
|
+
`zodiac` is a simple gem for getting a zodiac sign from a given date of birth. It extends `Time`, `Date` and `DateTime` objects with a `#zodiac_sign` method and can also extend `ActiveRecord::Base` with several instance (delegated to some date attribute of the model object) and class methods (allowing you to search for objects with a certain zodiac sign)
|
3
|
+
|
4
|
+
## Installation
|
5
|
+
|
6
|
+
``` bash
|
7
|
+
gem install zodiac
|
8
|
+
```
|
9
|
+
|
10
|
+
Or, if you want to extend your rails app, add the following to the `Gemfile`:
|
11
|
+
|
12
|
+
``` ruby
|
13
|
+
gem 'zodiac', '>= 0.2'
|
14
|
+
```
|
15
|
+
|
16
|
+
and run `bundle install`
|
17
|
+
|
18
|
+
## Usage
|
19
|
+
|
20
|
+
### Time/Date/DateTime usage
|
21
|
+
|
22
|
+
``` ruby
|
23
|
+
require 'zodiac'
|
24
|
+
Time.now.zodiac_sign # => "Aries"
|
25
|
+
require 'date'
|
26
|
+
Date.new(2011, 1, 1).zodiac_sign # => "Capricorn"
|
27
|
+
DateTime.new(2011, 4, 30).zodiac_sign # => "Taurus"
|
28
|
+
```
|
29
|
+
|
30
|
+
`#zodiac_sign` returns values using `I18n` with "zodiac.#{sign}" path, so if you want your own translations, you can put them in your locale with keys like `zodiac.aries`, `zodiac.taurus` etc. See examples [here](http://github.com/7even/zodiac/blob/master/lib/locales/en.yml).
|
31
|
+
|
32
|
+
There are also predicate methods which return `true` if the date is matching the specified zodiac sign (and `false` otherwise).
|
33
|
+
|
34
|
+
``` ruby
|
35
|
+
Date.new(1989, 2, 26).pisces? # => true
|
36
|
+
Time.gm(1978, 7, 12).gemini? # => false
|
37
|
+
```
|
38
|
+
|
39
|
+
### ActiveRecord usage
|
40
|
+
|
41
|
+
The first thing you need to do is to add `gem 'zodiac'` to your `Gemfile` as described before.
|
42
|
+
|
43
|
+
To add zodiac methods to your model you just call a `zodiac_reader` macro in your model passing it the name of the attribute containing the date of birth:
|
44
|
+
|
45
|
+
``` ruby
|
46
|
+
class Person
|
47
|
+
zodiac_reader :dob
|
48
|
+
end
|
49
|
+
```
|
50
|
+
|
51
|
+
and then you'll be able to get zodiac sign of your object just by calling `#zodiac_sign` on it:
|
52
|
+
|
53
|
+
``` ruby
|
54
|
+
@person = Person.first
|
55
|
+
@person.zodiac_sign # => "Taurus"
|
56
|
+
```
|
57
|
+
|
58
|
+
You can also use the predicate methods like `#libra?`
|
59
|
+
|
60
|
+
``` ruby
|
61
|
+
@person.libra? # => false
|
62
|
+
@person.taurus? # => true
|
63
|
+
```
|
64
|
+
|
65
|
+
If you also need to search for all geminis in your `people` table, you should add an integer field containing a numerical id of the person's zodiac sign to that table. `zodiac` can help you with that - it already includes a generator `zodiac:migration` which creates a migration adding that field to your table (and an index on that field). You should specify the name of your model class as the first argument while calling the generator:
|
66
|
+
|
67
|
+
``` bash
|
68
|
+
rails generate zodiac:migration Person
|
69
|
+
```
|
70
|
+
|
71
|
+
(Note that you must call `zodiac_reader` in your model in order for the migration to run correctly - after creating a new field the migration tries to update it for all existing records)
|
72
|
+
|
73
|
+
Now `zodiac_reader` macro in your model gives you some scopes to filter objects by a zodiac sign:
|
74
|
+
|
75
|
+
``` ruby
|
76
|
+
Person.with_zodiac_sign('libra') # returns all libras
|
77
|
+
Person.gemini # all the geminis
|
78
|
+
```
|
79
|
+
|
80
|
+
To keep the consistency of a zodiac sign with the date of birth, `zodiac_reader` also installs a `before_save` filter to your model, which updates the sign field every time you change the date-of-birth attribute.
|
81
|
+
|
82
|
+
If you don't like the name of the field containing zodiac sign (by default it's `zodiac_sign_id`), you can customize it, passing the wanted name as an option to `zodiac_reader` in your model and then as the second parameter to the generator:
|
83
|
+
|
84
|
+
``` ruby
|
85
|
+
class Person
|
86
|
+
zodiac_reader :dob, :sign_id_attribute => :custom_sign_id
|
87
|
+
end
|
88
|
+
```
|
89
|
+
|
90
|
+
``` bash
|
91
|
+
rails generate zodiac:migration Person custom_sign_id
|
92
|
+
```
|
93
|
+
|
94
|
+
## Included locales
|
95
|
+
|
96
|
+
* en
|
97
|
+
* ru
|
98
|
+
* pt-BR (thanks [jeffrydegrande](https://github.com/jeffrydegrande))
|
99
|
+
|
100
|
+
## Changelog
|
101
|
+
|
102
|
+
* 0.1 Initial version with Time/Date/DateTime extension and [:ru, :en] locales
|
103
|
+
* 0.1.1 Added pt-BR locale (thanks [jeffrydegrande](https://github.com/jeffrydegrande))
|
104
|
+
* 0.2 Added ActiveRecord support (scopes, predicate methods and delegating `#zodiac_sign` to date-of-birth attribute)
|
105
|
+
|
106
|
+
## Roadmap
|
107
|
+
|
108
|
+
1. Rdoc coverage of everything
|
109
|
+
|
110
|
+
2. Other ORMs support (DataMapper, Sequel, Mongoid)
|
111
|
+
|
112
|
+
## Contributing
|
113
|
+
|
114
|
+
Fork the repository, push your changes to a topic branch and send me a pull request.
|
data/Rakefile
CHANGED
@@ -2,11 +2,13 @@ require 'bundler'
|
|
2
2
|
require 'rspec/core/rake_task'
|
3
3
|
Bundler::GemHelper.install_tasks
|
4
4
|
|
5
|
-
desc 'Fires up the console with preloaded zodiac'
|
5
|
+
desc 'Fires up the console with preloaded zodiac (and active_record)'
|
6
6
|
task :console do
|
7
|
-
sh '
|
7
|
+
sh 'pry -I ./lib/ -rubygems -r active_record -r ./lib/zodiac.rb'
|
8
8
|
end
|
9
9
|
|
10
10
|
RSpec::Core::RakeTask.new do |t|
|
11
11
|
t.rspec_opts = '--color --format doc'
|
12
12
|
end
|
13
|
+
|
14
|
+
task :default => :spec
|
@@ -0,0 +1 @@
|
|
1
|
+
Generates a migration which adds a zodiac_sign_id (unless overridden) field to the specified model table so that you can search objects by a zodiac sign.
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Zodiac
|
2
|
+
class MigrationGenerator < Rails::Generators::Base
|
3
|
+
source_root File.expand_path('../templates', __FILE__)
|
4
|
+
argument :model_name, :type => :string
|
5
|
+
argument :sign_attribute, :type => :string, :default => 'zodiac_sign_id'
|
6
|
+
|
7
|
+
def copy_files
|
8
|
+
template template_name, "db/migrate/#{migration_filename}.rb"
|
9
|
+
end
|
10
|
+
private
|
11
|
+
def template_name
|
12
|
+
if Rails.version < '3.1'
|
13
|
+
'migration30.rb.erb'
|
14
|
+
else
|
15
|
+
'migration31.rb.erb'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def date_prefix
|
20
|
+
Time.now.strftime('%Y%m%d%H%M%S') # filename prefix like 20110922205139
|
21
|
+
end
|
22
|
+
|
23
|
+
def migration_filename
|
24
|
+
"#{date_prefix}_add_#{sign_attribute}_to_#{table_name}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def migration_classname
|
28
|
+
"Add#{sign_attribute.camelcase}To#{model_name.gsub('::', '').camelcase.pluralize}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def model_classname
|
32
|
+
model_name.camelcase.singularize
|
33
|
+
end
|
34
|
+
|
35
|
+
def table_name
|
36
|
+
model_name.underscore.gsub('/', '_').pluralize
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<%# migration for ActiveRecord 3.0 -%>
|
2
|
+
class <%= migration_classname %> < ActiveRecord::Migration
|
3
|
+
def self.up
|
4
|
+
add_column :<%= table_name %>, :<%= sign_attribute.underscore %>, :integer
|
5
|
+
add_index :<%= table_name %>, :<%= sign_attribute.underscore %>
|
6
|
+
|
7
|
+
<%= model_classname %>.all.each do |<%= model_name.underscore.singularize %>|
|
8
|
+
<%= model_name.underscore.singularize %>.send(:update_sign_id)
|
9
|
+
<%= model_name.underscore.singularize %>.save
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.down
|
14
|
+
remove_index :<%= table_name %>, :<%= sign_attribute.underscore %>
|
15
|
+
remove_column :<%= table_name %>, :<%= sign_attribute.underscore %>
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<%# migration for ActiveRecord 3.1 and higher -%>
|
2
|
+
class <%= migration_classname %> < ActiveRecord::Migration
|
3
|
+
def change
|
4
|
+
add_column :<%= table_name %>, :<%= sign_attribute.underscore %>, :integer
|
5
|
+
add_index :<%= table_name %>, :<%= sign_attribute.underscore %>
|
6
|
+
|
7
|
+
<%= model_classname %>.all.each do |<%= model_name.underscore.singularize %>|
|
8
|
+
<%= model_name.underscore.singularize %>.send(:update_sign_id)
|
9
|
+
<%= model_name.underscore.singularize %>.save
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/zodiac.rb
CHANGED
@@ -3,4 +3,12 @@ require 'i18n'
|
|
3
3
|
I18n.config.load_path += Dir.glob(File.dirname(File.expand_path(__FILE__)) + '/locales/*.yml')
|
4
4
|
|
5
5
|
require 'zodiac/finder'
|
6
|
+
|
7
|
+
module Zodiac
|
8
|
+
def self.each_sign(&block)
|
9
|
+
Finder::SIGN_IDS.each(&block)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
6
13
|
require 'zodiac/date'
|
14
|
+
require 'zodiac/activerecord'
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Zodiac
|
2
|
+
module ActiveRecord
|
3
|
+
module InstanceMethods
|
4
|
+
def zodiac_sign
|
5
|
+
raise 'You should call #zodiac_reader in your class for this to work' unless self.class.respond_to?(:date_for_zodiac)
|
6
|
+
self.send(self.class.date_for_zodiac).try(:zodiac_sign)
|
7
|
+
end
|
8
|
+
|
9
|
+
Zodiac.each_sign do |symbol, integer|
|
10
|
+
method_name = "#{symbol}?"
|
11
|
+
define_method(method_name) do
|
12
|
+
raise 'You should call #zodiac_reader in your class for this to work' unless self.class.respond_to?(:date_for_zodiac)
|
13
|
+
self.send(self.class.date_for_zodiac).try(method_name)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
private
|
17
|
+
def update_sign_id
|
18
|
+
sign_id_method = "#{self.class.zodiac_sign_id_field}="
|
19
|
+
new_sign_id = self.send(self.class.date_for_zodiac).try(:zodiac_sign_id)
|
20
|
+
self.send(sign_id_method, new_sign_id)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
module ClassMethods
|
25
|
+
attr_reader :date_for_zodiac, :zodiac_sign_id_field
|
26
|
+
|
27
|
+
def zodiac_reader(dob_attribute, options = {:sign_id_attribute => :zodiac_sign_id})
|
28
|
+
@date_for_zodiac = dob_attribute
|
29
|
+
@zodiac_sign_id_field = options[:sign_id_attribute]
|
30
|
+
|
31
|
+
# if the migration was applied, we should update the sign attribute before each save
|
32
|
+
# and define some scopes
|
33
|
+
if self.column_names.include?(@zodiac_sign_id_field.to_s)
|
34
|
+
self.before_save do |object|
|
35
|
+
object.send(:update_sign_id)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Person.by_zodiac(7 || :libra) == Person.where(:zodiac_sign_id => 7)
|
39
|
+
scope :by_zodiac, lambda { |sign|
|
40
|
+
case sign
|
41
|
+
when Symbol
|
42
|
+
where(self.zodiac_sign_id_field => Zodiac::Finder::SIGN_IDS[sign])
|
43
|
+
when Fixnum
|
44
|
+
where(self.zodiac_sign_id_field => sign)
|
45
|
+
else
|
46
|
+
raise ArgumentError, "Invalid attribute type #{sign.class} for #{self}.by_zodiac"
|
47
|
+
end
|
48
|
+
}
|
49
|
+
|
50
|
+
# Person.gemini == Person.by_zodiac(3)
|
51
|
+
Zodiac.each_sign do |symbol, integer|
|
52
|
+
scope symbol, by_zodiac(integer)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.included(base)
|
59
|
+
base.send :include, InstanceMethods
|
60
|
+
base.extend ClassMethods
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
if defined?(::ActiveRecord)
|
66
|
+
ActiveRecord::Base.send(:include, Zodiac::ActiveRecord)
|
67
|
+
end
|
data/lib/zodiac/date.rb
CHANGED
@@ -4,6 +4,17 @@ module Zodiac
|
|
4
4
|
raise "#{self} should respond_to #month and #day" unless respond_to?(:month) && respond_to?(:day)
|
5
5
|
Finder.sign_for(:month => self.month, :day => self.day)
|
6
6
|
end
|
7
|
+
|
8
|
+
def zodiac_sign_id
|
9
|
+
raise "#{self} should respond_to #month and #day" unless respond_to?(:month) && respond_to?(:day)
|
10
|
+
Finder.sign_id_for(:month => self.month, :day => self.day)
|
11
|
+
end
|
12
|
+
|
13
|
+
Zodiac.each_sign do |symbol, integer|
|
14
|
+
define_method("#{symbol}?") do # def libra?
|
15
|
+
self.zodiac_sign_id == integer # self.zodiac_sign_id == 7
|
16
|
+
end # end
|
17
|
+
end
|
7
18
|
end
|
8
19
|
end
|
9
20
|
|
data/lib/zodiac/finder.rb
CHANGED
@@ -2,12 +2,15 @@ module Zodiac
|
|
2
2
|
module Finder
|
3
3
|
YEAR = 2011
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
5
|
+
class << self
|
6
|
+
def date_for(month, day)
|
7
|
+
DateTime.new(YEAR, month, day)
|
8
|
+
end
|
9
|
+
|
10
|
+
def range_for(month_start, day_start, month_end, day_end)
|
11
|
+
start, ending = date_for(month_start, day_start), date_for(month_end, day_end)
|
12
|
+
SimpleRange.new(start, ending)
|
13
|
+
end
|
11
14
|
end
|
12
15
|
|
13
16
|
RANGES = {
|
@@ -26,13 +29,37 @@ module Zodiac
|
|
26
29
|
range_for(12, 23, 12, 31) => :capricorn
|
27
30
|
}
|
28
31
|
|
32
|
+
SIGN_IDS = {
|
33
|
+
:aries => 1,
|
34
|
+
:taurus => 2,
|
35
|
+
:gemini => 3,
|
36
|
+
:cancer => 4,
|
37
|
+
:leo => 5,
|
38
|
+
:virgo => 6,
|
39
|
+
:libra => 7,
|
40
|
+
:scorpio => 8,
|
41
|
+
:sagittarius => 9,
|
42
|
+
:capricorn => 10,
|
43
|
+
:aquarius => 11,
|
44
|
+
:pisces => 12
|
45
|
+
}
|
46
|
+
|
29
47
|
def self.sign_for(date)
|
48
|
+
I18n.t!("zodiac.#{self.sign_symbol_for date}")
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.sign_id_for(date)
|
52
|
+
SIGN_IDS[self.sign_symbol_for date]
|
53
|
+
end
|
54
|
+
private
|
55
|
+
def self.sign_symbol_for(date)
|
30
56
|
RANGES.each do |range, sign|
|
31
57
|
if range.days.include? date_for(date[:month], date[:day])
|
32
|
-
return
|
58
|
+
return sign
|
33
59
|
end
|
34
60
|
end
|
61
|
+
|
35
62
|
raise ArgumentError
|
36
63
|
end
|
37
64
|
end
|
38
|
-
end
|
65
|
+
end
|
data/lib/zodiac/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1 +1,10 @@
|
|
1
|
+
# bootstrap ActiveRecord
|
2
|
+
require 'active_record'
|
3
|
+
ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => 'spec/support/test.sqlite3')
|
4
|
+
|
1
5
|
require 'zodiac'
|
6
|
+
require 'pry'
|
7
|
+
|
8
|
+
require File.expand_path('../support/person.rb', __FILE__)
|
9
|
+
require File.expand_path('../support/lite_person.rb', __FILE__)
|
10
|
+
require File.expand_path('../support/custom_person.rb', __FILE__)
|
Binary file
|
@@ -0,0 +1,176 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Zodiac::ActiveRecord do
|
4
|
+
describe "class methods" do
|
5
|
+
context "standard model" do
|
6
|
+
before(:each) do
|
7
|
+
@gemini1 = Person.create :dob => Time.gm(1982, 5, 27)
|
8
|
+
@gemini2 = Person.create :dob => Time.gm(1987, 5, 29)
|
9
|
+
@libra = Person.create :dob => Time.gm(1984, 9, 27)
|
10
|
+
@nobody = Person.create :dob => nil
|
11
|
+
end
|
12
|
+
|
13
|
+
describe ".zodiac_reader" do
|
14
|
+
it "sets @date_for_zodiac with the given value" do
|
15
|
+
Person.date_for_zodiac.should == :dob
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe ".by_zodiac" do
|
20
|
+
context "with an integer argument" do
|
21
|
+
it "returns a scope with objects belonging to a given sign" do
|
22
|
+
gemini = Person.by_zodiac(3)
|
23
|
+
gemini.should include(@gemini1)
|
24
|
+
gemini.should include(@gemini2)
|
25
|
+
gemini.should_not include(@libra)
|
26
|
+
gemini.should_not include(@nobody)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "with a symbol argument" do
|
31
|
+
it "returns a scope with objects belonging to a given sign" do
|
32
|
+
libra = Person.by_zodiac(:libra)
|
33
|
+
libra.should_not include(@gemini1)
|
34
|
+
libra.should_not include(@gemini2)
|
35
|
+
libra.should include(@libra)
|
36
|
+
libra.should_not include(@nobody)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "named zodiac scopes (like .libra)" do
|
42
|
+
it "call .by_zodiac with a given sign and return its result" do
|
43
|
+
Person.libra.should_not include(@gemini1)
|
44
|
+
Person.libra.should_not include(@gemini2)
|
45
|
+
Person.libra.should include(@libra)
|
46
|
+
Person.libra.should_not include(@nobody)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
after(:each) do
|
51
|
+
Person.delete_all
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context "custom model" do
|
56
|
+
before(:each) do
|
57
|
+
@gemini1 = CustomPerson.create :dob => Time.gm(1982, 5, 27)
|
58
|
+
@gemini2 = CustomPerson.create :dob => Time.gm(1987, 5, 29)
|
59
|
+
@libra = CustomPerson.create :dob => Time.gm(1984, 9, 27)
|
60
|
+
@nobody = CustomPerson.create :dob => nil
|
61
|
+
end
|
62
|
+
|
63
|
+
describe ".zodiac_reader" do
|
64
|
+
it "sets @date_for_zodiac with the given value" do
|
65
|
+
CustomPerson.date_for_zodiac.should == :dob
|
66
|
+
end
|
67
|
+
|
68
|
+
it "sets @zodiac_sign_id_field with the given value" do
|
69
|
+
CustomPerson.zodiac_sign_id_field.should == :custom_sign_id
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe ".by_zodiac" do
|
74
|
+
it "returns a scope with objects belonging to a given sign" do
|
75
|
+
gemini = CustomPerson.by_zodiac(3)
|
76
|
+
gemini.should include(@gemini1)
|
77
|
+
gemini.should include(@gemini2)
|
78
|
+
gemini.should_not include(@libra)
|
79
|
+
gemini.should_not include(@nobody)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
after(:each) do
|
84
|
+
CustomPerson.delete_all
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "instance_methods" do
|
90
|
+
before(:each) do
|
91
|
+
dob = Time.gm(1955, 2, 24)
|
92
|
+
@person = Person.create(:name => 'Steve', :dob => dob)
|
93
|
+
@lite_person = LitePerson.create(:name => 'Steve lite', :dob => dob)
|
94
|
+
@nobody = Person.create(:name => 'Nobody', :dob => nil)
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "#zodiac_sign" do
|
98
|
+
context "on a migrated model" do
|
99
|
+
it "returns a correct zodiac sign based on date_for_zodiac attribute" do
|
100
|
+
@person.zodiac_sign.should == I18n.t('zodiac.pisces')
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context "on a non-migrated model" do
|
105
|
+
it "returns a correct zodiac sign based on date_for_zodiac attribute" do
|
106
|
+
@lite_person.zodiac_sign.should == I18n.t('zodiac.pisces')
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context "on a model with a nil date" do
|
111
|
+
it "returns nil" do
|
112
|
+
@nobody.zodiac_sign.should be_nil
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe "predicate methods (like #libra?)" do
|
118
|
+
context "on a migrated model" do
|
119
|
+
it "return true if the sign is correct" do
|
120
|
+
@person.should be_pisces
|
121
|
+
end
|
122
|
+
|
123
|
+
it "return false if the sign is incorrect" do
|
124
|
+
@person.should_not be_libra
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
context "on a non-migrated model" do
|
129
|
+
it "return true if the sign is correct" do
|
130
|
+
@lite_person.should be_pisces
|
131
|
+
end
|
132
|
+
|
133
|
+
it "return false if the sign is incorrect" do
|
134
|
+
@lite_person.should_not be_libra
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
context "on a model with a nil date" do
|
139
|
+
it "return false" do
|
140
|
+
@nobody.should_not be_pisces
|
141
|
+
@nobody.should_not be_libra
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
describe "before_save callback" do
|
147
|
+
before(:each) do
|
148
|
+
@new_dob = Time.gm(1955, 10, 28)
|
149
|
+
end
|
150
|
+
|
151
|
+
context "on a migrated model" do
|
152
|
+
it "updates the zodiac_sign_id attribute" do
|
153
|
+
@person.update_attribute(:dob, @new_dob)
|
154
|
+
@person.zodiac_sign_id.should == 8
|
155
|
+
end
|
156
|
+
|
157
|
+
it "sets nil for a nil date" do
|
158
|
+
@person.update_attribute(:dob, nil)
|
159
|
+
@person.zodiac_sign_id.should be_nil
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
context "on a non-migrated model" do
|
164
|
+
it "doesn't break saving" do
|
165
|
+
@lite_person.update_attribute(:dob, @new_dob)
|
166
|
+
@lite_person.reload.dob.should == @new_dob
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
after(:all) do
|
172
|
+
Person.delete_all
|
173
|
+
LitePerson.delete_all
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
data/spec/zodiac/date_spec.rb
CHANGED
@@ -5,12 +5,38 @@ module Zodiac
|
|
5
5
|
%w(Time Date DateTime).each do |date_class|
|
6
6
|
context "included into #{date_class}" do
|
7
7
|
before(:each) do
|
8
|
-
|
8
|
+
klass = Object.const_get(date_class)
|
9
|
+
if klass == Time
|
10
|
+
@date = Time.gm(Finder::YEAR, 9, 27)
|
11
|
+
else
|
12
|
+
@date = klass.new(Finder::YEAR, 9, 27)
|
13
|
+
end
|
9
14
|
end
|
10
15
|
|
11
16
|
it 'provides #zodiac_sign' do
|
12
17
|
@date.zodiac_sign.should == I18n.t('zodiac.libra')
|
13
18
|
end
|
19
|
+
|
20
|
+
it "provides #zodiac_sign_id" do
|
21
|
+
@date.zodiac_sign_id.should == 7
|
22
|
+
end
|
23
|
+
|
24
|
+
Zodiac.each_sign do |symbol, integer|
|
25
|
+
method_name = "#{symbol}?"
|
26
|
+
it "provides ##{method_name}" do
|
27
|
+
@date.should respond_to(method_name)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "predicate methods (like #libra?)" do
|
32
|
+
it "return true if the sign is correct" do
|
33
|
+
@date.should be_libra
|
34
|
+
end
|
35
|
+
|
36
|
+
it "return false if the sign is incorrect" do
|
37
|
+
@date.should_not be_gemini
|
38
|
+
end
|
39
|
+
end
|
14
40
|
end
|
15
41
|
end
|
16
42
|
end
|
data/spec/zodiac/finder_spec.rb
CHANGED
@@ -1,13 +1,21 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
describe
|
5
|
-
it "generates
|
6
|
-
|
3
|
+
describe Zodiac::Finder do
|
4
|
+
describe ".date_for" do
|
5
|
+
it "generates correct dates" do
|
6
|
+
subject.date_for(9, 27).should == DateTime.new(subject::YEAR, 9, 27)
|
7
7
|
end
|
8
|
-
|
8
|
+
end
|
9
|
+
|
10
|
+
describe ".sign_for" do
|
9
11
|
it "returns correct zodiac sign" do
|
10
|
-
|
12
|
+
subject.sign_for(:month => 9, :day => 27).should == I18n.t('zodiac.libra')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe ".sign_id_for" do
|
17
|
+
it "returns correct sign id" do
|
18
|
+
subject.sign_id_for(:month => 9, :day => 27).should == 7
|
11
19
|
end
|
12
20
|
end
|
13
21
|
end
|
data/zodiac.gemspec
CHANGED
@@ -1,23 +1,28 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
$:.push File.expand_path(
|
3
|
-
require
|
2
|
+
$:.push File.expand_path('../lib', __FILE__)
|
3
|
+
require 'zodiac/version'
|
4
4
|
|
5
5
|
Gem::Specification.new do |s|
|
6
|
-
s.name =
|
6
|
+
s.name = 'zodiac'
|
7
7
|
s.version = Zodiac::VERSION
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
|
-
s.authors = [
|
10
|
-
s.email = [
|
11
|
-
s.homepage =
|
9
|
+
s.authors = ['Vsevolod Romashov']
|
10
|
+
s.email = ['7@7vn.ru']
|
11
|
+
s.homepage = 'https://github.com/7even/zodiac'
|
12
12
|
s.summary = %q{Zodiac sign calculator for any date}
|
13
|
-
s.description = %q{Adds methods for getting a zodiac sign from any Date/Time object containing a date of birth}
|
13
|
+
s.description = %q{Adds methods for getting a zodiac sign from any Date/Time object containing a date of birth, and can also extend ActiveRecord::Base adding some handy instance and class methods (for searching by a given zodiac sign and more).}
|
14
14
|
|
15
15
|
s.add_dependency 'funtimes'
|
16
16
|
s.add_dependency 'i18n'
|
17
|
+
s.add_development_dependency 'rake'
|
17
18
|
s.add_development_dependency 'rspec'
|
19
|
+
s.add_development_dependency 'activerecord', '~> 3'
|
20
|
+
s.add_development_dependency 'sqlite3'
|
21
|
+
s.add_development_dependency 'pry'
|
22
|
+
s.add_development_dependency 'awesome_print'
|
18
23
|
|
19
24
|
s.files = `git ls-files`.split("\n")
|
20
25
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
21
26
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
22
|
-
s.require_paths = [
|
27
|
+
s.require_paths = ['lib']
|
23
28
|
end
|
metadata
CHANGED
@@ -1,105 +1,174 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: zodiac
|
3
|
-
version: !ruby/object:Gem::Version
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
4
5
|
prerelease:
|
5
|
-
version: 0.1.1
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
7
|
+
authors:
|
8
8
|
- Vsevolod Romashov
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
dependencies:
|
16
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2011-09-25 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
17
15
|
name: funtimes
|
18
|
-
|
19
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: &70172017103080 !ruby/object:Gem::Requirement
|
20
17
|
none: false
|
21
|
-
requirements:
|
22
|
-
- -
|
23
|
-
- !ruby/object:Gem::Version
|
24
|
-
version:
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
25
22
|
type: :runtime
|
26
|
-
version_requirements: *id001
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: i18n
|
29
23
|
prerelease: false
|
30
|
-
|
24
|
+
version_requirements: *70172017103080
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: i18n
|
27
|
+
requirement: &70172017102620 !ruby/object:Gem::Requirement
|
31
28
|
none: false
|
32
|
-
requirements:
|
33
|
-
- -
|
34
|
-
- !ruby/object:Gem::Version
|
35
|
-
version:
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
36
33
|
type: :runtime
|
37
|
-
|
38
|
-
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70172017102620
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rake
|
38
|
+
requirement: &70172017102120 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70172017102120
|
47
|
+
- !ruby/object:Gem::Dependency
|
39
48
|
name: rspec
|
49
|
+
requirement: &70172017101680 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
40
56
|
prerelease: false
|
41
|
-
|
57
|
+
version_requirements: *70172017101680
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: activerecord
|
60
|
+
requirement: &70172017101140 !ruby/object:Gem::Requirement
|
42
61
|
none: false
|
43
|
-
requirements:
|
44
|
-
- -
|
45
|
-
- !ruby/object:Gem::Version
|
46
|
-
version:
|
62
|
+
requirements:
|
63
|
+
- - ~>
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '3'
|
47
66
|
type: :development
|
48
|
-
|
49
|
-
|
50
|
-
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70172017101140
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: sqlite3
|
71
|
+
requirement: &70172017100700 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *70172017100700
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: pry
|
82
|
+
requirement: &70172017100220 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *70172017100220
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: awesome_print
|
93
|
+
requirement: &70172017099760 !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
type: :development
|
100
|
+
prerelease: false
|
101
|
+
version_requirements: *70172017099760
|
102
|
+
description: Adds methods for getting a zodiac sign from any Date/Time object containing
|
103
|
+
a date of birth, and can also extend ActiveRecord::Base adding some handy instance
|
104
|
+
and class methods (for searching by a given zodiac sign and more).
|
105
|
+
email:
|
51
106
|
- 7@7vn.ru
|
52
107
|
executables: []
|
53
|
-
|
54
108
|
extensions: []
|
55
|
-
|
56
109
|
extra_rdoc_files: []
|
57
|
-
|
58
|
-
files:
|
110
|
+
files:
|
59
111
|
- .gitignore
|
60
112
|
- Gemfile
|
61
|
-
- README.
|
113
|
+
- README.md
|
62
114
|
- Rakefile
|
115
|
+
- lib/generators/zodiac/migration/USAGE
|
116
|
+
- lib/generators/zodiac/migration/migration_generator.rb
|
117
|
+
- lib/generators/zodiac/migration/templates/migration30.rb.erb
|
118
|
+
- lib/generators/zodiac/migration/templates/migration31.rb.erb
|
63
119
|
- lib/locales/en.yml
|
64
120
|
- lib/locales/pt-BR.yml
|
65
121
|
- lib/locales/ru.yml
|
66
122
|
- lib/zodiac.rb
|
123
|
+
- lib/zodiac/activerecord.rb
|
67
124
|
- lib/zodiac/date.rb
|
68
125
|
- lib/zodiac/finder.rb
|
69
126
|
- lib/zodiac/version.rb
|
70
127
|
- spec/spec_helper.rb
|
128
|
+
- spec/support/custom_person.rb
|
129
|
+
- spec/support/lite_person.rb
|
130
|
+
- spec/support/person.rb
|
131
|
+
- spec/support/test.sqlite3
|
132
|
+
- spec/zodiac/activerecord_spec.rb
|
71
133
|
- spec/zodiac/date_spec.rb
|
72
134
|
- spec/zodiac/finder_spec.rb
|
73
135
|
- zodiac.gemspec
|
74
|
-
|
75
|
-
homepage: ""
|
136
|
+
homepage: https://github.com/7even/zodiac
|
76
137
|
licenses: []
|
77
|
-
|
78
138
|
post_install_message:
|
79
139
|
rdoc_options: []
|
80
|
-
|
81
|
-
require_paths:
|
140
|
+
require_paths:
|
82
141
|
- lib
|
83
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
142
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
84
143
|
none: false
|
85
|
-
requirements:
|
86
|
-
- -
|
87
|
-
- !ruby/object:Gem::Version
|
88
|
-
version:
|
89
|
-
|
144
|
+
requirements:
|
145
|
+
- - ! '>='
|
146
|
+
- !ruby/object:Gem::Version
|
147
|
+
version: '0'
|
148
|
+
segments:
|
149
|
+
- 0
|
150
|
+
hash: 3417073026465186875
|
151
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
152
|
none: false
|
91
|
-
requirements:
|
92
|
-
- -
|
93
|
-
- !ruby/object:Gem::Version
|
94
|
-
version:
|
153
|
+
requirements:
|
154
|
+
- - ! '>='
|
155
|
+
- !ruby/object:Gem::Version
|
156
|
+
version: '0'
|
157
|
+
segments:
|
158
|
+
- 0
|
159
|
+
hash: 3417073026465186875
|
95
160
|
requirements: []
|
96
|
-
|
97
161
|
rubyforge_project:
|
98
|
-
rubygems_version: 1.
|
162
|
+
rubygems_version: 1.8.10
|
99
163
|
signing_key:
|
100
164
|
specification_version: 3
|
101
165
|
summary: Zodiac sign calculator for any date
|
102
|
-
test_files:
|
166
|
+
test_files:
|
103
167
|
- spec/spec_helper.rb
|
168
|
+
- spec/support/custom_person.rb
|
169
|
+
- spec/support/lite_person.rb
|
170
|
+
- spec/support/person.rb
|
171
|
+
- spec/support/test.sqlite3
|
172
|
+
- spec/zodiac/activerecord_spec.rb
|
104
173
|
- spec/zodiac/date_spec.rb
|
105
174
|
- spec/zodiac/finder_spec.rb
|
data/README.textile
DELETED
@@ -1,50 +0,0 @@
|
|
1
|
-
h1. zodiac
|
2
|
-
|
3
|
-
@zodiac@ is a simple gem for getting a zodiac sign from a given date of birth. It extends @Time@, @Date@ and @DateTime@ objects with a @zodiac_sign@ method.
|
4
|
-
|
5
|
-
h2. Installation
|
6
|
-
|
7
|
-
<pre>gem install zodiac</pre>
|
8
|
-
|
9
|
-
h2. Usage
|
10
|
-
|
11
|
-
<pre>
|
12
|
-
require 'zodiac'
|
13
|
-
Time.now.zodiac_sign # => "Aries"
|
14
|
-
require 'date'
|
15
|
-
Date.new(2011, 1, 1).zodiac_sign # => "Capricorn"
|
16
|
-
DateTime.new(2011, 4, 30).zodiac_sign # => "Taurus"
|
17
|
-
</pre>
|
18
|
-
|
19
|
-
@#zodiac_sign@ returns values using I18n with "zodiac.#{sign}" path, so if you want your own translations, you can put them in your locale with keys like @zodiac.aries@, @zodiac.taurus@ etc. See examples "here":http://github.com/7even/zodiac/blob/master/lib/locales/en.yml
|
20
|
-
|
21
|
-
h2. Included locales
|
22
|
-
|
23
|
-
<pre>
|
24
|
-
en
|
25
|
-
ru
|
26
|
-
pt-BR (thanks "jeffrydegrande":https://github.com/jeffrydegrande)
|
27
|
-
</pre>
|
28
|
-
|
29
|
-
h2. Changelog
|
30
|
-
|
31
|
-
* 0.1 Initial version with Time/Date/DateTime extension and [:ru, :en] locales
|
32
|
-
* 0.1.1 Added pt-BR locale (thanks "jeffrydegrande":https://github.com/jeffrydegrande)
|
33
|
-
|
34
|
-
h2. Roadmap
|
35
|
-
|
36
|
-
1. Rdoc coverage of everything
|
37
|
-
|
38
|
-
2. ActiveRecord macro:
|
39
|
-
|
40
|
-
<pre>
|
41
|
-
class Person < ActiveRecord::Base
|
42
|
-
zodiac_reader :dob # dob is a DateTime attribute containing person's date of birth
|
43
|
-
end
|
44
|
-
Person.first.zodiac_sign # => "scorpio"
|
45
|
-
Person.find_by_zodiac_sign("gemini") # => AR::Relation
|
46
|
-
</pre>
|
47
|
-
|
48
|
-
h2. Contributing
|
49
|
-
|
50
|
-
Fork the repository, push your changes to a topic branch and send me a pull request.
|