rollout-dynamodb 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fec540bc701467a7e30414f581699009230e0185
4
- data.tar.gz: 28dff4465caca5250270c6216cc104de4efa8312
3
+ metadata.gz: dbe73c5e20cb8e44d3a6b3c039c98c07c7b35090
4
+ data.tar.gz: bea9f702c2b8ea0d33a87c39d5ca6107ff541122
5
5
  SHA512:
6
- metadata.gz: e8b2c4128eb2c427ec632c90219d4fa5d86f8fd9c828196e27b3aeec9315a0d01d0c0d2dcb331c5d2b95db420bd7a2d95337311eaa37033e6f9f94816592d21d
7
- data.tar.gz: 380f702669187f9dd65bd83e71baf2583b256aafc7cc7cf1f8dd78d4a4b1535705f4b81ee3c48932d7d1fc29a617ce79c7b0907a59e99a22a5f7d452c3a215a1
6
+ metadata.gz: fd41ae08bb42d32fb069badc5ec43f692aef3603cc45e63f01dfd6aac0c863350a2eb37fe22e5a6c5efc8cb084907ccd72aca07db97fa2cdc9dd42b4d3b2fdfd
7
+ data.tar.gz: 9334c5fc8f01ac16411228cd89ae9bd4bee1bf04e482e5a0981d66d3e7c7578815142c399c9254bfe74a77048f30939ee5e2d1c92a349bb008921172db072a4a
data/.env.test ADDED
@@ -0,0 +1,6 @@
1
+ #EXCON_DEBUG=true
2
+ TEST_DYNAMO_ACCESS_KEY=
3
+ TEST_DYNAMO_SECRET_KEY=
4
+ TEST_DYNAMO_TABLE_NAME=
5
+ TEST_DYNAMO_REGION=
6
+ TEST_SKIP_SLOW=yes
data/README.md CHANGED
@@ -40,6 +40,25 @@ $rollout.active?(:chat)
40
40
  # -> true
41
41
  ```
42
42
 
43
+ ### Testing
44
+
45
+ You might want to test this code. You can get started like so:
46
+
47
+ ```bash
48
+ foreman run rake
49
+ ```
50
+
51
+ Note that there are integration tests bundled in with the specs. If you want to run them, follow the steps below, otherwise they will be skipped.
52
+
53
+ 1. Go to the AWS console for DynamoDB
54
+ 2. Create a new table, indexed by hash key named `id` of type `String`
55
+ 3. Set up the environment
56
+
57
+ ```bash
58
+ mv .env.test .env
59
+ $EDITOR .env # set config vars
60
+ ```
61
+
43
62
  ## Contributing
44
63
 
45
64
  1. Fork it ( https://github.com/chooper/rollout-dynamodb/fork )
data/Rakefile CHANGED
@@ -4,89 +4,3 @@ require 'rspec/core/rake_task'
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
  task :default => :spec
6
6
 
7
- def name
8
- @name ||= Dir['*.gemspec'].first.split('.').first
9
- end
10
-
11
- def version
12
- line = File.read("lib/#{name}.rb")[/^\s*VERSION\s*=\s*.*/]
13
- line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1]
14
- end
15
-
16
- def date
17
- Date.today.to_s
18
- end
19
-
20
- def rubyforge_project
21
- name
22
- end
23
-
24
- def gemspec_file
25
- "#{name}.gemspec"
26
- end
27
-
28
- def gem_file
29
- "#{name}-#{version}.gem"
30
- end
31
-
32
- def replace_header(head, header_name)
33
- head.sub!(/(\.#{header_name}\s*= ').*'/) { "#{$1}#{send(header_name)}'"}
34
- end
35
-
36
- desc "Open an irb session preloaded with this library"
37
- task :console do
38
- sh "irb -rubygems -r ./lib/#{name}.rb"
39
- end
40
-
41
- desc "Create tag v#{version} and build and push #{gem_file} to Rubygems"
42
- task :release => :build do
43
- unless `git branch` =~ /^\* master$/
44
- puts "You must be on the master branch to release!"
45
- exit!
46
- end
47
- sh "git commit --allow-empty -a -m 'Release #{version}'"
48
- sh "git tag v#{version}"
49
- sh "git push origin master"
50
- sh "git push origin v#{version}"
51
- sh "gem push pkg/#{name}-#{version}.gem"
52
- end
53
-
54
- desc "Build #{gem_file} into the pkg directory"
55
- task :build => :gemspec do
56
- sh "mkdir -p pkg"
57
- sh "gem build #{gemspec_file}"
58
- sh "mv #{gem_file} pkg"
59
- end
60
-
61
- desc "Generate #{gemspec_file}"
62
- task :gemspec => :validate do
63
- # read spec file and split out manifest section
64
- spec = File.read(gemspec_file)
65
- #head, manifest, tail = spec,split(" # = MANIFEST =\n")
66
-
67
- # replace name version and date
68
- replace_header(spec, :name)
69
- replace_header(spec, :version)
70
- replace_header(spec, :date)
71
- #comment this out if your rubyforge_project has a different name
72
- replace_header(spec, :rubyforge_project)
73
-
74
- # piece file back together and write
75
- File.open(gemspec_file, 'w') { |io| io.write(spec) }
76
- puts "Updated #{gemspec_file}"
77
- end
78
-
79
- desc "Validate #{gemspec_file}"
80
- task :validate do
81
- prefix = name[/^([^-]*)/, 1]
82
- libfiles = Dir['lib/*'] - ["lib/#{name}.rb", "lib/#{name}", "lib/#{prefix}"]
83
- unless libfiles.empty?
84
- puts "Directory `lib` should only contain a `#{name}.rb` file and `#{name}` dir."
85
- exit!
86
- end
87
- unless Dir['VERSION*'].empty?
88
- puts "A `VERSION` file at root level violates Gem best practices."
89
- exit!
90
- end
91
- end
92
-
@@ -1,5 +1,8 @@
1
1
  class Rollout
2
+
3
+ ##
4
+ # This module contains all of the DynamoDB related code
2
5
  module DynamoDB
3
- VERSION = "0.0.3"
6
+ VERSION = "0.0.4"
4
7
  end
5
8
  end
@@ -1,8 +1,21 @@
1
1
 
2
2
  require 'fog'
3
3
 
4
+ ##
5
+ # This module is a container for all things related to Rollout+DynamoDB functionality
4
6
  module Rollout::DynamoDB
7
+
8
+ ##
9
+ # This class implements the Storage API for Rollout
5
10
  class Storage
11
+
12
+ ##
13
+ # `options` is a Hash which may include:
14
+ # * `:connection_options` - a Hash which may in turn include:
15
+ # * `:connect_timeout` - Connection timeout to DynamoDB in seconds (default: `3`)
16
+ # * `:read_timeout` - Read timeout to DynamoDB in seconds (default: `3`)
17
+ # * `:write_timeout` - Write timeout to DynamoDB in seconds (default: `3`)
18
+ # * `:retry_limit` - Number of times to retry HTTP requests to DynamoDB (default: `4`)
6
19
  def initialize(aws_access_key, aws_secret_key, table_name, region, options = {})
7
20
  @aws_access_key = aws_access_key
8
21
  @aws_secret_key = aws_secret_key
@@ -18,23 +31,42 @@ module Rollout::DynamoDB
18
31
  @options[:connection_options][:retry_limit] ||= 4
19
32
  end
20
33
 
34
+ ##
35
+ # Gets the value (*String*) of a key (*String*) from DynamoDB. Returns the
36
+ # value or raises an exception on error
21
37
  def get(key)
22
38
  response = db.get_item(@table_name, {'HashKeyElement' => {'S' => key}})
23
39
  get_item_from_body(response.body)
24
40
  end
25
41
 
42
+ ##
43
+ # Sets the value (*String*) of a key (*String*) in DynamoDB. Returns `true`
44
+ # on success, raises an exception on error
26
45
  def set(key, value)
27
46
  response = db.put_item(@table_name, {'id' => {'S' => key}, 'value' => {'S' => value}})
28
47
  true
29
48
  end
30
49
 
50
+ ##
51
+ # Deletes a key (*String*) from DynamoDB. Returns `true` on success or
52
+ # raises an exception on errror
31
53
  def del(key)
32
54
  response = db.delete_item(@table_name, {'HashKeyElement' => {'S' => key}})
33
55
  true
34
56
  end
35
57
 
58
+ ##
59
+ # Returns an `Array` of keys (`String`) from DynamoDB. Not used by the
60
+ # Storage API, but provided as a convenience and used in tests.
61
+ def list
62
+ response = db.scan(@table_name)
63
+ response.body['Items'].map { |x| get_key_from_result(x) }
64
+ end
65
+
36
66
  private
37
67
 
68
+ ##
69
+ # Returns the DynamoDB connection object
38
70
  def db
39
71
  @db ||= Fog::AWS::DynamoDB.new(
40
72
  @options.merge(
@@ -43,8 +75,22 @@ module Rollout::DynamoDB
43
75
  :region => @region))
44
76
  end
45
77
 
78
+ ##
79
+ # Extracts and returns a key (*String*) from a DynamoDB result set. May be `nil`.
80
+ def get_key_from_result(res)
81
+ res.fetch('id', {}).fetch('S', nil)
82
+ end
83
+
84
+ ##
85
+ # Extracts and returns a value (*String*) from a DynamoDB result set. May be `nil`.
86
+ def get_item_from_result(res)
87
+ res.fetch('value', {}).fetch('S', nil)
88
+ end
89
+
90
+ ##
91
+ # Returns an item (*Hash*) from a DynamoDB result body
46
92
  def get_item_from_body(body)
47
- body.fetch('Item', {}).fetch('value', {}).fetch('S', nil)
93
+ get_item_from_result(body.fetch('Item', {}))
48
94
  end
49
95
  end
50
96
  end
@@ -21,6 +21,7 @@ Gem::Specification.new do |spec|
21
21
  spec.add_development_dependency "bundler", "~> 1.7"
22
22
  spec.add_development_dependency "foreman", "~> 0.77"
23
23
  spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "bourne", "~> 1.6.0"
24
25
  spec.add_development_dependency "rspec", "~> 3.2"
25
26
  spec.add_development_dependency "webmock", "~> 1.20"
26
27
  spec.add_dependency 'rollout', "~> 2.0"
@@ -0,0 +1,58 @@
1
+ require "spec_helper"
2
+
3
+ describe Rollout::DynamoDB do
4
+ before do
5
+ skip("DynamoDB env vars not set") unless dynamodb_configured?
6
+ WebMock.allow_net_connect!
7
+
8
+ aws_access_key = ENV['TEST_DYNAMO_ACCESS_KEY']
9
+ aws_secret_key = ENV['TEST_DYNAMO_SECRET_KEY']
10
+ aws_table_name = ENV['TEST_DYNAMO_TABLE_NAME']
11
+ aws_region = ENV['TEST_DYNAMO_REGION']
12
+
13
+ @storage = Rollout::DynamoDB::Storage.new(aws_access_key, aws_secret_key, aws_table_name, aws_region)
14
+ clear_table!(@storage, aws_table_name) if dynamodb_configured? and !skip_slow_tests?
15
+ end
16
+
17
+ describe "DynamoDB integration" do
18
+ it "get works correctly when key doesn't exist" do
19
+ value = @storage.get("my-key")
20
+ assert_nil value
21
+ end
22
+
23
+ it "set and get work correctly for new keys" do
24
+ value = @storage.set("my-key", "my-value")
25
+ assert value
26
+
27
+ value = @storage.get("my-key")
28
+ assert_equal "my-value", value
29
+ end
30
+
31
+ it "set and get work correctly for existing keys" do
32
+ value = @storage.set("my-reused-key", "my-old-value")
33
+ assert value
34
+
35
+ value = @storage.set("my-reused-key", "my-new-value")
36
+ assert value
37
+
38
+ value = @storage.get("my-reused-key")
39
+ assert_equal "my-new-value", value
40
+ end
41
+
42
+ it "delete works on key that doesn't exist" do
43
+ value = @storage.del("my-nonexistent-key")
44
+ assert value
45
+ end
46
+
47
+ it "delete works for existing keys" do
48
+ value = @storage.set("my-deleted-key", "delete me")
49
+ assert value
50
+
51
+ value = @storage.del("my-deleted-key")
52
+ assert value
53
+
54
+ value = @storage.get("my-deleted-key")
55
+ assert_nil value
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,322 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require 'rollout'
3
+
4
+ describe "Rollout" do
5
+ before do
6
+ skip("Skipping slow tests") if skip_slow_tests?
7
+ skip("DynamoDB env vars not set") unless dynamodb_configured?
8
+ WebMock.allow_net_connect!
9
+ aws_access_key = ENV['TEST_DYNAMO_ACCESS_KEY']
10
+ aws_secret_key = ENV['TEST_DYNAMO_SECRET_KEY']
11
+ aws_table_name = ENV['TEST_DYNAMO_TABLE_NAME']
12
+ aws_region = ENV['TEST_DYNAMO_REGION']
13
+
14
+ @storage = Rollout::DynamoDB::Storage.new(aws_access_key, aws_secret_key, aws_table_name, aws_region)
15
+ @rollout = Rollout.new(@storage)
16
+ clear_table!(@storage, aws_table_name) if dynamodb_configured? and !skip_slow_tests?
17
+ end
18
+
19
+ describe "when a group is activated" do
20
+ before do
21
+ @rollout.define_group(:fivesonly) { |user| user.id == 5 }
22
+ @rollout.activate_group(:chat, :fivesonly)
23
+ end
24
+
25
+ it "the feature is active for users for which the block evaluates to true" do
26
+ @rollout.should be_active(:chat, stub(:id => 5))
27
+ end
28
+
29
+ it "is not active for users for which the block evaluates to false" do
30
+ @rollout.should_not be_active(:chat, stub(:id => 1))
31
+ end
32
+
33
+ it "is not active if a group is found in Redis but not defined in Rollout" do
34
+ @rollout.activate_group(:chat, :fake)
35
+ @rollout.should_not be_active(:chat, stub(:id => 1))
36
+ end
37
+ end
38
+
39
+ describe "the default all group" do
40
+ before do
41
+ @rollout.activate_group(:chat, :all)
42
+ end
43
+
44
+ it "evaluates to true no matter what" do
45
+ @rollout.should be_active(:chat, stub(:id => 0))
46
+ end
47
+ end
48
+
49
+ describe "deactivating a group" do
50
+ before do
51
+ @rollout.define_group(:fivesonly) { |user| user.id == 5 }
52
+ @rollout.activate_group(:chat, :all)
53
+ @rollout.activate_group(:chat, :some)
54
+ @rollout.activate_group(:chat, :fivesonly)
55
+ @rollout.deactivate_group(:chat, :all)
56
+ @rollout.deactivate_group(:chat, "some")
57
+ end
58
+
59
+ it "deactivates the rules for that group" do
60
+ @rollout.should_not be_active(:chat, stub(:id => 10))
61
+ end
62
+
63
+ it "leaves the other groups active" do
64
+ @rollout.get(:chat).groups.should == [:fivesonly]
65
+ end
66
+ end
67
+
68
+ describe "deactivating a feature completely" do
69
+ before do
70
+ @rollout.define_group(:fivesonly) { |user| user.id == 5 }
71
+ @rollout.activate_group(:chat, :all)
72
+ @rollout.activate_group(:chat, :fivesonly)
73
+ @rollout.activate_user(:chat, stub(:id => 51))
74
+ @rollout.activate_percentage(:chat, 100)
75
+ @rollout.activate(:chat)
76
+ @rollout.deactivate(:chat)
77
+ end
78
+
79
+ it "removes all of the groups" do
80
+ @rollout.should_not be_active(:chat, stub(:id => 0))
81
+ end
82
+
83
+ it "removes all of the users" do
84
+ @rollout.should_not be_active(:chat, stub(:id => 51))
85
+ end
86
+
87
+ it "removes the percentage" do
88
+ @rollout.should_not be_active(:chat, stub(:id => 24))
89
+ end
90
+
91
+ it "removes globally" do
92
+ @rollout.should_not be_active(:chat)
93
+ end
94
+ end
95
+
96
+ describe "activating a specific user" do
97
+ before do
98
+ @rollout.activate_user(:chat, stub(:id => 42))
99
+ end
100
+
101
+ it "is active for that user" do
102
+ @rollout.should be_active(:chat, stub(:id => 42))
103
+ end
104
+
105
+ it "remains inactive for other users" do
106
+ @rollout.should_not be_active(:chat, stub(:id => 24))
107
+ end
108
+ end
109
+
110
+ describe "activating a specific user by ID" do
111
+ before do
112
+ @rollout.activate_user(:chat, 42)
113
+ end
114
+
115
+ it "is active for that user" do
116
+ @rollout.should be_active(:chat, stub(:id => 42))
117
+ end
118
+
119
+ it "remains inactive for other users" do
120
+ @rollout.should_not be_active(:chat, stub(:id => 24))
121
+ end
122
+ end
123
+
124
+ describe "activating a specific user with a string id" do
125
+ before do
126
+ @rollout.activate_user(:chat, stub(:id => 'user-72'))
127
+ end
128
+
129
+ it "is active for that user" do
130
+ @rollout.should be_active(:chat, stub(:id => 'user-72'))
131
+ end
132
+
133
+ it "remains inactive for other users" do
134
+ @rollout.should_not be_active(:chat, stub(:id => 'user-12'))
135
+ end
136
+ end
137
+
138
+ describe "deactivating a specific user" do
139
+ before do
140
+ @rollout.activate_user(:chat, stub(:id => 42))
141
+ @rollout.activate_user(:chat, stub(:id => 4242))
142
+ @rollout.activate_user(:chat, stub(:id => 24))
143
+ @rollout.deactivate_user(:chat, stub(:id => 42))
144
+ @rollout.deactivate_user(:chat, stub(:id => "4242"))
145
+ end
146
+
147
+ it "that user should no longer be active" do
148
+ @rollout.should_not be_active(:chat, stub(:id => 42))
149
+ end
150
+
151
+ it "remains active for other active users" do
152
+ @rollout.get(:chat).users.should == %w(24)
153
+ end
154
+ end
155
+
156
+ describe "activating a feature globally" do
157
+ before do
158
+ @rollout.activate(:chat)
159
+ end
160
+
161
+ it "activates the feature" do
162
+ @rollout.should be_active(:chat)
163
+ end
164
+ end
165
+
166
+ describe "activating a feature for a percentage of users" do
167
+ before do
168
+ @rollout.activate_percentage(:chat, 20)
169
+ end
170
+
171
+ it "activates the feature for that percentage of the users" do
172
+ (1..120).select { |id| @rollout.active?(:chat, stub(:id => id)) }.length.should be_within(1).of(20)
173
+ end
174
+ end
175
+
176
+ describe "activating a feature for a percentage of users" do
177
+ before do
178
+ @rollout.activate_percentage(:chat, 20)
179
+ end
180
+
181
+ it "activates the feature for that percentage of the users" do
182
+ (1..200).select { |id| @rollout.active?(:chat, stub(:id => id)) }.length.should be_within(5).of(40)
183
+ end
184
+ end
185
+
186
+ describe "activating a feature for a percentage of users" do
187
+ before do
188
+ @rollout.activate_percentage(:chat, 5)
189
+ end
190
+
191
+ it "activates the feature for that percentage of the users" do
192
+ (1..100).select { |id| @rollout.active?(:chat, stub(:id => id)) }.length.should be_within(2).of(5)
193
+ end
194
+ end
195
+
196
+ describe "activating a feature for a group as a string" do
197
+ before do
198
+ @rollout.define_group(:admins) { |user| user.id == 5 }
199
+ @rollout.activate_group(:chat, 'admins')
200
+ end
201
+
202
+ it "the feature is active for users for which the block evaluates to true" do
203
+ @rollout.should be_active(:chat, stub(:id => 5))
204
+ end
205
+
206
+ it "is not active for users for which the block evaluates to false" do
207
+ @rollout.should_not be_active(:chat, stub(:id => 1))
208
+ end
209
+ end
210
+
211
+ describe "deactivating the percentage of users" do
212
+ before do
213
+ @rollout.activate_percentage(:chat, 100)
214
+ @rollout.deactivate_percentage(:chat)
215
+ end
216
+
217
+ it "becomes inactivate for all users" do
218
+ @rollout.should_not be_active(:chat, stub(:id => 24))
219
+ end
220
+ end
221
+
222
+ describe "deactivating the feature globally" do
223
+ before do
224
+ @rollout.activate(:chat)
225
+ @rollout.deactivate(:chat)
226
+ end
227
+
228
+ it "becomes inactivate" do
229
+ @rollout.should_not be_active(:chat)
230
+ end
231
+ end
232
+
233
+ describe "setting a feature on" do
234
+ before do
235
+ @rollout.set(:chat, true)
236
+ end
237
+
238
+ it "becomes activated" do
239
+ @rollout.should be_active(:chat)
240
+ end
241
+ end
242
+
243
+ describe "setting a feature off" do
244
+ before do
245
+ @rollout.set(:chat, false)
246
+ end
247
+
248
+ it "becomes activated" do
249
+ @rollout.should_not be_active(:chat)
250
+ end
251
+ end
252
+
253
+ describe "keeps a list of features" do
254
+ it "saves the feature" do
255
+ @rollout.activate(:chat)
256
+ @rollout.features.should be_include(:chat)
257
+ end
258
+
259
+ it "does not contain doubles" do
260
+ @rollout.activate(:chat)
261
+ @rollout.activate(:chat)
262
+ @rollout.features.size.should == 1
263
+ end
264
+
265
+ it "does not contain doubles when using string" do
266
+ @rollout.activate(:chat)
267
+ @rollout.activate("chat")
268
+ @rollout.features.size.should == 1
269
+ end
270
+ end
271
+
272
+ describe "#get" do
273
+ before do
274
+ @rollout.activate_percentage(:chat, 10)
275
+ @rollout.activate_group(:chat, :caretakers)
276
+ @rollout.activate_group(:chat, :greeters)
277
+ @rollout.activate(:signup)
278
+ @rollout.activate_user(:chat, stub(:id => 42))
279
+ end
280
+
281
+ it "returns the feature object" do
282
+ feature = @rollout.get(:chat)
283
+ feature.groups.should == [:caretakers, :greeters]
284
+ feature.percentage.should == 10
285
+ feature.users.should == %w(42)
286
+ feature.to_hash.should == {
287
+ :groups => [:caretakers, :greeters],
288
+ :percentage => 10,
289
+ :users => %w(42)
290
+ }
291
+
292
+ feature = @rollout.get(:signup)
293
+ feature.groups.should be_empty
294
+ feature.users.should be_empty
295
+ feature.percentage.should == 100
296
+ end
297
+ end
298
+
299
+ describe "#clear" do
300
+ let(:features) { %w(signup beta alpha gm) }
301
+
302
+ before do
303
+ features.each { |f| @rollout.activate(f) }
304
+
305
+ @rollout.clear!
306
+ end
307
+
308
+ it "each feature is cleared" do
309
+ features.each do |feature|
310
+ @rollout.get(feature).to_hash.should == {
311
+ :percentage => 0,
312
+ :users => [],
313
+ :groups => []
314
+ }
315
+ end
316
+ end
317
+
318
+ it "removes all features" do
319
+ @rollout.features.should be_empty
320
+ end
321
+ end
322
+ end
data/spec/spec_helper.rb CHANGED
@@ -3,10 +3,31 @@ require "bundler"
3
3
 
4
4
  Bundler.require(:default, :development)
5
5
 
6
- require "webmock/rspec"
7
6
 
8
7
  require "rollout/dynamodb/storage"
8
+ require "rollout"
9
+ require "webmock/rspec"
10
+ require "rspec"
11
+ require "bourne"
12
+
13
+ def dynamodb_configured?
14
+ [
15
+ ENV['TEST_DYNAMO_ACCESS_KEY'],
16
+ ENV['TEST_DYNAMO_SECRET_KEY'],
17
+ ENV['TEST_DYNAMO_TABLE_NAME'],
18
+ ENV['TEST_DYNAMO_REGION'],
19
+ ].all?
20
+ end
21
+
22
+ def skip_slow_tests?
23
+ ENV['TEST_SKIP_SLOW'] && !["false", "0"].include?(ENV['TEST_SKIP_SLOW'].upcase)
24
+ end
25
+
26
+ def clear_table!(storage, table)
27
+ storage.list.map { |item| storage.del(item) }
28
+ end
9
29
 
10
30
  RSpec.configure do |config|
11
- config.expect_with :test_unit
31
+ config.expect_with :rspec, :test_unit
32
+ config.mock_with :mocha
12
33
  end
@@ -84,6 +84,22 @@ describe Rollout::DynamoDB do
84
84
  assert response
85
85
  end
86
86
  end
87
+
88
+ describe "#list" do
89
+ it "sends a valid post and returns valid data" do
90
+ stub_request(:post, @dynamo_url).
91
+ to_return(:body => "{\"ConsumedCapacityUnits\":0.5,\"Count\":4,\"Items\":[{\"id\":{\"S\":\"my-reused-key\"},\"value\":{\"S\":\"my-new-value\"}},{\"value\":{\"S\":\"0||\"},\"id\":{\"S\":\"feature:chat\"}},{\"id\":{\"S\":\"my-key\"},\"value\":{\"S\":\"my-value\"}},{\"value\":{\"S\":\"feature:__features__,chat\"},\"id\":{\"S\":\"feature:__features__\"}}],\"ScannedCount\":4}")
92
+
93
+ result_set = @storage.list
94
+ assert_requested(:post, @dynamo_url) do |req|
95
+ body = MultiJson.decode(req.body)
96
+
97
+ body == {"TableName"=>"table"} &&
98
+ req.headers["X-Amz-Target"] == "DynamoDB_20111205.Scan"
99
+ end
100
+ assert_equal result_set, ["my-reused-key", "feature:chat", "my-key", "feature:__features__"]
101
+ end
102
+ end
87
103
  # ...
88
104
  end
89
105
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rollout-dynamodb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Charles Hooper
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-10 00:00:00.000000000 Z
11
+ date: 2015-03-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bourne
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 1.6.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.6.0
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rspec
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -115,6 +129,7 @@ executables: []
115
129
  extensions: []
116
130
  extra_rdoc_files: []
117
131
  files:
132
+ - ".env.test"
118
133
  - ".gitignore"
119
134
  - ".rspec"
120
135
  - ".travis.yml"
@@ -125,8 +140,10 @@ files:
125
140
  - lib/rollout-dynamodb.rb
126
141
  - lib/rollout/dynamodb/storage.rb
127
142
  - rollout-dynamodb.gemspec
128
- - spec/dynamodb_spec.rb
143
+ - spec/dynamodb_integration_spec.rb
144
+ - spec/rollout_dynamodb_integration_spec.rb
129
145
  - spec/spec_helper.rb
146
+ - spec/storage_spec.rb
130
147
  - spec/version_spec.rb
131
148
  homepage: https://github.com/chooper/rollout-dynamodb
132
149
  licenses:
@@ -153,6 +170,8 @@ signing_key:
153
170
  specification_version: 4
154
171
  summary: DynamoDB storage adapter for Rollout
155
172
  test_files:
156
- - spec/dynamodb_spec.rb
173
+ - spec/dynamodb_integration_spec.rb
174
+ - spec/rollout_dynamodb_integration_spec.rb
157
175
  - spec/spec_helper.rb
176
+ - spec/storage_spec.rb
158
177
  - spec/version_spec.rb