inferx 0.2.3 → 0.2.4

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.
@@ -1,3 +1,3 @@
1
1
  class Inferx
2
- VERSION = '0.2.3'
2
+ VERSION = '0.2.4'
3
3
  end
@@ -8,74 +8,179 @@ describe Inferx::Categories do
8
8
  end
9
9
 
10
10
  describe Inferx::Categories, '#initialize' do
11
- it 'calls Inferx::Adapter#initialize' do
12
- redis = redis_stub
13
- categories = described_class.new(redis, :namespace => 'example', :manual => true)
14
- categories.instance_eval { @redis }.should == redis
15
- categories.instance_eval { @namespace }.should == 'example'
16
- categories.should be_manual
11
+ before do
12
+ @categories = described_class.new(redis_stub)
13
+ end
14
+
15
+ it 'sets "inferx:categories" to key attribute by default' do
16
+ @categories.key.should == 'inferx:categories'
17
+ end
18
+
19
+ it 'is not manual save by default' do
20
+ @categories.should_not be_manual
21
+ end
22
+
23
+ context 'with :namespace option' do
24
+ it 'considers the value to key attribute' do
25
+ categories = described_class.new(redis_stub, :namespace => 'example')
26
+ categories.key.should == 'inferx:example:categories'
27
+ end
28
+ end
29
+
30
+ context 'with :manual option' do
31
+ it 'is manual save if the value is true' do
32
+ categories = described_class.new(redis_stub, :manual => true)
33
+ categories.should be_manual
34
+ end
35
+
36
+ it 'is not manual save if the value is false' do
37
+ categories = described_class.new(redis_stub, :manual => false)
38
+ categories.should_not be_manual
39
+ end
17
40
  end
18
41
  end
19
42
 
20
- describe Inferx::Categories, '#all' do
21
- it 'calls Redis#hkeys' do
43
+ describe Inferx::Categories, '#filter' do
44
+ before do
22
45
  redis = redis_stub do |s|
23
- s.should_receive(:hkeys).with('inferx:categories')
46
+ s.stub!(:hkeys => %w(red green blue))
24
47
  end
25
48
 
26
- categories = described_class.new(redis)
27
- categories.all
49
+ @categories = described_class.new(redis)
28
50
  end
29
51
 
30
- it 'returns an empty array if the key is missing' do
52
+ it "returns an instance of #{described_class}" do
53
+ categories = @categories.filter('red', 'green')
54
+ categories.should be_an(described_class)
55
+ end
56
+
57
+ it 'returns an instance that is different from their own' do
58
+ categories = @categories.filter('red', 'green')
59
+ categories.object_id.should_not == @categories.object_id
60
+ end
61
+
62
+ it 'returns categories filtered by the category names' do
63
+ categories = @categories.filter('red', 'green')
64
+ categories.all.should == %w(red green)
65
+ end
66
+
67
+ context 'when calling many times' do
68
+ it 'returns categories filtered by the collective category names' do
69
+ categories = @categories.filter('red', 'green').filter('green')
70
+ categories.all.should == %w(green)
71
+ end
72
+ end
73
+ end
74
+
75
+ describe Inferx::Categories, '#except' do
76
+ before do
31
77
  redis = redis_stub do |s|
32
- s.stub!(:hkeys => [])
78
+ s.stub!(:hkeys => %w(red green blue))
33
79
  end
34
80
 
35
- categories = described_class.new(redis)
36
- categories.all.should be_empty
81
+ @categories = described_class.new(redis)
82
+ end
83
+
84
+ it "returns an instance of #{described_class}" do
85
+ categories = @categories.except('red')
86
+ categories.should be_an(described_class)
87
+ end
88
+
89
+ it 'returns an instance that is different from their own' do
90
+ categories = @categories.except('red')
91
+ categories.object_id.should_not == @categories.object_id
92
+ end
93
+
94
+ it 'returns categories filtered by the category names' do
95
+ categories = @categories.except('red')
96
+ categories.all.should == %w(green blue)
97
+ end
98
+
99
+ context 'when calling many times' do
100
+ it 'returns categories filtered by the successive category names' do
101
+ categories = @categories.except('red').except('green')
102
+ categories.all.should == %w(blue)
103
+ end
37
104
  end
38
105
  end
39
106
 
40
- describe Inferx::Categories, '#get' do
41
- it 'calls Redis#hget' do
42
- redis = redis_stub do |s|
43
- s.should_receive(:hget).with('inferx:categories', 'red').and_return('2')
107
+ describe Inferx::Categories, '#all' do
108
+ before do
109
+ @redis = redis_stub do |s|
110
+ s.stub!(:hkeys => %w(red green blue))
44
111
  end
45
112
 
46
- categories = described_class.new(redis)
47
- categories.get('red')
113
+ @categories = described_class.new(@redis)
48
114
  end
49
115
 
50
- it 'calles Inferx::Category.new with the instance of Redis, the category name and the options' do
51
- redis = redis_stub do |s|
52
- s.stub!(:hget => '2')
116
+ it 'calls Redis#hkeys' do
117
+ @redis.should_receive(:hkeys).with('inferx:categories')
118
+ @categories.all
119
+ end
120
+
121
+ it 'returns an instance of Array' do
122
+ @categories.all.should be_an(Array)
123
+ end
124
+
125
+ it 'returns an empty array if the key is missing' do
126
+ @redis.stub!(:hkeys => nil)
127
+ @categories.all.should be_empty
128
+ end
129
+
130
+ context 'when filtered' do
131
+ it 'returns filtered category names' do
132
+ categories = @categories.filter('red', 'green').except('red')
133
+ categories.all.should == %w(green)
134
+ end
135
+ end
136
+ end
137
+
138
+ describe Inferx::Categories, '#get' do
139
+ before do
140
+ @redis = redis_stub do |s|
141
+ s.stub!(:hget => '2', :hkeys => %w(red green blue))
53
142
  end
143
+ end
54
144
 
55
- Inferx::Category.should_receive(:new).with(redis, 'red', 2, :namespace => 'example', :manual => true)
56
- categories = described_class.new(redis, :namespace => 'example', :manual => true)
145
+ it 'calls Redis#hget' do
146
+ @redis.should_receive(:hget).with('inferx:categories', 'red').and_return('2')
147
+ categories = described_class.new(@redis)
57
148
  categories.get('red')
58
149
  end
59
150
 
60
- it 'returns an instance of Inferx::Category' do
61
- redis = redis_stub do |s|
62
- s.stub!(:hget => '2')
63
- end
151
+ it 'calles Inferx::Category.new with the instance of Redis, the categories, the category name and total of scores' do
152
+ categories = described_class.new(@redis)
153
+ Inferx::Category.should_receive(:new).with(@redis, categories, 'red', 2)
154
+ categories.get('red')
155
+ end
64
156
 
65
- categories = described_class.new(redis)
157
+ it 'returns an instance of Inferx::Category' do
158
+ categories = described_class.new(@redis)
66
159
  categories.get('red').should be_an(Inferx::Category)
67
160
  end
68
161
 
69
162
  context 'with a missing category' do
70
163
  it 'raises ArgumentError' do
71
- redis = redis_stub do |s|
72
- s.stub!(:hget => nil)
73
- end
74
-
75
- categories = described_class.new(redis)
164
+ @redis.stub!(:hget => nil)
165
+ categories = described_class.new(@redis)
76
166
  lambda { categories.get('red') }.should raise_error(ArgumentError, /"red" is missing/)
77
167
  end
78
168
  end
169
+
170
+ context 'when filtered' do
171
+ it 'raises ArgumentError if the category is not defined in filtered categories' do
172
+ categories = described_class.new(@redis)
173
+ categories = categories.filter('red', 'green').except('red')
174
+ lambda { categories.get('red') }.should raise_error(ArgumentError, '"red" does not exist in filtered categories')
175
+ end
176
+ end
177
+
178
+ context 'when construct with :complementary option' do
179
+ it 'returns an instance of Inferx::Category::Complementary' do
180
+ categories = described_class.new(@redis, :complementary => true)
181
+ categories.get('red').should be_an(Inferx::Category::Complementary)
182
+ end
183
+ end
79
184
  end
80
185
 
81
186
  describe Inferx::Categories, '#add' do
@@ -152,38 +257,39 @@ describe Inferx::Categories, '#remove' do
152
257
  end
153
258
 
154
259
  describe Inferx::Categories, '#exists?' do
155
- it 'calls Redis#hexists' do
260
+ before do
156
261
  redis = redis_stub.tap do |s|
157
- s.should_receive(:hexists).with('inferx:categories', 'red')
262
+ s.stub!(:hkeys => %w(red green blue))
158
263
  end
159
264
 
160
- categories = described_class.new(redis)
161
- categories.exists?('red')
265
+ @categories = described_class.new(redis)
162
266
  end
163
267
 
164
268
  it 'returns true if the category is defined' do
165
- redis = redis_stub.tap do |s|
166
- s.stub!(:hexists => true)
167
- end
168
-
169
- categories = described_class.new(redis)
170
- categories.should be_exists('red')
269
+ @categories.should be_exists('red')
171
270
  end
172
271
 
173
272
  it 'returns false if the category is not defined' do
174
- redis = redis_stub.tap do |s|
175
- s.stub!(:hexists => false)
273
+ @categories.should_not be_exists('cyan')
274
+ end
275
+
276
+ context 'when filtered' do
277
+ it 'returns true if the category is defined in filtered categories' do
278
+ categories = @categories.filter('red', 'green').except('red')
279
+ categories.should be_exists('green')
176
280
  end
177
281
 
178
- categories = described_class.new(redis)
179
- categories.should_not be_exists('red')
282
+ it 'returns false if the category is not defined in filtered categories' do
283
+ categories = @categories.filter('red', 'green').except('red')
284
+ categories.should_not be_exists('red')
285
+ end
180
286
  end
181
287
  end
182
288
 
183
289
  describe Inferx::Categories, '#each' do
184
290
  before do
185
291
  @redis = redis_stub do |s|
186
- s.stub!(:hgetall => {
292
+ s.stub!(:hkeys => %w(red green blue), :hgetall => {
187
293
  'red' => 2,
188
294
  'green' => 3,
189
295
  'blue' => 1
@@ -202,21 +308,181 @@ describe Inferx::Categories, '#each' do
202
308
  categories.each { |category| n += 1 }
203
309
  n.should == 3
204
310
  end
311
+
312
+ context 'when filtered' do
313
+ it 'passes an instance of Inferx::Category in filtered categories to the block' do
314
+ categories = described_class.new(@redis)
315
+ categories = categories.filter('red', 'green').except('red')
316
+ category_names = []
317
+ categories.each { |category| category_names << category.name }
318
+ category_names.should == %w(green)
319
+ end
320
+ end
321
+
322
+ context 'when construct with :complementary option' do
323
+ it 'passes an instance of Inferx::Category::Complementary to the block' do
324
+ categories = described_class.new(@redis, :complementary => true)
325
+ categories.each { |category| category.should be_an(Inferx::Category::Complementary) }
326
+ end
327
+ end
205
328
  end
206
329
 
207
- describe Inferx::Categories, '#spawn_category' do
330
+ describe Inferx::Categories, '#inject' do
208
331
  before do
209
- @categories = described_class.new(redis_stub).tap do |s|
210
- s.stub!(:spawn => 'category')
332
+ @redis = redis_stub do |s|
333
+ s.stub!(:hkeys => %w(red green blue))
334
+ s.stub!(:zincrby)
335
+ s.stub!(:hincrby)
336
+ end
337
+
338
+ @categories = described_class.new(@redis).filter('red', 'green')
339
+ end
340
+
341
+ it 'calls Redis#zincrby and Redis#hincrby for the categories' do
342
+ @redis.tap do |s|
343
+ s.should_receive(:zincrby).with('inferx:categories:red', 2, 'apple')
344
+ s.should_receive(:zincrby).with('inferx:categories:red', 3, 'strawberry')
345
+ s.should_receive(:hincrby).with('inferx:categories', 'red', 5)
346
+
347
+ s.should_receive(:zincrby).with('inferx:categories:green', 2, 'apple')
348
+ s.should_receive(:zincrby).with('inferx:categories:green', 3, 'strawberry')
349
+ s.should_receive(:hincrby).with('inferx:categories', 'green', 5)
350
+
351
+ s.should_not_receive(:zincrby).with('inferx:categories:blue', 2, 'apple')
352
+ s.should_not_receive(:zincrby).with('inferx:categories:blue', 3, 'strawberry')
353
+ s.should_not_receive(:hincrby).with('inferx:categories', 'blue', 5)
354
+
355
+ s.should_receive(:save)
211
356
  end
357
+
358
+ @categories.inject(%w(apple strawberry apple strawberry strawberry))
212
359
  end
213
360
 
214
- it 'calls #spawn with Inferx::Category and the arguments' do
215
- @categories.should_receive(:spawn).with(Inferx::Category, 'arg1', 'arg2')
216
- @categories.__send__(:spawn_category, 'arg1', 'arg2')
361
+ it 'returns an instance of Hash' do
362
+ increases = @categories.inject(%w(apple strawberry apple strawberry strawberry))
363
+ increases.should be_a(Hash)
364
+ end
365
+
366
+ it 'returns increase for each category' do
367
+ increases = @categories.inject(%w(apple strawberry apple strawberry strawberry))
368
+ increases.should == {'red' => 5, 'green' => 5}
369
+ end
370
+
371
+ context 'with empty categories' do
372
+ it 'returns an empty hash' do
373
+ categories = @categories.except('red', 'green')
374
+ increases = categories.inject(%w(apple strawberry apple strawberry strawberry))
375
+ increases.should be_empty
376
+ end
217
377
  end
218
378
 
219
- it 'returns the return value from #spawn' do
220
- @categories.__send__(:spawn_category, 'arg1', 'arg2').should == 'category'
379
+ context 'with empty words' do
380
+ it 'returns zero fluctuation' do
381
+ increases = @categories.inject([])
382
+ increases.should == {'red' => 0, 'green' => 0}
383
+ end
384
+ end
385
+
386
+ context 'with manual save' do
387
+ it 'does not call Redis#save' do
388
+ @redis.tap do |s|
389
+ s.should_not_receive(:save)
390
+ end
391
+
392
+ categories = described_class.new(@redis, :manual => true)
393
+ categories.inject(%w(apple strawberry apple strawberry strawberry))
394
+ end
395
+ end
396
+ end
397
+
398
+ describe Inferx::Categories, '#eject' do
399
+ before do
400
+ @redis = redis_stub do |s|
401
+ s.stub!(:hkeys => %w(red green blue))
402
+
403
+ s.stub!(:pipelined).and_return do |&block|
404
+ block.call
405
+ %w(3 2 0) + %w(3 2 0)
406
+ end
407
+
408
+ s.stub!(:zincrby)
409
+ s.stub!(:zremrangebyscore)
410
+ s.stub!(:hincrby)
411
+ end
412
+
413
+ @categories = described_class.new(@redis).filter('red', 'green')
414
+ end
415
+
416
+ it 'calls Redis#zincrby, Redis#zremrangebyscore and Redis#hincrby for the categories' do
417
+ @redis.tap do |s|
418
+ s.should_receive(:zincrby).with('inferx:categories:red', -2, 'apple')
419
+ s.should_receive(:zincrby).with('inferx:categories:red', -3, 'strawberry')
420
+ s.should_receive(:zremrangebyscore).with('inferx:categories:red', '-inf', 0)
421
+ s.should_receive(:hincrby).with('inferx:categories', 'red', -5)
422
+
423
+ s.should_receive(:zincrby).with('inferx:categories:green', -2, 'apple')
424
+ s.should_receive(:zincrby).with('inferx:categories:green', -3, 'strawberry')
425
+ s.should_receive(:zremrangebyscore).with('inferx:categories:green', '-inf', 0)
426
+ s.should_receive(:hincrby).with('inferx:categories', 'green', -5)
427
+
428
+ s.should_not_receive(:zincrby).with('inferx:categories:blue', 2, 'apple')
429
+ s.should_not_receive(:zincrby).with('inferx:categories:blue', 3, 'strawberry')
430
+ s.should_not_receive(:zremrangebyscore).with('inferx:categories:blue', '-inf', 0)
431
+ s.should_not_receive(:hincrby).with('inferx:categories', 'blue', 5)
432
+
433
+ s.should_receive(:save)
434
+ end
435
+
436
+ @categories.eject(%w(apple strawberry apple strawberry strawberry))
437
+ end
438
+
439
+ it 'returns an instance of Hash' do
440
+ decreases = @categories.eject(%w(apple strawberry apple strawberry strawberry))
441
+ decreases.should be_a(Hash)
442
+ end
443
+
444
+ it 'returns decrease for each category' do
445
+ decreases = @categories.eject(%w(apple strawberry apple strawberry strawberry))
446
+ decreases.should == {'red' => 5, 'green' => 5}
447
+ end
448
+
449
+ it 'adjusts decrease' do
450
+ @redis.tap do |s|
451
+ s.stub!(:pipelined).and_return do |&block|
452
+ block.call
453
+ %w(3 2 0) + %w(-1 -2 2)
454
+ end
455
+
456
+ s.should_receive(:hincrby).with('inferx:categories', 'green', -2)
457
+ end
458
+
459
+ decreases = @categories.eject(%w(apple strawberry apple strawberry strawberry))
460
+ decreases.should == {'red' => 5, 'green' => 2}
461
+ end
462
+
463
+ context 'with empty categories' do
464
+ it 'returns an empty hash' do
465
+ categories = @categories.except('red', 'green')
466
+ decreases = categories.eject(%w(apple strawberry apple strawberry strawberry))
467
+ decreases.should be_empty
468
+ end
469
+ end
470
+
471
+ context 'with empty words' do
472
+ it 'returns zero fluctuation' do
473
+ decreases = @categories.eject([])
474
+ decreases.should == {'red' => 0, 'green' => 0}
475
+ end
476
+ end
477
+
478
+ context 'with manual save' do
479
+ it 'does not call Redis#save' do
480
+ @redis.tap do |s|
481
+ s.should_not_receive(:save)
482
+ end
483
+
484
+ categories = described_class.new(@redis, :manual => true)
485
+ categories.eject(%w(apple strawberry apple strawberry strawberry))
486
+ end
221
487
  end
222
488
  end