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.
- data/lib/chronicle.rb +81 -18
- data/lib/chronicle/version.rb +1 -1
- data/spec/chronicle_spec.rb +36 -1
- metadata +8 -2
data/lib/chronicle.rb
CHANGED
|
@@ -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
|
-
#
|
|
65
|
-
|
|
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
|
-
|
|
76
|
-
|
|
127
|
+
# .. or newest to oldest
|
|
128
|
+
eras = eras.reverse unless order == :desc
|
|
77
129
|
|
|
78
|
-
|
|
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
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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
|
data/lib/chronicle/version.rb
CHANGED
data/spec/chronicle_spec.rb
CHANGED
|
@@ -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
|
|
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.
|
|
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:
|
|
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
|