kpi 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,24 +1,24 @@
1
1
  module KPI
2
2
  class Report
3
3
  extend KPI::Report::SuppressMemoization
4
- extend ActiveSupport::Memoizable
5
-
4
+ extend KPI::Memoizable
5
+
6
6
  include KPI::Report::DynamicDefinitions
7
-
7
+
8
8
  blacklist :initialize, :collect!, :entries, :time, :title, :defined_kpis, :result, :method_missing
9
-
9
+
10
10
  def initialize(*args)
11
11
  @options = args.extract_options!
12
12
  @time = @options[:time] || Time.now
13
13
  @title = @options[:title] || self.class.name
14
14
  end
15
15
  attr_reader :time, :title
16
-
16
+
17
17
  def collect!
18
18
  self.defined_kpis.each {|kpi_method| send(kpi_method) }
19
19
  self
20
20
  end
21
-
21
+
22
22
  def entries
23
23
  Enumerator.new do |yielder|
24
24
  self.class.defined_kpis.each do |kpi_method|
@@ -26,7 +26,7 @@ module KPI
26
26
  end
27
27
  end
28
28
  end
29
-
29
+
30
30
  def defined_kpis
31
31
  self.class.defined_kpis.map(&:to_sym)
32
32
  end
@@ -34,16 +34,16 @@ module KPI
34
34
  def result(*args)
35
35
  KPI::Entry.new *args
36
36
  end
37
-
37
+
38
38
  def method_missing(name, *args)
39
39
  # check if KPI exists in report if name of missing method has trailing '?'
40
40
  return kpi_exists?($1.to_sym) if (/(.*)\?/ =~ name.to_s)
41
41
  super
42
42
  end
43
-
43
+
44
44
  private
45
-
46
- def kpi_exists?(name)
45
+
46
+ def kpi_exists?(name)
47
47
  self.defined_kpis.include?(name.to_sym)
48
48
  end
49
49
  end
@@ -0,0 +1,109 @@
1
+ require 'active_support/core_ext/kernel/singleton_class'
2
+ require 'active_support/core_ext/module/aliasing'
3
+
4
+ module KPI
5
+ module Memoizable
6
+ def self.memoized_ivar_for(symbol)
7
+ "@_memoized_#{symbol.to_s.sub(/\?\Z/, '_query').sub(/!\Z/, '_bang')}".to_sym
8
+ end
9
+
10
+ module InstanceMethods
11
+ def self.included(base)
12
+ base.class_eval do
13
+ unless base.method_defined?(:freeze_without_memoizable)
14
+ alias_method_chain :freeze, :memoizable
15
+ end
16
+ end
17
+ end
18
+
19
+ def freeze_with_memoizable
20
+ memoize_all unless frozen?
21
+ freeze_without_memoizable
22
+ end
23
+
24
+ def memoize_all
25
+ prime_cache ".*"
26
+ end
27
+
28
+ def unmemoize_all
29
+ flush_cache ".*"
30
+ end
31
+
32
+ def prime_cache(*syms)
33
+ syms.each do |sym|
34
+ methods.each do |m|
35
+ if m.to_s =~ /^_unmemoized_(#{sym})/
36
+ if method(m).arity == 0
37
+ __send__($1)
38
+ else
39
+ ivar = ActiveSupport::Memoizable.memoized_ivar_for($1)
40
+ instance_variable_set(ivar, {})
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ def flush_cache(*syms)
48
+ syms.each do |sym|
49
+ (methods + private_methods + protected_methods).each do |m|
50
+ if m.to_s =~ /^_unmemoized_(#{sym.to_s.gsub(/\?\Z/, '\?')})/
51
+ ivar = ActiveSupport::Memoizable.memoized_ivar_for($1)
52
+ instance_variable_get(ivar).clear if instance_variable_defined?(ivar)
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ def memoize(*symbols)
60
+ symbols.each do |symbol|
61
+ original_method = :"_unmemoized_#{symbol}"
62
+ memoized_ivar = ActiveSupport::Memoizable.memoized_ivar_for(symbol)
63
+
64
+ class_eval <<-EOS, __FILE__, __LINE__ + 1
65
+ include InstanceMethods # include InstanceMethods
66
+ #
67
+ if method_defined?(:#{original_method}) # if method_defined?(:_unmemoized_mime_type)
68
+ raise "Already memoized #{symbol}" # raise "Already memoized mime_type"
69
+ end # end
70
+ alias #{original_method} #{symbol} # alias _unmemoized_mime_type mime_type
71
+ #
72
+ if instance_method(:#{symbol}).arity == 0 # if instance_method(:mime_type).arity == 0
73
+ def #{symbol}(reload = false) # def mime_type(reload = false)
74
+ if reload || !defined?(#{memoized_ivar}) || #{memoized_ivar}.empty? # if reload || !defined?(@_memoized_mime_type) || @_memoized_mime_type.empty?
75
+ #{memoized_ivar} = [#{original_method}] # @_memoized_mime_type = [_unmemoized_mime_type]
76
+ end # end
77
+ #{memoized_ivar}[0] # @_memoized_mime_type[0]
78
+ end # end
79
+ else # else
80
+ def #{symbol}(*args) # def mime_type(*args)
81
+ #{memoized_ivar} ||= {} unless frozen? # @_memoized_mime_type ||= {} unless frozen?
82
+ args_length = method(:#{original_method}).arity # args_length = method(:_unmemoized_mime_type).arity
83
+ if args.length == args_length + 1 && # if args.length == args_length + 1 &&
84
+ (args.last == true || args.last == :reload) # (args.last == true || args.last == :reload)
85
+ reload = args.pop # reload = args.pop
86
+ end # end
87
+ #
88
+ if defined?(#{memoized_ivar}) && #{memoized_ivar} # if defined?(@_memoized_mime_type) && @_memoized_mime_type
89
+ if !reload && #{memoized_ivar}.has_key?(args) # if !reload && @_memoized_mime_type.has_key?(args)
90
+ #{memoized_ivar}[args] # @_memoized_mime_type[args]
91
+ elsif #{memoized_ivar} # elsif @_memoized_mime_type
92
+ #{memoized_ivar}[args] = #{original_method}(*args) # @_memoized_mime_type[args] = _unmemoized_mime_type(*args)
93
+ end # end
94
+ else # else
95
+ #{original_method}(*args) # _unmemoized_mime_type(*args)
96
+ end # end
97
+ end # end
98
+ end # end
99
+ #
100
+ if private_method_defined?(#{original_method.inspect}) # if private_method_defined?(:_unmemoized_mime_type)
101
+ private #{symbol.inspect} # private :mime_type
102
+ elsif protected_method_defined?(#{original_method.inspect}) # elsif protected_method_defined?(:_unmemoized_mime_type)
103
+ protected #{symbol.inspect} # protected :mime_type
104
+ end # end
105
+ EOS
106
+ end
107
+ end
108
+ end
109
+ end
data/lib/kpi.rb CHANGED
@@ -3,10 +3,11 @@ require 'array/extract_options'
3
3
  module KPI
4
4
  require 'engine' if defined?(Rails) && Rails::VERSION::MAJOR == 3
5
5
  require 'kpi/18compatibility' if RUBY_VERSION < '1.9'
6
-
6
+ require 'kpi/memoizable'
7
+
7
8
  require File.join(File.dirname(__FILE__), '..', 'app/models/kpi/entry')
8
9
  require File.join(File.dirname(__FILE__), '..', 'app/models/kpi/report/dynamic_definitions')
9
10
  require File.join(File.dirname(__FILE__), '..', 'app/models/kpi/report/suppress_memoization')
10
11
  require File.join(File.dirname(__FILE__), '..', 'app/models/kpi/report')
11
12
  require File.join(File.dirname(__FILE__), '..', 'app/models/kpi/merged_report')
12
- end
13
+ end
metadata CHANGED
@@ -1,122 +1,72 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: kpi
3
- version: !ruby/object:Gem::Version
4
- hash: 7
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.7.0
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 6
9
- - 0
10
- version: 0.6.0
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Artur Roszczyk
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2011-05-19 00:00:00 +02:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
12
+ date: 2012-12-03 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
22
15
  name: actionmailer
23
- version_requirements: &id001 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
24
17
  none: false
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- hash: 5
29
- segments:
30
- - 2
31
- - 3
32
- version: "2.3"
33
- prerelease: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '2.3'
34
22
  type: :runtime
35
- requirement: *id001
36
- - !ruby/object:Gem::Dependency
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '2.3'
30
+ - !ruby/object:Gem::Dependency
37
31
  name: activesupport
38
- version_requirements: &id002 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
39
33
  none: false
40
- requirements:
41
- - - ">="
42
- - !ruby/object:Gem::Version
43
- hash: 5
44
- segments:
45
- - 2
46
- - 3
47
- version: "2.3"
48
- prerelease: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '2.3'
49
38
  type: :runtime
50
- requirement: *id002
51
- - !ruby/object:Gem::Dependency
52
- name: minitest
53
- version_requirements: &id003 !ruby/object:Gem::Requirement
54
- none: false
55
- requirements:
56
- - - ">="
57
- - !ruby/object:Gem::Version
58
- hash: 3
59
- segments:
60
- - 0
61
- version: "0"
62
39
  prerelease: false
63
- type: :development
64
- requirement: *id003
65
- - !ruby/object:Gem::Dependency
66
- name: bundler
67
- version_requirements: &id004 !ruby/object:Gem::Requirement
40
+ version_requirements: !ruby/object:Gem::Requirement
68
41
  none: false
69
- requirements:
70
- - - ~>
71
- - !ruby/object:Gem::Version
72
- hash: 15
73
- segments:
74
- - 1
75
- - 0
76
- version: "1.0"
77
- prerelease: false
78
- type: :development
79
- requirement: *id004
80
- - !ruby/object:Gem::Dependency
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '2.3'
46
+ - !ruby/object:Gem::Dependency
81
47
  name: jeweler
82
- version_requirements: &id005 !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
83
49
  none: false
84
- requirements:
85
- - - ~>
86
- - !ruby/object:Gem::Version
87
- hash: 7
88
- segments:
89
- - 1
90
- - 5
91
- - 2
92
- version: 1.5.2
93
- prerelease: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
94
54
  type: :development
95
- requirement: *id005
96
- - !ruby/object:Gem::Dependency
97
- name: rcov
98
- version_requirements: &id006 !ruby/object:Gem::Requirement
99
- none: false
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- hash: 3
104
- segments:
105
- - 0
106
- version: "0"
107
55
  prerelease: false
108
- type: :development
109
- requirement: *id006
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
110
62
  description: This gem helps you to track key indicators in your Rails app.
111
63
  email: artur.roszczyk@gmail.com
112
64
  executables: []
113
-
114
65
  extensions: []
115
-
116
- extra_rdoc_files:
66
+ extra_rdoc_files:
117
67
  - LICENSE.txt
118
68
  - README.rdoc
119
- files:
69
+ files:
120
70
  - app/models/kpi/entry.rb
121
71
  - app/models/kpi/merged_report.rb
122
72
  - app/models/kpi/report.rb
@@ -128,48 +78,35 @@ files:
128
78
  - lib/generators/kpi/kpi_generator.rb
129
79
  - lib/kpi.rb
130
80
  - lib/kpi/18compatibility.rb
81
+ - lib/kpi/memoizable.rb
131
82
  - LICENSE.txt
132
83
  - README.rdoc
133
- - test/test_helper.rb
134
- - test/unit/kpi/entry_test.rb
135
- - test/unit/kpi/merged_report_test.rb
136
- - test/unit/kpi/report_test.rb
137
- has_rdoc: true
138
84
  homepage: http://github.com/sevos/kpi
139
- licenses:
85
+ licenses:
140
86
  - MIT
141
87
  post_install_message:
142
88
  rdoc_options: []
143
-
144
- require_paths:
89
+ require_paths:
145
90
  - lib
146
- required_ruby_version: !ruby/object:Gem::Requirement
91
+ required_ruby_version: !ruby/object:Gem::Requirement
147
92
  none: false
148
- requirements:
149
- - - ">="
150
- - !ruby/object:Gem::Version
151
- hash: 3
152
- segments:
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ segments:
153
98
  - 0
154
- version: "0"
155
- required_rubygems_version: !ruby/object:Gem::Requirement
99
+ hash: 3682157988565917255
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
156
101
  none: false
157
- requirements:
158
- - - ">="
159
- - !ruby/object:Gem::Version
160
- hash: 3
161
- segments:
162
- - 0
163
- version: "0"
102
+ requirements:
103
+ - - ! '>='
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
164
106
  requirements: []
165
-
166
107
  rubyforge_project:
167
- rubygems_version: 1.5.2
108
+ rubygems_version: 1.8.24
168
109
  signing_key:
169
110
  specification_version: 3
170
111
  summary: Key Performance Indicators for Rails 3.x
171
- test_files:
172
- - test/test_helper.rb
173
- - test/unit/kpi/entry_test.rb
174
- - test/unit/kpi/merged_report_test.rb
175
- - test/unit/kpi/report_test.rb
112
+ test_files: []
data/test/test_helper.rb DELETED
@@ -1,11 +0,0 @@
1
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
- $LOAD_PATH.unshift(File.dirname(__FILE__))
3
- require 'minitest/autorun'
4
-
5
- require 'active_support'
6
- require 'action_mailer'
7
- require 'kpi'
8
-
9
- # Requires supporting files with custom matchers and macros, etc,
10
- # in ./support/ and its subdirectories.
11
- # Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
@@ -1,66 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
2
-
3
- describe "KPI::Entry" do
4
- it "should require exactly 2 arguments" do
5
- assert_raises(ArgumentError) { KPI::Entry.new }
6
- assert_raises(ArgumentError) { KPI::Entry.new "test" }
7
- assert_raises(ArgumentError) { KPI::Entry.new "test", 1, "aaa" }
8
- end
9
-
10
- describe "when title and value given" do
11
- before { @entry = KPI::Entry.new "name", "value" }
12
-
13
- it "returns name" do
14
- assert_equal("name", @entry.name)
15
- end
16
-
17
- it "returns value" do
18
- assert_equal("value", @entry.value)
19
- end
20
-
21
- it "returns nil as description" do
22
- assert_nil(@entry.description)
23
- end
24
- describe "when description given" do
25
- before { @entry = KPI::Entry.new "name", "value", :description => "desc" }
26
-
27
- it "returns description" do
28
- assert_equal("desc", @entry.description)
29
- end
30
- end
31
-
32
- describe "when unit given" do
33
- before { @entry = KPI::Entry.new "Income", 1294.23, :unit => "EUR" }
34
-
35
- it "returns description" do
36
- assert_equal("EUR", @entry.unit)
37
- end
38
- end
39
-
40
- describe "when entry is important" do
41
- before { @entry = KPI::Entry.new "Income", 1294.23, :important => true }
42
-
43
- it "returns true" do
44
- assert @entry.important
45
- end
46
- end
47
-
48
- describe :important? do
49
- describe "when entry is important" do
50
- before { @entry = KPI::Entry.new "Income", 1294.23, :important => true }
51
-
52
- it "returns true" do
53
- assert @entry.important?
54
- end
55
- end
56
-
57
- describe "when entry is not important" do
58
- before { @entry = KPI::Entry.new "Income", 1294.23 }
59
-
60
- it "returns false" do
61
- assert !@entry.important?
62
- end
63
- end
64
- end
65
- end
66
- end
@@ -1,207 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
2
-
3
- describe "KPI::MergedReport" do
4
-
5
- before do
6
- class TestKpi < KPI::Report
7
- def initialize return_value = 1
8
- super()
9
- @return = return_value
10
- end
11
-
12
- def test_kpi
13
- result "title", @return, :description => "description"
14
- end
15
-
16
- def test_kpi_2
17
- result "title 2 ", @return*2, :unit => 'EUR', :important => true
18
- end
19
- end
20
- class AnotherReport < KPI::Report
21
- def test_kpi
22
- result "title", 3, :description => "description"
23
- end
24
-
25
- def another_kpi
26
- result "another", 5
27
- end
28
- end
29
- end
30
-
31
- after do
32
- Object.send(:remove_const, :TestKpi)
33
- Object.send(:remove_const, :AnotherReport)
34
- end
35
-
36
- describe "when initializing" do
37
- it "should initialize with list of KPI::Report::Base objects and block" do
38
- KPI::MergedReport.new(TestKpi.new) {}
39
- KPI::MergedReport.new(TestKpi.new, TestKpi.new) {}
40
- KPI::MergedReport.new(TestKpi.new,TestKpi.new, TestKpi.new) {}
41
- end
42
-
43
- it "should require at least one element when initializing" do
44
- assert_raises(ArgumentError) do
45
- KPI::MergedReport.new() {}
46
- end
47
- end
48
-
49
- it "should allow objects of the same type when initializing" do
50
- KPI::MergedReport.new(TestKpi.new, AnotherReport.new) {}
51
- end
52
-
53
- it "should require block when initializing" do
54
- assert_raises(Exception) do
55
- KPI::MergedReport.new(TestKpi.new)
56
- end
57
- end
58
- end
59
-
60
- describe "when two identical reports given for average" do
61
- before do
62
- @report1 = TestKpi.new(2)
63
- @report2 = TestKpi.new(8)
64
-
65
- @average = KPI::MergedReport.new(@report1, @report2) do |*entries|
66
- average = entries.map(&:value).sum / entries.size
67
- KPI::Entry.new "Average $$", average, :description => "$$ (average)"
68
- end
69
- end
70
-
71
- it "should calculate value using block given in initializer when asking for KPI" do
72
- assert_equal 5, @average.test_kpi.value
73
- end
74
-
75
- it "should change $$ in title to indicator title" do
76
- assert_equal "Average title", @average.test_kpi.name
77
- end
78
-
79
- it "should change $$ in description to indicator descripiton" do
80
- assert_equal "description (average)", @average.test_kpi.description
81
- end
82
-
83
- it "should return nil description when no description" do
84
- assert_nil @average.test_kpi_2.description
85
- end
86
-
87
- it "should have unit" do
88
- assert_equal "EUR", @average.test_kpi_2.unit
89
- end
90
-
91
- it "should allow to override unit" do
92
- @merged = KPI::MergedReport.new(@report1, @report2) do |*entries|
93
- KPI::Entry.new "merged $$", 1, :unit => "$"
94
- end
95
- assert_equal '$', @merged.test_kpi.unit
96
- assert_equal '$', @merged.test_kpi_2.unit
97
- end
98
-
99
- it "should pass important flag" do
100
- assert @average.test_kpi_2.important?
101
- end
102
-
103
- it "should allow to override important flag" do
104
- @merged = KPI::MergedReport.new(@report1, @report2) do |*entries|
105
- KPI::Entry.new "merged $$", 1, :important => true
106
- end
107
- assert @merged.test_kpi.important?
108
- assert @merged.test_kpi_2.important?
109
- end
110
-
111
- describe "entries" do
112
- it "should return enumerator with entries" do
113
- assert_kind_of Enumerable, @average.entries
114
- end
115
-
116
- it "should pack average entries to enumerator" do
117
- assert @average.entries.all? { |e| e.instance_of?(KPI::Entry) }
118
- end
119
-
120
- it "should have each average entry for each indicator" do
121
- assert_equal TestKpi.defined_kpis.size, @average.entries.to_a.size
122
- end
123
-
124
- it "should calculate averages for each indicator" do
125
- assert_equal [5,10], @average.entries.map(&:value)
126
- end
127
- end
128
-
129
- describe :defined_kpis do
130
- it "should return KPIs defined by all compounds" do
131
- assert_equal TestKpi.defined_kpis, @average.defined_kpis
132
- end
133
-
134
- it "should check if defined_kpis return array of symbol" do
135
- assert_same true, @average.defined_kpis.map(&:class).uniq === [Symbol]
136
- end
137
-
138
- it "should return true when calling test_kpi?" do
139
- assert @average.test_kpi?
140
- end
141
-
142
- it "should return false when calling non existing method with '?'" do
143
- assert !@average.test_kpi_23?
144
- end
145
- end
146
- end
147
-
148
- describe :title do
149
- before do
150
- @partial_report = TestKpi.new
151
- end
152
-
153
- it "should return title passed in options" do
154
- report = KPI::MergedReport.new(@partial_report, :title => "my title") {}
155
- assert_equal "my title", report.title
156
- end
157
-
158
- it "should return title of first report by default" do
159
- report = KPI::MergedReport.new(@partial_report) {}
160
- assert_equal @partial_report.title, report.title
161
- end
162
- end
163
-
164
- describe "when different reports given for merge" do
165
- before do
166
- @report1 = TestKpi.new(2)
167
- @report2 = AnotherReport.new
168
- end
169
-
170
- describe "when intersection" do
171
- before do
172
- @merge = KPI::MergedReport.new(@report1, @report2) do |test, another|
173
- KPI::Entry.new "$$", {:test => test, :another => another}, :description => '$$'
174
- end
175
- end
176
-
177
- it "should have only common KPI defined" do
178
- assert_equal [:test_kpi], @merge.defined_kpis
179
- end
180
-
181
- it "should not repospond for not common KPI" do
182
- assert_raises(NoMethodError) { @merge.another_kpi }
183
- end
184
-
185
- it "should return values for common KPI" do
186
- assert_instance_of Hash, @merge.test_kpi.value
187
- end
188
- end
189
-
190
- describe "when conjunction" do
191
- before do
192
- @merge = KPI::MergedReport.new(@report1, @report2, :mode => :|) do |test, another|
193
- merge = {:test => test.try(:value), :another => another.try(:value)}
194
- KPI::Entry.new "$$", merge, :description => '$$'
195
- end
196
- end
197
-
198
- it "should have all KPI of both reports" do
199
- assert_equal [:test_kpi, :test_kpi_2, :another_kpi], @merge.defined_kpis
200
- end
201
-
202
- it "should return KPI" do
203
- assert_equal({:test => nil, :another => 5}, @merge.another_kpi.value)
204
- end
205
- end
206
- end
207
- end
@@ -1,105 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
2
-
3
- describe "KPI::Report" do
4
- before do
5
- class TestKpi < KPI::Report
6
- def test_kpi
7
- return KPI::Entry.new "title", 1, :description => "description"
8
- end
9
-
10
- def another_kpi
11
- return KPI::Entry.new "another title", 0
12
- end
13
- end
14
- @kpi = TestKpi.new
15
- end
16
-
17
- after { Object.send(:remove_const, :TestKpi) }
18
-
19
- it "should define indicators" do
20
- assert_equal [:test_kpi, :another_kpi], TestKpi.defined_kpis
21
- end
22
-
23
- it "should not define indicator from private method" do
24
- class TestKpi
25
- private
26
- def not_kpi
27
- end
28
- end
29
- assert !TestKpi.defined_kpis.include?(:not_kpi)
30
- end
31
-
32
- describe :collect! do
33
- it "should collect all KPIs" do
34
- assert_equal 2, @kpi.collect!.entries.count
35
- end
36
- end
37
-
38
- describe :defined_kpis do
39
- it "should return KPIs defined by class" do
40
- assert_equal TestKpi.defined_kpis, @kpi.defined_kpis
41
- end
42
- end
43
-
44
- describe :entries do
45
- it "should return enumerator" do
46
- assert @kpi.entries.kind_of?(Enumerable)
47
- end
48
-
49
- it "should return enumerator with entries" do
50
- assert @kpi.entries.first.kind_of?(KPI::Entry)
51
- end
52
-
53
- it "should fill entries with names" do
54
- assert_equal ["title", "another title"], @kpi.entries.map(&:name)
55
- end
56
-
57
- it "should fill entries with values" do
58
- assert_equal [1, 0], @kpi.entries.map(&:value)
59
- end
60
-
61
- it "should fill entries with descriptions" do
62
- assert_equal ["description", nil], @kpi.entries.map(&:description)
63
- end
64
- end
65
-
66
- describe :title do
67
- it "should return class name by default" do
68
- assert_equal "TestKpi", @kpi.title
69
- end
70
-
71
- it "should allow to override title in definition" do
72
- class AnotherKpi < KPI::Report
73
- def title; "title"; end
74
- end
75
- @kpi = AnotherKpi.new
76
- assert_equal "title", @kpi.title
77
- assert !@kpi.defined_kpis.include?(:title), 'report should not have :title KPI'
78
- end
79
-
80
- it "should allow to override title in options" do
81
- assert_equal "my title", TestKpi.new(:title => "my title").title
82
- end
83
- end
84
-
85
- describe :time do
86
- it "should return overriden time" do
87
- assert_equal(:time, TestKpi.new(:time => :time).time)
88
- end
89
- end
90
-
91
- describe :result do
92
- it "creates KPI::Entry" do
93
- class TestKpi
94
- def super_kpi
95
- result "test", 2, :description => "desc"
96
- end
97
- end
98
-
99
- @entry = TestKpi.new.super_kpi
100
- assert_equal("test", @entry.name)
101
- assert_equal(2, @entry.value)
102
- assert_equal("desc", @entry.description)
103
- end
104
- end
105
- end