ghaki-stats 2011.11.29.1

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/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