chronicle 0.0.5 → 0.0.6

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.
@@ -51,40 +51,103 @@ module Chronicle
51
51
  "3 minutes ago",
52
52
  "2 minutes ago",
53
53
  "1 minute ago",
54
- "just now"
54
+ "just now",
55
+ "1 minute from now",
56
+ "2 minutes from now",
57
+ "3 minutes from now",
58
+ "5 minutes from now",
59
+ "10 minutes from now",
60
+ "20 minutes from now",
61
+ "30 minutes from now",
62
+ "1 hour from now",
63
+ "2 hours from now",
64
+ "3 hours from now",
65
+ "4 hours from now",
66
+ "5 hours from now",
67
+ "6 hours from now",
68
+ "7 hours from now",
69
+ "8 hours from now",
70
+ "1 day from now",
71
+ "2 days from now",
72
+ "3 days from now",
73
+ "4 days from now",
74
+ "5 days from now",
75
+ "6 days from now",
76
+ "1 week from now",
77
+ "2 weeks from now",
78
+ "3 weeks from now",
79
+ "1 month from now",
80
+ "2 months from now",
81
+ "3 months from now",
82
+ "4 months from now",
83
+ "5 months from now",
84
+ "6 months from now",
85
+ "7 months from now",
86
+ "1 year from now",
87
+ "2 years from now",
88
+ "3 years from now",
89
+ "4 years from now",
90
+ "5 years from now",
91
+ "6 years from now",
92
+ "7 years from now",
55
93
  ]
56
94
  end
57
-
95
+
58
96
  class ChronicleHash < Hash
59
97
 
60
98
  def initialize(collection, options)
61
99
 
62
100
  eras = options[:eras]
63
-
64
- # Make sure 'just now' is included, so no objects fall through the cracks
65
- eras << "just now" unless eras.any? {|era| era =~ /now/i }
66
-
101
+
102
+ # Sort order, defaut is new to old
103
+ order = options[:order] || :desc
104
+
105
+ # Remove objects with nil timestamps
106
+ collection = collection.reject {|obj| obj.send(options[:date_attr]).nil? }
107
+
108
+ # Sort collection by date
109
+ collection = collection.sort_by {|obj| obj.send(options[:date_attr])}
110
+ collection = collection.reverse if order == :desc
111
+
67
112
  # Ensure all eras can be parsed
68
113
  eras.each do |era|
69
114
  raise "Could not parse era: #{era}" if Chronic.parse(era).nil?
70
115
  end
116
+
117
+ if order == :desc && Time.now > collection.first.send(options[:date_attr])
118
+ eras << "just now"
119
+ end
71
120
 
121
+ # Parse date strings
122
+ # { "7 years ago"=>2006-01-02 23:29:05 -0800, ... }
123
+ era_date_pairs = eras.inject({}) {|h,e| h[e] = Chronic.parse(e); h }
124
+
72
125
  # Sort eras oldest to newest
73
126
  eras = eras.sort_by {|era| Chronic.parse(era) }
74
-
75
- era_to_date = eras.inject({}) {|h,e| h[e] = Chronic.parse(e); h }
76
-
127
+ # .. or newest to oldest
128
+ eras = eras.reverse unless order == :desc
77
129
 
78
- # Initialize all hash keys chronologically (newest to oldest)
79
- eras.reverse.each {|era| self[era] = [] }
80
-
81
- # Remove objects with nil timestamps
82
- collection = collection.reject {|obj| obj.send(options[:date_attr]).nil? }
130
+ if order == :desc
83
131
 
84
- # Find the oldest era in which each object was created
85
- collection.sort_by {|obj| obj.send(options[:date_attr])}.reverse.each do |obj|
86
- era = eras.find {|era| obj.send(options[:date_attr]) < era_to_date[era] }
87
- self[era] << obj
132
+ # Initialize all hash keys chronologically (newest to oldest)
133
+ eras.reverse.each {|era| self[era] = [] }
134
+
135
+ # Find the oldest era in which each object was created
136
+ collection.each do |obj|
137
+ # puts ("\n #{obj.send(options[:date_attr])} < #{era_date_pairs[era]}")
138
+ era = eras.find {|era| obj.send(options[:date_attr]) < era_date_pairs[era] }
139
+ self[era] << obj
140
+ end
141
+ else
142
+
143
+ # Initialize all hash keys chronologically (oldest to newest)
144
+ eras.reverse.each {|era| self[era] = [] }
145
+
146
+ # Find the newest era in which each object was created
147
+ collection.each do |obj|
148
+ era = eras.find {|era| obj.send(options[:date_attr]) > era_date_pairs[era] }
149
+ self[era] << obj
150
+ end
88
151
  end
89
152
 
90
153
  # Remove keys for empty eras
@@ -1,3 +1,3 @@
1
1
  module Chronicle
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  end
@@ -56,7 +56,7 @@ describe Chronicle do
56
56
  @chronicle.keys.should == ['just now', '3 minutes ago', '35 days ago']
57
57
  end
58
58
 
59
- it "raises an exception for eras that cannot be parse" do
59
+ it "raises an exception for eras that cannot be parsed" do
60
60
  expect { Chronicle.new(@things, :eras => ['63 eons hence']) }.to raise_error("Could not parse era: 63 eons hence")
61
61
  end
62
62
 
@@ -93,5 +93,40 @@ describe Chronicle do
93
93
  end
94
94
 
95
95
  end
96
+
97
+ context "future dates" do
98
+
99
+ before(:each) do
100
+ @things = [
101
+ double("thing", :created_at => Time.now + 39*@day),
102
+ double("thing", :created_at => Time.now + 8*@day),
103
+ double("thing", :created_at => Time.now + 9*@day),
104
+ double("thing", :created_at => Time.now + 3*@day),
105
+ double("thing", :created_at => Time.now + 9*@minute),
106
+ ]
107
+ @chronicle = Chronicle.new(@things, order: :asc)
108
+ end
109
+
110
+ it "doesn't have any empty eras" do
111
+ @chronicle.values.all? {|v| !v.empty? }.should == true
112
+ end
113
+
114
+ it "sorts era keys from oldest to newest" do
115
+ @chronicle.keys.first.should == '5 minutes from now'
116
+ @chronicle.keys.last.should == '1 month from now'
117
+ end
118
+
119
+ it "sorts objects in eras from oldest to newest" do
120
+ era = @chronicle['1 week from now']
121
+ era.size.should == 2
122
+ era.last.created_at.should be > era.first.created_at
123
+ end
124
+
125
+ it "doesn't lose any items during processing" do
126
+ @chronicle.values.flatten.size.should == @things.size
127
+ end
128
+
129
+ end
130
+
96
131
 
97
132
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chronicle
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
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-12-10 00:00:00.000000000 Z
12
+ date: 2013-01-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: hoe
@@ -104,12 +104,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
104
104
  - - ! '>='
105
105
  - !ruby/object:Gem::Version
106
106
  version: '0'
107
+ segments:
108
+ - 0
109
+ hash: -4597408090393416326
107
110
  required_rubygems_version: !ruby/object:Gem::Requirement
108
111
  none: false
109
112
  requirements:
110
113
  - - ! '>='
111
114
  - !ruby/object:Gem::Version
112
115
  version: '0'
116
+ segments:
117
+ - 0
118
+ hash: -4597408090393416326
113
119
  requirements: []
114
120
  rubyforge_project: chronicle
115
121
  rubygems_version: 1.8.24