hystorical 0.2.0 → 1.0.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 CHANGED
@@ -99,11 +99,17 @@ $ rails g hystorical:dates Subscription
99
99
  $ create db/migrate/20120917150948_add_start_date_end_date_to_subscriptions.rb
100
100
  ```
101
101
 
102
+ ## Filtering
103
+
104
+ You can filter a dataset by passing in a block. This works similarly to Enumerable's `select` method.
105
+
106
+ ```ruby
107
+ Hystorical.current subscriptions { |subscription| subscription.type == :gold }
108
+ ```
109
+
102
110
  ## Philosophy
103
111
  This gem was created using TDD and README-driven development. The architecture was designed with a strong focus on modularity and extensibility. Using ruby's `Enumerable` methods to return current object was chosen because of it's great flexibility to adapt to all ruby projects. However, when working with large datasets stored in a relational database, using SQL would yield greater performance. An adapter was added for ActiveRecord, but extending this to another ORM (such as DataMapper or Mongoid) is as simple as creating a new class that defines all the methods in the public api and adding a conditional in `Hystorical.delegate_class`.
104
112
 
105
- ## TODO
106
- * Add ability to pass in a block option that can further filter results
107
113
 
108
114
  ## Contributing
109
115
 
@@ -2,11 +2,13 @@ module Hystorical
2
2
  class ARRelation
3
3
  class << self
4
4
  def current(collection)
5
- collection.where(end_date: nil)
5
+ current_items = collection.where(end_date: nil)
6
+ block_given? ? current_items.select { |item| yield item } : current_items
6
7
  end
7
8
 
8
9
  def current_on(collection, date)
9
- collection.where("? BETWEEN start_date AND end_date", date)
10
+ current_items = collection.where("? BETWEEN start_date AND end_date", date)
11
+ block_given? ? current_items.select { |item| yield item } : current_items
10
12
  end
11
13
  end
12
14
  end
@@ -3,18 +3,24 @@ module Hystorical
3
3
  class << self
4
4
 
5
5
  def current(collection)
6
- collection.select { |obj| obj.respond_to?(:[]) ? obj[:end_date].nil? : obj.end_date.nil? }
6
+ collection.select do |obj|
7
+ current = get_attr(obj, :end_date).nil?
8
+ block_given? ? (yield obj) && current : current
9
+ end
7
10
  end
8
11
 
9
12
  def current_on(collection, date)
10
13
  collection.select do |obj|
11
- if obj.respond_to?(:[])
12
- obj[:start_date] <= date && obj[:end_date] >= date
13
- else
14
- obj.start_date <= date && obj.end_date >= date
15
- end
14
+ current = (get_attr(obj, :start_date) <= date) && (get_attr(obj, :end_date) >= date)
15
+ block_given? ? (yield obj) && current : current
16
16
  end
17
17
  end
18
+
19
+ private
20
+ def get_attr(obj, attribute)
21
+ obj.respond_to?(:[]) ? obj[attribute] : obj.send(attribute)
22
+ end
23
+
18
24
  end
19
25
  end
20
26
  end
@@ -1,3 +1,3 @@
1
1
  module Hystorical
2
- VERSION = "0.2.0"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -5,6 +5,7 @@ describe Hystorical::ARRelation do
5
5
  with_model :Subscription do
6
6
  table do |t|
7
7
  t.integer :user_id
8
+ t.string :service
8
9
  t.date :start_date
9
10
  t.date :end_date
10
11
  end
@@ -17,16 +18,25 @@ describe Hystorical::ARRelation do
17
18
  end
18
19
 
19
20
  describe "current" do
20
- let!(:obj1) { Subscription.create(user_id: 1, start_date: Date.new(2012, 9, 1), end_date: nil) }
21
- let!(:obj2) { Subscription.create(user_id: 2, start_date: Date.new(2012, 9, 6), end_date: Date.new(2012, 9, 10)) }
22
- let!(:obj3) { Subscription.create(user_id: 2, start_date: Date.new(2012, 9, 11), end_date: nil) }
21
+ let!(:obj1) { Subscription.create(user_id: 1, service: "gold", start_date: Date.new(2012, 9, 1), end_date: nil) }
22
+ let!(:obj2) { Subscription.create(user_id: 2, service: "silver", start_date: Date.new(2012, 9, 6), end_date: Date.new(2012, 9, 10)) }
23
+ let!(:obj3) { Subscription.create(user_id: 2, service: "gold", start_date: Date.new(2012, 9, 11), end_date: nil) }
23
24
 
24
25
  it "should return the current subscription" do
25
26
  Hystorical::ARRelation.current(Subscription.for_user(2)).should eq [obj3]
26
27
  end
28
+
29
+ context "block filter" do
30
+ let!(:obj4) { Subscription.create(user_id: 2, service: "silver", start_date: Date.new(2012, 9, 6), end_date: nil) }
31
+ it "should return the current filtered subscriptions" do
32
+ Hystorical::ARRelation.current Subscription.for_user(2) do |sub|
33
+ sub.service == "silver"
34
+ end.should eq [obj4]
35
+ end
36
+ end
27
37
  end
28
38
 
29
- describe "current" do
39
+ describe "current_on" do
30
40
  let!(:obj1) { Subscription.create(user_id: 1, start_date: Date.new(2012, 9, 1), end_date: nil) }
31
41
  let!(:obj2) { Subscription.create(user_id: 2, start_date: Date.new(2012, 9, 6), end_date: Date.new(2012, 9, 10)) }
32
42
  let!(:obj3) { Subscription.create(user_id: 2, start_date: Date.new(2012, 9, 11), end_date: nil) }
@@ -34,5 +44,14 @@ describe Hystorical::ARRelation do
34
44
  it "should return the current subscription as of Sept 8" do
35
45
  Hystorical::ARRelation.current_on(Subscription.for_user(2), Date.new(2012, 9, 8)).should eq [obj2]
36
46
  end
47
+
48
+ context "block filter" do
49
+ let!(:obj4) { Subscription.create(user_id: 2, service: "gold", start_date: Date.new(2012, 9, 6), end_date: Date.new(2012, 9, 10)) }
50
+ it "should return the current filtered subscriptions" do
51
+ Hystorical::ARRelation.current_on Subscription.for_user(2), Date.new(2012, 9, 8) do |sub|
52
+ sub.service == "gold"
53
+ end.should eq [obj4]
54
+ end
55
+ end
37
56
  end
38
57
  end
@@ -2,23 +2,24 @@ require 'spec_helper'
2
2
 
3
3
  describe Hystorical::RubyCollection do
4
4
  class HistoricalObjet
5
- attr_accessor :start_date, :end_date
5
+ attr_accessor :start_date, :end_date, :type
6
6
 
7
- def initialize(start_date, end_date)
7
+ def initialize(type, start_date, end_date)
8
+ @type = type
8
9
  @start_date = start_date
9
10
  @end_date = end_date
10
11
  end
11
12
  end
12
13
 
13
- let(:obj1) { {start_date: Date.new(2012, 8, 15), end_date: Date.new(2012, 8, 26)} }
14
- let(:obj2) { {start_date: Date.new(2012, 8, 27), end_date: Date.new(2012, 9, 4)} }
15
- let(:obj3) { {start_date: Date.new(2012, 9, 5), end_date: nil} }
14
+ let(:obj1) { {type: :gold, start_date: Date.new(2012, 8, 15), end_date: Date.new(2012, 8, 26)} }
15
+ let(:obj2) { {type: :silver, start_date: Date.new(2012, 8, 27), end_date: Date.new(2012, 9, 4)} }
16
+ let(:obj3) { {type: :gold, start_date: Date.new(2012, 9, 5), end_date: nil} }
16
17
  let(:collection) { [obj1, obj2, obj3] }
17
18
 
18
19
 
19
- let(:obj4) { HistoricalObjet.new(Date.new(2012, 8, 15), Date.new(2012, 8, 26)) }
20
- let(:obj5) { HistoricalObjet.new(Date.new(2012, 8, 27), Date.new(2012, 9, 4)) }
21
- let(:obj6) { HistoricalObjet.new(Date.new(2012, 9, 5), nil) }
20
+ let(:obj4) { HistoricalObjet.new(:gold, Date.new(2012, 8, 15), Date.new(2012, 8, 26)) }
21
+ let(:obj5) { HistoricalObjet.new(:silver, Date.new(2012, 8, 27), Date.new(2012, 9, 4)) }
22
+ let(:obj6) { HistoricalObjet.new(:gold, Date.new(2012, 9, 5), nil) }
22
23
  let(:collection2) { [obj4, obj5, obj6] }
23
24
 
24
25
  describe ".current" do
@@ -33,6 +34,15 @@ describe Hystorical::RubyCollection do
33
34
  Hystorical::RubyCollection.current(collection2).should eq [obj6]
34
35
  end
35
36
  end
37
+
38
+ context "filter block" do
39
+ let(:obj5) { HistoricalObjet.new(:silver, Date.new(2012, 8, 27), nil) }
40
+ it "should be filterable via a block" do
41
+ Hystorical::RubyCollection.current collection2 do |sub|
42
+ sub.type == :silver
43
+ end.should eq [obj5]
44
+ end
45
+ end
36
46
  end
37
47
 
38
48
  describe ".current_on" do
@@ -49,5 +59,14 @@ describe Hystorical::RubyCollection do
49
59
  Hystorical::RubyCollection.current_on(collection2, date).should eq [obj5]
50
60
  end
51
61
  end
62
+
63
+ context "filter block" do
64
+ let(:obj6) { HistoricalObjet.new(:gold, Date.new(2012, 9, 5), Date.new(2012, 9, 4)) }
65
+ it "should be filterable via a block" do
66
+ Hystorical::RubyCollection.current_on collection2, date do |sub|
67
+ sub.type == :silver
68
+ end.should eq [obj5]
69
+ end
70
+ end
52
71
  end
53
72
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hystorical
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 1.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-17 00:00:00.000000000 Z
12
+ date: 2012-09-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec