influxer 0.2.4 → 0.3.1

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.
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