sleek 0.0.1 → 0.0.2
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/README.md +95 -20
- data/lib/sleek.rb +4 -2
- data/lib/sleek/core_ext/range.rb +6 -7
- data/lib/sleek/event.rb +4 -1
- data/lib/sleek/filter.rb +11 -0
- data/lib/sleek/group_by_criteria.rb +144 -0
- data/lib/sleek/interval.rb +21 -20
- data/lib/sleek/{base.rb → namespace.rb} +13 -8
- data/lib/sleek/queries.rb +0 -1
- data/lib/sleek/queries/average.rb +1 -1
- data/lib/sleek/queries/count_unique.rb +1 -1
- data/lib/sleek/queries/maximum.rb +1 -1
- data/lib/sleek/queries/minimum.rb +1 -1
- data/lib/sleek/queries/query.rb +70 -37
- data/lib/sleek/queries/sum.rb +1 -1
- data/lib/sleek/query_collection.rb +3 -3
- data/lib/sleek/query_command.rb +71 -0
- data/lib/sleek/timeframe.rb +45 -52
- data/lib/sleek/version.rb +1 -1
- data/spec/lib/sleek/event_spec.rb +3 -3
- data/spec/lib/sleek/filter_spec.rb +3 -3
- data/spec/lib/sleek/group_by_criteria_spec.rb +139 -0
- data/spec/lib/sleek/interval_spec.rb +6 -5
- data/spec/lib/sleek/{base_spec.rb → namespace_spec.rb} +15 -8
- data/spec/lib/sleek/queries/average_spec.rb +1 -1
- data/spec/lib/sleek/queries/count_spec.rb +1 -1
- data/spec/lib/sleek/queries/count_unique_spec.rb +1 -1
- data/spec/lib/sleek/queries/maximum_spec.rb +1 -1
- data/spec/lib/sleek/queries/minimum_spec.rb +1 -1
- data/spec/lib/sleek/queries/query_spec.rb +58 -84
- data/spec/lib/sleek/queries/sum_spec.rb +1 -1
- data/spec/lib/sleek/query_collection_spec.rb +11 -9
- data/spec/lib/sleek/query_command_spec.rb +171 -0
- data/spec/lib/sleek/timeframe_spec.rb +70 -36
- data/spec/lib/sleek_spec.rb +2 -2
- metadata +11 -8
- data/lib/sleek/queries/targetable.rb +0 -13
- data/spec/lib/sleek/queries/targetable_spec.rb +0 -29
data/lib/sleek/version.rb
CHANGED
@@ -3,18 +3,18 @@ require 'spec_helper'
|
|
3
3
|
describe Sleek::Event do
|
4
4
|
describe ".create_with_namespace" do
|
5
5
|
it "creates event record" do
|
6
|
-
expect {
|
6
|
+
expect { described_class.create_with_namespace(:default, "signups", { name: 'John Doe', email: 'john@doe.com' }) }.to change { Sleek::Event.count }.by(1)
|
7
7
|
end
|
8
8
|
|
9
9
|
it "sets namespace and bucket" do
|
10
|
-
evt =
|
10
|
+
evt = described_class.create_with_namespace(:default, "signups", {})
|
11
11
|
expect(evt.namespace).to eq :default
|
12
12
|
expect(evt.bucket).to eq "signups"
|
13
13
|
end
|
14
14
|
|
15
15
|
it "sets the data" do
|
16
16
|
data = { name: 'John Doe', email: 'j@d.com' }
|
17
|
-
evt =
|
17
|
+
evt = described_class.create_with_namespace(:ns, "buc", data)
|
18
18
|
expect(evt.data).to eq data
|
19
19
|
end
|
20
20
|
end
|
@@ -4,20 +4,20 @@ describe Sleek::Filter do
|
|
4
4
|
describe "#initialize" do
|
5
5
|
context "when valid operator is passed" do
|
6
6
|
it "does not raise an exception" do
|
7
|
-
expect {
|
7
|
+
expect { described_class.new(:test, :eq, 1) }.to_not raise_exception ArgumentError
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
11
|
context "when invalid operator is passed" do
|
12
12
|
it "raises an exception" do
|
13
|
-
expect {
|
13
|
+
expect { described_class.new(:test, :lol, 1) }.to raise_exception ArgumentError, "unsupported operator - lol"
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
18
|
describe "#apply" do
|
19
19
|
it "appleis the filter to the criteria" do
|
20
|
-
filter =
|
20
|
+
filter = described_class.new(:test, :eq, 1)
|
21
21
|
criteria = stub('criteria')
|
22
22
|
criteria.should_receive(:eq).with("d.test" => 1)
|
23
23
|
filter.apply(criteria)
|
@@ -0,0 +1,139 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Sleek::GroupByCriteria do
|
4
|
+
let(:collection) { mock('collection', aggregate: []) }
|
5
|
+
let(:criteria) { mock('criteria', collection: collection) }
|
6
|
+
let(:group_by) { "d.field" }
|
7
|
+
let(:db_group) { "$d.field" }
|
8
|
+
subject(:crit) { described_class.new(criteria, group_by) }
|
9
|
+
|
10
|
+
describe "#aggregates" do
|
11
|
+
it "makes up the pipeline" do
|
12
|
+
crit.should_receive(:aggregates_pipeline).with(:some_field, false)
|
13
|
+
|
14
|
+
crit.aggregates(:some_field, false)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "aggregates on the collection" do
|
18
|
+
pipeline = double('pipeline')
|
19
|
+
result_a = double('result_a')
|
20
|
+
result = double('result', to_a: result_a)
|
21
|
+
crit.stub(:aggregates_pipeline).and_return(pipeline)
|
22
|
+
collection.should_receive(:aggregate).with(pipeline).and_return(result)
|
23
|
+
|
24
|
+
expect(crit.aggregates(:some_field, false)).to eq result_a
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#aggregates_prop" do
|
29
|
+
it "aggregates on the collection" do
|
30
|
+
crit.should_receive(:aggregates).with(:some_field, false).and_return([])
|
31
|
+
crit.aggregates_prop(:some_field, "count", false)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "maps the result" do
|
35
|
+
crit.stub(:aggregates).and_return([{"_id" => :a, "count" => 1}, {"_id" => :b, "count" => 4}])
|
36
|
+
expect(crit.aggregates_prop(:some_field, "count", false)).to eq({ a: 1, b: 4 })
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "#aggregates_pipeline" do
|
41
|
+
let(:new_criteria) { stub('new_criteria') }
|
42
|
+
let(:selector) { stub('selector') }
|
43
|
+
|
44
|
+
context "when not aggregating on specific field" do
|
45
|
+
let(:pipeline) { crit.aggregates_pipeline }
|
46
|
+
|
47
|
+
before do
|
48
|
+
criteria.should_receive(:ne).with(group_by => nil).and_return(new_criteria)
|
49
|
+
new_criteria.should_receive(:selector).and_return(selector)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "adds group_by_field != nil to criteria and matches the criteria" do
|
53
|
+
expect(pipeline.first).to eq "$match" => selector
|
54
|
+
end
|
55
|
+
|
56
|
+
it "groups with count" do
|
57
|
+
expect(pipeline.last).to eq "$group" => { "_id" => db_group, "count" => { "$sum" => 1 } }
|
58
|
+
end
|
59
|
+
|
60
|
+
it "has only two operators" do
|
61
|
+
expect(pipeline).to have(2).items
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context "when aggregating on specific field" do
|
66
|
+
let(:field) { "d.property" }
|
67
|
+
let(:db_field) { "$d.property" }
|
68
|
+
let(:new_criteria2) { stub('new_criteria2') }
|
69
|
+
|
70
|
+
before do
|
71
|
+
criteria.should_receive(:ne).with(field => nil).and_return(new_criteria)
|
72
|
+
new_criteria.should_receive(:ne).with(group_by => nil).and_return(new_criteria2)
|
73
|
+
new_criteria2.should_receive(:selector).and_return(selector)
|
74
|
+
end
|
75
|
+
|
76
|
+
context "when not including unique counter" do
|
77
|
+
let(:pipeline) { crit.aggregates_pipeline(field) }
|
78
|
+
|
79
|
+
it "adds group_by_field != nil and field != nil to criteria and matches the criteria" do
|
80
|
+
expect(pipeline.first).to eq "$match" => selector
|
81
|
+
end
|
82
|
+
|
83
|
+
it "groups with count, min, max, sum, avg" do
|
84
|
+
expect(pipeline.last).to eq "$group" => {
|
85
|
+
"_id" => db_group,
|
86
|
+
"count" => { "$sum" => 1 },
|
87
|
+
"max" => { "$max" => db_field },
|
88
|
+
"min" => { "$min" => db_field },
|
89
|
+
"sum" => { "$sum" => db_field },
|
90
|
+
"avg" => { "$avg" => db_field }
|
91
|
+
}
|
92
|
+
end
|
93
|
+
|
94
|
+
it "has 2 operators" do
|
95
|
+
expect(pipeline).to have(2).items
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context "when including unique counter" do
|
100
|
+
let(:pipeline) { crit.aggregates_pipeline(field, true) }
|
101
|
+
|
102
|
+
it "adds group_by_field != nil and field != nil to criteria and matches the criteria" do
|
103
|
+
expect(pipeline.first).to eq "$match" => selector
|
104
|
+
end
|
105
|
+
|
106
|
+
it "groups with count, min, max, sum, avg" do
|
107
|
+
expect(pipeline[1]).to eq "$group" => {
|
108
|
+
"_id" => db_group,
|
109
|
+
"count" => { "$sum" => 1 },
|
110
|
+
"max" => { "$max" => db_field },
|
111
|
+
"min" => { "$min" => db_field },
|
112
|
+
"sum" => { "$sum" => db_field },
|
113
|
+
"avg" => { "$avg" => db_field },
|
114
|
+
"unique_set" => { "$addToSet" => db_field }
|
115
|
+
}
|
116
|
+
end
|
117
|
+
|
118
|
+
it "unwinds the set of unique values" do
|
119
|
+
expect(pipeline[2]).to eq "$unwind" => "$unique_set"
|
120
|
+
end
|
121
|
+
|
122
|
+
it "groups aggregates back and counts unique values" do
|
123
|
+
expect(pipeline.last).to eq "$group" => {
|
124
|
+
"_id" => "$_id",
|
125
|
+
"count_unique" => { "$sum" => 1 },
|
126
|
+
"count" => { "$first" => "count" },
|
127
|
+
"max" => { "$first" => "max" },
|
128
|
+
"min" => { "$first" => "min" },
|
129
|
+
"avg" => { "$first" => "avg" }
|
130
|
+
}
|
131
|
+
end
|
132
|
+
|
133
|
+
it "has 4 operators" do
|
134
|
+
expect(pipeline).to have(4).items
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
@@ -3,20 +3,21 @@ require 'spec_helper'
|
|
3
3
|
describe Sleek::Interval do
|
4
4
|
describe "#initialize" do
|
5
5
|
it "transforms interval description into value" do
|
6
|
-
|
7
|
-
|
6
|
+
described_class.should_receive(:interval_value).with(:hourly)
|
7
|
+
described_class.new(:hourly, Time.now.all_day)
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
11
|
describe "#timeframes" do
|
12
12
|
it "slices timeframe into interval-long timeframes" do
|
13
|
-
|
14
|
-
|
13
|
+
now = ActiveSupport::TimeZone.new('UTC').now
|
14
|
+
bd = now.beginning_of_day
|
15
|
+
interval = described_class.new(:hourly, now.all_day)
|
15
16
|
expect(interval.timeframes.count).to eq 23
|
16
17
|
|
17
18
|
23.times do |i|
|
18
19
|
subtf = interval.timeframes[i]
|
19
|
-
expect(subtf.
|
20
|
+
expect(subtf.begin).to eq bd + 1.hour * i
|
20
21
|
expect(subtf.end).to eq bd + 1.hour * (i + 1)
|
21
22
|
end
|
22
23
|
end
|
@@ -1,30 +1,37 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Sleek::
|
4
|
-
subject(:sleek) {
|
3
|
+
describe Sleek::Namespace do
|
4
|
+
subject(:sleek) { described_class.new(:default) }
|
5
5
|
|
6
6
|
describe "#initialize" do
|
7
7
|
it "sets the namespace" do
|
8
|
-
sleek =
|
9
|
-
expect(sleek.
|
8
|
+
sleek = described_class.new(:my_namespace)
|
9
|
+
expect(sleek.name).to eq :my_namespace
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
13
|
describe "#record" do
|
14
14
|
it "creates an event record" do
|
15
15
|
data = { name: 'John Doe', email: 'j@d.com' }
|
16
|
-
|
17
16
|
Sleek::Event.should_receive(:create_with_namespace).with(:default, "signups", data)
|
18
|
-
|
19
17
|
sleek.record("signups", data)
|
20
18
|
end
|
21
19
|
end
|
22
20
|
|
23
21
|
describe "#queries" do
|
24
22
|
it "returns QueryCollection for current namespace" do
|
25
|
-
Sleek::QueryCollection.should_receive(:new).with(
|
23
|
+
Sleek::QueryCollection.should_receive(:new).with(sleek).and_call_original
|
26
24
|
qc = sleek.queries
|
27
|
-
expect(qc.namespace).to eq
|
25
|
+
expect(qc.namespace).to eq sleek
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "#delete!" do
|
30
|
+
it "deletes everything from the namespace" do
|
31
|
+
events = stub('events')
|
32
|
+
sleek.should_receive(:events).and_return(events)
|
33
|
+
events.should_receive(:delete_all)
|
34
|
+
sleek.delete!
|
28
35
|
end
|
29
36
|
end
|
30
37
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Sleek::Queries::Average do
|
4
|
-
subject(:query) {
|
4
|
+
subject(:query) { described_class.new(:default, :purchases, target_property: "total") }
|
5
5
|
|
6
6
|
describe "#perform" do
|
7
7
|
it "counts the events" do
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Sleek::Queries::CountUnique do
|
4
|
-
subject(:query) {
|
4
|
+
subject(:query) { described_class.new(:default, :purchases, target_property: "customer.id") }
|
5
5
|
|
6
6
|
describe "#perform" do
|
7
7
|
it "counts the events" do
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Sleek::Queries::Maximum do
|
4
|
-
subject(:query) {
|
4
|
+
subject(:query) { described_class.new(:default, :purchases, target_property: "total") }
|
5
5
|
|
6
6
|
describe "#perform" do
|
7
7
|
it "counts the events" do
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Sleek::Queries::Minimum do
|
4
|
-
subject(:query) {
|
4
|
+
subject(:query) { described_class.new(:default, :purchases, target_property: "total") }
|
5
5
|
|
6
6
|
describe "#perform" do
|
7
7
|
it "counts the events" do
|
@@ -1,13 +1,22 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Sleek::Queries::Query do
|
4
|
-
let(:query_class) {
|
5
|
-
|
4
|
+
let(:query_class) { described_class }
|
5
|
+
let(:namespace) { mock('namespace', name: :default) }
|
6
|
+
subject(:query) { query_class.new(namespace, :purchases) }
|
7
|
+
|
8
|
+
describe ".require_target_property!" do
|
9
|
+
it "sets a flag indicating target property is required by the query" do
|
10
|
+
klass = Class.new(query_class)
|
11
|
+
expect { klass.require_target_property! }.to change { klass.require_target_property? }.from(false).to(true)
|
12
|
+
end
|
13
|
+
end
|
6
14
|
|
7
15
|
describe "#initialize" do
|
8
16
|
it "sets the namespace and bucket" do
|
9
|
-
|
10
|
-
|
17
|
+
my_namespace = double('my_namespace', name: :my_namespace)
|
18
|
+
query = described_class.new(my_namespace, :purchases)
|
19
|
+
expect(query.namespace).to eq my_namespace
|
11
20
|
expect(query.bucket).to eq :purchases
|
12
21
|
end
|
13
22
|
|
@@ -29,10 +38,34 @@ describe Sleek::Queries::Query do
|
|
29
38
|
end
|
30
39
|
|
31
40
|
describe "#events" do
|
41
|
+
let(:evts) { double('events') }
|
42
|
+
|
43
|
+
context "when group_by is specified" do
|
44
|
+
before { query.stub(options: { group_by: "group" }) }
|
45
|
+
|
46
|
+
it "creates a group_by criteria from Mongoid::Criteria" do
|
47
|
+
namespace.should_receive(:events).and_return(evts)
|
48
|
+
Sleek::GroupByCriteria.should_receive(:new).with(evts, "d.group")
|
49
|
+
|
50
|
+
query.events
|
51
|
+
end
|
52
|
+
|
53
|
+
it "returns a group_by criteria" do
|
54
|
+
namespace.stub(events: evts)
|
55
|
+
|
56
|
+
crit = query.events
|
57
|
+
|
58
|
+
expect(crit.class).to eq Sleek::GroupByCriteria
|
59
|
+
expect(crit.criteria).to eq evts
|
60
|
+
expect(crit.group_by).to eq "d.group"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
32
64
|
context "when no timeframe is specifies" do
|
33
65
|
context "when no filter is specified" do
|
34
66
|
it "returns events in current namespace and bucket" do
|
35
|
-
|
67
|
+
namespace.stub(events: evts)
|
68
|
+
namespace.should_receive(:events).with(:purchases)
|
36
69
|
query.events
|
37
70
|
end
|
38
71
|
end
|
@@ -42,6 +75,7 @@ describe Sleek::Queries::Query do
|
|
42
75
|
|
43
76
|
it "applies filters" do
|
44
77
|
final = stub('final_criteria')
|
78
|
+
namespace.stub(events: evts)
|
45
79
|
query.should_receive(:apply_filters).and_return(final)
|
46
80
|
expect(query.events).to eq final
|
47
81
|
end
|
@@ -51,12 +85,12 @@ describe Sleek::Queries::Query do
|
|
51
85
|
context "when timeframe is specified" do
|
52
86
|
let(:start) { 1.day.ago }
|
53
87
|
let(:finish) { Time.now }
|
54
|
-
before { query.stub(:
|
88
|
+
before { query.stub(:timeframe).and_return(start..finish) }
|
55
89
|
|
56
90
|
context "when no filter is specified" do
|
57
91
|
it "gets only events between timeframe ends" do
|
58
92
|
pre_evts = stub('pre_events')
|
59
|
-
|
93
|
+
namespace.should_receive(:events).with(:purchases).and_return(pre_evts)
|
60
94
|
pre_evts.should_receive(:between).with("s.t" => start..finish)
|
61
95
|
query.events
|
62
96
|
end
|
@@ -69,7 +103,7 @@ describe Sleek::Queries::Query do
|
|
69
103
|
pre_evts = stub('pre_events')
|
70
104
|
criteria = stub('criteria')
|
71
105
|
final = stub('final_criteria')
|
72
|
-
|
106
|
+
namespace.should_receive(:events).with(:purchases).and_return(pre_evts)
|
73
107
|
pre_evts.should_receive(:between).and_return(criteria)
|
74
108
|
query.should_receive(:apply_filters).with(criteria).and_return(final)
|
75
109
|
expect(query.events).to eq final
|
@@ -120,35 +154,9 @@ describe Sleek::Queries::Query do
|
|
120
154
|
end
|
121
155
|
end
|
122
156
|
|
123
|
-
describe "#timeframe" do
|
124
|
-
context "when timeframe is specified" do
|
125
|
-
let(:tf) { stub('timeframe') }
|
126
|
-
before { query.stub(options: { timeframe: tf }) }
|
127
|
-
|
128
|
-
it "creates new timeframe instance" do
|
129
|
-
Sleek::Timeframe.should_receive(:new).with(tf)
|
130
|
-
query.timeframe
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
describe "#series" do
|
136
|
-
context "when timeframe and interval are specified" do
|
137
|
-
let(:tf) { stub('timeframe') }
|
138
|
-
before { query.stub(options: { timeframe: 'this_day', interval: :hourly }, timeframe: tf) }
|
139
|
-
|
140
|
-
it "splits timeframe into intervals of sub-timeframes" do
|
141
|
-
interval = stub('interval')
|
142
|
-
Sleek::Interval.should_receive(:new).with(:hourly, tf).and_return(interval)
|
143
|
-
interval.should_receive(:timeframes)
|
144
|
-
query.series
|
145
|
-
end
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
157
|
describe "#valid_options?" do
|
150
158
|
context "when options is a hash" do
|
151
|
-
context "when
|
159
|
+
context "when target property is not required" do
|
152
160
|
before { query.stub(options: {}) }
|
153
161
|
|
154
162
|
it "is true" do
|
@@ -156,25 +164,22 @@ describe Sleek::Queries::Query do
|
|
156
164
|
end
|
157
165
|
end
|
158
166
|
|
159
|
-
context "when
|
160
|
-
|
161
|
-
before { query.stub(options: { interval: :hourly, timeframe: Time.now.all_day }) }
|
167
|
+
context "when target property is required" do
|
168
|
+
before { query.stub(require_target_property?: true) }
|
162
169
|
|
163
|
-
|
164
|
-
|
165
|
-
|
170
|
+
it "is true if target property is specified" do
|
171
|
+
query.stub(options: { target_property: "total" })
|
172
|
+
expect(query.valid_options?).to be_true
|
166
173
|
end
|
167
174
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
expect(query.valid_options?).to be_false
|
172
|
-
end
|
175
|
+
it "is false if target property is not specified" do
|
176
|
+
query.stub(options: {})
|
177
|
+
expect(query.valid_options?).to be_false
|
173
178
|
end
|
174
179
|
end
|
175
180
|
end
|
176
181
|
|
177
|
-
context "when options
|
182
|
+
context "when options is not a hash" do
|
178
183
|
before { query.stub(options: 1) }
|
179
184
|
|
180
185
|
it "is false" do
|
@@ -184,43 +189,12 @@ describe Sleek::Queries::Query do
|
|
184
189
|
end
|
185
190
|
|
186
191
|
describe "#run" do
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
query.run
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
context "when series were requested" do
|
198
|
-
let(:series) { (0..23).to_a.map { |i| stub(to_time_range: (i..(i+1))) } }
|
199
|
-
before { query.stub(options: { timeframe: 'this_day', interval: :hourly }, series: series) }
|
200
|
-
|
201
|
-
it "performs query on each of sub-timeframes" do
|
202
|
-
24.times do |i|
|
203
|
-
evts = stub('events')
|
204
|
-
query.should_receive(:events).with(i..(i+1)).and_return(evts)
|
205
|
-
query.should_receive(:perform).with(evts)
|
206
|
-
end
|
207
|
-
|
208
|
-
query.run
|
209
|
-
end
|
210
|
-
|
211
|
-
it "returns the array of results" do
|
212
|
-
results = []
|
213
|
-
|
214
|
-
24.times do |i|
|
215
|
-
evts = stub('events')
|
216
|
-
value = stub('value')
|
217
|
-
results << { timeframe: series[i], value: value }
|
218
|
-
query.should_receive(:events).with(i..(i+1)).and_return(evts)
|
219
|
-
query.should_receive(:perform).with(evts).and_return(value)
|
220
|
-
end
|
221
|
-
|
222
|
-
expect(query.run).to eq results
|
223
|
-
end
|
192
|
+
it "performs query on events" do
|
193
|
+
events = double('events')
|
194
|
+
result = double('result')
|
195
|
+
query.should_receive(:perform).with(events).and_return(result)
|
196
|
+
query.stub(events: events)
|
197
|
+
query.run
|
224
198
|
end
|
225
199
|
end
|
226
200
|
end
|