influxer 0.2.4 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +12 -0
  4. data/.travis.yml +1 -17
  5. data/Changelog.md +7 -0
  6. data/Gemfile +7 -0
  7. data/README.md +6 -20
  8. data/Rakefile +4 -0
  9. data/gemfiles/rails42.gemfile +4 -1
  10. data/influxer.gemspec +6 -6
  11. data/lib/influxer/client.rb +4 -44
  12. data/lib/influxer/config.rb +23 -14
  13. data/lib/influxer/engine.rb +0 -1
  14. data/lib/influxer/metrics/metrics.rb +40 -7
  15. data/lib/influxer/metrics/relation/calculations.rb +13 -7
  16. data/lib/influxer/metrics/relation/time_query.rb +14 -8
  17. data/lib/influxer/metrics/relation/where_clause.rb +62 -0
  18. data/lib/influxer/metrics/relation.rb +67 -76
  19. data/lib/influxer/metrics/scoping.rb +4 -4
  20. data/lib/influxer/model.rb +4 -0
  21. data/lib/influxer/rails/client.rb +47 -0
  22. data/lib/influxer/version.rb +1 -1
  23. data/lib/influxer.rb +4 -2
  24. data/spec/cases/points_spec.rb +34 -0
  25. data/spec/client_spec.rb +21 -24
  26. data/spec/fixtures/empty_result.json +21 -0
  27. data/spec/fixtures/single_series.json +29 -0
  28. data/spec/metrics/metrics_spec.rb +139 -113
  29. data/spec/metrics/relation_spec.rb +160 -105
  30. data/spec/metrics/scoping_spec.rb +11 -17
  31. data/spec/model/user_spec.rb +44 -0
  32. data/spec/spec_helper.rb +38 -8
  33. data/spec/support/metrics/action_metrics.rb +3 -0
  34. data/spec/support/metrics/custom_metrics.rb +4 -0
  35. data/spec/support/{dummy_metrics.rb → metrics/dummy_metrics.rb} +2 -1
  36. data/spec/support/metrics/user_metrics.rb +4 -0
  37. data/spec/support/metrics/visits_metrics.rb +4 -0
  38. data/spec/support/shared_contexts/shared_query.rb +16 -0
  39. data/spec/support/user.rb +14 -0
  40. metadata +42 -71
  41. data/gemfiles/rails40.gemfile +0 -7
  42. data/gemfiles/rails41.gemfile +0 -7
  43. data/lib/influxer/metrics/fanout.rb +0 -65
  44. data/lib/influxer/metrics/relation/fanout_query.rb +0 -49
  45. data/lib/tasks/influxer_tasks.rake +0 -4
  46. data/spec/config_spec.rb +0 -17
  47. data/spec/dummy/README.rdoc +0 -28
  48. data/spec/dummy/Rakefile +0 -6
  49. data/spec/dummy/app/assets/images/.keep +0 -0
  50. data/spec/dummy/app/assets/javascripts/application.js +0 -13
  51. data/spec/dummy/app/assets/stylesheets/application.css +0 -15
  52. data/spec/dummy/app/controllers/application_controller.rb +0 -5
  53. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  54. data/spec/dummy/app/helpers/application_helper.rb +0 -2
  55. data/spec/dummy/app/mailers/.keep +0 -0
  56. data/spec/dummy/app/metrics/testo_metrics.rb +0 -3
  57. data/spec/dummy/app/models/.keep +0 -0
  58. data/spec/dummy/app/models/concerns/.keep +0 -0
  59. data/spec/dummy/app/models/testo.rb +0 -6
  60. data/spec/dummy/app/views/layouts/application.html.erb +0 -14
  61. data/spec/dummy/bin/bundle +0 -3
  62. data/spec/dummy/bin/rails +0 -4
  63. data/spec/dummy/bin/rake +0 -4
  64. data/spec/dummy/config/application.rb +0 -23
  65. data/spec/dummy/config/boot.rb +0 -5
  66. data/spec/dummy/config/database.yml +0 -25
  67. data/spec/dummy/config/environment.rb +0 -5
  68. data/spec/dummy/config/environments/development.rb +0 -37
  69. data/spec/dummy/config/environments/production.rb +0 -83
  70. data/spec/dummy/config/environments/test.rb +0 -38
  71. data/spec/dummy/config/influxdb.yml +0 -5
  72. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
  73. data/spec/dummy/config/initializers/cookies_serializer.rb +0 -3
  74. data/spec/dummy/config/initializers/filter_parameter_logging.rb +0 -4
  75. data/spec/dummy/config/initializers/inflections.rb +0 -16
  76. data/spec/dummy/config/initializers/mime_types.rb +0 -4
  77. data/spec/dummy/config/initializers/session_store.rb +0 -3
  78. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -14
  79. data/spec/dummy/config/locales/en.yml +0 -23
  80. data/spec/dummy/config/routes.rb +0 -56
  81. data/spec/dummy/config/secrets.yml +0 -25
  82. data/spec/dummy/config.ru +0 -4
  83. data/spec/dummy/db/migrate/20140730133818_add_testos.rb +0 -11
  84. data/spec/dummy/db/migrate/20140731162044_add_column_to_testos.rb +0 -5
  85. data/spec/dummy/db/schema.rb +0 -22
  86. data/spec/dummy/db/test.sqlite3 +0 -0
  87. data/spec/dummy/lib/assets/.keep +0 -0
  88. data/spec/dummy/log/.keep +0 -0
  89. data/spec/dummy/public/404.html +0 -67
  90. data/spec/dummy/public/422.html +0 -67
  91. data/spec/dummy/public/500.html +0 -66
  92. data/spec/dummy/public/favicon.ico +0 -0
  93. data/spec/fixtures/fanout_series.json +0 -23
  94. data/spec/metrics/fanout_spec.rb +0 -61
  95. data/spec/model/testo_spec.rb +0 -27
@@ -1,205 +1,245 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Influxer::Relation do
4
- before do
5
- allow_any_instance_of(Influxer::Client).to receive(:query) do |_, sql|
6
- sql
7
- end
8
- end
9
-
3
+ describe Influxer::Relation, :query do
10
4
  let(:rel) { Influxer::Relation.new DummyMetrics }
11
5
  let(:rel2) { Influxer::Relation.new DummyComplexMetrics }
12
6
 
13
- specify { expect(rel).to respond_to :write }
14
- specify { expect(rel).to respond_to :build }
15
-
16
- # read
17
- specify { expect(rel).to respond_to :select }
18
- specify { expect(rel).to respond_to :where }
19
- specify { expect(rel).to respond_to :limit }
20
- specify { expect(rel).to respond_to :group }
7
+ context "instance methods" do
8
+ subject { rel }
21
9
 
22
- # delete
23
- specify { expect(rel).to respond_to :delete_all }
10
+ specify { is_expected.to respond_to :write }
11
+ specify { is_expected.to respond_to :select }
12
+ specify { is_expected.to respond_to :where }
13
+ specify { is_expected.to respond_to :limit }
14
+ specify { is_expected.to respond_to :group }
15
+ specify { is_expected.to respond_to :delete_all }
16
+ specify { is_expected.to respond_to :to_sql }
17
+ end
24
18
 
25
- specify { expect(rel).to respond_to :to_sql }
19
+ describe "#build" do
20
+ specify { expect(rel.build).to be_a DummyMetrics }
21
+ specify { expect(rel.new).to be_a DummyMetrics }
22
+ end
26
23
 
27
24
  describe "#merge!" do
28
- it "should merge multi values" do
25
+ it "merge multi values" do
29
26
  r1 = rel.where(id: [1, 2], dummy: 'qwe').time(:hour)
30
- r2 = Influxer::Relation.new(DummyMetrics).where.not(user_id: 0).group(:user_id)
27
+ r2 = Influxer::Relation.new(DummyMetrics).where.not(user_id: 0).group(:user_id).order(user_id: :asc)
31
28
  r1.merge!(r2)
32
- expect(r1.to_sql).to eq "select * from \"dummy\" group by time(1h),user_id where (id=1 or id=2) and (dummy='qwe') and (user_id<>0)"
29
+ expect(r1.to_sql)
30
+ .to eq "select * from \"dummy\" where (id=1 or id=2) and (dummy='qwe') and (user_id<>0) " \
31
+ "group by time(1h),user_id order by user_id asc"
33
32
  end
34
33
 
35
- it "should merge single values" do
36
- r1 = rel.time(:hour, fill: 0).limit(10)
37
- r2 = Influxer::Relation.new(DummyMetrics).merge(:doomy).limit(5)
34
+ it "merge single values" do
35
+ r1 = rel.time(:hour, fill: 0).slimit(10)
36
+ r2 = Influxer::Relation.new(DummyMetrics).group(:dummy_id).offset(10).slimit(5)
38
37
  r1.merge!(r2)
39
- expect(r1.to_sql).to eq "select * from \"dummy\" merge \"doomy\" group by time(1h) fill(0) limit 5"
38
+ expect(r1.to_sql).to eq "select * from \"dummy\" group by time(1h),dummy_id fill(0) offset 10 slimit 5"
40
39
  end
41
40
  end
42
41
 
43
- describe "sql generation" do
44
- describe "from clause" do
45
- it "should generate valid from if no conditions" do
42
+ context "sql generation" do
43
+ describe "#from" do
44
+ it "generates valid from if no conditions" do
46
45
  expect(rel.to_sql).to eq "select * from \"dummy\""
47
46
  end
48
47
  end
49
48
 
50
49
  describe "#select" do
51
- it "should select array of symbols" do
50
+ it "select array of symbols" do
52
51
  expect(rel.select(:user_id, :dummy_id).to_sql).to eq "select user_id,dummy_id from \"dummy\""
53
52
  end
54
53
 
55
- it "should select string" do
54
+ it "select string" do
56
55
  expect(rel.select("count(user_id)").to_sql).to eq "select count(user_id) from \"dummy\""
57
56
  end
57
+
58
+ it "select expression" do
59
+ expect(rel.select("(value + 6) / 10").to_sql).to eq "select (value + 6) / 10 from \"dummy\""
60
+ end
58
61
  end
59
62
 
60
63
  describe "#where" do
61
- it "should generate valid conditions from hash" do
62
- Timecop.freeze(Time.now) do
63
- expect(rel.where(user_id: 1, dummy: 'q', timer: Time.now).to_sql).to eq "select * from \"dummy\" where (user_id=1) and (dummy='q') and (timer=#{Time.now.to_i}s)"
64
- end
64
+ it "sgenerate valid conditions from hash" do
65
+ Timecop.freeze(Time.now)
66
+ expect(rel.where(user_id: 1, dummy: 'q', timer: Time.now).to_sql).to eq "select * from \"dummy\" where (user_id=1) and (dummy='q') and (timer=#{Time.now.to_i}s)"
65
67
  end
66
68
 
67
- it "should generate valid conditions from strings" do
69
+ it "generate valid conditions from strings" do
68
70
  expect(rel.where("time > now() - 1d").to_sql).to eq "select * from \"dummy\" where (time > now() - 1d)"
69
71
  end
70
72
 
71
- it "should handle regexps" do
73
+ it "handle regexps" do
72
74
  expect(rel.where(user_id: 1, dummy: /^du.*/).to_sql).to eq "select * from \"dummy\" where (user_id=1) and (dummy=~/^du.*/)"
73
75
  end
74
76
 
75
- it "should handle ranges" do
77
+ it "handle ranges" do
76
78
  expect(rel.where(user_id: 1..4).to_sql).to eq "select * from \"dummy\" where (user_id>1 and user_id<4)"
77
79
  end
78
80
 
79
- it "should handle arrays" do
81
+ it "handle arrays" do
80
82
  expect(rel.where(user_id: [1, 2, 3]).to_sql).to eq "select * from \"dummy\" where (user_id=1 or user_id=2 or user_id=3)"
81
83
  end
84
+
85
+ context "with tags" do
86
+ it "integer tag values" do
87
+ expect(rel.where(dummy_id: 10).to_sql).to eq "select * from \"dummy\" where (dummy_id='10')"
88
+ end
89
+
90
+ it "array tag values" do
91
+ expect(rel.where(dummy_id: [10, 'some']).to_sql).to eq "select * from \"dummy\" where (dummy_id='10' or dummy_id='some')"
92
+ end
93
+ end
82
94
  end
83
95
 
84
96
  describe "#not" do
85
- it "should negate simple values" do
97
+ it "negate simple values" do
86
98
  expect(rel.where.not(user_id: 1, dummy: :a).to_sql).to eq "select * from \"dummy\" where (user_id<>1) and (dummy<>'a')"
87
99
  end
88
100
 
89
- it "should handle regexp" do
101
+ it "handle regexp" do
90
102
  expect(rel.where.not(user_id: 1, dummy: /^du.*/).to_sql).to eq "select * from \"dummy\" where (user_id<>1) and (dummy!~/^du.*/)"
91
103
  end
92
104
 
93
- it "should handle ranges" do
105
+ it "handle ranges" do
94
106
  expect(rel.where.not(user_id: 1..4).to_sql).to eq "select * from \"dummy\" where (user_id<1 and user_id>4)"
95
107
  end
96
108
 
97
- it "should handle arrays" do
109
+ it "handle arrays" do
98
110
  expect(rel.where.not(user_id: [1, 2, 3]).to_sql).to eq "select * from \"dummy\" where (user_id<>1 and user_id<>2 and user_id<>3)"
99
111
  end
100
112
  end
101
113
 
102
- describe "#merge" do
103
- it "should merge with one series" do
104
- expect(rel.merge("dubby").to_sql).to eq "select * from \"dummy\" merge \"dubby\""
105
- end
106
-
107
- it "should merge with one series as regexp" do
108
- expect(rel.merge(/^du[1-6]+$/).to_sql).to eq "select * from \"dummy\" merge /^du[1-6]+$/"
109
- end
110
- end
111
-
112
114
  describe "#past" do
113
- it "should work with predefined symbols" do
115
+ it "work with predefined symbols" do
114
116
  expect(rel.past(:hour).to_sql).to eq "select * from \"dummy\" where (time > now() - 1h)"
115
117
  end
116
118
 
117
- it "should work with any symbols" do
119
+ it "work with any symbols" do
118
120
  expect(rel.past(:s).to_sql).to eq "select * from \"dummy\" where (time > now() - 1s)"
119
121
  end
120
122
 
121
- it "should work with strings" do
123
+ it "work with strings" do
122
124
  expect(rel.past("3d").to_sql).to eq "select * from \"dummy\" where (time > now() - 3d)"
123
125
  end
124
126
 
125
- it "should work with numbers" do
127
+ it "work with numbers" do
126
128
  expect(rel.past(1.day).to_sql).to eq "select * from \"dummy\" where (time > now() - 86400s)"
127
129
  end
128
130
  end
129
131
 
130
132
  describe "#since" do
131
- it "should work with datetime" do
133
+ it "work with datetime" do
132
134
  expect(rel.since(Time.utc(2014, 12, 31)).to_sql).to eq "select * from \"dummy\" where (time > 1419984000s)"
133
135
  end
134
136
  end
135
137
 
136
138
  describe "#group" do
137
- it "should generate valid groups" do
139
+ it "generate valid groups" do
138
140
  expect(rel.group(:user_id, "time(1m) fill(0)").to_sql).to eq "select * from \"dummy\" group by user_id,time(1m) fill(0)"
139
141
  end
140
142
 
141
143
  context "group by time predefined values" do
142
- it "should group by hour" do
144
+ it "group by hour" do
143
145
  expect(rel.time(:hour).to_sql).to eq "select * from \"dummy\" group by time(1h)"
144
146
  end
145
147
 
146
- it "should group by minute" do
148
+ it "group by minute" do
147
149
  expect(rel.time(:minute).to_sql).to eq "select * from \"dummy\" group by time(1m)"
148
150
  end
149
151
 
150
- it "should group by second" do
152
+ it "group by second" do
151
153
  expect(rel.time(:second).to_sql).to eq "select * from \"dummy\" group by time(1s)"
152
154
  end
153
155
 
154
- it "should group by millisecond" do
155
- expect(rel.time(:ms).to_sql).to eq "select * from \"dummy\" group by time(1u)"
156
+ it "group by millisecond" do
157
+ expect(rel.time(:ms).to_sql).to eq "select * from \"dummy\" group by time(1ms)"
156
158
  end
157
159
 
158
- it "should group by day" do
160
+ it "group by microsecond" do
161
+ expect(rel.time(:u).to_sql).to eq "select * from \"dummy\" group by time(1u)"
162
+ end
163
+
164
+ it "group by day" do
159
165
  expect(rel.time(:day).to_sql).to eq "select * from \"dummy\" group by time(1d)"
160
166
  end
161
167
 
162
- it "should group by week" do
168
+ it "group by week" do
163
169
  expect(rel.time(:week).to_sql).to eq "select * from \"dummy\" group by time(1w)"
164
170
  end
165
171
 
166
- it "should group by month" do
172
+ it "group by month" do
167
173
  expect(rel.time(:month).to_sql).to eq "select * from \"dummy\" group by time(30d)"
168
174
  end
169
175
 
170
- it "should group by hour and fill" do
176
+ it "group by hour and fill" do
171
177
  expect(rel.time(:month, fill: 0).to_sql).to eq "select * from \"dummy\" group by time(30d) fill(0)"
172
178
  end
173
179
  end
174
180
 
175
- it "should group by time with string value" do
181
+ it "group by time with string value" do
176
182
  expect(rel.time("4d").to_sql).to eq "select * from \"dummy\" group by time(4d)"
177
183
  end
178
184
 
179
- it "should group by time with string value and fill null" do
180
- expect(rel.time("4d", fill: :null).to_sql).to eq "select * from \"dummy\" group by time(4d) fill(null)"
185
+ %w(null previous none).each do |val|
186
+ it "group by time with string value and fill #{val}" do
187
+ expect(rel.time("4d", fill: val.to_sym).to_sql).to eq "select * from \"dummy\" group by time(4d) fill(#{val})"
188
+ end
181
189
  end
182
190
 
183
- it "should group by time and other fields with fill null" do
191
+ it "group by time and other fields with fill zero" do
184
192
  expect(rel.time("4d", fill: 0).group(:dummy_id).to_sql).to eq "select * from \"dummy\" group by time(4d),dummy_id fill(0)"
185
193
  end
194
+
195
+ it "group by time and other fields with fill negative" do
196
+ expect(rel.time("4d", fill: -1).group(:dummy_id).to_sql).to eq "select * from \"dummy\" group by time(4d),dummy_id fill(-1)"
197
+ end
198
+ end
199
+
200
+ describe "#order" do
201
+ it "generate valid order" do
202
+ expect(rel.order(time_spent: :asc).to_sql).to eq "select * from \"dummy\" order by time_spent asc"
203
+ end
204
+
205
+ it "generate order from string" do
206
+ expect(rel.order('cpu desc, val asc').to_sql).to eq "select * from \"dummy\" order by cpu desc, val asc"
207
+ end
186
208
  end
187
209
 
188
210
  describe "#limit" do
189
- it "should generate valid limi" do
211
+ it "generate valid limit" do
190
212
  expect(rel.limit(100).to_sql).to eq "select * from \"dummy\" limit 100"
191
213
  end
192
214
  end
193
215
 
194
- describe "calculations" do
216
+ describe "#slimit" do
217
+ it "generate valid slimit" do
218
+ expect(rel.slimit(100).to_sql).to eq "select * from \"dummy\" slimit 100"
219
+ end
220
+ end
221
+
222
+ describe "#offset" do
223
+ it "generate valid offset" do
224
+ expect(rel.limit(100).offset(10).to_sql).to eq "select * from \"dummy\" limit 100 offset 10"
225
+ end
226
+ end
227
+
228
+ describe "#soffset" do
229
+ it "generate valid soffset" do
230
+ expect(rel.soffset(10).to_sql).to eq "select * from \"dummy\" soffset 10"
231
+ end
232
+ end
233
+
234
+ context "calculations" do
195
235
  context "one arg calculation methods" do
196
236
  [
197
237
  :count, :min, :max, :mean,
198
238
  :mode, :median, :distinct, :derivative,
199
- :stddev, :sum, :first, :last, :difference, :histogram
239
+ :stddev, :sum, :first, :last
200
240
  ].each do |method|
201
241
  describe "##{method}" do
202
- it do
242
+ specify do
203
243
  expect(rel.where(user_id: 1).calc(method, :column_name).to_sql)
204
244
  .to eq "select #{method}(column_name) from \"dummy\" where (user_id=1)"
205
245
  end
@@ -207,62 +247,77 @@ describe Influxer::Relation do
207
247
  end
208
248
  end
209
249
 
210
- context "two args calculation methods" do
211
- [
212
- :percentile, :histogram, :top, :bottom
213
- ].each do |method|
214
- describe "##{method}" do
215
- it do
216
- expect(rel.where(user_id: 1).calc(method, :column_name, 10).to_sql)
217
- .to eq "select #{method}(column_name,10) from \"dummy\" where (user_id=1)"
218
- end
219
- end
250
+ context "with aliases" do
251
+ it "select count as alias" do
252
+ expect(rel.count(:val, 'total').to_sql).to eq "select count(val) as total from \"dummy\""
220
253
  end
254
+
255
+ it "select percentile as alias" do
256
+ expect(rel.percentile(:val, 90, 'p1').to_sql).to eq "select percentile(val,90) as p1 from \"dummy\""
257
+ end
258
+ end
259
+ end
260
+
261
+ context "complex queries" do
262
+ it "group + where" do
263
+ expect(rel.count('user_id').group(:traffic_source).fill(0).where(user_id: 123).past('28d').to_sql)
264
+ .to eq "select count(user_id) from \"dummy\" where (user_id=123) and (time > now() - 28d) " \
265
+ "group by traffic_source fill(0)"
266
+ end
267
+
268
+ it "where + group + order + limit" do
269
+ expect(rel.group(:user_id).where(account_id: 123).order(account_id: :desc).limit(10).offset(10).to_sql)
270
+ .to eq "select * from \"dummy\" where (account_id=123) group by user_id " \
271
+ "order by account_id desc limit 10 offset 10"
272
+ end
273
+
274
+ it "offset + slimit" do
275
+ expect(rel.where(account_id: 123).slimit(10).offset(10).to_sql)
276
+ .to eq "select * from \"dummy\" where (account_id=123) " \
277
+ "offset 10 slimit 10"
221
278
  end
222
279
  end
223
280
  end
224
281
 
225
282
  describe "#empty?" do
226
- after(:each) { Influxer.reset }
227
- it "should return false if has points" do
228
- Influxer.client.stub(:query) { { points: [{ time: 1, id: 2 }] } }
283
+ it "return false if has points" do
284
+ allow(client).to receive(:query) { [{ "values" => [{ time: 1, id: 2 }] }] }
229
285
  expect(rel.empty?).to be_falsey
230
286
  expect(rel.present?).to be_truthy
231
287
  end
232
288
 
233
- it "should return true if no points" do
234
- Influxer.client.stub(:query) { {} }
289
+ it "return true if no points" do
290
+ allow(client).to receive(:query) { [] }
235
291
  expect(rel.empty?).to be_truthy
236
292
  expect(rel.present?).to be_falsey
237
293
  end
238
294
  end
239
295
 
240
296
  describe "#delete_all" do
241
- it do
242
- Timecop.freeze(Time.now) do
243
- expect(rel.where(user_id: 1, dummy: 'q', timer: Time.now).delete_all)
244
- .to eq "delete from \"dummy\" where (user_id=1) and (dummy='q') and (timer=#{Time.now.to_i}s)"
245
- end
297
+ it "without tags" do
298
+ expect(rel.delete_all)
299
+ .to eq "drop series from \"dummy\""
246
300
  end
247
- end
248
301
 
249
- describe "#inspect" do
250
- after(:each) do
251
- Influxer.reset
302
+ it "with tags" do
303
+ expect(rel.where(dummy_id: 1, host: 'eu').delete_all)
304
+ .to eq "drop series from \"dummy\" where (dummy_id='1') and (host='eu')"
252
305
  end
306
+ end
253
307
 
254
- it "should return correct String represantation of empty relation" do
255
- Influxer.client.stub(:query) { {} }
308
+ describe "#inspect" do
309
+ it "return correct String represantation of empty relation" do
310
+ allow(rel).to receive(:to_a) { [] }
256
311
  expect(rel.inspect).to eq "#<Influxer::Relation []>"
257
312
  end
258
313
 
259
- it "should return correct String represantation of non-empty relation" do
260
- Influxer.client.stub(:query) { { "dummy" => [1, 2, 3] } }
314
+ it "return correct String represantation of non-empty relation" do
315
+ allow(rel).to receive(:to_a) { [1, 2, 3] }
261
316
  expect(rel.inspect).to eq "#<Influxer::Relation [1, 2, 3]>"
262
317
  end
263
318
 
264
- it "should return correct String represantation of non-empty large (>11) relation" do
265
- Influxer.client.stub(:query) { { "dummy" => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] } }
319
+ it "return correct String represantation of non-empty large (>11) relation" do
320
+ allow(rel).to receive(:to_a) { [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] }
266
321
  expect(rel.inspect).to eq "#<Influxer::Relation [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...]>"
267
322
  end
268
323
  end
@@ -1,12 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Influxer::Metrics do
4
- before do
5
- allow_any_instance_of(Influxer::Client).to receive(:query) do |_, sql|
6
- sql
7
- end
8
- end
9
-
3
+ describe Influxer::Metrics, :query do
10
4
  let(:klass) do
11
5
  Class.new(Influxer::Metrics) do
12
6
  set_series 'dummy'
@@ -34,37 +28,37 @@ describe Influxer::Metrics do
34
28
  end
35
29
 
36
30
  describe "default scope" do
37
- it "should work without default scope" do
31
+ it "works without default scope" do
38
32
  expect(klass.all.to_sql).to eq "select * from \"dummy\""
39
33
  end
40
34
 
41
- it "should work with default scope" do
35
+ it "works with default scope" do
42
36
  expect(dummy.all.to_sql).to eq "select * from \"dummy\" group by time(1h)"
43
37
  end
44
38
 
45
- it "should work with unscoped" do
39
+ it "works with unscoped" do
46
40
  expect(dummy.unscoped.to_sql).to eq "select * from \"dummy\""
47
41
  end
48
42
 
49
- it "should work with several defaults" do
43
+ it "works with several defaults" do
50
44
  expect(dappy.where(user_id: 1).to_sql)
51
- .to eq "select * from \"dummy\" group by time(1h) where (user_id=1) limit 100"
45
+ .to eq "select * from \"dummy\" where (user_id=1) group by time(1h) limit 100"
52
46
  end
53
47
  end
54
48
 
55
49
  describe "named scope" do
56
- it "should work with named scope" do
50
+ it "works with named scope" do
57
51
  expect(doomy.by_user(1).to_sql)
58
- .to eq "select * from \"dummy\" group by time(1h) where (user_id=1) limit 100"
52
+ .to eq "select * from \"dummy\" where (user_id=1) group by time(1h) limit 100"
59
53
  end
60
54
 
61
- it "should work with named scope with empty relation" do
55
+ it "works with named scope with empty relation" do
62
56
  expect(doomy.by_user(nil).to_sql).to eq "select * from \"dummy\" group by time(1h) limit 100"
63
57
  end
64
58
 
65
- it "should work with several scopes" do
59
+ it "works with several scopes" do
66
60
  expect(doomy.where(dummy_id: 100).by_user([1, 2, 3]).daily.to_sql)
67
- .to eq "select * from \"dummy\" group by time(1d) where (dummy_id=100) and (user_id=1 or user_id=2 or user_id=3) limit 100"
61
+ .to eq "select * from \"dummy\" where (dummy_id=100) and (user_id=1 or user_id=2 or user_id=3) group by time(1d) limit 100"
68
62
  end
69
63
  end
70
64
  end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ fdescribe User do
4
+ let(:user) { described_class.create age: 20, gender: 1, email: 'user@example.com' }
5
+ subject { user }
6
+
7
+ specify { is_expected.to respond_to :metrics }
8
+ specify { is_expected.to respond_to :visits_metrics }
9
+ specify { is_expected.to respond_to :action_metrics }
10
+ specify { is_expected.to respond_to :custom_metrics }
11
+
12
+ describe "#metrics" do
13
+ subject { user.metrics.new }
14
+
15
+ it "add foreign key" do
16
+ expect(subject.user_id).to eq user.id
17
+ end
18
+ end
19
+
20
+ describe "#visits_metrics" do
21
+ subject { user.visits_metrics.new }
22
+
23
+ it "adds inherited attributes" do
24
+ expect(subject.age).to eq 20
25
+ expect(subject.gender).to eq 1
26
+ end
27
+ end
28
+
29
+ describe "#action_metrics" do
30
+ subject { user.action_metrics.new }
31
+
32
+ it "adds custom foreign key" do
33
+ expect(subject.user).to eq user.id
34
+ end
35
+ end
36
+
37
+ describe "#custom_metrics" do
38
+ subject { user.custom_metrics.new }
39
+
40
+ it "doesn't add foreign key" do
41
+ expect(subject.user_id).to be_nil
42
+ end
43
+ end
44
+ end
data/spec/spec_helper.rb CHANGED
@@ -3,21 +3,51 @@ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
3
 
4
4
  ENV["RAILS_ENV"] ||= 'test'
5
5
 
6
- # require 'simplecov'
7
- # SimpleCov.root File.join(File.dirname(__FILE__), '..', 'lib')
8
- # SimpleCov.start
6
+ if ENV['COVER']
7
+ require 'simplecov'
8
+ SimpleCov.root File.join(File.dirname(__FILE__), '..')
9
+ SimpleCov.start
10
+ end
9
11
 
10
12
  require 'rspec'
11
- require 'pry'
12
- require 'rails/all'
13
- require 'rspec/rails'
13
+ require "webmock/rspec"
14
+ require 'pry-byebug'
14
15
  require 'timecop'
15
16
 
16
- require "dummy/config/environment"
17
+ require 'active_record'
18
+ require 'sqlite3'
19
+
20
+ require "influxer"
21
+
22
+ # Rails stub
23
+ class Rails
24
+ class << self
25
+ def cache
26
+ @cache ||= ActiveSupport::Cache::MemoryStore.new
27
+ end
28
+
29
+ def logger
30
+ @logger ||= Logger.new(nil)
31
+ end
32
+
33
+ def env
34
+ 'test'
35
+ end
36
+ end
37
+ end
38
+
39
+ require "influxer/rails/client"
40
+
41
+ ActiveRecord::Base.send :include, Influxer::Model
17
42
 
43
+ ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
44
+
45
+ Dir["#{File.dirname(__FILE__)}/support/metrics/*.rb"].each { |f| require f }
18
46
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
19
47
 
20
48
  RSpec.configure do |config|
21
49
  config.mock_with :rspec
22
- config.use_transactional_fixtures = true
50
+
51
+ config.after(:each) { Influxer.reset! }
52
+ config.after(:each) { Timecop.return }
23
53
  end
@@ -0,0 +1,3 @@
1
+ class ActionMetrics < Influxer::Metrics
2
+ tags :user, :action
3
+ end
@@ -0,0 +1,4 @@
1
+ class CustomMetrics < Influxer::Metrics
2
+ tags :code, :user_id
3
+ attributes :val
4
+ end
@@ -1,5 +1,6 @@
1
1
  class DummyMetrics < Influxer::Metrics # :nodoc:
2
- attributes :dummy_id, :user_id
2
+ tags :dummy_id, :host
3
+ attributes :user_id
3
4
 
4
5
  validates_presence_of :dummy_id, :user_id
5
6
 
@@ -0,0 +1,4 @@
1
+ class UserMetrics < Influxer::Metrics
2
+ tags :user_id
3
+ attributes :time_spent
4
+ end
@@ -0,0 +1,4 @@
1
+ class VisitsMetrics < Influxer::Metrics
2
+ tags :user_id, :gender
3
+ attributes :age, :page
4
+ end
@@ -0,0 +1,16 @@
1
+ shared_context "stub_query", :query do
2
+ let(:client) { Influxer.client }
3
+
4
+ before do
5
+ # Stub all query methods
6
+ allow_any_instance_of(InfluxDB::Client).to receive(:query) do |_, sql|
7
+ sql
8
+ end
9
+
10
+ allow_any_instance_of(Influxer::Client).to receive(:exec) do |_, sql|
11
+ sql
12
+ end
13
+
14
+ allow_any_instance_of(InfluxDB::Client).to receive(:post)
15
+ end
16
+ end
@@ -0,0 +1,14 @@
1
+ ActiveRecord::Schema.define do
2
+ create_table :users do |t|
3
+ t.string :email
4
+ t.integer :age
5
+ t.integer :gender
6
+ end
7
+ end
8
+
9
+ class User < ActiveRecord::Base
10
+ has_metrics
11
+ has_metrics :visits_metrics, class_name: "VisitsMetrics", inherits: [:gender, :age]
12
+ has_metrics :action_metrics, class_name: "ActionMetrics", foreign_key: :user
13
+ has_metrics :custom_metrics, class_name: "CustomMetrics", foreign_key: nil
14
+ end