cubicle 0.1.30 → 0.1.31
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/CHANGELOG.rdoc +4 -0
- data/cubicle.gemspec +2 -2
- data/lib/cubicle/aggregation/aggregation_manager.rb +264 -260
- data/lib/cubicle/aggregation/dsl.rb +142 -135
- data/lib/cubicle/version.rb +1 -1
- data/test/cubicle/aggregation/ad_hoc_test.rb +1 -0
- data/test/cubicle/cubicle_query_test.rb +487 -485
- data/test/cubicles/defect_cubicle.rb +2 -0
- data/test/models/defect.rb +28 -8
- metadata +4 -4
@@ -1,136 +1,143 @@
|
|
1
|
-
module Cubicle
|
2
|
-
module Aggregation
|
3
|
-
module Dsl
|
4
|
-
|
5
|
-
def source_collection_name(collection_name = nil)
|
6
|
-
|
7
|
-
@source_collection
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
@
|
32
|
-
end
|
33
|
-
|
34
|
-
def
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
end
|
45
|
-
|
46
|
-
def
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
options
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
end
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
options
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
duration(*
|
85
|
-
end
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
options[
|
91
|
-
duration(*(args<<options))
|
92
|
-
end
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
end
|
100
|
-
alias
|
101
|
-
|
102
|
-
|
103
|
-
def
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
def
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
end
|
134
|
-
|
135
|
-
|
1
|
+
module Cubicle
|
2
|
+
module Aggregation
|
3
|
+
module Dsl
|
4
|
+
|
5
|
+
def source_collection_name(collection_name = nil, query={})
|
6
|
+
filter query unless query.blank?
|
7
|
+
return @source_collection = collection_name if collection_name
|
8
|
+
@source_collection ||= name.chomp("Cubicle").chomp("Cube").chomp("Aggregation").underscore.pluralize
|
9
|
+
end
|
10
|
+
alias source_collection_name= source_collection_name
|
11
|
+
alias source_collection source_collection_name
|
12
|
+
|
13
|
+
def target_collection_name(collection_name = nil)
|
14
|
+
return nil if transient?
|
15
|
+
return @target_name = collection_name if collection_name
|
16
|
+
@target_name ||= "cubicle.fact.#{name.blank? ? source_collection_name : name.underscore}"
|
17
|
+
end
|
18
|
+
alias target_collection_name= target_collection_name
|
19
|
+
|
20
|
+
def filter(query=nil)
|
21
|
+
return (@query ||= nil) unless query
|
22
|
+
@query = query
|
23
|
+
end
|
24
|
+
|
25
|
+
def dimension(*args)
|
26
|
+
dimensions << Cubicle::Dimension.new(*args)
|
27
|
+
dimensions[-1]
|
28
|
+
end
|
29
|
+
|
30
|
+
def named_expressions
|
31
|
+
return @named_expressions ||= OrderedHashWithIndifferentAccess.new
|
32
|
+
end
|
33
|
+
|
34
|
+
def dimensions(*args)
|
35
|
+
return (@dimensions ||= Cubicle::MemberList.new) if args.length < 1
|
36
|
+
args = args[0] if args.length == 1 && args[0].is_a?(Array)
|
37
|
+
args.each {|dim| dimension dim }
|
38
|
+
@dimensions
|
39
|
+
end
|
40
|
+
|
41
|
+
def measure(*args)
|
42
|
+
measures << Measure.new(*args)
|
43
|
+
measures[-1]
|
44
|
+
end
|
45
|
+
|
46
|
+
def measures(*args)
|
47
|
+
return (@measures ||= Cubicle::MemberList.new) if args.length < 1
|
48
|
+
args = args[0] if args.length == 1 && args[0].is_a?(Array)
|
49
|
+
args.each {|m| measure m}
|
50
|
+
@measures
|
51
|
+
end
|
52
|
+
|
53
|
+
def count(*args)
|
54
|
+
options = args.extract_options!
|
55
|
+
options[:aggregation_method] = :count
|
56
|
+
measure(*(args << options))
|
57
|
+
end
|
58
|
+
|
59
|
+
def average(*args)
|
60
|
+
options = args.extract_options!
|
61
|
+
options[:aggregation_method] = :average
|
62
|
+
measure(*(args << options))
|
63
|
+
#Averaged fields need a count of non-null values to properly calculate the average
|
64
|
+
args[0] = "#{args[0]}_count".to_sym
|
65
|
+
count *args
|
66
|
+
end
|
67
|
+
alias avg average
|
68
|
+
|
69
|
+
def sum(*args)
|
70
|
+
options = args.extract_options!
|
71
|
+
options[:aggregation_method] = :sum
|
72
|
+
measure(*(args << options))
|
73
|
+
end
|
74
|
+
|
75
|
+
def duration(*args)
|
76
|
+
options = args.extract_options!
|
77
|
+
options[:in] ||= durations_in
|
78
|
+
args << options
|
79
|
+
measures << (dur = Duration.new(*args))
|
80
|
+
count("#{dur.name}_count".to_sym, :expression=>dur.expression, :condition=>dur.condition) if dur.aggregation_method == :average
|
81
|
+
end
|
82
|
+
|
83
|
+
def average_duration(*args)
|
84
|
+
duration(*args)
|
85
|
+
end
|
86
|
+
alias avg_duration average_duration
|
87
|
+
|
88
|
+
def total_duration(*args)
|
89
|
+
options = args.extract_options!
|
90
|
+
options[:aggregation_method] = :sum
|
91
|
+
duration(*(args<<options))
|
92
|
+
end
|
93
|
+
|
94
|
+
def duration_since(*args)
|
95
|
+
options = args.extract_options!
|
96
|
+
ms1 = args.length > 1 ? args.delete_at(1) : args.shift
|
97
|
+
options[ms1] = :now
|
98
|
+
duration(*(args<<options))
|
99
|
+
end
|
100
|
+
alias age_since duration_since
|
101
|
+
alias elapsed duration_since
|
102
|
+
|
103
|
+
def durations_in(unit_of_time = nil)
|
104
|
+
return (@duration_unit ||= :seconds) unless unit_of_time
|
105
|
+
@duration_unit = unit_of_time.to_s.pluralize.to_sym
|
106
|
+
end
|
107
|
+
alias :duration_unit :durations_in
|
108
|
+
|
109
|
+
|
110
|
+
def ratio(member_name, numerator, denominator)
|
111
|
+
measures << Ratio.new(member_name, numerator, denominator)
|
112
|
+
end
|
113
|
+
|
114
|
+
def difference(member_name, left, right)
|
115
|
+
measures << Difference.new(member_name,left,right)
|
116
|
+
end
|
117
|
+
|
118
|
+
def bucketize(dimension_name, source_measure_name, bucket_range, options={}, &block)
|
119
|
+
source_measure = measures[source_measure_name]
|
120
|
+
raise "#{source_measure_name} does not appear to be a valid measure name. bucketize/categorize declarations must be placed AFTER any measures it uses have been defined." unless source_measure
|
121
|
+
dimensions << BucketizedDimension.new(dimension_name, source_measure, bucket_range, options, &block)
|
122
|
+
end
|
123
|
+
alias categorize bucketize
|
124
|
+
|
125
|
+
def aggregation(*member_list)
|
126
|
+
member_list = member_list[0] if member_list[0].is_a?(Array)
|
127
|
+
aggregations << member_list
|
128
|
+
end
|
129
|
+
|
130
|
+
def time_dimension(*args)
|
131
|
+
return (@time_dimension ||= nil) unless args.length > 0
|
132
|
+
@time_dimension = dimension(*args)
|
133
|
+
end
|
134
|
+
alias time_dimension= time_dimension
|
135
|
+
alias date time_dimension
|
136
|
+
alias time time_dimension
|
137
|
+
|
138
|
+
def define(name,expression)
|
139
|
+
named_expressions[name] = expression
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
136
143
|
end
|
data/lib/cubicle/version.rb
CHANGED
@@ -5,6 +5,7 @@ class AdHocTest < ActiveSupport::TestCase
|
|
5
5
|
setup do
|
6
6
|
Defect.create_test_data
|
7
7
|
@results = Cubicle::Aggregation::AdHoc.new("defects") do
|
8
|
+
filter :account_id=>"a1"
|
8
9
|
dimension :product, :field_name=>"product.name"
|
9
10
|
count :total, :field_name=>"defect_id"
|
10
11
|
end.query
|
@@ -1,486 +1,488 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
|
3
|
-
class CubicleQueryTest < ActiveSupport::TestCase
|
4
|
-
context "CubicleQuery#select" do
|
5
|
-
setup do
|
6
|
-
Defect.create_test_data
|
7
|
-
end
|
8
|
-
should "raise an exception when given a non-existent member" do
|
9
|
-
assert_raise RuntimeError do
|
10
|
-
DefectCubicle.query do
|
11
|
-
select :does_not_exist
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
should "query the underlying data source of cubicle rather than the persistent cache when :transient=>true" do
|
16
|
-
query = DefectCubicle.query :defer=>true do
|
17
|
-
transient!
|
18
|
-
select :product, :total_defects
|
19
|
-
end
|
20
|
-
query.execute()
|
21
|
-
assert_equal "defects", query.source_collection_name
|
22
|
-
end
|
23
|
-
should "query the persistent cache when transient=>false" do
|
24
|
-
query = DefectCubicle.query :defer=>true do
|
25
|
-
select :product, :total_defects
|
26
|
-
end
|
27
|
-
query.execute()
|
28
|
-
assert query.source_collection_name =~ /cubicle.aggregation.DefectCubicle._+/
|
29
|
-
end
|
30
|
-
should "Select dimensions in the by clause" do
|
31
|
-
query_results = DefectCubicle.query do
|
32
|
-
select :all_measures
|
33
|
-
by :product
|
34
|
-
end
|
35
|
-
assert_equal :product, query_results.name
|
36
|
-
assert_equal "Brush Fire Bottle Rockets", query_results.member_names[0]
|
37
|
-
end
|
38
|
-
should "Select aliased dimensions in the by clause" do
|
39
|
-
query_results = DefectCubicle.query do
|
40
|
-
select :all_measures
|
41
|
-
by :date
|
42
|
-
end
|
43
|
-
assert_equal :manufacture_date, query_results.name
|
44
|
-
assert_equal "2009-12-09", query_results.member_names[0]
|
45
|
-
end
|
46
|
-
context "when specifying a dimension" do
|
47
|
-
setup do
|
48
|
-
@results = DefectCubicle.query(:product, :all_measures)
|
49
|
-
end
|
50
|
-
should "return the specified subset of data, including all measures" do
|
51
|
-
assert_equal 3, @results.length
|
52
|
-
|
53
|
-
assert_equal "Brush Fire Bottle Rockets", @results[0]["product"]
|
54
|
-
assert_equal 1, @results[0]["total_defects"]
|
55
|
-
assert_equal 0, @results[0]["preventable_defects"]
|
56
|
-
assert_equal 0.43, @results[0]["total_cost"]
|
57
|
-
assert_equal 0.43, @results[0]["avg_cost"]
|
58
|
-
assert_equal 0, @results[0]["preventable_pct"]
|
59
|
-
end
|
60
|
-
|
61
|
-
end
|
62
|
-
context "when specifying a dimension using an alias" do
|
63
|
-
setup do
|
64
|
-
@results = DefectCubicle.query(:date, :all_measures)
|
65
|
-
end
|
66
|
-
should "return the specified subset of data, including all measures" do
|
67
|
-
assert_equal 4, @results.length
|
68
|
-
assert_equal "2009-12-09", @results[0]["date"]
|
69
|
-
assert_equal 1, @results[0]["total_defects"]
|
70
|
-
assert_equal 0, @results[0]["preventable_defects"]
|
71
|
-
assert_equal 0.43, @results[0]["total_cost"]
|
72
|
-
assert_equal 0.43, @results[0]["avg_cost"]
|
73
|
-
assert_equal 0, @results[0]["preventable_pct"]
|
74
|
-
end
|
75
|
-
end
|
76
|
-
context "when specifying a dimension from a transient query" do
|
77
|
-
setup do
|
78
|
-
#DefectCubicle.transient!
|
79
|
-
@results = DefectCubicle.query do |q|
|
80
|
-
q.transient!
|
81
|
-
q.select :product, :all_measures
|
82
|
-
end
|
83
|
-
end
|
84
|
-
should "return the specified subset of data, including all measures" do
|
85
|
-
assert_equal 3, @results.length
|
86
|
-
|
87
|
-
assert_equal "Brush Fire Bottle Rockets", @results[0]["product"]
|
88
|
-
assert_equal 1, @results[0]["total_defects"]
|
89
|
-
assert_equal 0, @results[0]["preventable_defects"]
|
90
|
-
assert_equal 0.43, @results[0]["total_cost"]
|
91
|
-
assert_equal 0.43, @results[0]["avg_cost"]
|
92
|
-
assert_equal 0, @results[0]["preventable_pct"]
|
93
|
-
end
|
94
|
-
|
95
|
-
end
|
96
|
-
context "when specifying a dimensional filter on a transient query" do
|
97
|
-
setup do
|
98
|
-
@results = DefectCubicle.query do
|
99
|
-
transient!
|
100
|
-
select :product, :all_measures
|
101
|
-
where :product=>"Sad Day Moonshine"
|
102
|
-
end
|
103
|
-
end
|
104
|
-
should "return a filtered subset of data" do
|
105
|
-
assert_equal 1, @results.length
|
106
|
-
assert_equal "Sad Day Moonshine", @results[0]["product"]
|
107
|
-
assert_equal 3, @results[0]["total_defects"]
|
108
|
-
assert_equal 2, @results[0]["preventable_defects"]
|
109
|
-
assert_equal 2, @results[0]["conditioned_preventable"]
|
110
|
-
assert_equal 21.63, @results[0]["total_cost"]
|
111
|
-
assert_equal 21.63/3, @results[0]["avg_cost"]
|
112
|
-
assert_equal 2/3.0, @results[0]["preventable_pct"]
|
113
|
-
end
|
114
|
-
|
115
|
-
end
|
116
|
-
context "when specifying a dimensional filter on a transient query using an alias" do
|
117
|
-
setup do
|
118
|
-
#DefectCubicle.transient!
|
119
|
-
@results = DefectCubicle.query do
|
120
|
-
transient!
|
121
|
-
select :manufacture_date, :all_measures
|
122
|
-
|
123
|
-
where :date=>"2009-12-09"
|
124
|
-
end
|
125
|
-
end
|
126
|
-
should "return a filtered subset of data" do
|
127
|
-
assert_equal 1, @results.length
|
128
|
-
assert_equal "2009-12-09", @results[0]["manufacture_date"]
|
129
|
-
assert_equal 1, @results[0]["total_defects"]
|
130
|
-
assert_equal 0, @results[0]["preventable_defects"]
|
131
|
-
assert_equal 0.43, @results[0]["total_cost"]
|
132
|
-
assert_equal 0.43, @results[0]["avg_cost"]
|
133
|
-
assert_equal 0, @results[0]["preventable_pct"]
|
134
|
-
end
|
135
|
-
|
136
|
-
end
|
137
|
-
context "when specifying a dimensional filter on a non-transient query" do
|
138
|
-
setup do
|
139
|
-
@results = DefectCubicle.query do
|
140
|
-
select :product, :all_measures
|
141
|
-
where :product=>"Sad Day Moonshine"
|
142
|
-
end
|
143
|
-
end
|
144
|
-
should "return a filtered subset of data" do
|
145
|
-
assert_equal 1, @results.length
|
146
|
-
assert_equal "Sad Day Moonshine", @results[0]["product"]
|
147
|
-
assert_equal 3, @results[0]["total_defects"]
|
148
|
-
assert_equal 2, @results[0]["preventable_defects"]
|
149
|
-
assert_equal 2, @results[0]["conditioned_preventable"]
|
150
|
-
assert_in_delta 21.63, @results[0]["total_cost"],0.0001
|
151
|
-
assert_in_delta 21.63/3, @results[0]["avg_cost"],0.0001
|
152
|
-
assert_in_delta 2/3.0, @results[0]["preventable_pct"],0.0001
|
153
|
-
end
|
154
|
-
|
155
|
-
end
|
156
|
-
context "when specifying a dimensional filter on a non-transient query using an alias" do
|
157
|
-
setup do
|
158
|
-
@results = DefectCubicle.query do
|
159
|
-
select :date, :all_measures
|
160
|
-
where :date=>"2009-12-09"
|
161
|
-
end
|
162
|
-
end
|
163
|
-
should "return a filtered subset of data" do
|
164
|
-
assert_equal 1, @results.length
|
165
|
-
assert_equal "2009-12-09", @results[0]["manufacture_date"]
|
166
|
-
assert_equal "2009-12-09", @results[0]["date"]
|
167
|
-
assert_equal 1, @results[0]["total_defects"]
|
168
|
-
assert_equal 0, @results[0]["preventable_defects"]
|
169
|
-
assert_equal 0.43, @results[0]["total_cost"]
|
170
|
-
assert_equal 0.43, @results[0]["avg_cost"]
|
171
|
-
assert_equal 0, @results[0]["preventable_pct"]
|
172
|
-
end
|
173
|
-
|
174
|
-
end
|
175
|
-
context "when specifying a dimensional filter on a non-transient query using $where" do
|
176
|
-
setup do
|
177
|
-
@results = DefectCubicle.query do
|
178
|
-
select :product, :all_measures
|
179
|
-
where "$where"=>"this._id.product=='Sad Day Moonshine'"
|
180
|
-
end
|
181
|
-
end
|
182
|
-
should "return a filtered subset of data" do
|
183
|
-
assert_equal 1, @results.length
|
184
|
-
assert_equal "Sad Day Moonshine", @results[0]["product"]
|
185
|
-
assert_equal 3, @results[0]["total_defects"]
|
186
|
-
assert_equal 2, @results[0]["preventable_defects"]
|
187
|
-
assert_equal 2, @results[0]["conditioned_preventable"]
|
188
|
-
assert_in_delta 21.63, @results[0]["total_cost"],0.0001
|
189
|
-
assert_in_delta 21.63/3, @results[0]["avg_cost"],0.0001
|
190
|
-
assert_equal 2/3.0, @results[0]["preventable_pct"]
|
191
|
-
end
|
192
|
-
|
193
|
-
end
|
194
|
-
context "when specifying a dimensional filter on a transient query using $where" do
|
195
|
-
setup do
|
196
|
-
@results = DefectCubicle.query do
|
197
|
-
transient!
|
198
|
-
select :product, :all_measures
|
199
|
-
where "$where"=>"this.product.name=='Sad Day Moonshine'"
|
200
|
-
end
|
201
|
-
end
|
202
|
-
should "return a filtered subset of data" do
|
203
|
-
assert_equal 1, @results.length
|
204
|
-
assert_equal "Sad Day Moonshine", @results[0]["product"]
|
205
|
-
assert_equal 3, @results[0]["total_defects"]
|
206
|
-
assert_equal 2, @results[0]["preventable_defects"]
|
207
|
-
assert_equal 2, @results[0]["conditioned_preventable"]
|
208
|
-
assert_equal 21.63, @results[0]["total_cost"]
|
209
|
-
assert_equal 21.63/3, @results[0]["avg_cost"]
|
210
|
-
assert_equal 2/3.0, @results[0]["preventable_pct"]
|
211
|
-
end
|
212
|
-
|
213
|
-
end
|
214
|
-
context "when specifying a dimensional filter for an expression based dimension on a transient query" do
|
215
|
-
setup do
|
216
|
-
@results = DefectCubicle.query do
|
217
|
-
transient!
|
218
|
-
select :product,:all_measures
|
219
|
-
where :month=>"2010-01"
|
220
|
-
end
|
221
|
-
end
|
222
|
-
should "return a filtered subset of data" do
|
223
|
-
|
224
|
-
assert_equal
|
225
|
-
assert_equal "
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
assert_equal
|
239
|
-
assert_equal "
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
assert_equal
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
assert_equal
|
279
|
-
assert_equal "
|
280
|
-
assert_equal "
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
assert_equal
|
294
|
-
assert_equal "
|
295
|
-
assert_equal "
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
assert_equal
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
assert_equal
|
418
|
-
assert_equal
|
419
|
-
assert_equal
|
420
|
-
assert_equal
|
421
|
-
|
422
|
-
|
423
|
-
assert_in_delta
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
assert_equal
|
434
|
-
assert_equal "
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
assert_equal
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
assert_equal
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class CubicleQueryTest < ActiveSupport::TestCase
|
4
|
+
context "CubicleQuery#select" do
|
5
|
+
setup do
|
6
|
+
Defect.create_test_data
|
7
|
+
end
|
8
|
+
should "raise an exception when given a non-existent member" do
|
9
|
+
assert_raise RuntimeError do
|
10
|
+
DefectCubicle.query do
|
11
|
+
select :does_not_exist
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
should "query the underlying data source of cubicle rather than the persistent cache when :transient=>true" do
|
16
|
+
query = DefectCubicle.query :defer=>true do
|
17
|
+
transient!
|
18
|
+
select :product, :total_defects
|
19
|
+
end
|
20
|
+
query.execute()
|
21
|
+
assert_equal "defects", query.source_collection_name
|
22
|
+
end
|
23
|
+
should "query the persistent cache when transient=>false" do
|
24
|
+
query = DefectCubicle.query :defer=>true do
|
25
|
+
select :product, :total_defects
|
26
|
+
end
|
27
|
+
query.execute()
|
28
|
+
assert query.source_collection_name =~ /cubicle.aggregation.DefectCubicle._+/
|
29
|
+
end
|
30
|
+
should "Select dimensions in the by clause" do
|
31
|
+
query_results = DefectCubicle.query do
|
32
|
+
select :all_measures
|
33
|
+
by :product
|
34
|
+
end
|
35
|
+
assert_equal :product, query_results.name
|
36
|
+
assert_equal "Brush Fire Bottle Rockets", query_results.member_names[0]
|
37
|
+
end
|
38
|
+
should "Select aliased dimensions in the by clause" do
|
39
|
+
query_results = DefectCubicle.query do
|
40
|
+
select :all_measures
|
41
|
+
by :date
|
42
|
+
end
|
43
|
+
assert_equal :manufacture_date, query_results.name
|
44
|
+
assert_equal "2009-12-09", query_results.member_names[0]
|
45
|
+
end
|
46
|
+
context "when specifying a dimension" do
|
47
|
+
setup do
|
48
|
+
@results = DefectCubicle.query(:product, :all_measures)
|
49
|
+
end
|
50
|
+
should "return the specified subset of data, including all measures" do
|
51
|
+
assert_equal 3, @results.length
|
52
|
+
|
53
|
+
assert_equal "Brush Fire Bottle Rockets", @results[0]["product"]
|
54
|
+
assert_equal 1, @results[0]["total_defects"]
|
55
|
+
assert_equal 0, @results[0]["preventable_defects"]
|
56
|
+
assert_equal 0.43, @results[0]["total_cost"]
|
57
|
+
assert_equal 0.43, @results[0]["avg_cost"]
|
58
|
+
assert_equal 0, @results[0]["preventable_pct"]
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
context "when specifying a dimension using an alias" do
|
63
|
+
setup do
|
64
|
+
@results = DefectCubicle.query(:date, :all_measures)
|
65
|
+
end
|
66
|
+
should "return the specified subset of data, including all measures" do
|
67
|
+
assert_equal 4, @results.length
|
68
|
+
assert_equal "2009-12-09", @results[0]["date"]
|
69
|
+
assert_equal 1, @results[0]["total_defects"]
|
70
|
+
assert_equal 0, @results[0]["preventable_defects"]
|
71
|
+
assert_equal 0.43, @results[0]["total_cost"]
|
72
|
+
assert_equal 0.43, @results[0]["avg_cost"]
|
73
|
+
assert_equal 0, @results[0]["preventable_pct"]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
context "when specifying a dimension from a transient query" do
|
77
|
+
setup do
|
78
|
+
#DefectCubicle.transient!
|
79
|
+
@results = DefectCubicle.query do |q|
|
80
|
+
q.transient!
|
81
|
+
q.select :product, :all_measures
|
82
|
+
end
|
83
|
+
end
|
84
|
+
should "return the specified subset of data, including all measures" do
|
85
|
+
assert_equal 3, @results.length
|
86
|
+
|
87
|
+
assert_equal "Brush Fire Bottle Rockets", @results[0]["product"]
|
88
|
+
assert_equal 1, @results[0]["total_defects"]
|
89
|
+
assert_equal 0, @results[0]["preventable_defects"]
|
90
|
+
assert_equal 0.43, @results[0]["total_cost"]
|
91
|
+
assert_equal 0.43, @results[0]["avg_cost"]
|
92
|
+
assert_equal 0, @results[0]["preventable_pct"]
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
context "when specifying a dimensional filter on a transient query" do
|
97
|
+
setup do
|
98
|
+
@results = DefectCubicle.query do
|
99
|
+
transient!
|
100
|
+
select :product, :all_measures
|
101
|
+
where :product=>"Sad Day Moonshine"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
should "return a filtered subset of data" do
|
105
|
+
assert_equal 1, @results.length
|
106
|
+
assert_equal "Sad Day Moonshine", @results[0]["product"]
|
107
|
+
assert_equal 3, @results[0]["total_defects"]
|
108
|
+
assert_equal 2, @results[0]["preventable_defects"]
|
109
|
+
assert_equal 2, @results[0]["conditioned_preventable"]
|
110
|
+
assert_equal 21.63, @results[0]["total_cost"]
|
111
|
+
assert_equal 21.63/3, @results[0]["avg_cost"]
|
112
|
+
assert_equal 2/3.0, @results[0]["preventable_pct"]
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
context "when specifying a dimensional filter on a transient query using an alias" do
|
117
|
+
setup do
|
118
|
+
#DefectCubicle.transient!
|
119
|
+
@results = DefectCubicle.query do
|
120
|
+
transient!
|
121
|
+
select :manufacture_date, :all_measures
|
122
|
+
|
123
|
+
where :date=>"2009-12-09"
|
124
|
+
end
|
125
|
+
end
|
126
|
+
should "return a filtered subset of data" do
|
127
|
+
assert_equal 1, @results.length
|
128
|
+
assert_equal "2009-12-09", @results[0]["manufacture_date"]
|
129
|
+
assert_equal 1, @results[0]["total_defects"]
|
130
|
+
assert_equal 0, @results[0]["preventable_defects"]
|
131
|
+
assert_equal 0.43, @results[0]["total_cost"]
|
132
|
+
assert_equal 0.43, @results[0]["avg_cost"]
|
133
|
+
assert_equal 0, @results[0]["preventable_pct"]
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
context "when specifying a dimensional filter on a non-transient query" do
|
138
|
+
setup do
|
139
|
+
@results = DefectCubicle.query do
|
140
|
+
select :product, :all_measures
|
141
|
+
where :product=>"Sad Day Moonshine"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
should "return a filtered subset of data" do
|
145
|
+
assert_equal 1, @results.length
|
146
|
+
assert_equal "Sad Day Moonshine", @results[0]["product"]
|
147
|
+
assert_equal 3, @results[0]["total_defects"]
|
148
|
+
assert_equal 2, @results[0]["preventable_defects"]
|
149
|
+
assert_equal 2, @results[0]["conditioned_preventable"]
|
150
|
+
assert_in_delta 21.63, @results[0]["total_cost"],0.0001
|
151
|
+
assert_in_delta 21.63/3, @results[0]["avg_cost"],0.0001
|
152
|
+
assert_in_delta 2/3.0, @results[0]["preventable_pct"],0.0001
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
context "when specifying a dimensional filter on a non-transient query using an alias" do
|
157
|
+
setup do
|
158
|
+
@results = DefectCubicle.query do
|
159
|
+
select :date, :all_measures
|
160
|
+
where :date=>"2009-12-09"
|
161
|
+
end
|
162
|
+
end
|
163
|
+
should "return a filtered subset of data" do
|
164
|
+
assert_equal 1, @results.length
|
165
|
+
assert_equal "2009-12-09", @results[0]["manufacture_date"]
|
166
|
+
assert_equal "2009-12-09", @results[0]["date"]
|
167
|
+
assert_equal 1, @results[0]["total_defects"]
|
168
|
+
assert_equal 0, @results[0]["preventable_defects"]
|
169
|
+
assert_equal 0.43, @results[0]["total_cost"]
|
170
|
+
assert_equal 0.43, @results[0]["avg_cost"]
|
171
|
+
assert_equal 0, @results[0]["preventable_pct"]
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
context "when specifying a dimensional filter on a non-transient query using $where" do
|
176
|
+
setup do
|
177
|
+
@results = DefectCubicle.query do
|
178
|
+
select :product, :all_measures
|
179
|
+
where "$where"=>"this._id.product=='Sad Day Moonshine'"
|
180
|
+
end
|
181
|
+
end
|
182
|
+
should "return a filtered subset of data" do
|
183
|
+
assert_equal 1, @results.length
|
184
|
+
assert_equal "Sad Day Moonshine", @results[0]["product"]
|
185
|
+
assert_equal 3, @results[0]["total_defects"]
|
186
|
+
assert_equal 2, @results[0]["preventable_defects"]
|
187
|
+
assert_equal 2, @results[0]["conditioned_preventable"]
|
188
|
+
assert_in_delta 21.63, @results[0]["total_cost"],0.0001
|
189
|
+
assert_in_delta 21.63/3, @results[0]["avg_cost"],0.0001
|
190
|
+
assert_equal 2/3.0, @results[0]["preventable_pct"]
|
191
|
+
end
|
192
|
+
|
193
|
+
end
|
194
|
+
context "when specifying a dimensional filter on a transient query using $where" do
|
195
|
+
setup do
|
196
|
+
@results = DefectCubicle.query do
|
197
|
+
transient!
|
198
|
+
select :product, :all_measures
|
199
|
+
where "$where"=>"this.product.name=='Sad Day Moonshine'"
|
200
|
+
end
|
201
|
+
end
|
202
|
+
should "return a filtered subset of data" do
|
203
|
+
assert_equal 1, @results.length
|
204
|
+
assert_equal "Sad Day Moonshine", @results[0]["product"]
|
205
|
+
assert_equal 3, @results[0]["total_defects"]
|
206
|
+
assert_equal 2, @results[0]["preventable_defects"]
|
207
|
+
assert_equal 2, @results[0]["conditioned_preventable"]
|
208
|
+
assert_equal 21.63, @results[0]["total_cost"]
|
209
|
+
assert_equal 21.63/3, @results[0]["avg_cost"]
|
210
|
+
assert_equal 2/3.0, @results[0]["preventable_pct"]
|
211
|
+
end
|
212
|
+
|
213
|
+
end
|
214
|
+
context "when specifying a dimensional filter for an expression based dimension on a transient query" do
|
215
|
+
setup do
|
216
|
+
@results = DefectCubicle.query do
|
217
|
+
transient!
|
218
|
+
select :product,:all_measures
|
219
|
+
where :month=>"2010-01"
|
220
|
+
end
|
221
|
+
end
|
222
|
+
should "return a filtered subset of data" do
|
223
|
+
puts @results.inspect
|
224
|
+
assert_equal 2, @results.length
|
225
|
+
assert_equal "Evil's Pickling Spice", @results[0]["product"]
|
226
|
+
assert_equal "Sad Day Moonshine", @results[1]["product"]
|
227
|
+
end
|
228
|
+
end
|
229
|
+
context "when specifying a special dimensional filter for an expression based dimension on a transient query" do
|
230
|
+
setup do
|
231
|
+
@results = DefectCubicle.query do
|
232
|
+
transient!
|
233
|
+
select :product,:all_measures
|
234
|
+
where :month=>{"$ne"=>"2010-01"}
|
235
|
+
end
|
236
|
+
end
|
237
|
+
should "return a filtered subset of data" do
|
238
|
+
assert_equal 2, @results.length
|
239
|
+
assert_equal "Brush Fire Bottle Rockets", @results[0]["product"]
|
240
|
+
assert_equal "Sad Day Moonshine", @results[1]["product"]
|
241
|
+
end
|
242
|
+
end
|
243
|
+
context "when specifying several special dimensional filters for an expression based dimension on a transient query" do
|
244
|
+
setup do
|
245
|
+
@results = DefectCubicle.query do
|
246
|
+
transient!
|
247
|
+
select :product,:all_measures
|
248
|
+
where :month=>{"$gt"=>"2010-01", "$lte"=>"2010-02"}
|
249
|
+
end
|
250
|
+
end
|
251
|
+
should "return a filtered subset of data" do
|
252
|
+
assert_equal 1, @results.length
|
253
|
+
assert_equal "Sad Day Moonshine", @results[0]["product"]
|
254
|
+
end
|
255
|
+
end
|
256
|
+
context "when specifying a special dimensional filter for an expression based bucketized dimension on a transient query" do
|
257
|
+
setup do
|
258
|
+
@results = DefectCubicle.query do
|
259
|
+
transient!
|
260
|
+
select :product, :all_measures
|
261
|
+
where :avg_cost_category=>{"$ne"=>"< $1"}
|
262
|
+
end
|
263
|
+
end
|
264
|
+
should "return a filtered subset of data" do
|
265
|
+
puts @results.inspect
|
266
|
+
assert_equal 1, @results.length
|
267
|
+
end
|
268
|
+
end
|
269
|
+
context "when specifying a sort order on a transient query" do
|
270
|
+
setup do
|
271
|
+
@results = DefectCubicle.query do
|
272
|
+
transient!
|
273
|
+
select :product,:all_measures
|
274
|
+
order_by [:product, :desc]
|
275
|
+
end
|
276
|
+
end
|
277
|
+
should "return sorted data" do
|
278
|
+
assert_equal 3, @results.length
|
279
|
+
assert_equal "Sad Day Moonshine", @results[0]["product"]
|
280
|
+
assert_equal "Evil's Pickling Spice", @results[1]["product"]
|
281
|
+
assert_equal "Brush Fire Bottle Rockets", @results[2]["product"]
|
282
|
+
end
|
283
|
+
|
284
|
+
end
|
285
|
+
context "when specifying a sort order on a non transient query" do
|
286
|
+
setup do
|
287
|
+
@results = DefectCubicle.query do
|
288
|
+
select :product,:all_measures
|
289
|
+
order_by [:product, :desc]
|
290
|
+
end
|
291
|
+
end
|
292
|
+
should "return sorted data" do
|
293
|
+
assert_equal 3, @results.length
|
294
|
+
assert_equal "Sad Day Moonshine", @results[0]["product"]
|
295
|
+
assert_equal "Evil's Pickling Spice", @results[1]["product"]
|
296
|
+
assert_equal "Brush Fire Bottle Rockets", @results[2]["product"]
|
297
|
+
end
|
298
|
+
|
299
|
+
end
|
300
|
+
context "when requesting YTD" do
|
301
|
+
setup do
|
302
|
+
Time.now = "2010-01-04"
|
303
|
+
@results = DefectCubicle.query do
|
304
|
+
select :date, :all_measures
|
305
|
+
year_to_date
|
306
|
+
end
|
307
|
+
end
|
308
|
+
should "present YTD data based on Time.now" do
|
309
|
+
assert_equal 1, @results.length
|
310
|
+
assert_in_delta 18.69, @results[0]["total_cost"],0.0001
|
311
|
+
end
|
312
|
+
end
|
313
|
+
context "when requesting MTD in a non-transient query do" do
|
314
|
+
setup do
|
315
|
+
Time.now = "2010-01-05"
|
316
|
+
@results = DefectCubicle.query do
|
317
|
+
select :month, :all_measures
|
318
|
+
month_to_date
|
319
|
+
end
|
320
|
+
end
|
321
|
+
should "present MTD data based on Time.now" do
|
322
|
+
assert_equal 1, @results.length
|
323
|
+
assert_in_delta 18.71, @results[0]["total_cost"],0.0001
|
324
|
+
end
|
325
|
+
end
|
326
|
+
context "when requesting MTD in a transient query do" do
|
327
|
+
setup do
|
328
|
+
Time.now = "2010-01-05"
|
329
|
+
@results = DefectCubicle.query do
|
330
|
+
transient!
|
331
|
+
select :month, :all_measures
|
332
|
+
month_to_date
|
333
|
+
end
|
334
|
+
end
|
335
|
+
should "present MTD data based on Time.now" do
|
336
|
+
puts @results.inspect
|
337
|
+
assert_equal 1, @results.length
|
338
|
+
assert_in_delta 18.71, @results[0]["total_cost"],0.0001
|
339
|
+
end
|
340
|
+
end
|
341
|
+
context "when requesting for_the_last_complete 1.months" do
|
342
|
+
setup do
|
343
|
+
Time.now = "2010-01-30"
|
344
|
+
@results = DefectCubicle.query do
|
345
|
+
select :month, :all_measures
|
346
|
+
for_the_last_complete :month
|
347
|
+
end
|
348
|
+
end
|
349
|
+
should "present data for the previous month" do
|
350
|
+
assert_equal 1, @results.length
|
351
|
+
assert_equal 0.43, @results[0]["total_cost"]
|
352
|
+
end
|
353
|
+
end
|
354
|
+
context "when requesting an exclusive date range" do
|
355
|
+
setup do
|
356
|
+
Time.now = "2010-01-30"
|
357
|
+
@results = DefectCubicle.query do
|
358
|
+
select :month, :all_measures
|
359
|
+
for_the_last_complete 12.months
|
360
|
+
by :month
|
361
|
+
end
|
362
|
+
end
|
363
|
+
should "provide an entry for each month, even months without data" do
|
364
|
+
assert_equal [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.0], @results.flatten(:total_defects)
|
365
|
+
assert_equal "2009-01", @results.keys[0]
|
366
|
+
assert_equal "2009-12", @results.keys[-1]
|
367
|
+
end
|
368
|
+
end
|
369
|
+
context "when requesting a date range with no results" do
|
370
|
+
setup do
|
371
|
+
Time.now = "2020-01-01"
|
372
|
+
@results = DefectCubicle.query do
|
373
|
+
select :month, :all_measures
|
374
|
+
for_the_last_complete 12.months
|
375
|
+
by :month
|
376
|
+
end
|
377
|
+
end
|
378
|
+
should "provide an empty entry for each month" do
|
379
|
+
assert_equal 12, @results.count
|
380
|
+
assert_equal [0,0,0,0,0,0,0,0,0,0,0,0], @results.flatten(:total_defects)
|
381
|
+
end
|
382
|
+
end
|
383
|
+
context "Date filters against native Time types" do
|
384
|
+
setup do
|
385
|
+
Time.now = "2010-01-30"
|
386
|
+
Cubicle::DateTime.db_time_format = :native
|
387
|
+
@results = DefectCubicle.query do
|
388
|
+
time_dimension :manufacture_time
|
389
|
+
select :month, :all_measures
|
390
|
+
for_the_last_complete :month
|
391
|
+
end
|
392
|
+
end
|
393
|
+
should "dance like a butterfly and sting like a bee" do
|
394
|
+
assert_equal 1, @results.length
|
395
|
+
assert_equal 0.43, @results[0]["total_cost"]
|
396
|
+
end
|
397
|
+
teardown do
|
398
|
+
Cubicle::DateTime.db_time_format = :iso8601
|
399
|
+
end
|
400
|
+
end
|
401
|
+
context "when a query level alias has been specified" do
|
402
|
+
should "respect the alias in the by clause" do
|
403
|
+
query_results = DefectCubicle.query do
|
404
|
+
alias_member :date=>:my_crazy_date
|
405
|
+
select :all_measures
|
406
|
+
by :my_crazy_date
|
407
|
+
end
|
408
|
+
assert_equal :manufacture_date, query_results.name
|
409
|
+
assert_equal "2009-12-09", query_results.member_names[0]
|
410
|
+
end
|
411
|
+
should "respect the alias in the where clause" do
|
412
|
+
results = DefectCubicle.query do
|
413
|
+
alias_member :product=>:my_crazy_product
|
414
|
+
select :product, :all_measures
|
415
|
+
where :my_crazy_product=>"Sad Day Moonshine"
|
416
|
+
end
|
417
|
+
assert_equal 1, results.length
|
418
|
+
assert_equal "Sad Day Moonshine", results[0]["product"]
|
419
|
+
assert_equal "Sad Day Moonshine", results[0]["my_crazy_product"]
|
420
|
+
assert_equal 3, results[0]["total_defects"]
|
421
|
+
assert_equal 2, results[0]["preventable_defects"]
|
422
|
+
assert_equal 2, results[0]["conditioned_preventable"]
|
423
|
+
assert_in_delta 21.63, results[0]["total_cost"],0.0001
|
424
|
+
assert_in_delta 21.63/3, results[0]["avg_cost"],0.0001
|
425
|
+
assert_in_delta 2/3.0, results[0]["preventable_pct"],0.0001
|
426
|
+
end
|
427
|
+
should "respect the alias in the order by clause" do
|
428
|
+
results = DefectCubicle.query do
|
429
|
+
alias_member :product=>:my_crazy_product
|
430
|
+
select :product,:all_measures
|
431
|
+
order_by [:my_crazy_product, :desc]
|
432
|
+
end
|
433
|
+
assert_equal 3, results.length
|
434
|
+
assert_equal "Sad Day Moonshine", results[0]["product"]
|
435
|
+
assert_equal "Evil's Pickling Spice", results[1]["product"]
|
436
|
+
assert_equal "Brush Fire Bottle Rockets", results[2]["product"]
|
437
|
+
end
|
438
|
+
should "calculate distinct counts properly" do
|
439
|
+
results = DefectCubicle.query do
|
440
|
+
select :year, :distinct_products
|
441
|
+
where :year=>"2010"
|
442
|
+
end
|
443
|
+
puts results.inspect
|
444
|
+
assert_equal 1, results.length
|
445
|
+
assert_equal 2, results[0]["distinct_products"]
|
446
|
+
end
|
447
|
+
end
|
448
|
+
context "Aggregation level 'define' calls" do
|
449
|
+
should "override the default of Time.now" do
|
450
|
+
results = DefectCubicle.query do
|
451
|
+
transient!
|
452
|
+
select :year, :defects_this_year
|
453
|
+
end
|
454
|
+
puts results.inspect
|
455
|
+
assert_equal 2, results.length
|
456
|
+
assert_equal 0, results[0].defects_this_year
|
457
|
+
assert_equal 4, results[1].defects_this_year
|
458
|
+
end
|
459
|
+
end
|
460
|
+
context "Query level 'define' calls" do
|
461
|
+
should "override the defaults" do
|
462
|
+
results = DefectCubicle.query do
|
463
|
+
transient!
|
464
|
+
define :time_now, "2009-01-01".to_time
|
465
|
+
|
466
|
+
select :year, :defects_this_year
|
467
|
+
end
|
468
|
+
puts results.inspect
|
469
|
+
assert_equal 2, results.length
|
470
|
+
assert_equal 1, results[0].defects_this_year
|
471
|
+
assert_equal 0, results[1].defects_this_year
|
472
|
+
end
|
473
|
+
end
|
474
|
+
context "Grouping by day" do
|
475
|
+
should "not cause the system to hang" do
|
476
|
+
Time.now = "2010-01-01"
|
477
|
+
results = DefectCubicle.query do
|
478
|
+
select :defects_this_year
|
479
|
+
by :date
|
480
|
+
for_the_last 5.days
|
481
|
+
end
|
482
|
+
puts results.inspect
|
483
|
+
assert_not_nil results
|
484
|
+
end
|
485
|
+
|
486
|
+
end
|
487
|
+
end
|
486
488
|
end
|