aggtive_record 0.1.2 → 0.1.5

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.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YzUxOTY3OTI2MWVmYjg0ZWU0YzVmOTUyMjA0NzhmNGEzMTU5ODhhMg==
4
+ NzM2ZGIxNTQ3MjU2MmI0ZGQ2YmJmOTJjMjQxYjQxZTJmNGYwODI1ZQ==
5
5
  data.tar.gz: !binary |-
6
- YmIzZWJjOGMzMzEzYTc0NzQwZjc0ODQ1YjUyNTVjZWU4ZTFhMmNmZA==
6
+ MmY0YmQ4ZDE1NGNkNTU2ZDZkNjFmNzg2YTczNjIyY2Q4NjIxZGFkNQ==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- ZDBhZGYwOThkN2U5NjQ4NjNiOTA1ZDdkMTA1MTE4YmNmYjI3M2VjZWQxZDg0
10
- NWZkNDE2NDYxNGRiM2QxYjMwMTJmNDIwMDM2MGFhYTAzNDBhM2Y5MGFmMjQw
11
- MzI3NGRiYjkzZjMwNWU5NjdiYzhkMjA4OTA5YjBkMmZhNzExYzg=
9
+ MGZkMWFhMTFiMGMzODllNmY0ZDI5MmNmYWM4Zjg0NDA4MjRkZjQ4YmNhNzFm
10
+ MmQ1ODRlMWVlMjg1ZDY0MmJjNDZmOTBiMDRmMjNmMzBiZDYxOTc4NjFlNWM0
11
+ M2JhMWM3NDJhN2IxMWNkOWU5ZTNmMTJlYTg2MjU0YWFiMTZjYzg=
12
12
  data.tar.gz: !binary |-
13
- ZWQyMjNiMzE3Y2ZlYzZiYmE5MWJkYjdhOWQ1NGM3ODY4YzhmYmUyZDJhNWJl
14
- MTg4MWUxOWRlZThkNTYyMWM5ZWUyNWZkN2QwN2MyNzQwNmRjNDhjYzM1ZDc0
15
- NzdhMGU3OWVhNGVmMDRhZjNmMDkyY2Q4Yzk4NTVjODlkYzc1ZjY=
13
+ MGQyOWZhNWMzMjgwMjVmNGM1N2RkMGJhZDA0NjI1MWEyZjNiNzk4YjJiNTNm
14
+ ZjRiMzNjNjlhZmYyMWUzODcwNTA3OWYwNzRhNzhlZWQ1NzhlMTZhMzE3Y2I1
15
+ MmI5Mzk2NWI0MzM2NGJkZmJhNGYyODkyOTNmNDAwNTlkODNjMjU=
data/Gemfile CHANGED
@@ -9,6 +9,7 @@ group :development do
9
9
  gem 'database_cleaner', '~> 1.0.1'
10
10
  gem 'mysql2'
11
11
  gem 'activerecord', '~> 3.2.14'
12
+ gem 'timecop'
12
13
  end
13
14
 
14
15
  gem 'groupdate'
data/Gemfile.lock CHANGED
@@ -76,6 +76,7 @@ GEM
76
76
  diff-lcs (>= 1.1.3, < 2.0)
77
77
  rspec-mocks (2.14.3)
78
78
  slop (3.4.6)
79
+ timecop (0.6.3)
79
80
  tzinfo (0.3.37)
80
81
 
81
82
  PLATFORMS
@@ -91,3 +92,4 @@ DEPENDENCIES
91
92
  mysql2
92
93
  pry
93
94
  rspec (~> 2.14.1)
95
+ timecop
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.2
1
+ 0.1.5
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "aggtive_record"
8
- s.version = "0.1.2"
8
+ s.version = "0.1.5"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Dan Nguyen"]
12
- s.date = "2013-09-23"
12
+ s.date = "2013-10-02"
13
13
  s.description = "This is not even remotely finished or even started on. Please don't download."
14
14
  s.email = "dansonguyen@gmail.com"
15
15
  s.extra_rdoc_files = [
@@ -35,12 +35,13 @@ Gem::Specification.new do |s|
35
35
  "lib/aggtive_record/egg_scopes.rb",
36
36
  "lib/aggtive_record/egg_scopes/collation.rb",
37
37
  "lib/aggtive_record/egg_scopes/collation/count_by.rb",
38
- "lib/aggtive_record/egg_scopes/collation/rate.rb",
38
+ "lib/aggtive_record/egg_scopes/collation/rate_per.rb",
39
39
  "lib/aggtive_record/egg_scopes/time_bucket.rb",
40
40
  "lib/aggtive_record/egg_scopes/time_span.rb",
41
41
  "lib/aggtive_record/memo.rb",
42
42
  "lib/aggtive_record/time.rb",
43
43
  "spec/functional/basic_object_run_spec.rb",
44
+ "spec/functional/collation_spec.rb",
44
45
  "spec/lib/aggable_spec.rb",
45
46
  "spec/lib/count_by_spec.rb",
46
47
  "spec/lib/rate_spec.rb",
@@ -67,6 +68,7 @@ Gem::Specification.new do |s|
67
68
  s.add_development_dependency(%q<database_cleaner>, ["~> 1.0.1"])
68
69
  s.add_development_dependency(%q<mysql2>, [">= 0"])
69
70
  s.add_development_dependency(%q<activerecord>, ["~> 3.2.14"])
71
+ s.add_development_dependency(%q<timecop>, [">= 0"])
70
72
  else
71
73
  s.add_dependency(%q<groupdate>, [">= 0"])
72
74
  s.add_dependency(%q<activesupport>, ["~> 3.2.14"])
@@ -77,6 +79,7 @@ Gem::Specification.new do |s|
77
79
  s.add_dependency(%q<database_cleaner>, ["~> 1.0.1"])
78
80
  s.add_dependency(%q<mysql2>, [">= 0"])
79
81
  s.add_dependency(%q<activerecord>, ["~> 3.2.14"])
82
+ s.add_dependency(%q<timecop>, [">= 0"])
80
83
  end
81
84
  else
82
85
  s.add_dependency(%q<groupdate>, [">= 0"])
@@ -88,6 +91,7 @@ Gem::Specification.new do |s|
88
91
  s.add_dependency(%q<database_cleaner>, ["~> 1.0.1"])
89
92
  s.add_dependency(%q<mysql2>, [">= 0"])
90
93
  s.add_dependency(%q<activerecord>, ["~> 3.2.14"])
94
+ s.add_dependency(%q<timecop>, [">= 0"])
91
95
  end
92
96
  end
93
97
 
@@ -12,8 +12,19 @@ module AggtiveRecord
12
12
  span_foo = "by_#{time_period}"
13
13
  self.send(span_foo).count
14
14
  end
15
+
16
+ # define dynamically
17
+ AggtiveRecord::Time.periods.each do |period_name|
18
+ foo_name = "count_by_#{period_name}".to_sym
19
+ # defining scope here, dynamically
20
+ define_method foo_name do
21
+ self.count_by(period_name)
22
+ end
23
+ end
15
24
  end
16
25
 
26
+
27
+
17
28
  end
18
29
  end
19
30
  end
@@ -0,0 +1,76 @@
1
+ module AggtiveRecord
2
+ module EggScopes
3
+ module Collation
4
+ module Rate
5
+ extend ActiveSupport::Concern
6
+
7
+ # Public: a rate
8
+ # expects that ActiveRelation has a grouping
9
+ # self is a ActiveRecord scope
10
+
11
+ module ClassMethods
12
+
13
+ # Public
14
+ #
15
+ # Returns float indicating rate of records per given time period
16
+ def rate_per(time_period, timespan_in_seconds = nil)
17
+ # tk: this may be unnecessary
18
+ records = self.scoped.to_a
19
+
20
+ time_period_secs = AggtiveRecord::Time.to_seconds(time_period)
21
+ timespan_in_seconds ||= self.timespan_to_now(records)
22
+
23
+
24
+
25
+ return records.size.to_f * time_period_secs / timespan_in_seconds
26
+ end
27
+
28
+ # defines rate_per_year, rate_per_hour
29
+ # except that rate_per_year also accepts an optional argument
30
+
31
+ AggtiveRecord::Time.periods.each do |period_name|
32
+ foo_name = "rate_per_#{period_name}".to_sym
33
+ # defining scope here, dynamically
34
+ define_method foo_name do |*args|
35
+
36
+
37
+ if args[0].present?
38
+ # i.e: #rate_per_month(:past_year)
39
+ past_scope = args[0] # past_year
40
+ raise ArgumentError, "Must be a scope with 'past_'" unless past_scope.to_s =~ /^past_/
41
+
42
+ time_scoped_records = self.send( past_scope )
43
+ past_time_span_name = past_scope.to_s.match(/past_(\w+)/)[1]
44
+ past_period_in_seconds = AggtiveRecord::Time.to_seconds(past_time_span_name)
45
+ else
46
+ time_scoped_records = scoped
47
+ past_period_in_seconds = self.timespan_to_now(time_scoped_records)
48
+ end
49
+
50
+ # puts "Past #{past_time_span_name} in seconds: #{past_period_in_seconds}"
51
+ time_scoped_records.send( :rate_per, period_name, past_period_in_seconds )
52
+ end
53
+ end
54
+ end
55
+
56
+
57
+ # included do
58
+
59
+ # # singular time periods
60
+ # # e.g. scope :past_year, ->{ past_time_periods(1, :year)}
61
+
62
+
63
+ # end
64
+
65
+ end
66
+ end
67
+ end
68
+ end
69
+
70
+ =begin
71
+
72
+ Record.rate_per :hour
73
+ .rate_per :day
74
+
75
+
76
+ =end
@@ -1,5 +1,5 @@
1
1
  require_relative 'collation/count_by'
2
- require_relative 'collation/rate'
2
+ require_relative 'collation/rate_per'
3
3
 
4
4
  module AggtiveRecord
5
5
  module EggScopes
@@ -21,8 +21,12 @@ module AggtiveRecord
21
21
  SECONDS_PER_DAY = 60 * 60 * 24
22
22
 
23
23
  # probably reinventing the wheel here...
24
- def self.to_seconds(sym)
25
- case sym.to_sym
24
+ def self.to_seconds(str)
25
+
26
+ num, period = str.to_s.match(/^(\d*)_?(\w+?)s?$/)[1..2]
27
+ num = num.to_i > 0 ? num.to_i : 1 # ugh
28
+
29
+ secs = case period.to_sym
26
30
  when :year
27
31
  SECONDS_PER_DAY * 365
28
32
  when :month
@@ -38,6 +42,8 @@ module AggtiveRecord
38
42
  when :second
39
43
  1
40
44
  end
45
+
46
+ num * secs
41
47
  end
42
48
 
43
49
 
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ describe AggtiveRecord do
5
+
6
+
7
+ context 'collation methods acting in concert' do
8
+ before(:each) do
9
+ Timecop.freeze(Time.parse '2013-10-02')
10
+ MusicRecord.create(published_at: 5.days.ago)
11
+ MusicRecord.create(published_at: 1.month.ago)
12
+ MusicRecord.create(published_at: 9.months.ago)
13
+ MusicRecord.create(published_at: 14.months.ago)
14
+ end
15
+
16
+
17
+ it '#past_14_days' do
18
+ expect(MusicRecord.past_14_days.count).to eq 1
19
+ end
20
+
21
+ it '#rate_per_week(:past_14_days)' do
22
+ expect(MusicRecord.rate_per_week(:past_14_days)).to eq 0.5
23
+ end
24
+
25
+ it '#past_year' do
26
+ expect(MusicRecord.past_year.count).to eq 3
27
+ end
28
+
29
+
30
+ it '#past_year.count_by_year' do
31
+ expect(MusicRecord.past_year.count_by_year).to eq( {Time.new(Time.now.year) => 3})
32
+ end
33
+
34
+
35
+ it '#past_year.count_by_week' do
36
+ expect(MusicRecord.past_year.count_by_week).to eq(
37
+ { Time.parse( "2012-12-30 00:00:00 -0500") =>1,
38
+ Time.parse( "2013-09-01 00:00:00 -0400") =>1,
39
+ Time.parse( "2013-09-22 00:00:00 -0400") =>1
40
+ }
41
+ )
42
+ end
43
+
44
+ end
45
+ end
@@ -3,47 +3,34 @@ require 'spec_helper'
3
3
  describe "AggtiveRecord::EggScopes -- .rate" do
4
4
 
5
5
 
6
- describe '#rate_for' do
6
+ describe '#rate_per' do
7
7
  context 'singular periods' do
8
8
  it 'should get about 1 a year' do
9
9
  @record = MusicRecord.create published_at: 12.months.ago
10
10
  expect(MusicRecord.scoped.rate_per(:year) ).to be_within(0.1).of 1
11
11
  end
12
- end
13
-
14
- context 'has two optional parameters' do
15
-
16
- before(:each) do
17
- MusicRecord.create(published_at: 1.day.ago )
18
- end
12
+
19
13
 
20
- let(:records){ MusicRecord.scoped }
21
-
22
- context 'first parameter is the :start_time' do
23
- it 'bounds range with :start_time and Time.now' do
24
- pending 'rethink'
25
- expect(records.rate_per(:day, 2.days.ago)).to be_within(0.1).of 0.5
14
+ context 'meta methods' do
15
+ it 'should have #rate_per_month' do
16
+ MusicRecord.create published_at: (1.month.ago - 1.second)
17
+ MusicRecord.create published_at: 12.days.ago
18
+ expect(MusicRecord.rate_per_month ).to be_within(0.01).of 2
26
19
  end
27
- end
28
20
 
29
- context 'second parameter is the end_time' do
30
- it 'bounds range with :start_time and :end_time' do
31
- pending 'rethink'
32
- expect(records.rate_per(:day, 2.days.ago)).to be_within(0.1).of 0.5
21
+ it 'should have #rate_per_hour' do
22
+ MusicRecord.create published_at: (59.minutes.ago)
23
+ MusicRecord.create published_at: 59.minutes.ago
24
+ expect(MusicRecord.rate_per_hour ).to be_within(0.1).of 2
33
25
  end
34
26
 
35
- it 'has no effect on :where' do
36
- pending('This is troublesome. What if a user calls:
37
- records.past_year.rate_per(:day, 10.days.ago, 3.days.ago)
38
- -- too many surprises here!
39
- ')
40
- end
41
27
  end
42
28
 
43
-
29
+
44
30
  it 'should raise an error when a non-time period is passed in'
45
- it 'should play nicely with other methods'
31
+
46
32
  end
33
+
47
34
  end
48
35
 
49
36
  describe '#timespan_of' do
@@ -64,6 +51,36 @@ describe "AggtiveRecord::EggScopes -- .rate" do
64
51
 
65
52
  it 'should get #latest record in a set without re-querying database'
66
53
  end
54
+ end
55
+
56
+
57
+ # This is not usable
58
+ #
59
+ # context 'has two optional parameters' do
60
+
61
+ # before(:each) do
62
+ # MusicRecord.create(published_at: 1.day.ago )
63
+ # end
64
+
65
+ # let(:records){ MusicRecord.scoped }
66
+
67
+ # context 'first parameter is the :start_time' do
68
+ # it 'bounds range with :start_time and Time.now' do
69
+ # pending 'rethink'
70
+ # expect(records.rate_per(:day, 2.days.ago)).to be_within(0.1).of 0.5
71
+ # end
72
+ # end
67
73
 
74
+ # context 'second parameter is the end_time' do
75
+ # it 'bounds range with :start_time and :end_time' do
76
+ # pending 'rethink'
77
+ # expect(records.rate_per(:day, 2.days.ago)).to be_within(0.1).of 0.5
78
+ # end
68
79
 
69
- end
80
+ # it 'has no effect on :where' do
81
+ # pending('This is troublesome. What if a user calls:
82
+ # records.past_year.rate_per(:day, 10.days.ago, 3.days.ago)
83
+ # -- too many surprises here!
84
+ # ')
85
+ # end
86
+ # end
data/spec/spec_helper.rb CHANGED
@@ -9,6 +9,8 @@ require 'database_cleaner'
9
9
  require 'aggtive_record'
10
10
  require 'pry'
11
11
 
12
+ require 'timecop'
13
+
12
14
  # Requires supporting files with custom matchers and macros, etc,
13
15
  # in ./support/ and its subdirectories.
14
16
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aggtive_record
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Nguyen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-09-23 00:00:00.000000000 Z
11
+ date: 2013-10-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: groupdate
@@ -136,6 +136,20 @@ dependencies:
136
136
  - - ~>
137
137
  - !ruby/object:Gem::Version
138
138
  version: 3.2.14
139
+ - !ruby/object:Gem::Dependency
140
+ name: timecop
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ! '>='
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ! '>='
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
139
153
  description: This is not even remotely finished or even started on. Please don't download.
140
154
  email: dansonguyen@gmail.com
141
155
  executables: []
@@ -162,12 +176,13 @@ files:
162
176
  - lib/aggtive_record/egg_scopes.rb
163
177
  - lib/aggtive_record/egg_scopes/collation.rb
164
178
  - lib/aggtive_record/egg_scopes/collation/count_by.rb
165
- - lib/aggtive_record/egg_scopes/collation/rate.rb
179
+ - lib/aggtive_record/egg_scopes/collation/rate_per.rb
166
180
  - lib/aggtive_record/egg_scopes/time_bucket.rb
167
181
  - lib/aggtive_record/egg_scopes/time_span.rb
168
182
  - lib/aggtive_record/memo.rb
169
183
  - lib/aggtive_record/time.rb
170
184
  - spec/functional/basic_object_run_spec.rb
185
+ - spec/functional/collation_spec.rb
171
186
  - spec/lib/aggable_spec.rb
172
187
  - spec/lib/count_by_spec.rb
173
188
  - spec/lib/rate_spec.rb
@@ -1,35 +0,0 @@
1
- module AggtiveRecord
2
- module EggScopes
3
- module Collation
4
- module Rate
5
- extend ActiveSupport::Concern
6
-
7
- # Public: a rate
8
- # expects that ActiveRelation has a grouping
9
- # self is a ActiveRecord scope
10
-
11
- module ClassMethods
12
-
13
- # Public
14
- #
15
- # Returns float indicating rate of records per given time period
16
- def rate_per(time_period)
17
- time_period_secs = AggtiveRecord::Time.to_seconds(time_period)
18
- records = self.scoped.to_a
19
-
20
- return records.size.to_f * time_period_secs / self.timespan_to_now(records)
21
- end
22
- end
23
-
24
- end
25
- end
26
- end
27
- end
28
-
29
- =begin
30
-
31
- Record.rate_per :hour
32
- .rate_per :day
33
-
34
-
35
- =end