by_star 1.0.1 → 2.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +23 -0
- data/Gemfile +1 -7
- data/Gemfile.lock +77 -29
- data/README.markdown +28 -172
- data/by_star.gemspec +6 -0
- data/lib/by_star.rb +48 -28
- data/lib/by_star/by_day.rb +30 -0
- data/lib/by_star/by_direction.rb +52 -0
- data/lib/by_star/by_fortnight.rb +54 -0
- data/lib/by_star/by_month.rb +35 -0
- data/lib/by_star/by_week.rb +30 -0
- data/lib/by_star/by_weekend.rb +17 -0
- data/lib/by_star/by_year.rb +60 -0
- data/lib/by_star/instance_methods.rb +13 -0
- data/lib/by_star/time_ext.rb +2 -1
- data/lib/by_star/version.rb +1 -1
- data/spec/by_star/by_day_spec.rb +52 -0
- data/spec/by_star/by_direction_spec.rb +82 -0
- data/spec/by_star/by_fortnight_spec.rb +46 -0
- data/spec/by_star/by_month_spec.rb +60 -0
- data/spec/by_star/by_week_spec.rb +39 -0
- data/spec/by_star/by_weekend_spec.rb +12 -0
- data/spec/by_star/by_year_spec.rb +57 -0
- data/spec/database.yml +13 -7
- data/spec/fixtures/models.rb +7 -60
- data/spec/spec_helper.rb +13 -7
- data/spec/time_ext_spec.rb +10 -0
- metadata +114 -59
- data/init.rb +0 -2
- data/lib/by_star/calculations.rb +0 -23
- data/lib/by_star/calculations/count.rb +0 -20
- data/lib/by_star/calculations/sum.rb +0 -25
- data/lib/by_star/neighbours.rb +0 -15
- data/lib/by_star/range_calculations.rb +0 -23
- data/lib/by_star/shared.rb +0 -18
- data/lib/by_star/vanilla.rb +0 -276
- data/spec/by_star_spec.rb +0 -722
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
describe "before" do
|
3
|
+
def posts_count(*args)
|
4
|
+
Post.before(*args).count
|
5
|
+
end
|
6
|
+
|
7
|
+
it "should show the correct number of posts in the past" do
|
8
|
+
posts_count.should == 5
|
9
|
+
end
|
10
|
+
|
11
|
+
it "is aliased as before_now" do
|
12
|
+
Post.before_now.count.should == 5
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should find for a given time" do
|
16
|
+
posts_count(Time.zone.now - 2.days).should eql(2)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should find for a given date" do
|
20
|
+
posts_count(Date.today - 2).should eql(2)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should find for a given string" do
|
24
|
+
posts_count("next tuesday").should eql(8)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "raises an exception when Chronic can't parse" do
|
28
|
+
lambda { posts_count(";aosdjbjisdabdgofbi") }.should raise_error(ByStar::ParseError)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should be able to find all events before Ryan's birthday using a non-standard field" do
|
32
|
+
Event.before(Time.local(Time.zone.now.year+2), :field => "start_time").count.should eql(8)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "future" do
|
37
|
+
def posts_count(*args)
|
38
|
+
Post.after(*args).count
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should show the correct number of posts in the future" do
|
42
|
+
Post.after.count.should eql(posts_count)
|
43
|
+
Post.after_now.count.should eql(posts_count)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should find for a given date" do
|
47
|
+
posts_count(Date.today - 2).should eql(19)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should find for a given string" do
|
51
|
+
posts_count("next tuesday").should eql(13)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should be able to find all events before Dad's birthday using a non-standard field" do
|
55
|
+
Event.after(Time.zone.local(Time.zone.now.year, 7, 5), :field => "start_time").count.should eql(3)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "previous and next" do
|
60
|
+
let(:current_post) { Post.find_by_text("post 1") }
|
61
|
+
let(:current_event) { Event.find_by_name("Mum's birthday!") }
|
62
|
+
|
63
|
+
context "previous" do
|
64
|
+
it "can find the previous post" do
|
65
|
+
current_post.previous.text.should == "Yesterday's post"
|
66
|
+
end
|
67
|
+
|
68
|
+
it "takes the field option" do
|
69
|
+
current_event.previous(:field => "start_time").name.should == "Dad's birthday!"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context "next" do
|
74
|
+
it "can find the next post" do
|
75
|
+
current_post.next.text.should == "Today's post"
|
76
|
+
end
|
77
|
+
|
78
|
+
it "takes the field option" do
|
79
|
+
current_event.next(:field => "start_time").name.should == "Ryan's birthday!"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "by fortnight" do
|
4
|
+
|
5
|
+
def find_posts(*args)
|
6
|
+
Post.by_fortnight(*args)
|
7
|
+
end
|
8
|
+
|
9
|
+
def posts_count(*args)
|
10
|
+
find_posts(*args).count
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should be able to find posts in the current fortnight" do
|
14
|
+
posts_count.should eql(6)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should be able to find posts in the 1st fortnight of the current year" do
|
18
|
+
posts_count(0).should eql(6)
|
19
|
+
posts_count("0").should eql(6)
|
20
|
+
# There was previously a situation where incorrect time zone math
|
21
|
+
# caused the 'post 1' post to NOT appear, so count would be 7, rather than 8.
|
22
|
+
# So this line simply regression tests that problem.
|
23
|
+
Post.by_fortnight(0).map(&:text).should include("post 1")
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should be able to find posts for a fortnight ago" do
|
27
|
+
posts_count(2.weeks.ago).should eql(2)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should be able to find posts for a given fortnight in a year" do
|
31
|
+
posts_count(0, :year => Time.zone.now.year - 1).should eql(1)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should be able to find posts for the current fortnight in a specific year" do
|
35
|
+
posts_count(:year => Time.zone.now.year - 1).should eql(1)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should raise an error when given an invalid argument" do
|
39
|
+
lambda { find_posts(27) }.should raise_error(ByStar::ParseError, "by_fortnight takes only a Time, Date or a Fixnum (less than or equal to 26).")
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should be able to use an alternative field" do
|
43
|
+
Event.by_fortnight(nil, :field => "start_time").count.should eql(2)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "by_month" do
|
4
|
+
def find_posts(time=Time.zone.now, options={})
|
5
|
+
Post.by_month(time, options)
|
6
|
+
end
|
7
|
+
|
8
|
+
def posts_count(time=Time.zone.now, options={})
|
9
|
+
find_posts(time, options).count
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should be able to find posts for the current month" do
|
13
|
+
posts_count.should eql(6)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should be able to find a single post for January" do
|
17
|
+
# If it is January we'll have all the "current" posts in there.
|
18
|
+
# This makes the count 10.
|
19
|
+
# I'm sure you can guess what happens when it's not January.
|
20
|
+
posts_count("January").should eql(6)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should be able to find two posts for the 2nd month" do
|
24
|
+
# If it is February we'll have all the "current" posts in there.
|
25
|
+
# This makes the count 10.
|
26
|
+
# I'm sure you can guess what happens when it's not February.
|
27
|
+
posts_count(2).should eql(1)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should be able to find three posts for the 3rd month, using time instance" do
|
31
|
+
# If it is March we'll have all the "current" posts in there.
|
32
|
+
# This makes the count 10.
|
33
|
+
# I'm sure you can guess what happens when it's not March.
|
34
|
+
time = Time.local(Time.zone.now.year, 3, 1)
|
35
|
+
posts_count(time).should eql(1)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should be able to find a single post from January last year" do
|
39
|
+
posts_count("January", :year => Time.zone.now.year - 1).should eql(1)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should fail when given incorrect months" do
|
43
|
+
lambda { find_posts(0) }.should raise_error(ByStar::ParseError)
|
44
|
+
lambda { find_posts(13) }.should raise_error(ByStar::ParseError)
|
45
|
+
lambda { find_posts("Ryan") }.should raise_error(ByStar::ParseError)
|
46
|
+
# LOL arrays
|
47
|
+
lambda { find_posts([1,2,3]) }.should raise_error(NoMethodError)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should be able to use an alternative field" do
|
51
|
+
Timecop.freeze(Time.zone.local(Time.zone.now.year, 12, 1, 0, 0, 0)) do
|
52
|
+
Event.by_month(:field => "start_time").size.should eql(1)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should be able to specify the year as a string" do
|
57
|
+
posts_count(1, :year => (Time.zone.now.year - 1).to_s).should eql(1)
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
describe "by week" do
|
3
|
+
def posts_count(*args)
|
4
|
+
find_posts(*args).count
|
5
|
+
end
|
6
|
+
|
7
|
+
def find_posts(*args)
|
8
|
+
Post.by_week(*args)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should be able to find posts in the current week" do
|
12
|
+
posts_count.should eql(5)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should be able to find posts in the 1st week" do
|
16
|
+
posts_count(0).should eql(6)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should be able to find posts in the 1st week of last year" do
|
20
|
+
posts_count(0, :year => Time.zone.now.year-1).should eql(1)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should not find any posts from a week ago" do
|
24
|
+
posts_count(1.week.ago).should eql(1)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should be able to use an alternative field" do
|
28
|
+
Event.by_week(:field => "start_time").size.should eql(2)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should find posts at the start of the year" do
|
32
|
+
posts_count(0).should eql(6)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should find posts at the end of the year" do
|
36
|
+
posts_count(Time.zone.now.end_of_year).should eql(1)
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'by weekend' do
|
4
|
+
|
5
|
+
it "should be able to find the posts on the weekend of the 1st of January" do
|
6
|
+
Post.by_weekend.count.should eql(6)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should be able to use an alternative field" do
|
10
|
+
Event.by_weekend(:field => "start_time").count.should eql(3)
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "by_year" do
|
4
|
+
def posts_count(*args)
|
5
|
+
find_posts(*args).count
|
6
|
+
end
|
7
|
+
|
8
|
+
def find_posts(*args)
|
9
|
+
options = args.extract_options!
|
10
|
+
Post.by_year(args.first, options)
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:this_years_posts) { 18 }
|
14
|
+
|
15
|
+
it "should be able to find all the posts in the current year" do
|
16
|
+
posts_count.should eql(this_years_posts)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should be able to find if given a string" do
|
20
|
+
posts_count(Time.zone.now.year.to_s).should eql(this_years_posts)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should be able to find a single post from last year" do
|
24
|
+
posts_count(Time.zone.now.year-1).should eql(3)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "knows what last year's posts were" do
|
28
|
+
find_posts(Time.zone.now.year-1).map(&:text).should =~ ["A week ago", "This time, last year", "Yesterday's post"]
|
29
|
+
end
|
30
|
+
|
31
|
+
it "can find posts given a 2-digit year" do
|
32
|
+
# Should be good for at least a couple of years.
|
33
|
+
posts_count(Time.zone.now.year-2001).should eql(3)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should be able to use an alternative field (string)" do
|
37
|
+
Event.by_year(:field => "start_time").count.should eql(6)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should be able to use an alternative field (symbol)" do
|
41
|
+
Event.by_year(:field => :start_time).count.should eql(6)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should not have to specify the field when using by_star_field" do
|
45
|
+
Event.by_year.count.should eql(6)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should not include yesterday's (Dec 31st <last year>) event in by_year" do
|
49
|
+
Event.by_year.map(&:name).should_not include("Yesterday")
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should be able to order the result set" do
|
53
|
+
scope = find_posts(Time.zone.now.year, :order => "created_at DESC")
|
54
|
+
scope.order_values.should == ["created_at DESC"]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
data/spec/database.yml
CHANGED
@@ -1,9 +1,15 @@
|
|
1
|
+
sqlite:
|
2
|
+
adapter: sqlite3
|
3
|
+
database: by_star.sqlite3
|
4
|
+
|
5
|
+
postgres:
|
6
|
+
adapter: postgresql
|
7
|
+
database: by_star_test
|
8
|
+
username: postgres
|
9
|
+
min_messages: warning
|
10
|
+
|
1
11
|
mysql:
|
12
|
+
adapter: mysql2
|
13
|
+
database: by_star_test
|
2
14
|
username: root
|
3
|
-
|
4
|
-
database: by_star
|
5
|
-
adapter: mysql
|
6
|
-
|
7
|
-
sqlite3:
|
8
|
-
adapter: sqlite3
|
9
|
-
database: by_star.sqlite3
|
15
|
+
encoding: utf8
|
data/spec/fixtures/models.rb
CHANGED
@@ -7,26 +7,11 @@ class Post < ActiveRecord::Base
|
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
|
-
class Tag < ActiveRecord::Base
|
11
|
-
has_and_belongs_to_many :posts
|
12
|
-
end
|
13
|
-
|
14
10
|
class Event < ActiveRecord::Base
|
15
11
|
by_star_field :start_time
|
16
12
|
scope :secret, :conditions => { :public => false }
|
17
13
|
end
|
18
14
|
|
19
|
-
class Invoice < ActiveRecord::Base
|
20
|
-
has_many :day_entries
|
21
|
-
def self.factory(value, created_at = nil)
|
22
|
-
create!(:value => value, :created_at => created_at, :number => value)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
class DayEntry < ActiveRecord::Base
|
27
|
-
|
28
|
-
end
|
29
|
-
|
30
15
|
## seed data:
|
31
16
|
|
32
17
|
year = Time.zone.now.year
|
@@ -35,23 +20,11 @@ year = Time.zone.now.year
|
|
35
20
|
Post.factory "post #{month}", Time.zone.now.beginning_of_year + (month - 1).months
|
36
21
|
end
|
37
22
|
|
38
|
-
1.upto(12) do |month|
|
39
|
-
Invoice.factory 10000, Time.zone.now.beginning_of_year + (month - 1).months
|
40
|
-
end
|
41
|
-
|
42
|
-
# Inovice for 2nd January for sum_by_day
|
43
|
-
Invoice.factory 5500, Time.zone.now.beginning_of_year + 1.day
|
44
|
-
|
45
|
-
# Invoice from last year
|
46
|
-
Invoice.factory 10000, Time.local(Time.zone.now.year-1, 1, 1)
|
47
|
-
|
48
|
-
# Invoice without a number for count_by_year test
|
49
|
-
Invoice.create!(:value => 10000, :number => nil)
|
50
|
-
|
51
23
|
Post.factory "Today's post", Time.zone.now
|
52
|
-
Post.factory "Yesterday's post",
|
53
|
-
Post.factory "
|
54
|
-
|
24
|
+
Post.factory "Yesterday's post", 1.day.ago
|
25
|
+
Post.factory "A week ago", 1.week.ago
|
26
|
+
Post.factory "Tomorrow's post", 1.day.from_now
|
27
|
+
Post.factory "This time, last year", 1.year.ago
|
55
28
|
Post.factory "That's it!", Time.zone.now.end_of_year
|
56
29
|
|
57
30
|
# For by_weekend scoped test
|
@@ -61,31 +34,11 @@ weekend_time += 1.day while weekend_time.wday != 6
|
|
61
34
|
|
62
35
|
# For by_weekend scoped test
|
63
36
|
post = Post.factory "Weekend", weekend_time
|
64
|
-
post.tags.create(:name => "weekend")
|
65
|
-
|
66
|
-
# For by_day scoped test
|
67
|
-
post = Post.factory "Today", Time.zone.now
|
68
|
-
post.tags.create(:name => "today")
|
69
|
-
|
70
|
-
# For yesterday scoped test
|
71
|
-
post = Post.factory "Yesterday", Time.zone.now.yesterday
|
72
|
-
post.tags.create(:name => "yesterday")
|
73
|
-
|
74
|
-
# For tomorrow scoped test
|
75
|
-
post = Post.factory "Tomorrow's Another Day", Time.zone.now.tomorrow
|
76
|
-
post.tags.create(:name => "tomorrow")
|
77
37
|
|
78
|
-
|
79
|
-
post.
|
38
|
+
# Offset by two seconds to stop it clashing with "Today's post" in next test
|
39
|
+
post = Post.factory "The 'Current' Fortnight", Time.zone.now + 2.seconds
|
80
40
|
|
81
|
-
post = Post.factory "
|
82
|
-
post.tags.create(:name => "final")
|
83
|
-
|
84
|
-
post = Post.factory "The 'Current' Fortnight", Time.zone.now
|
85
|
-
post.tags.create(:name => "fortnight")
|
86
|
-
|
87
|
-
post = Post.factory "The 'Current' Week", Time.zone.now
|
88
|
-
post.tags.create(:name => "week")
|
41
|
+
post = Post.factory "The 'Current' Week", Time.zone.now + 2.seconds
|
89
42
|
|
90
43
|
|
91
44
|
Event.create(:name => "Ryan's birthday!", :start_time => "04-12-#{Time.zone.now.year}".to_time)
|
@@ -95,10 +48,4 @@ Event.create(:name => "Mum's birthday!", :start_time => "17-11-#{Time.zone.now
|
|
95
48
|
Event.create(:name => "Today", :start_time => Time.zone.now)
|
96
49
|
Event.create(:name => "Yesterday", :start_time => Time.zone.now.yesterday)
|
97
50
|
Event.create(:name => "Tomorrow", :start_time => Time.zone.now.tomorrow)
|
98
|
-
|
99
|
-
# For by_weekend test
|
100
|
-
Event.create(:name => "1st of August", :start_time => "01-08-#{Time.zone.now.year}".to_time)
|
101
|
-
|
102
51
|
Event.create(:name => "FBI meeting", :start_time => "02-03-#{Time.zone.now.year}".to_time, :public => false)
|
103
|
-
|
104
|
-
# Invoice.first.day_entries.create(:spent_at => Time.zone.now + 1.hour, :name => "Working harder, better, faster stronger.")
|
data/spec/spec_helper.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
Bundler.setup
|
2
4
|
require 'active_record'
|
3
5
|
require 'fileutils'
|
4
6
|
require 'logger'
|
@@ -10,17 +12,21 @@ require 'active_support'
|
|
10
12
|
require 'active_support/core_ext/string/conversions'
|
11
13
|
require 'by_star'
|
12
14
|
require 'rspec'
|
15
|
+
require 'timecop'
|
13
16
|
|
14
17
|
# Define time zone before loading test_helper
|
15
18
|
zone = "UTC"
|
16
19
|
Time.zone = zone
|
17
|
-
ActiveRecord::Base.default_timezone =
|
20
|
+
ActiveRecord::Base.default_timezone = :utc
|
21
|
+
|
22
|
+
ActiveRecord::Base.configurations = YAML::load_file(File.dirname(__FILE__) + "/database.yml")
|
23
|
+
ActiveRecord::Base.establish_connection(ENV["DB"] || "sqlite")
|
24
|
+
load File.dirname(__FILE__) + "/fixtures/schema.rb"
|
25
|
+
|
26
|
+
# Freeze time to Jan 1st of this year
|
27
|
+
Timecop.travel(Time.zone.local(Time.zone.now.year, 1, 1, 0, 0, 1, 0))
|
28
|
+
load File.dirname(__FILE__) + "/fixtures/models.rb"
|
18
29
|
|
19
|
-
YAML::load_file(File.dirname(__FILE__) + "/database.yml").each do |key, connection|
|
20
|
-
ActiveRecord::Base.establish_connection(connection)
|
21
|
-
load File.dirname(__FILE__) + "/fixtures/schema.rb"
|
22
|
-
load File.dirname(__FILE__) + "/fixtures/models.rb"
|
23
|
-
end
|
24
30
|
|
25
31
|
# Print the location of puts/p calls so you can find them later
|
26
32
|
# def puts str
|
@@ -33,4 +39,4 @@ end
|
|
33
39
|
# super obj
|
34
40
|
# end
|
35
41
|
|
36
|
-
ActiveRecord::Base.logger = Logger.new("tmp/activerecord.log")
|
42
|
+
ActiveRecord::Base.logger = Logger.new("tmp/activerecord.log")
|