ghaki-stats 2011.11.29.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2010 Gerald Kalafut
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,23 @@
1
+ = Ghaki Stats - Simple statistics.
2
+
3
+ Ghaki Stats is simple tracker for counted statistics.
4
+
5
+ == Download
6
+
7
+ The latest version of Ghaki Stats can be found at
8
+
9
+ * git@github.com:ghaki/ghaki-stats.git
10
+
11
+ == Installation
12
+
13
+ The preferred method of installing Ghaki Stats is through its GEM file.
14
+
15
+ % [sudo] gem install ghaki-stats-1.0.0.gem
16
+
17
+ == License
18
+
19
+ Ghaki Stats is released under the MIT license.
20
+
21
+ == Support
22
+
23
+ Contact mailto:gerald@kalafut.org
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 2011.11.29.1
@@ -0,0 +1,14 @@
1
+ require 'ghaki/app/plugin'
2
+ require 'ghaki/stats/base'
3
+
4
+ module Ghaki #:nodoc:
5
+ module Stats #:nodoc:
6
+
7
+ # Application wide statistics tracker.
8
+
9
+ class App < Ghaki::App::Plugin
10
+ app_plugin_make Base, :stats
11
+ app_plugin_link :stats
12
+ end
13
+
14
+ end end
@@ -0,0 +1,216 @@
1
+ require 'ghaki/stats/errors'
2
+ require 'ghaki/stats/format/logger'
3
+
4
+ ############################################################################
5
+ module Ghaki #:nodoc
6
+ module Stats #:nodoc
7
+
8
+ class Base
9
+
10
+ attr_accessor :title # Title of statistics output report.
11
+ attr_writer :format # Statistics output report Formatting object.
12
+
13
+ =begin
14
+ [+format+] Statistics report formatting object.
15
+ [+title+] Title of statistics output report.
16
+ =end
17
+
18
+ def initialize opts={}
19
+ clear
20
+ @format = opts[:format]
21
+ @title = opts[:title] || ''
22
+ end
23
+
24
+ # Get the formatter for the statistical report.
25
+ #
26
+ # Note: Will generate default formatting object if not already set.
27
+
28
+ def format
29
+ @format ||= self._format_default
30
+ end
31
+
32
+
33
+ # Assign zeroe to a stats count if its not already set.
34
+
35
+ def def_zero major, minor
36
+ def_value major, minor, 0
37
+ end
38
+
39
+ # Assign zeroes to multiple stats counts if they're not already set.
40
+
41
+ def def_zeros major_to_minor
42
+ major_to_minor.each_pair do |major,minor_s|
43
+ [*minor_s].each do |minor|
44
+ def_zero major, minor
45
+ end
46
+ end
47
+ end
48
+
49
+ # Assign multiple stats counts if not already set.
50
+
51
+ def def_values major, value, *minors
52
+ minors.each { |minor| def_value major, minor, value }
53
+ end
54
+
55
+ # Assign default stats count value if not already set.
56
+
57
+ def def_value major, minor, value
58
+ @stats[major] ||= {}
59
+ @stats[major][minor] = value unless @stats[major].has_key?(minor)
60
+ end
61
+
62
+ # Increase stats count by 1.
63
+
64
+ def incr major, minor
65
+ incr_by major, minor, 1
66
+ end
67
+
68
+ # Decrease stats count by 1.
69
+
70
+ def decr major, minor
71
+ decr_by major, minor, 1
72
+ end
73
+
74
+ # Increase stats count by a given value.
75
+
76
+ def incr_by major, minor, value
77
+ def_zero major, minor
78
+ @stats[major][minor] += value
79
+ end
80
+
81
+ # Decrease stats count by a given value
82
+
83
+ def decr_by major, minor, value
84
+ def_zero major, minor
85
+ @stats[major][minor] -= value
86
+ end
87
+
88
+ # Set stats count to a given value.
89
+
90
+ def put major, minor, value
91
+ @stats[major] ||= {}
92
+ @stats[major][minor] = value
93
+ end
94
+
95
+ # Is stat present?
96
+
97
+ def has? major, minor=nil
98
+ if @stats.has_key?(major)
99
+ if minor.nil?
100
+ true
101
+ else
102
+ @stats[major].has_key?(minor)
103
+ end
104
+ else
105
+ false
106
+ end
107
+ end
108
+
109
+ # Is stat missing?
110
+
111
+ def lacks? major, minor=nil
112
+ ! has?(major,minor)
113
+ end
114
+
115
+ # Throw exception if stat is mising.
116
+
117
+ def has! major, minor=nil
118
+ return self if has? major, minor
119
+ if minor.nil?
120
+ raise MissingMajorStatsError.new(major)
121
+ else
122
+ raise MissingMinorStatsError.new(major, minor)
123
+ end
124
+ end
125
+
126
+ # Get current value of stats count. Defaults to zero when not present.
127
+
128
+ def get major, minor
129
+ return 0 unless @stats.has_key?(major)
130
+ return 0 unless @stats[major].has_key?(minor)
131
+ return @stats[major][minor]
132
+ end
133
+
134
+ # Get current value or throw exception.
135
+
136
+ def get! major, minor
137
+ has!(major,minor).get(major,minor)
138
+ end
139
+
140
+ # Get current value of stats count. Defaults to specified when not present.
141
+
142
+ def get? major, minor, defval=nil
143
+ if has? major, minor
144
+ get major, minor
145
+ else
146
+ defval
147
+ end
148
+ end
149
+
150
+ # Set stats value if given value is greater than current value.
151
+
152
+ def set_gt major, minor, value
153
+ if not @stats.has_key?(major)
154
+ @stats[major] = { minor => value }
155
+ elsif not @stats[major].has_key?(minor)
156
+ @stats[major][minor] = value
157
+ elsif @stats[major][minor] < value
158
+ @stats[major][minor] = value
159
+ end
160
+ end
161
+
162
+ # Set stats value if given value is less than current value.
163
+
164
+ def set_lt major, minor, value
165
+ if not @stats.has_key?(major)
166
+ @stats[major] = { minor => value }
167
+ elsif not @stats[major].has_key?(minor)
168
+ @stats[major][minor] = value
169
+ elsif @stats[major][minor] > value
170
+ @stats[major][minor] = value
171
+ end
172
+ end
173
+
174
+ # Clears statistic counts.
175
+
176
+ def clear
177
+ @stats = {}
178
+ end
179
+
180
+ # Writes statistics report to specified output file.
181
+
182
+ def dump out_file, title=@title
183
+ format.dump @stats, out_file, title
184
+ end
185
+
186
+ # Logger specific dump. (DEPRECATED)
187
+
188
+ def log_dump logger, title=@title
189
+ warn "[DEPRECATED] 'log_dump' is deprecated. Please use 'dump' instead."
190
+ dump logger, title
191
+ end
192
+
193
+ # Writes statistics report to specified output file, and clears statistic counts.
194
+ def flush out_file, title=@title
195
+ dump out_file, title
196
+ ensure
197
+ clear
198
+ end
199
+
200
+ # Logger specific flush. (DEPRECATED)
201
+
202
+ def log_flush logger, title=@title
203
+ warn "[DEPRECATED] 'log_flush' is deprecated. Please use 'flush' instead."
204
+ flush logger, title
205
+ end
206
+
207
+ protected
208
+
209
+ def _format_default #:nodoc
210
+ opts = {}
211
+ opts[:title] = @title unless @title.nil?
212
+ Ghaki::Stats::Format::Logger.new( opts )
213
+ end
214
+
215
+ end
216
+ end end
@@ -0,0 +1,27 @@
1
+ require 'ghaki/stats/errors'
2
+
3
+ module Ghaki #:nodoc:
4
+
5
+ class MissingMajorStatsError < RuntimeError
6
+ attr_accessor :major
7
+ def blurb
8
+ " Major (#{@major})"
9
+ end
10
+ def initialize maj, msg='Missing Statistic'
11
+ @major = maj
12
+ super( msg + ':' + blurb() )
13
+ end
14
+ end
15
+
16
+ class MissingMinorStatsError < MissingMajorStatsError
17
+ attr_accessor :minor
18
+ def blurb
19
+ super() + " Minor (#{@minor})"
20
+ end
21
+ def initialize maj, min, msg='Missing Statistic'
22
+ @minor = min
23
+ super( maj, msg )
24
+ end
25
+ end
26
+
27
+ end
@@ -0,0 +1,39 @@
1
+ ############################################################################
2
+ module Ghaki #:nodoc:
3
+ module Stats #:nodoc:
4
+ module Format #:nodoc:
5
+
6
+ # Base for Statistics Report formatting objects.
7
+
8
+ class Base
9
+
10
+ attr_accessor :title # Name of statistics report.
11
+
12
+ def initialize opts={}
13
+ @title = opts[:title] || ''
14
+ end
15
+
16
+ # Dump output from statistics object.
17
+
18
+ def dump stats, out, title=@title
19
+ dump_head stats, out, title
20
+ dump_body stats, out, title
21
+ dump_tail stats, out, title
22
+ end
23
+
24
+ # Generate header of report.
25
+
26
+ def dump_head stats, out, title
27
+ end
28
+
29
+ # Generate body of report.
30
+ def dump_body stats, out, title
31
+ end
32
+
33
+ # Generate footer of report.
34
+
35
+ def dump_tail stats, out, title
36
+ end
37
+
38
+ end
39
+ end end end
@@ -0,0 +1,33 @@
1
+ require 'ghaki/stats/format/output'
2
+
3
+ ############################################################################
4
+ module Ghaki #:nodoc:
5
+ module Stats #:nodoc:
6
+ module Format #:nodoc:
7
+
8
+ # Default formatting for generating Statistics Reports using a Logger object.
9
+
10
+ class Logger < Output
11
+
12
+ # Dump heading info, which in this case is a minor began log.
13
+
14
+ def dump_head stats, log, title
15
+ if title.empty?
16
+ log.minor.began 'dumping statistics'
17
+ else
18
+ log.box title
19
+ end
20
+ end
21
+
22
+ # Dump footer info, which in this case is a minor ended log.
23
+
24
+ def dump_tail stats, log, title
25
+ if title.empty?
26
+ log.minor.ended 'dumping statistics'
27
+ else
28
+ log.liner
29
+ end
30
+ end
31
+
32
+ end # class
33
+ end end end
@@ -0,0 +1,12 @@
1
+ require 'ghaki/stats/format/base'
2
+
3
+ module Ghaki #:nodoc:
4
+ module Stats #:nodoc:
5
+ module Format #:nodoc:
6
+
7
+ # Write formatting to nowhere. Null sink.
8
+
9
+ class Null < Base
10
+ end
11
+
12
+ end end end
@@ -0,0 +1,24 @@
1
+ require 'ghaki/stats/format/base'
2
+
3
+ module Ghaki #:nodoc:
4
+ module Stats #:nodoc:
5
+ module Format #:nodoc:
6
+
7
+ # Default formatting for generating Statistics Reports using an output file object.
8
+
9
+ class Output < Base
10
+
11
+ # Dumps body of stats.
12
+
13
+ def dump_body stats, log, title
14
+ stats.keys.sort.each do |major|
15
+ log.puts major + ':'
16
+ stats[major].keys.sort.each do |minor|
17
+ count = stats[major][minor]
18
+ log.puts ' ' + count.to_s.rjust(8) + ' : ' + minor
19
+ end
20
+ end
21
+ end
22
+
23
+ end # class
24
+ end end end
@@ -0,0 +1,27 @@
1
+ require 'ghaki/app/mixable'
2
+ require 'ghaki/stats/base'
3
+
4
+ module Ghaki #:nodoc
5
+ module Stats #:nodoc
6
+
7
+ # Mixin stats object with auto-first use object creation.
8
+ #
9
+ # Note: Creates new Base stats object, does not grab copy from App Engine.
10
+ # ==== Example
11
+ #
12
+ # class MyAction
13
+ # include Ghaki::Stats::Mixin
14
+ # def do_something
15
+ # stats.incr 'Did', 'Something'
16
+ # end
17
+ # end
18
+ #
19
+ # myact = MyAction.new
20
+ # myact.do_something
21
+
22
+ module Mixin
23
+ include Ghaki::App::Mixable
24
+ app_mixin_accessor Base, :stats
25
+ end
26
+
27
+ end end
@@ -0,0 +1,26 @@
1
+ require 'ghaki/stats/base'
2
+ require 'ghaki/stats/format/null'
3
+
4
+ module Ghaki #:nodoc:
5
+ module Stats #:nodoc:
6
+
7
+ # Helper for mocking Ghaki::Stats objects in unit tests.
8
+ module SpecHelper
9
+
10
+ DEF_CLASS=Ghaki::Stats::Base
11
+
12
+ # Creates Ghaki::Stats object:
13
+ # - Using null sink formatting to avoid file access.
14
+ def make_safe_stats klass=DEF_CLASS
15
+ obj = klass.new
16
+ obj.format = Ghaki::Stats::Format::Null.new
17
+ obj
18
+ end
19
+
20
+ # Creates @stats member using :make_safe_stats
21
+ def setup_safe_stats klass=DEF_CLASS
22
+ @stats = make_safe_stats(klass)
23
+ end
24
+
25
+ end
26
+ end end
@@ -0,0 +1,36 @@
1
+ require 'ghaki/stats/app'
2
+
3
+ describe Ghaki::App::Engine do
4
+
5
+ before(:all) do
6
+ @app_eng = Ghaki::App::Engine.instance
7
+ @sta_app = Ghaki::Stats::App.instance
8
+ end
9
+
10
+ context 'singleton' do
11
+ subject { @app_eng }
12
+ it { should respond_to :stats }
13
+ it { should respond_to :stats= }
14
+ it { should respond_to :stats_opts }
15
+ it { should respond_to :stats_opts= }
16
+ it { should respond_to :stats_defs }
17
+ it { should respond_to :stats_defs= }
18
+ end
19
+
20
+ describe '#stats' do
21
+ subject { @app_eng.stats }
22
+ specify { should be_an_instance_of(Ghaki::Stats::Base) }
23
+ specify { should equal(@sta_app.stats ) }
24
+ end
25
+
26
+ describe '#stats_opts' do
27
+ subject { @app_eng.stats_opts }
28
+ specify { should be_an_instance_of(::Hash) }
29
+ end
30
+
31
+ describe '#stats_defs' do
32
+ subject { @app_eng.stats_defs }
33
+ specify { should be_an_instance_of(::Hash) }
34
+ end
35
+
36
+ end
@@ -0,0 +1,45 @@
1
+ ############################################################################
2
+ require 'ghaki/stats/app'
3
+
4
+ ############################################################################
5
+ module Ghaki module Stats module AppTesting
6
+ describe Ghaki::Stats::App do
7
+
8
+ ########################################################################
9
+ context 'singleton' do
10
+ subject { Ghaki::Stats::App.instance }
11
+ it { should respond_to :stats }
12
+ it { should respond_to :stats= }
13
+ it { should respond_to :stats_opts }
14
+ it { should respond_to :stats_opts= }
15
+ end
16
+
17
+ ########################################################################
18
+ context 'singleton methods' do
19
+
20
+ describe '#stats' do
21
+ subject { Ghaki::Stats::App.instance.stats }
22
+ specify { should be_an_instance_of(Ghaki::Stats::Base) }
23
+ end
24
+
25
+ describe '#stats_opts' do
26
+ subject { Ghaki::Stats::App.instance.stats_opts }
27
+ specify { should be_an_instance_of(::Hash) }
28
+ end
29
+
30
+ context 'default settings' do
31
+ describe '#title' do
32
+ subject { Ghaki::Stats::App.instance.stats.title }
33
+ specify { should be_empty }
34
+ end
35
+ describe '#format' do
36
+ subject { Ghaki::Stats::App.instance.stats.format }
37
+ specify { should be_an_instance_of(Ghaki::Stats::Format::Logger) }
38
+ end
39
+ end
40
+
41
+ end
42
+
43
+ end
44
+ end end end
45
+ ############################################################################
@@ -0,0 +1,302 @@
1
+ require 'ghaki/stats/errors'
2
+ require 'ghaki/stats/base'
3
+ require 'ghaki/stats/spec_helper'
4
+
5
+ module Ghaki module Stats module Base_Testing
6
+ describe Ghaki::Stats::Base do
7
+ include Ghaki::Stats::SpecHelper
8
+
9
+ before(:each) do
10
+ setup_safe_stats
11
+ end
12
+
13
+ subject { @stats }
14
+
15
+ it { should respond_to :title }
16
+ it { should respond_to :title= }
17
+ it { should respond_to :format= }
18
+
19
+ describe '#put' do
20
+ it 'stores value' do
21
+ subject.put 'inputs', 'wrote', 3
22
+ subject.get('inputs','wrote').should == 3
23
+ end
24
+ end
25
+
26
+ describe '#has?' do
27
+ context 'using major only' do
28
+ it 'detects missing' do
29
+ subject.put 'a', 'b', 3
30
+ subject.has?('c').should be_false
31
+ end
32
+ it 'detects present' do
33
+ subject.put 'a', 'b', 3
34
+ subject.has?('a').should be_true
35
+ end
36
+ end
37
+ context 'using major and minor' do
38
+ it 'detects missing' do
39
+ subject.put 'a', 'b', 3
40
+ subject.has?('a','c').should be_false
41
+ end
42
+ it 'detects present' do
43
+ subject.put 'a', 'b', 3
44
+ subject.has?('a','b').should be_true
45
+ end
46
+ end
47
+ end
48
+
49
+ describe '#lacks?' do
50
+ context 'using major only' do
51
+ it 'detects missing' do
52
+ subject.put 'a', 'b', 3
53
+ subject.lacks?('c').should be_true
54
+ end
55
+ it 'detects present' do
56
+ subject.put 'a', 'b', 3
57
+ subject.lacks?('a').should be_false
58
+ end
59
+ end
60
+ context 'using major and minor' do
61
+ it 'detects missing' do
62
+ subject.put 'a', 'b', 3
63
+ subject.lacks?('a','c').should be_true
64
+ end
65
+ it 'detects present' do
66
+ subject.put 'a', 'b', 3
67
+ subject.lacks?('a','b').should be_false
68
+ end
69
+ end
70
+ end
71
+
72
+ describe '#has!' do
73
+ context 'using major only' do
74
+ it 'fails on missing' do
75
+ subject.put 'a', 'b', 3
76
+ lambda do
77
+ subject.has!('c')
78
+ end.should raise_error(MissingMajorStatsError)
79
+ end
80
+ it 'detects present' do
81
+ subject.put 'a', 'b', 3
82
+ subject.has!('a').should == subject
83
+ end
84
+ end
85
+ context 'using major and minor' do
86
+ it 'fails on missing' do
87
+ subject.put 'a', 'b', 3
88
+ lambda do
89
+ subject.has!('a','c')
90
+ end.should raise_error(MissingMinorStatsError)
91
+ end
92
+ it 'detects present' do
93
+ subject.put 'a', 'b', 3
94
+ subject.has!('a','b').should == subject
95
+ end
96
+ end
97
+ end
98
+
99
+ describe '#get' do
100
+ it 'retrieves value when set' do
101
+ subject.put 'inputs','present',23
102
+ subject.get('inputs','present').should == 23
103
+ end
104
+ it "defaults to zero when not set" do
105
+ subject.get('inputs','bogus').should == 0
106
+ end
107
+ end
108
+
109
+ describe '#get?' do
110
+ context 'when stat is present' do
111
+ it 'gets value' do
112
+ subject.put 'inputs','present',23
113
+ subject.get?('inputs','present').should == 23
114
+ end
115
+ end
116
+ context 'when stat is missing' do
117
+ it 'returns nil without specified default' do
118
+ subject.get?('inputs','bogus').should be_nil
119
+ end
120
+ it 'returns specified default' do
121
+ subject.get?('inputs','bogus',54).should == 54
122
+ end
123
+ end
124
+ end
125
+
126
+ describe '#get!' do
127
+ it 'fails on missing' do
128
+ subject.put 'a', 'b', 3
129
+ lambda do
130
+ subject.get!('c','b')
131
+ end.should raise_error(MissingMinorStatsError)
132
+ end
133
+ it 'detects present' do
134
+ subject.put 'a', 'b', 3
135
+ subject.has!('a','b').should == subject
136
+ end
137
+ end
138
+
139
+ describe '#clear' do
140
+ it 'removes all values' do
141
+ subject.put 'inputs', 'broke', 3
142
+ subject.clear
143
+ subject.has?('inputs','broke').should be_false
144
+ end
145
+ end
146
+
147
+ describe '#def_value' do
148
+ it 'stores given value when not present' do
149
+ subject.def_value 'inputs', 'shadoobie', 23
150
+ subject.get('inputs','shadoobie').should == 23
151
+ end
152
+ it "leaves stored value alone" do
153
+ subject.put 'inputs', 'shapoopie', 67
154
+ subject.def_value 'inputs', 'shapoopie', 23
155
+ subject.get('inputs','shapoopie').should == 67
156
+ end
157
+ end
158
+
159
+ describe '#def_values' do
160
+ it 'stores given value when not present' do
161
+ subject.def_values 'output', 100, 'zip', 'zap'
162
+ subject.get('output','zip').should == 100
163
+ subject.get('output','zap').should == 100
164
+ end
165
+ end
166
+
167
+ describe '#def_zero' do
168
+ it "stores zero when not present" do
169
+ subject.def_zero 'inputs', 'newbie'
170
+ subject.get('inputs','newbie').should == 0
171
+ end
172
+ it "leaves stored value alone" do
173
+ subject.put('inputs','boogie',23)
174
+ subject.def_zero 'inputs', 'boogie'
175
+ subject.get('inputs','boogie').should == 23
176
+ end
177
+ end
178
+
179
+ describe '#def_zeros' do
180
+ it "stores zeros when not present" do
181
+ subject.def_zeros({ 'animal' => 'cow', 'animal' => 'bear' })
182
+ subject.get('animal','bear').should == 0
183
+ subject.get('animal','cow').should == 0
184
+ end
185
+ end
186
+
187
+ describe '#decr' do
188
+ it "decrements stored value" do
189
+ subject.put 'inputs', 'lost', 100
190
+ subject.decr 'inputs', 'lost'
191
+ subject.get('inputs','lost').should == 99
192
+ end
193
+ end
194
+
195
+ describe '#incr' do
196
+ it "increments stored value" do
197
+ subject.put 'inputs', 'found', 100
198
+ subject.incr 'inputs', 'found'
199
+ subject.get('inputs','found').should == 101
200
+ end
201
+ end
202
+
203
+ describe '#decr_by' do
204
+ it 'decrements stored value by a given value' do
205
+ subject.put 'inputs', 'mu', 100
206
+ subject.decr_by 'inputs', 'mu', 3
207
+ subject.get('inputs','mu').should == 97
208
+ end
209
+ end
210
+
211
+ describe '#incr_by' do
212
+ it 'increments stored value by a given value' do
213
+ subject.put 'inputs', 'pu', 100
214
+ subject.incr_by 'inputs', 'pu', 3
215
+ subject.get('inputs','pu').should == 103
216
+ end
217
+ end
218
+
219
+ describe '#set_lt' do
220
+ it 'should set when less' do
221
+ subject.put 'particle', 'proton', 100
222
+ subject.set_lt 'particle', 'proton', 90
223
+ subject.get('particle','proton').should == 90
224
+ end
225
+ it 'should ignore when not less' do
226
+ subject.put 'particle', 'proton', 100
227
+ subject.set_lt 'particle', 'proton', 110
228
+ subject.get('particle','proton').should == 100
229
+ end
230
+ end
231
+
232
+ describe '#set_gt' do
233
+ it 'should set when greater' do
234
+ subject.put 'particle', 'proton', 100
235
+ subject.set_gt 'particle', 'proton', 110
236
+ subject.get('particle','proton').should == 110
237
+ end
238
+ it 'should ignore when not greater' do
239
+ subject.put 'particle', 'proton', 100
240
+ subject.set_gt 'particle', 'proton', 90
241
+ subject.get('particle','proton').should == 100
242
+ end
243
+ end
244
+
245
+ def setup_fake_values
246
+ @stats.put 'a', 'b', 3
247
+ @stats.put 'c', 'd', 5
248
+ @expected_hash = { 'a' => { 'b' => 3 }, 'c' => { 'd' => 5 } }
249
+ end
250
+ def setup_fake_output
251
+ @out = stub_everything()
252
+ end
253
+
254
+ describe '#dump' do
255
+ before(:each) do setup_fake_values; setup_fake_output end
256
+ it 'outputs to formatter' do
257
+ subject.format.expects(:dump).with(@expected_hash,@out,'msg').once
258
+ subject.dump @out, 'msg'
259
+ end
260
+ end
261
+
262
+ describe '#flush' do
263
+ before(:each) do setup_fake_values; setup_fake_output end
264
+ it 'dumps to formatter' do
265
+ subject.expects(:dump).with(@out,'msg').once
266
+ subject.flush @out, 'msg'
267
+ end
268
+ it 'clears all values' do
269
+ subject.flush @out, 'msg'
270
+ subject.has?('a','b').should be_false
271
+ subject.has?('c','d').should be_false
272
+ end
273
+ end
274
+
275
+ describe '#log_dump' do
276
+ before(:each) do setup_fake_output end
277
+ it 'warns of deprecation' do
278
+ subject.expects(:warn).with(regexp_matches(%r{\[DEPRECATED\]})).once
279
+ subject.log_flush @out, 'msg'
280
+ end
281
+ it 'calls #dump' do
282
+ subject.expects(:warn).once
283
+ subject.expects(:dump).with(@out,'msg').once
284
+ subject.log_dump @out, 'msg'
285
+ end
286
+ end
287
+
288
+ describe '#log_flush' do
289
+ before(:each) do setup_fake_output end
290
+ it 'warns of deprecation' do
291
+ subject.expects(:warn).with(regexp_matches(%r{\[DEPRECATED\]})).once
292
+ subject.log_flush @out, 'msg'
293
+ end
294
+ it 'calls #flush' do
295
+ subject.expects(:warn).once
296
+ subject.expects(:flush).with(@out,'msg').once
297
+ subject.log_flush @out, 'msg'
298
+ end
299
+ end
300
+
301
+ end
302
+ end end end
@@ -0,0 +1,44 @@
1
+ require 'ghaki/stats/format/base'
2
+
3
+ module Ghaki module Stats module Format module Base_Testing
4
+ describe Ghaki::Stats::Format::Base do
5
+
6
+ before(:all) do
7
+ @subj = Format::Base.new
8
+ @stats = {}
9
+ @out = 'file'
10
+ @title = 'msg'
11
+ end
12
+
13
+ subject { @subj }
14
+
15
+ describe '#initialize' do
16
+ it 'accepts option :title' do
17
+ Format::Base.new( :title => 'msg' ).title.should == 'msg'
18
+ end
19
+ it 'defaults option: title' do
20
+ Format::Base.new().title.should == ''
21
+ end
22
+ end
23
+
24
+ it { should respond_to :dump_head }
25
+ it { should respond_to :dump_body }
26
+ it { should respond_to :dump_tail }
27
+
28
+ describe '#dump' do
29
+ it 'dump header' do
30
+ subject.expects(:dump_head).with(@stats,@out,@title).once
31
+ subject.dump @stats, @out, @title
32
+ end
33
+ it 'dump stats body' do
34
+ subject.expects(:dump_body).with(@stats,@out,@title).once
35
+ subject.dump @stats, @out, @title
36
+ end
37
+ it 'dump footer' do
38
+ subject.expects(:dump_tail).with(@stats,@out,@title).once
39
+ subject.dump @stats, @out, @title
40
+ end
41
+ end
42
+
43
+ end
44
+ end end end end
@@ -0,0 +1,54 @@
1
+ require 'ghaki/stats/format/logger'
2
+ require 'ghaki/logger/spec_helper'
3
+
4
+ module Ghaki module Stats module Format module Logger_Testing
5
+ describe Format::Logger do
6
+ include Ghaki::Logger::SpecHelper
7
+
8
+ before(:each) do
9
+ setup_safe_logger
10
+ @subj = Format::Logger.new
11
+ @stats = {
12
+ 'a' => { 'b' => 12 },
13
+ 'c' => { 'd' => 34 },
14
+ }
15
+ @out = 'file'
16
+ @title = 'msg'
17
+ end
18
+
19
+ subject { @subj }
20
+
21
+ it { should be_kind_of(Format::Output) }
22
+
23
+ describe '#dump_head' do
24
+ context 'with no title' do
25
+ it 'logs start of dump' do
26
+ @logger.minor.expects(:began).with('dumping statistics').once
27
+ subject.dump_head @stats, @logger, ''
28
+ end
29
+ end
30
+ context 'with given title' do
31
+ it 'logs header title' do
32
+ @logger.expects(:box).with(@title).once
33
+ subject.dump_head @stats, @logger, @title
34
+ end
35
+ end
36
+ end
37
+
38
+ describe '#dump_tail' do
39
+ context 'with no title' do
40
+ it 'logs ending of dump' do
41
+ @logger.minor.expects(:ended).with('dumping statistics').once
42
+ subject.dump_tail @stats, @logger, ''
43
+ end
44
+ end
45
+ context 'with given title' do
46
+ it 'logs footer line' do
47
+ @logger.expects(:liner).once
48
+ subject.dump_tail @stats, @logger, @title
49
+ end
50
+ end
51
+ end
52
+
53
+ end
54
+ end end end end
@@ -0,0 +1,15 @@
1
+ require 'ghaki/stats/format/null'
2
+
3
+ module Ghaki module Stats module Format module Null_Testing
4
+ describe Ghaki::Stats::Format::Null do
5
+
6
+ before(:all) do
7
+ @subj = Format::Null.new
8
+ end
9
+
10
+ subject { @subj }
11
+
12
+ it { should be_kind_of(Format::Base) }
13
+
14
+ end
15
+ end end end end
@@ -0,0 +1,37 @@
1
+ require 'ghaki/stats/format/output'
2
+ require 'ghaki/logger/spec_helper'
3
+
4
+ module Ghaki module Stats module Format module Output_Testing
5
+ describe Format::Output do
6
+ include Ghaki::Logger::SpecHelper
7
+
8
+ before(:each) do
9
+ setup_safe_logger
10
+ @subj = Format::Output.new
11
+ @stats = {
12
+ 'a' => { 'b' => 12 },
13
+ 'c' => { 'd' => 34 },
14
+ }
15
+ @out = 'file'
16
+ @title = 'msg'
17
+ end
18
+
19
+ subject { @subj }
20
+
21
+ it { should be_kind_of(Format::Base) }
22
+
23
+ describe '#dump_body' do
24
+ it 'writes output' do
25
+ subject.dump_body @stats, @logger, @title
26
+ @logger.with_file do |file|
27
+ file.rewind
28
+ file.read.split("\n").should == [
29
+ '# a:', sprintf('# %8s : %c', 12, 'b'),
30
+ '# c:', sprintf('# %8s : %s', 34, 'd'),
31
+ ]
32
+ end
33
+ end
34
+ end
35
+
36
+ end
37
+ end end end end
@@ -0,0 +1,25 @@
1
+ ############################################################################
2
+ require 'ghaki/stats/mixin'
3
+
4
+ ############################################################################
5
+ module Ghaki module Stats module MixinTesting
6
+ describe Ghaki::Stats::Mixin do
7
+
8
+ class UsingMixin
9
+ include Ghaki::Stats::Mixin
10
+ end
11
+
12
+ context 'object including' do
13
+ subject { UsingMixin.new }
14
+ it { should respond_to :stats }
15
+ it { should respond_to :stats= }
16
+ end
17
+
18
+ context '#stats' do
19
+ subject { UsingMixin.new.stats }
20
+ specify { should be_an_instance_of(Ghaki::Stats::Base) }
21
+ end
22
+
23
+ end
24
+ end end end
25
+ ############################################################################
@@ -0,0 +1,41 @@
1
+ require 'ghaki/stats/spec_helper'
2
+
3
+ module Ghaki module Stats module SpecHelper_Testing
4
+ describe SpecHelper do
5
+ include Ghaki::Stats::SpecHelper
6
+
7
+ class Fake < Stats::Base
8
+ end
9
+
10
+ before(:each) do
11
+ @stats = nil
12
+ end
13
+
14
+ describe '#make_safe_stats' do
15
+ it 'returns stats object' do
16
+ @stats = make_safe_stats()
17
+ @stats.should be_instance_of(Ghaki::Stats::Base)
18
+ end
19
+ it 'uses null sink for formatting' do
20
+ @stats = make_safe_stats()
21
+ @stats.format.should be_instance_of(Ghaki::Stats::Format::Null)
22
+ end
23
+ it 'accepts stats class' do
24
+ @stats = make_safe_stats(Fake)
25
+ @stats.should be_instance_of(Fake)
26
+ end
27
+ end
28
+
29
+ describe '#setup_safe_stats' do
30
+ it 'creates stats member value' do
31
+ setup_safe_stats()
32
+ @stats.should be_instance_of(Ghaki::Stats::Base)
33
+ end
34
+ it 'accepts stats class' do
35
+ setup_safe_stats(Fake)
36
+ @stats.should be_instance_of(Fake)
37
+ end
38
+ end
39
+
40
+ end
41
+ end end end
@@ -0,0 +1,6 @@
1
+ require 'mocha'
2
+
3
+ RSpec.configure do |cfg|
4
+ cfg.mock_with :mocha
5
+ cfg.color_enabled = true
6
+ end
metadata ADDED
@@ -0,0 +1,132 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ghaki-stats
3
+ version: !ruby/object:Gem::Version
4
+ version: 2011.11.29.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Gerald Kalafut
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-11-30 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: ghaki-app
16
+ requirement: &85199070 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 2011.11.29.1
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *85199070
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ requirement: &85198850 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: 2.4.0
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *85198850
36
+ - !ruby/object:Gem::Dependency
37
+ name: mocha
38
+ requirement: &85198620 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: 0.9.12
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *85198620
47
+ - !ruby/object:Gem::Dependency
48
+ name: rdoc
49
+ requirement: &85198390 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: 3.9.4
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *85198390
58
+ - !ruby/object:Gem::Dependency
59
+ name: ghaki-logger
60
+ requirement: &85198160 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: 2011.11.29.1
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *85198160
69
+ description: Simple tracker for counted statistics.
70
+ email: gerald@kalafut.org
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files:
74
+ - README
75
+ files:
76
+ - lib/ghaki/stats/mixin.rb
77
+ - lib/ghaki/stats/format/output.rb
78
+ - lib/ghaki/stats/format/null.rb
79
+ - lib/ghaki/stats/format/logger.rb
80
+ - lib/ghaki/stats/format/base.rb
81
+ - lib/ghaki/stats/spec_helper.rb
82
+ - lib/ghaki/stats/errors.rb
83
+ - lib/ghaki/stats/app.rb
84
+ - lib/ghaki/stats/base.rb
85
+ - README
86
+ - LICENSE
87
+ - VERSION
88
+ - spec/ghaki/stats/base_spec.rb
89
+ - spec/ghaki/stats/spec_helper_spec.rb
90
+ - spec/ghaki/stats/app_stats_spec.rb
91
+ - spec/ghaki/stats/mixin_spec.rb
92
+ - spec/ghaki/stats/format/null_spec.rb
93
+ - spec/ghaki/stats/format/output_spec.rb
94
+ - spec/ghaki/stats/format/base_spec.rb
95
+ - spec/ghaki/stats/format/logger_spec.rb
96
+ - spec/ghaki/stats/app_engine_spec.rb
97
+ - spec/spec_helper.rb
98
+ homepage: http://github.com/ghaki
99
+ licenses: []
100
+ post_install_message:
101
+ rdoc_options: []
102
+ require_paths:
103
+ - lib
104
+ required_ruby_version: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ required_rubygems_version: !ruby/object:Gem::Requirement
111
+ none: false
112
+ requirements:
113
+ - - ! '>='
114
+ - !ruby/object:Gem::Version
115
+ version: 1.3.6
116
+ requirements: []
117
+ rubyforge_project: ghaki-stats
118
+ rubygems_version: 1.8.10
119
+ signing_key:
120
+ specification_version: 3
121
+ summary: Statistical tracking
122
+ test_files:
123
+ - spec/ghaki/stats/base_spec.rb
124
+ - spec/ghaki/stats/spec_helper_spec.rb
125
+ - spec/ghaki/stats/app_stats_spec.rb
126
+ - spec/ghaki/stats/mixin_spec.rb
127
+ - spec/ghaki/stats/format/null_spec.rb
128
+ - spec/ghaki/stats/format/output_spec.rb
129
+ - spec/ghaki/stats/format/base_spec.rb
130
+ - spec/ghaki/stats/format/logger_spec.rb
131
+ - spec/ghaki/stats/app_engine_spec.rb
132
+ - spec/spec_helper.rb