swagger 1.4.0 → 1.4.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.
- data/.gitignore +1 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +62 -0
- data/README.rdoc +9 -7
- data/Rakefile +7 -43
- data/lib/resque_extension.rb +3 -3
- data/lib/resque_value.rb +0 -1
- data/lib/swagger.rb +5 -2
- data/lib/swagger/commands/helpers.rb +16 -0
- data/lib/swagger/commands/keys.rb +21 -0
- data/lib/swagger/commands/lists.rb +53 -0
- data/lib/swagger/commands/sets.rb +25 -0
- data/lib/swagger/commands/sorted_sets.rb +56 -0
- data/lib/swagger/commands/strings.rb +60 -0
- data/lib/swagger/redis.rb +26 -0
- data/lib/swagger/swallow.rb +14 -0
- data/lib/swagger/version.rb +7 -0
- data/spec/resque_extension_spec.rb +6 -7
- data/spec/spec_helper.rb +17 -14
- data/spec/support/helpers.rb +7 -0
- data/spec/swagger/commands/sorted_sets_spec.rb +175 -0
- data/spec/swagger/commands/strings_spec.rb +58 -0
- data/spec/swagger/redis_spec.rb +171 -0
- data/swagger.gemspec +12 -52
- metadata +74 -35
- data/VERSION +0 -1
- data/lib/redis_impersonator.rb +0 -129
- data/spec/redis_impersonator_spec.rb +0 -171
- data/spec/spec.opts +0 -1
@@ -0,0 +1,14 @@
|
|
1
|
+
module Swagger
|
2
|
+
module Swallow
|
3
|
+
|
4
|
+
def swallow(method, return_value = nil)
|
5
|
+
define_method(method) do |*args|
|
6
|
+
if defined?(LOGGER)
|
7
|
+
LOGGER.write "Swagger::Redis swallowed #{method} with the following arguments #{args.inspect}"
|
8
|
+
end
|
9
|
+
return_value
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
@@ -1,12 +1,11 @@
|
|
1
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe 'Resque' do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
it 'swaps redis implementation with Swagger::Redis' do
|
5
|
+
Resque.redis.should be_a(Swagger::Redis)
|
6
|
+
end
|
7
|
+
|
9
8
|
it 'can connect to the database' do
|
10
9
|
Resque.should.respond_to?(:connect_to_database)
|
11
10
|
end
|
12
|
-
end
|
11
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,31 +1,34 @@
|
|
1
1
|
require 'rubygems'
|
2
|
-
require '
|
2
|
+
require 'bundler'
|
3
|
+
Bundler.setup
|
3
4
|
|
4
|
-
|
5
|
-
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
5
|
+
require 'resque'
|
6
6
|
require 'swagger'
|
7
|
-
require 'spec'
|
8
|
-
require 'spec/autorun'
|
9
7
|
|
10
|
-
|
8
|
+
Dir['./spec/support/*.rb'].map {|f| require f }
|
11
9
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
10
|
+
RSpec.configure do |config|
|
11
|
+
config.color_enabled = true
|
12
|
+
config.before { ResqueValue.delete_all }
|
16
13
|
end
|
17
14
|
|
18
15
|
Resque.swagger!
|
19
16
|
|
20
17
|
ActiveRecord::Base.establish_connection('adapter' => 'sqlite3', 'database' => 'test.db')
|
21
18
|
|
22
|
-
|
19
|
+
begin
|
20
|
+
ActiveRecord::Base.connection.drop_table :resque_values
|
21
|
+
rescue
|
22
|
+
puts "unable to drop resque_values, probably because it has not been created yet"
|
23
|
+
end
|
24
|
+
|
23
25
|
ActiveRecord::Base.connection.create_table :resque_values do |table|
|
24
26
|
table.column :key, :string
|
25
27
|
table.column :key_type, :string
|
26
|
-
table.column :
|
28
|
+
table.column :score, :integer
|
29
|
+
table.column :value, :text
|
30
|
+
table.timestamps
|
27
31
|
end
|
28
32
|
|
29
33
|
ActiveRecord::Base.connection.add_index :resque_values, :key
|
30
|
-
ActiveRecord::Base.connection.add_index :resque_values, [:key, :key_type]
|
31
|
-
|
34
|
+
ActiveRecord::Base.connection.add_index :resque_values, [:key, :key_type]
|
@@ -0,0 +1,175 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Swagger
|
4
|
+
describe Redis, 'sorted sets' do
|
5
|
+
|
6
|
+
describe '#zadd' do
|
7
|
+
it 'adds a new record' do
|
8
|
+
expect_count_to_change { add_record }
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'sets the record attributes correctly' do
|
12
|
+
record = add_record
|
13
|
+
record.key.should eq('key')
|
14
|
+
record.score.should eq(100)
|
15
|
+
record.value.should eq('value')
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'with a record added' do
|
19
|
+
let!(:record) { add_record }
|
20
|
+
|
21
|
+
it 'does not add a new record if the values are the same' do
|
22
|
+
expect_count_to_not_change { add_record }
|
23
|
+
end
|
24
|
+
|
25
|
+
it "updates the record's score if it's different" do
|
26
|
+
add_record(:score => 500)
|
27
|
+
record.reload.score.should eq(500)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'adds another record if the key is different' do
|
31
|
+
expect_count_to_change { add_record(:key => 'key2') }
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'adds another record if the value is different' do
|
35
|
+
expect_count_to_change { add_record(:value => 'value2') }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '#zrem' do
|
41
|
+
context 'with a record added' do
|
42
|
+
let!(:record) { add_record(:key => 'k', :value => 'v') }
|
43
|
+
|
44
|
+
it 'deletes the record' do
|
45
|
+
expect_count_to_change(-1) { subject.zrem(:k, 'v') }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe '#zcard' do
|
51
|
+
context 'with 3 records added' do
|
52
|
+
before do
|
53
|
+
add_record(:score => '1', :value => '#1')
|
54
|
+
add_record(:score => '3', :value => '#3')
|
55
|
+
add_record(:score => '2', :value => '#2')
|
56
|
+
end
|
57
|
+
|
58
|
+
specify { subject.zcard(:key).should eq(3) }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe '#zrange' do
|
63
|
+
context 'with 5 records added' do
|
64
|
+
before do
|
65
|
+
add_record(:score => 1, :value => '#1')
|
66
|
+
add_record(:score => 3, :value => '#3')
|
67
|
+
add_record(:score => 2, :value => '#2')
|
68
|
+
add_record(:score => 5, :value => '#5')
|
69
|
+
add_record(:score => 4, :value => '#4')
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'given the entire range' do
|
73
|
+
let(:values) { subject.zrange(:key, 0, -1) }
|
74
|
+
|
75
|
+
specify { values.should have(5).values }
|
76
|
+
|
77
|
+
it 'sorts the values by score' do
|
78
|
+
values[0].should eq('#1')
|
79
|
+
values[1].should eq('#2')
|
80
|
+
values[2].should eq('#3')
|
81
|
+
values[3].should eq('#4')
|
82
|
+
values[4].should eq('#5')
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context 'given a range of 1 to 3' do
|
87
|
+
let(:values) { subject.zrange(:key, 1, 3) }
|
88
|
+
|
89
|
+
specify { values.should have(3).values }
|
90
|
+
|
91
|
+
it 'sorts the values by score' do
|
92
|
+
values[0].should eql('#2')
|
93
|
+
values[1].should eql('#3')
|
94
|
+
values[2].should eql('#4')
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe '#zrangebyscore' do
|
101
|
+
context 'with 5 records added' do
|
102
|
+
before do
|
103
|
+
add_record(:score => 1, :value => '#1')
|
104
|
+
add_record(:score => 3, :value => '#3')
|
105
|
+
add_record(:score => 2, :value => '#2')
|
106
|
+
add_record(:score => 5, :value => '#5')
|
107
|
+
add_record(:score => 4, :value => '#4')
|
108
|
+
end
|
109
|
+
|
110
|
+
context 'given the entire range' do
|
111
|
+
let(:values) { subject.zrangebyscore(:key, 1, 5) }
|
112
|
+
|
113
|
+
specify { values.should have(5).values }
|
114
|
+
|
115
|
+
it 'sorts the values by score' do
|
116
|
+
values[0].should eq('#1')
|
117
|
+
values[1].should eq('#2')
|
118
|
+
values[2].should eq('#3')
|
119
|
+
values[3].should eq('#4')
|
120
|
+
values[4].should eq('#5')
|
121
|
+
end
|
122
|
+
|
123
|
+
context 'and :limit option' do
|
124
|
+
context 'with 1 offset and 3 count' do
|
125
|
+
let(:values) do
|
126
|
+
subject.zrangebyscore(:key, 1, 5, :limit => [1, 3])
|
127
|
+
end
|
128
|
+
|
129
|
+
specify { values.should have(3).values }
|
130
|
+
|
131
|
+
it 'sorts the values by score' do
|
132
|
+
values[0].should eq('#2')
|
133
|
+
values[1].should eq('#3')
|
134
|
+
values[2].should eq('#4')
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
context 'given -inf (lowest score) and 3' do
|
141
|
+
let(:values) { subject.zrangebyscore(:key, '-inf', 3) }
|
142
|
+
|
143
|
+
specify { values.should have(3).values }
|
144
|
+
|
145
|
+
it 'sorts the values by score' do
|
146
|
+
values[0].should eq('#1')
|
147
|
+
values[1].should eq('#2')
|
148
|
+
values[2].should eq('#3')
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
context 'given 3 and +inf (highest score)' do
|
153
|
+
let(:values) { subject.zrangebyscore(:key, 3, '+inf') }
|
154
|
+
|
155
|
+
specify { values.should have(3).values }
|
156
|
+
|
157
|
+
it 'sorts the values by score' do
|
158
|
+
values[0].should eq('#3')
|
159
|
+
values[1].should eq('#4')
|
160
|
+
values[2].should eq('#5')
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def add_record(args = {})
|
167
|
+
key = args.fetch(:key) { 'key' }
|
168
|
+
score = args.fetch(:score) { 100 }
|
169
|
+
value = args.fetch(:value) { 'value' }
|
170
|
+
|
171
|
+
subject.zadd(key, score, value)
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Swagger
|
4
|
+
describe Redis, 'strings' do
|
5
|
+
|
6
|
+
describe '#setnx' do
|
7
|
+
it 'adds a new record' do
|
8
|
+
expect_count_to_change { add_record }
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'sets the record attributes correctly' do
|
12
|
+
record = add_record
|
13
|
+
record.key.should eq('key')
|
14
|
+
record.value.should eq('value')
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'with a record added' do
|
18
|
+
let!(:record) { add_record }
|
19
|
+
|
20
|
+
it 'does not add a new record if the values are the same' do
|
21
|
+
expect_count_to_not_change { add_record }
|
22
|
+
end
|
23
|
+
|
24
|
+
it "does not update the record's value if it's different" do
|
25
|
+
add_record(:value => 'foo')
|
26
|
+
record.reload.value.should eq('value')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#incr' do
|
32
|
+
let!(:record) { add_record(:value => '1') }
|
33
|
+
|
34
|
+
it "increments a record's value by one" do
|
35
|
+
subject.incr('key')
|
36
|
+
record.reload.value.should eq('2')
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '#decr' do
|
41
|
+
let!(:record) { add_record(:value => '1') }
|
42
|
+
|
43
|
+
it "decrements a record's value by one" do
|
44
|
+
subject.decr('key')
|
45
|
+
record.reload.value.should eq('0')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def add_record(args = {})
|
50
|
+
key = args.fetch(:key) { 'key' }
|
51
|
+
value = args.fetch(:value) { 'value' }
|
52
|
+
|
53
|
+
subject.setnx(key, value)
|
54
|
+
ResqueValue.find_by_key_and_value(key, value)
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,171 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Swagger
|
4
|
+
describe Redis do
|
5
|
+
it 'responds to info' do
|
6
|
+
subject.info.should_not be_nil
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'swallows calls to namespace' do
|
10
|
+
lambda{subject.namespace = 'value'}.should_not raise_error
|
11
|
+
end
|
12
|
+
|
13
|
+
describe 'manipulating key values' do
|
14
|
+
it 'it can get key values' do
|
15
|
+
subject.set('key', 'value').should == 'value'
|
16
|
+
subject.get('key').should == 'value'
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'can create new key values' do
|
20
|
+
subject.set('key', 'value').should == 'value'
|
21
|
+
ResqueValue.first.value.should == 'value'
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'can delete key values' do
|
25
|
+
subject.set('key', 'value').should == 'value'
|
26
|
+
subject.del('key')
|
27
|
+
subject.get('key').should be_nil
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'can get multiple values by keys' do
|
31
|
+
subject.set('key-1', 'one')
|
32
|
+
subject.set('key-2', 'two')
|
33
|
+
subject.mapped_mget('key-1', 'key-2')['key-1'].should == 'one'
|
34
|
+
subject.mapped_mget('key-1', 'key-2')['key-2'].should == 'two'
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'always returns all keys when pattern is *' do
|
38
|
+
subject.set('key-1', 'one')
|
39
|
+
subject.set('key-2', 'two')
|
40
|
+
subject.keys('*').should include('key-1', 'key-2')
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'raises error when pattern is not *' do
|
44
|
+
lambda{subject.keys('something not *')}.should raise_error
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe 'managing workes in a set' do
|
49
|
+
it 'can add workers to the queue' do
|
50
|
+
worker = Resque::Worker.new(queues = ['queue1'])
|
51
|
+
subject.sadd(:workers, worker)
|
52
|
+
ResqueValue.first.value.should == worker.to_s
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'returns all values in the workers set' do
|
56
|
+
worker = Resque::Worker.new(queues = ['queue1'])
|
57
|
+
subject.sadd(:workers, worker)
|
58
|
+
subject.smembers(:workers).first.should == worker.to_s
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'removes a worker from the workers set by name' do
|
62
|
+
worker = Resque::Worker.new(queues = ['queue1'])
|
63
|
+
subject.sadd(:workers, worker)
|
64
|
+
subject.srem(:workers, worker)
|
65
|
+
subject.smembers(:workers).should be_empty
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'should only add a value to a set once' do
|
69
|
+
subject.sadd(:test, 'one')
|
70
|
+
subject.sadd(:test, 'one')
|
71
|
+
subject.smembers(:test).size.should == 1
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'indicates when worker is in the workers set' do
|
75
|
+
worker = Resque::Worker.new(queues = ['queue1'])
|
76
|
+
|
77
|
+
subject.sismember(:workers, worker).should == false
|
78
|
+
subject.sadd(:workers, worker)
|
79
|
+
subject.sismember(:workers, worker).should == true
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'can delete a whole set by name' do
|
83
|
+
subject.sadd(:test, 'one')
|
84
|
+
subject.sadd(:test, 'two')
|
85
|
+
subject.del(:test)
|
86
|
+
subject.smembers(:test).should be_empty
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe 'working with lists' do
|
91
|
+
it 'should return nil if no items on a queue' do
|
92
|
+
subject.lpop('some_queue').should be_nil
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'ingores index and adds item to list' do
|
96
|
+
subject.lset('some_queue', 88, 'value')
|
97
|
+
subject.llen('some_queue').should == 1
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'should add item to queue and then pop it back off' do
|
101
|
+
subject.rpush('some_queue', 'value')
|
102
|
+
subject.lpop('some_queue').should == 'value'
|
103
|
+
subject.lpop('some_queue').should be_nil
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should tell you how many items are in a list' do
|
107
|
+
subject.rpush('some_queue', 'one')
|
108
|
+
subject.rpush('some_queue', 'two')
|
109
|
+
subject.llen('some_queue').should == 2
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'should be able to paginate through a list' do
|
113
|
+
subject.rpush('some_queue', 'one')
|
114
|
+
subject.rpush('some_queue', 'two')
|
115
|
+
subject.rpush('some_queue', 'three')
|
116
|
+
subject.lrange('some_queue', 0, 1).first.should == 'one'
|
117
|
+
subject.lrange('some_queue', 2, 3).first.should == 'three'
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'should get all results if you pass -1 to lrange' do
|
121
|
+
subject.rpush('some_queue', 'one')
|
122
|
+
subject.rpush('some_queue', 'two')
|
123
|
+
subject.rpush('some_queue', 'three')
|
124
|
+
subject.lrange('some_queue', 0, -1).should include('one', 'two', 'three')
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'should remove items from queue' do
|
128
|
+
subject.rpush('some_queue', 'one')
|
129
|
+
subject.rpush('some_queue', 'two')
|
130
|
+
subject.rpush('some_queue', 'two')
|
131
|
+
subject.lrem('some_queue', 0, 'two').should == 2
|
132
|
+
subject.lrange('some_queue', 0, -1).should include('one')
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should trim according to the specifed start and end" do
|
136
|
+
1.upto(6){|i| subject.rpush('some_queue', i)}
|
137
|
+
subject.ltrim('some_queue', 1, 3)
|
138
|
+
subject.llen('some_queue').should == 3
|
139
|
+
subject.lrange('some_queue', 0, 2).should == ["2","3","4"]
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should not affect other keys when trimming" do
|
143
|
+
1.upto(3){|i| subject.rpush('some_queue', i)}
|
144
|
+
subject.set('something_else', 'independent value')
|
145
|
+
subject.ltrim('some_queue', 0, 0)
|
146
|
+
subject.get('something_else').should == 'independent value'
|
147
|
+
end
|
148
|
+
|
149
|
+
it "should get a range of values" do
|
150
|
+
1.upto(6){|i| subject.rpush('some_queue', i)}
|
151
|
+
subject.lrange('some_queue', 0, 5).should == ['1','2','3','4','5','6']
|
152
|
+
subject.lrange('some_queue', 1, 3).should == ['2','3','4']
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'should increment a value' do
|
157
|
+
subject.incrby('something', 2)
|
158
|
+
subject.get('something').should == '2'
|
159
|
+
subject.incrby('something', 1)
|
160
|
+
subject.get('something').should == '3'
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'should decrement a value' do
|
164
|
+
subject.incrby('something', 2)
|
165
|
+
subject.get('something').should == '2'
|
166
|
+
subject.decrby('something', 1)
|
167
|
+
subject.get('something').should == '1'
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
171
|
+
end
|