active_metric 2.5.2
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.rdoc +5 -0
- data/Rakefile +37 -0
- data/lib/active_metric.rb +38 -0
- data/lib/active_metric/axis.rb +11 -0
- data/lib/active_metric/behavior/calculates_derivative.rb +18 -0
- data/lib/active_metric/behavior/graph_calculation.rb +78 -0
- data/lib/active_metric/calculators/reservoir.rb +81 -0
- data/lib/active_metric/calculators/standard_deviator.rb +39 -0
- data/lib/active_metric/config/initializers/inflections.rb +4 -0
- data/lib/active_metric/graph_view_model.rb +60 -0
- data/lib/active_metric/measurement.rb +13 -0
- data/lib/active_metric/point_series_data.rb +17 -0
- data/lib/active_metric/report.rb +57 -0
- data/lib/active_metric/report_view_model.rb +106 -0
- data/lib/active_metric/sample.rb +148 -0
- data/lib/active_metric/series_data.rb +26 -0
- data/lib/active_metric/stat.rb +72 -0
- data/lib/active_metric/stat_definition.rb +20 -0
- data/lib/active_metric/statistics/defaults.rb +157 -0
- data/lib/active_metric/statistics/standard_deviation.rb +43 -0
- data/lib/active_metric/subject.rb +117 -0
- data/lib/active_metric/version.rb +3 -0
- data/test/active_metric_test.rb +30 -0
- data/test/axis_test.rb +22 -0
- data/test/behavior_tests/calculates_derivative_test.rb +35 -0
- data/test/behavior_tests/graph_calculation_test.rb +68 -0
- data/test/config/mongoid.yml +13 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/test.log +18597 -0
- data/test/graph_view_model_test.rb +92 -0
- data/test/integration_test.rb +149 -0
- data/test/measurement_test.rb +45 -0
- data/test/mongoid_test.rb +24 -0
- data/test/point_series_data_test.rb +27 -0
- data/test/report_test.rb +73 -0
- data/test/report_view_model_test.rb +94 -0
- data/test/reservoir_test.rb +67 -0
- data/test/sample_test.rb +142 -0
- data/test/series_data_test.rb +20 -0
- data/test/standard_deviator_test.rb +45 -0
- data/test/stat_test.rb +222 -0
- data/test/subject_test.rb +22 -0
- data/test/test_helper.rb +76 -0
- metadata +123 -0
@@ -0,0 +1,92 @@
|
|
1
|
+
require_relative "test_helper"
|
2
|
+
|
3
|
+
module ActiveMetric
|
4
|
+
class GraphViewModelTest < ActiveSupport::TestCase
|
5
|
+
|
6
|
+
EULERS_DAY= MONGO_MAX_LIMIT = (1 << 31) - 1
|
7
|
+
|
8
|
+
test "can retrieve series by label" do
|
9
|
+
gvm = GraphViewModel.create
|
10
|
+
gvm.series_data << generate_series_data(5, "first")
|
11
|
+
gvm.series_data << generate_series_data(5, "second")
|
12
|
+
|
13
|
+
series = gvm.series_for("second")
|
14
|
+
|
15
|
+
assert_equal "second", series.label
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
test "size returns 0 if no series_data" do
|
20
|
+
gvm = GraphViewModel.create
|
21
|
+
assert_equal 0, gvm.size
|
22
|
+
end
|
23
|
+
|
24
|
+
test "can create from definitions" do
|
25
|
+
axises_defintions = [{index: 1, label: "second"},
|
26
|
+
{index: 0, label: "first"},
|
27
|
+
{index: 0, label: "actually first"}]
|
28
|
+
options = {name: "test graph"}
|
29
|
+
|
30
|
+
stat_definitions = []
|
31
|
+
stat_definitions << stat_definition(true)
|
32
|
+
stat_definitions << stat_definition(true)
|
33
|
+
stat_definitions << stat_definition(false)
|
34
|
+
|
35
|
+
gvm = GraphViewModel.create_from_meta_data(axises_defintions, stat_definitions, options)
|
36
|
+
|
37
|
+
assert_equal 2, gvm.y_axises.size
|
38
|
+
|
39
|
+
index_zero_axises = gvm.y_axises.select{|axis| axis.index == 0}
|
40
|
+
|
41
|
+
assert_equal 1, index_zero_axises.size
|
42
|
+
assert_equal 0, index_zero_axises.first.index
|
43
|
+
assert_equal "actually first", index_zero_axises.first.label
|
44
|
+
|
45
|
+
assert_equal 2, gvm.series_data.size
|
46
|
+
end
|
47
|
+
|
48
|
+
test "can read y_axises sorted by index" do
|
49
|
+
axises_defintions = [{index: 1, label: "second"},
|
50
|
+
{index: 0, label: "first"},
|
51
|
+
{index: 0, label: "actually first"}]
|
52
|
+
|
53
|
+
gvm = GraphViewModel.create_from_meta_data(axises_defintions, [], {})
|
54
|
+
|
55
|
+
axises = gvm.ordered_y_axises
|
56
|
+
|
57
|
+
assert_equal 2, axises.size
|
58
|
+
|
59
|
+
assert_equal 0, axises.first.index
|
60
|
+
assert_equal "actually first", axises.first.label
|
61
|
+
|
62
|
+
assert_equal 1, axises.second.index
|
63
|
+
assert_equal "second", axises.second.label
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
test "can retrieve partial array" do
|
68
|
+
subject = Subject.create
|
69
|
+
graph_view_model = subject.graph_view_model
|
70
|
+
graph_view_model.series_data << generate_series_data(4)
|
71
|
+
graph_view_model.series_data << generate_series_data(4,"label 2")
|
72
|
+
|
73
|
+
partial_graph = subject.graph_view_model_starting_at(2)
|
74
|
+
|
75
|
+
assert_equal [[2,2],[3,3]], partial_graph.series_data.first.data
|
76
|
+
assert_equal [[2,2],[3,3]], partial_graph.series_data.second.data
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
def generate_series_data(x_count, label = "label")
|
81
|
+
data = []
|
82
|
+
x_count.times {|x| data << [x,x]}
|
83
|
+
PointSeriesData.new(data: data, label: label)
|
84
|
+
end
|
85
|
+
|
86
|
+
def stat_definition(graphable)
|
87
|
+
axis = graphable ? 0 : -1
|
88
|
+
StatDefinition.new(:name_of_stat,Min,"min_name_of_stat",{axis: axis})
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
|
3
|
+
module ActiveMetric
|
4
|
+
|
5
|
+
class IntegrationTest < ActiveSupport::TestCase
|
6
|
+
|
7
|
+
test "can calculate correct eightieth percentile for subject" do
|
8
|
+
report = Report.create
|
9
|
+
subject = TestSubject.create :report => report
|
10
|
+
subject2 = TestSubject.create :report => report
|
11
|
+
10.times do |value|
|
12
|
+
subject.calculate TestMeasurement.new(:value => 100 - value, :timestamp => value)
|
13
|
+
end
|
14
|
+
10.times do |value|
|
15
|
+
subject2.calculate TestMeasurement.new(:value => 200 - value, :timestamp => value)
|
16
|
+
end
|
17
|
+
subject2.complete
|
18
|
+
subject.complete
|
19
|
+
assert_equal 99, subject.summary.eightieth_value.value
|
20
|
+
assert_equal 199, subject2.summary.eightieth_value.value
|
21
|
+
end
|
22
|
+
|
23
|
+
test "can calculate correct ninety eighth percentile for subject" do
|
24
|
+
report = Report.create
|
25
|
+
subject = TestSubject.create :report => report
|
26
|
+
subject2 = TestSubject.create :report => report
|
27
|
+
5.times do |value|
|
28
|
+
subject.calculate TestMeasurement.new(:value => 100 - value, :timestamp => value)
|
29
|
+
end
|
30
|
+
5.times do |value|
|
31
|
+
subject.calculate TestMeasurement.new(:value => 150 - value, :timestamp => value)
|
32
|
+
end
|
33
|
+
10.times do |value|
|
34
|
+
subject2.calculate TestMeasurement.new(:value => 200 - value, :timestamp => value)
|
35
|
+
end
|
36
|
+
subject2.complete
|
37
|
+
subject.complete
|
38
|
+
assert_equal 150, subject.summary.ninety_eighth_value.value
|
39
|
+
assert_equal 200, subject2.summary.ninety_eighth_value.value
|
40
|
+
end
|
41
|
+
|
42
|
+
test "can calculate correct percentiles with multiple subjects" do
|
43
|
+
report = Report.create
|
44
|
+
subject = TestSubject.create :report => report
|
45
|
+
subject2 = TestSubject.create :report => report
|
46
|
+
5.times do |value|
|
47
|
+
subject.calculate TestMeasurement.new(:value => 100 - value, :timestamp => value)
|
48
|
+
end
|
49
|
+
5.times do |value|
|
50
|
+
subject.calculate TestMeasurement.new(:value => 150 - value, :timestamp => value)
|
51
|
+
end
|
52
|
+
10.times do |value|
|
53
|
+
subject2.calculate TestMeasurement.new(:value => 155 - value, :timestamp => value)
|
54
|
+
end
|
55
|
+
subject2.complete
|
56
|
+
subject.complete
|
57
|
+
|
58
|
+
assert_equal 149, subject.summary.eightieth_value.value
|
59
|
+
assert_equal 150, subject.summary.ninety_eighth_value.value
|
60
|
+
|
61
|
+
assert_equal 154, subject2.summary.eightieth_value.value
|
62
|
+
assert_equal 155, subject2.summary.ninety_eighth_value.value
|
63
|
+
end
|
64
|
+
|
65
|
+
test "can calculate standard deviations" do
|
66
|
+
report = Report.create
|
67
|
+
subject = TestSubject.create :report => report
|
68
|
+
10.times do |value|
|
69
|
+
subject.calculate TestMeasurement.new(:value => 100 - value, :timestamp => value)
|
70
|
+
end
|
71
|
+
|
72
|
+
subject.complete
|
73
|
+
assert_close_to 2.87, subject.summary.standard_deviation_value.value
|
74
|
+
end
|
75
|
+
|
76
|
+
test "summary should update when samples changes" do
|
77
|
+
report = Report.create
|
78
|
+
subject = TestSubject.create :report => report
|
79
|
+
6.times do |value|
|
80
|
+
subject.calculate TestMeasurement.new(:value => value, :timestamp => value)
|
81
|
+
end
|
82
|
+
|
83
|
+
assert_equal 4.0, subject.summary.eightieth_value.value
|
84
|
+
|
85
|
+
subject.calculate TestMeasurement.new(:value => 6, :timestamp => 6)
|
86
|
+
|
87
|
+
assert_equal 4.0, subject.summary.eightieth_value.value
|
88
|
+
end
|
89
|
+
|
90
|
+
test "subjects should delegate to summaries" do
|
91
|
+
report = Report.create
|
92
|
+
subject = TestSubject.create :report => report
|
93
|
+
6.times do |value|
|
94
|
+
subject.calculate TestMeasurement.new(:value => value, :timestamp => value)
|
95
|
+
end
|
96
|
+
|
97
|
+
assert_equal 4.0, subject.eightieth_value
|
98
|
+
assert_equal 4.0, subject.eightieth_value
|
99
|
+
end
|
100
|
+
|
101
|
+
test "subjects should delegate to document before summaries" do
|
102
|
+
report = Report.create
|
103
|
+
subject = TestSubject.create :report => report, :test_field => "subject name"
|
104
|
+
6.times do |value|
|
105
|
+
subject.calculate TestMeasurement.new(:value => value, :timestamp => value)
|
106
|
+
end
|
107
|
+
assert_equal "subject name", subject.test_field
|
108
|
+
assert_equal 4.0, subject.eightieth_value
|
109
|
+
end
|
110
|
+
|
111
|
+
test "subjects should be able to delegate to non stat properties on summary" do
|
112
|
+
report = Report.create
|
113
|
+
subject = TestSubject.create :report => report
|
114
|
+
6.times do |value|
|
115
|
+
subject.calculate TestMeasurement.new(:value => value, :timestamp => value)
|
116
|
+
end
|
117
|
+
assert_equal 5, subject.duration_in_seconds
|
118
|
+
assert_equal 5, subject.duration_in_seconds
|
119
|
+
end
|
120
|
+
|
121
|
+
test "no measurements or interval samples should be in the database" do
|
122
|
+
report = Report.create
|
123
|
+
subject = TestSubject.create :report => report
|
124
|
+
subject2 = TestSubject.create :report => report
|
125
|
+
11.times do |value|
|
126
|
+
subject.calculate TestMeasurement.new(:value => 100 - value, :timestamp => value)
|
127
|
+
end
|
128
|
+
10.times do |value|
|
129
|
+
subject2.calculate TestMeasurement.new(:value => 200 - value, :timestamp => value)
|
130
|
+
end
|
131
|
+
subject2.complete
|
132
|
+
subject.complete
|
133
|
+
assert_equal 90, subject.min_value
|
134
|
+
assert_equal 191, subject2.min_value
|
135
|
+
|
136
|
+
assert_equal 0, ActiveMetric::Measurement.count
|
137
|
+
assert_equal 0, ActiveMetric::Sample.where(:interval.ne => nil).count
|
138
|
+
assert_equal 2, ActiveMetric::Sample.where(:interval => nil).count
|
139
|
+
end
|
140
|
+
|
141
|
+
private
|
142
|
+
|
143
|
+
def assert_within_threshold(threshold, actual, estimated)
|
144
|
+
range_val = actual * threshold
|
145
|
+
range = ((actual - range_val)..(actual + range_val))
|
146
|
+
assert_within_range range, estimated
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
|
3
|
+
module ActiveMetric
|
4
|
+
|
5
|
+
class MeasurementTest < ActiveSupport::TestCase
|
6
|
+
|
7
|
+
setup do
|
8
|
+
@measurement = TestMeasurement.new
|
9
|
+
end
|
10
|
+
|
11
|
+
test 'can create measurement' do
|
12
|
+
assert @measurement
|
13
|
+
end
|
14
|
+
|
15
|
+
test 'is a mongoid document' do
|
16
|
+
assert @measurement.kind_of? Mongoid::Document
|
17
|
+
end
|
18
|
+
|
19
|
+
test 'time returns datetime in seconds for timestamp' do
|
20
|
+
@measurement.timestamp = 1318338826385
|
21
|
+
assert_equal Time.at(1318338826), @measurement.time
|
22
|
+
end
|
23
|
+
|
24
|
+
test "converts appropriate fields to integer" do
|
25
|
+
assert_saves_as_integer @measurement, :timestamp
|
26
|
+
end
|
27
|
+
|
28
|
+
test "measurements default timestamp to now" do
|
29
|
+
assert @measurement.timestamp
|
30
|
+
sleep(1)
|
31
|
+
measurement2 = TestMeasurement.new
|
32
|
+
assert measurement2.timestamp
|
33
|
+
|
34
|
+
assert_not_equal @measurement.timestamp, measurement2.timestamp
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def assert_saves_as_integer(measurement, field)
|
40
|
+
measurement.send("#{field}=","12345")
|
41
|
+
measurement.save!
|
42
|
+
assert_equal 12345, measurement.send(field)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
|
3
|
+
class MongoidTest < ActiveSupport::TestCase
|
4
|
+
|
5
|
+
|
6
|
+
test "inherited documents from class dot new dont get a type" do
|
7
|
+
class TopLevel
|
8
|
+
include Mongoid::Document
|
9
|
+
end
|
10
|
+
|
11
|
+
class SecondLevel < TopLevel
|
12
|
+
end
|
13
|
+
|
14
|
+
second_level = SecondLevel.create
|
15
|
+
assert_equal "MongoidTest::SecondLevel", second_level._type
|
16
|
+
|
17
|
+
klass = Class.new(TopLevel)
|
18
|
+
MongoidTest.const_set(:NewKlass, klass)
|
19
|
+
|
20
|
+
new_object = NewKlass.create
|
21
|
+
assert_equal "MongoidTest::NewKlass", new_object._type
|
22
|
+
#assert_equal nil, new_object._type, "Mongoid correctly sets _type on Anonymous Classes now. Go remove the hack in stat: create_custom_stat WRT _type "
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require_relative "test_helper"
|
2
|
+
|
3
|
+
module ActiveMetric
|
4
|
+
class PointSeriesDataTest < ActiveSupport::TestCase
|
5
|
+
|
6
|
+
test "can push and pop atomically" do
|
7
|
+
gvm = GraphViewModel.create
|
8
|
+
psd = PointSeriesData.new(data: [[1,1],[2,2]])
|
9
|
+
gvm.series_data << psd
|
10
|
+
|
11
|
+
psd.pop_data
|
12
|
+
|
13
|
+
assert_equal [[1,1]], psd.data
|
14
|
+
|
15
|
+
psd.push_data([3,3])
|
16
|
+
|
17
|
+
assert_equal [[1,1],[3,3]], psd.data
|
18
|
+
end
|
19
|
+
|
20
|
+
test "can calculate size of data" do
|
21
|
+
psd = PointSeriesData.new(data: [[1,1],[2,2]])
|
22
|
+
|
23
|
+
assert_equal 2, psd.size
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
data/test/report_test.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
|
3
|
+
module ActiveMetric
|
4
|
+
|
5
|
+
class ReportTest < ActiveSupport::TestCase
|
6
|
+
|
7
|
+
|
8
|
+
test "method missing for subjects" do
|
9
|
+
report = Report.create
|
10
|
+
subjects = 2.times.map {TestSubject.create :report => report}
|
11
|
+
assert_equal subjects, report.test_subjects
|
12
|
+
end
|
13
|
+
|
14
|
+
test "responds properly to method missing if not a subject name" do
|
15
|
+
report = Report.create
|
16
|
+
assert_raises NoMethodError do
|
17
|
+
report.bad_method
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
test "can still use dynamic fields with overwritten method missing" do
|
22
|
+
report = Report.create :some_random_field => "value"
|
23
|
+
assert_equal "value", report.some_random_field
|
24
|
+
end
|
25
|
+
|
26
|
+
test "can still access dynamic fields with subjects in name" do
|
27
|
+
report = Report.create :some_subjects => "value"
|
28
|
+
assert_equal "value", report.some_subjects
|
29
|
+
end
|
30
|
+
|
31
|
+
test "can delete a report" do
|
32
|
+
report = Report.create
|
33
|
+
report.subjects.create
|
34
|
+
|
35
|
+
report.delete
|
36
|
+
|
37
|
+
assert_equal 0, ActiveMetric::Report.count
|
38
|
+
assert_equal 0, ActiveMetric::Subject.count
|
39
|
+
assert_equal 0, ActiveMetric::Sample.count
|
40
|
+
assert_equal 0, ActiveMetric::GraphViewModel.count
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
test "can set display name" do
|
45
|
+
class TestReport < Report
|
46
|
+
|
47
|
+
def set_display_name
|
48
|
+
"Overriden Display Name"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
report = TestReport.create
|
53
|
+
|
54
|
+
assert_equal "Overriden Display Name", report.display_name
|
55
|
+
end
|
56
|
+
|
57
|
+
test "can set display name through attribute" do
|
58
|
+
class TestReport < Report
|
59
|
+
|
60
|
+
def set_display_name
|
61
|
+
"TestReport Display Name"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
report = TestReport.create display_name: "Overriden Display Name"
|
66
|
+
|
67
|
+
assert_equal "Overriden Display Name", report.display_name
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require_relative "test_helper"
|
2
|
+
|
3
|
+
module ActiveMetric
|
4
|
+
class ReportViewModelTest < ActiveSupport::TestCase
|
5
|
+
|
6
|
+
class TestReportViewModel < ActiveMetric::ReportViewModel
|
7
|
+
|
8
|
+
table :table1 do
|
9
|
+
column "header 1", :field1
|
10
|
+
column "header 2", :field2, :precision => 2
|
11
|
+
column "header 3", :field3, :format => :duration_with_format
|
12
|
+
end
|
13
|
+
|
14
|
+
table :table2 do
|
15
|
+
column "header 1", :field1
|
16
|
+
column "header 2", :field2
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
test "can instantiate a view model" do
|
22
|
+
rvm = TestReportViewModel.new
|
23
|
+
rvm.add_table :table1, subjects
|
24
|
+
table = rvm.tables.first
|
25
|
+
|
26
|
+
expected_headers = ["header 1", "header 2", "header 3"]
|
27
|
+
assert_equal expected_headers, table.headers
|
28
|
+
|
29
|
+
expected_cells = ["name",2.8345, 3]
|
30
|
+
expected_cell_options = [{},{:precision =>2},{:format => :duration_with_format}]
|
31
|
+
table.rows.each do |row|
|
32
|
+
assert_equal expected_cells, row.cells.map(&:value)
|
33
|
+
assert_equal expected_cell_options, row.cells.map(&:format_options)
|
34
|
+
assert row.has_series
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
test "cannot add a table that does not exist" do
|
39
|
+
rvm = TestReportViewModel.new
|
40
|
+
assert_raise ReportViewModel::TableDoesNotExist do
|
41
|
+
rvm.add_table :bad_table, subjects
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
test "can have multiple tables" do
|
46
|
+
rvm = TestReportViewModel.new
|
47
|
+
rvm.add_table :table1, subjects
|
48
|
+
rvm.add_table :table2, subjects
|
49
|
+
rvm.add_table :table1, subjects
|
50
|
+
|
51
|
+
table1_headers = ["header 1", "header 2", "header 3"]
|
52
|
+
table2_headers = ["header 1", "header 2"]
|
53
|
+
|
54
|
+
assert_equal table1_headers, rvm.tables[0].headers
|
55
|
+
assert_equal table2_headers, rvm.tables[1].headers
|
56
|
+
assert_equal table1_headers, rvm.tables[2].headers
|
57
|
+
|
58
|
+
table1_data = ["name",2.8345, 3]
|
59
|
+
table2_data = ["name",2.8345]
|
60
|
+
table3_data = ["name",2.8345, 3]
|
61
|
+
|
62
|
+
assert_table_data table1_data, rvm.tables[0]
|
63
|
+
assert_table_data table2_data, rvm.tables[1]
|
64
|
+
assert_table_data table3_data, rvm.tables[2]
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
def assert_table_data(data, table)
|
69
|
+
table.rows.each do |row|
|
70
|
+
assert_equal data, row.cells.map(&:value)
|
71
|
+
assert_equal "1", row.row_id
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def subjects
|
76
|
+
subject = create_row_data(field1: "name",
|
77
|
+
field2: 2.8345,
|
78
|
+
field3: 3)
|
79
|
+
|
80
|
+
subject.stubs(:to_param).returns("1")
|
81
|
+
subject.stubs(:has_graph_data).returns(true)
|
82
|
+
[subject]
|
83
|
+
end
|
84
|
+
|
85
|
+
def create_row_data(values)
|
86
|
+
row_data = mock
|
87
|
+
values.each do |key,value|
|
88
|
+
row_data.stubs(key).returns(value)
|
89
|
+
end
|
90
|
+
row_data
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|