orchestrate 0.6.3 → 0.7.0
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.
- checksums.yaml +4 -4
- data/README.md +64 -27
- data/lib/orchestrate.rb +6 -1
- data/lib/orchestrate/api.rb +1 -0
- data/lib/orchestrate/api/errors.rb +3 -1
- data/lib/orchestrate/api/helpers.rb +1 -0
- data/lib/orchestrate/api/response.rb +43 -10
- data/lib/orchestrate/application.rb +55 -0
- data/lib/orchestrate/client.rb +5 -24
- data/lib/orchestrate/collection.rb +310 -0
- data/lib/orchestrate/key_value.rb +232 -0
- data/lib/orchestrate/version.rb +2 -1
- data/orchestrate.gemspec +1 -1
- data/test/orchestrate/api/{collections_test.rb → collections_api_test.rb} +1 -1
- data/test/orchestrate/api/exceptions_test.rb +9 -55
- data/test/orchestrate/api/{key_value_test.rb → key_value_api_test.rb} +1 -1
- data/test/orchestrate/application_test.rb +44 -0
- data/test/orchestrate/client_test.rb +19 -17
- data/test/orchestrate/collection_enumeration_test.rb +116 -0
- data/test/orchestrate/collection_kv_accessors_test.rb +145 -0
- data/test/orchestrate/collection_test.rb +63 -0
- data/test/orchestrate/key_value_persistence_test.rb +161 -0
- data/test/orchestrate/key_value_test.rb +116 -0
- data/test/test_helper.rb +134 -8
- metadata +24 -15
data/lib/orchestrate/version.rb
CHANGED
data/orchestrate.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.require_paths = ["lib"]
|
19
19
|
|
20
20
|
s.add_dependency "faraday", "~> 0.9"
|
21
|
-
s.add_dependency "
|
21
|
+
s.add_dependency "net-http-persistent", "~> 2.9"
|
22
22
|
s.add_development_dependency "bundler", "~> 1.6"
|
23
23
|
s.add_development_dependency "rake"
|
24
24
|
s.add_development_dependency "typhoeus"
|
@@ -8,10 +8,7 @@ class ExceptionsTest < MiniTest::Unit::TestCase
|
|
8
8
|
def test_raises_on_unauthroized
|
9
9
|
@stubs.get("/v0/foo") do |env|
|
10
10
|
assert_authorization @basic_auth, env
|
11
|
-
|
12
|
-
"message" => "Valid credentials are required.",
|
13
|
-
"code" => "security_unauthorized"
|
14
|
-
}.to_json ]
|
11
|
+
error_response(:unauthorized)
|
15
12
|
end
|
16
13
|
assert_raises Orchestrate::API::Unauthorized do
|
17
14
|
@client.list(:foo)
|
@@ -19,92 +16,49 @@ class ExceptionsTest < MiniTest::Unit::TestCase
|
|
19
16
|
end
|
20
17
|
|
21
18
|
def test_raises_on_bad_request
|
22
|
-
|
23
|
-
|
24
|
-
[400, response_headers, {
|
25
|
-
message: message,
|
26
|
-
code: "api_bad_request"
|
27
|
-
}.to_json ]
|
28
|
-
end
|
29
|
-
err = assert_raises Orchestrate::API::BadRequest do
|
19
|
+
@stubs.put("/v0/foo/bar") { error_response(:bad_request) }
|
20
|
+
assert_raises Orchestrate::API::BadRequest do
|
30
21
|
@client.put(:foo, "bar", {}, "'foo'")
|
31
22
|
end
|
32
|
-
assert_equal message, err.message
|
33
23
|
end
|
34
24
|
|
35
25
|
def test_raises_on_malformed_search_query
|
36
|
-
@stubs.get("/v0/foo")
|
37
|
-
[ 400, response_headers, {
|
38
|
-
message: "The search query provided is invalid.",
|
39
|
-
code: "search_query_malformed"
|
40
|
-
}.to_json ]
|
41
|
-
end
|
26
|
+
@stubs.get("/v0/foo") { error_response(:search_query_malformed) }
|
42
27
|
assert_raises Orchestrate::API::MalformedSearch do
|
43
28
|
@client.search(:foo, "foo=\"no")
|
44
29
|
end
|
45
30
|
end
|
46
31
|
|
47
32
|
def test_raises_on_invalid_search_param
|
48
|
-
@stubs.get("/v0/foo")
|
49
|
-
[ 400, response_headers, {
|
50
|
-
message: "A provided search query param is invalid.",
|
51
|
-
details: { query: "Query is empty." },
|
52
|
-
code: "search_param_invalid"
|
53
|
-
}.to_json ]
|
54
|
-
end
|
33
|
+
@stubs.get("/v0/foo") { error_response(:invalid_search_param) }
|
55
34
|
assert_raises Orchestrate::API::InvalidSearchParam do
|
56
35
|
@client.search(:foo, '')
|
57
36
|
end
|
58
37
|
end
|
59
38
|
|
60
39
|
def test_raises_on_malformed_ref
|
61
|
-
@stubs.put("/v0/foo/bar")
|
62
|
-
[ 400, response_headers, {
|
63
|
-
message: "The provided Item Ref is malformed.",
|
64
|
-
details: { ref: "blerg" },
|
65
|
-
code: "item_ref_malformed"
|
66
|
-
}.to_json ]
|
67
|
-
end
|
40
|
+
@stubs.put("/v0/foo/bar") { error_response(:malformed_ref) }
|
68
41
|
assert_raises Orchestrate::API::MalformedRef do
|
69
42
|
@client.put(:foo, "bar", {:blerg => 'blerg'}, "blerg")
|
70
43
|
end
|
71
44
|
end
|
72
45
|
|
73
46
|
def test_raises_on_indexing_conflict
|
74
|
-
@stubs.put("/v0/foo/bar")
|
75
|
-
[ 409, response_headers, {
|
76
|
-
message: "The item has been stored but conflicts were detected when indexing. Conflicting fields have not been indexed.",
|
77
|
-
details: {
|
78
|
-
conflicts: { name: { type: "string", expected: "long" } },
|
79
|
-
conflicts_uri: "/v0/test/one/refs/f8a86a25029a907b/conflicts"
|
80
|
-
},
|
81
|
-
code: "indexing_conflict"
|
82
|
-
}.to_json ]
|
83
|
-
end
|
47
|
+
@stubs.put("/v0/foo/bar") { error_response(:indexing_conflict) }
|
84
48
|
assert_raises Orchestrate::API::IndexingConflict do
|
85
49
|
@client.put(:foo, 'bar', {count: "foo"})
|
86
50
|
end
|
87
51
|
end
|
88
52
|
|
89
53
|
def test_raises_on_version_mismatch
|
90
|
-
@stubs.put("/v0/foo/bar")
|
91
|
-
[ 412, response_headers, {
|
92
|
-
message: "The version of the item does not match.",
|
93
|
-
code: "item_version_mismatch"
|
94
|
-
}.to_json ]
|
95
|
-
end
|
54
|
+
@stubs.put("/v0/foo/bar") { error_response(:version_mismatch) }
|
96
55
|
assert_raises Orchestrate::API::VersionMismatch do
|
97
56
|
@client.put(:foo, 'bar', {foo:'bar'}, "7ae8635207acbb2f")
|
98
57
|
end
|
99
58
|
end
|
100
59
|
|
101
60
|
def test_raises_on_item_already_present
|
102
|
-
@stubs.put("/v0/foo/bar")
|
103
|
-
[ 412, response_headers, {
|
104
|
-
message: "The item is already present.",
|
105
|
-
code: "item_already_present"
|
106
|
-
}.to_json ]
|
107
|
-
end
|
61
|
+
@stubs.put("/v0/foo/bar") { error_response(:already_present) }
|
108
62
|
assert_raises Orchestrate::API::AlreadyPresent do
|
109
63
|
@client.put_if_absent(:foo, 'bar', {foo:'bar'})
|
110
64
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class ApplicationTest < MiniTest::Unit::TestCase
|
4
|
+
|
5
|
+
def test_instantianes_with_api_key
|
6
|
+
stubs = Faraday::Adapter::Test::Stubs.new
|
7
|
+
pinged = false
|
8
|
+
stubs.head('/v0') do |env|
|
9
|
+
pinged = true
|
10
|
+
[200, response_headers, '']
|
11
|
+
end
|
12
|
+
|
13
|
+
app = Orchestrate::Application.new("api_key") do |conn|
|
14
|
+
conn.adapter :test, stubs
|
15
|
+
end
|
16
|
+
|
17
|
+
assert_equal "api_key", app.api_key
|
18
|
+
assert_kind_of Orchestrate::Client, app.client
|
19
|
+
assert pinged, "API wasn't pinged"
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_instantiates_with_client
|
23
|
+
client, stubs = make_client_and_artifacts
|
24
|
+
pinged = false
|
25
|
+
stubs.head('/v0') do |env|
|
26
|
+
pinged = true
|
27
|
+
[ 200, response_headers, '' ]
|
28
|
+
end
|
29
|
+
|
30
|
+
app = Orchestrate::Application.new(client)
|
31
|
+
assert_equal client.api_key, app.api_key
|
32
|
+
assert_equal client, app.client
|
33
|
+
assert pinged, "API wasn't pinged"
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_collection_accessor
|
37
|
+
app, stubs = make_application
|
38
|
+
users = app[:users]
|
39
|
+
assert_kind_of Orchestrate::Collection, users
|
40
|
+
assert_equal app, users.app
|
41
|
+
assert_equal 'users', users.name
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -1,34 +1,36 @@
|
|
1
1
|
require "test_helper"
|
2
2
|
|
3
|
-
|
3
|
+
class ClientTest < MiniTest::Unit::TestCase
|
4
4
|
|
5
|
-
|
5
|
+
def test_initialization
|
6
6
|
client = Orchestrate::Client.new('8c3')
|
7
|
-
client.
|
7
|
+
assert_equal '8c3', client.api_key
|
8
8
|
end
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
def test_parallelism
|
11
|
+
thing_body = {"foo" => "bar"}
|
12
|
+
list_body = {"count" => 1, "results" => [{"value"=>{"a" => "b"}, "path" => {}, "reftime" => ""}] }
|
13
|
+
client, stubs = make_client_and_artifacts(true)
|
12
14
|
stubs.get("/v0/foo") do |env|
|
13
|
-
[ 200, response_headers,
|
15
|
+
[ 200, response_headers, list_body.to_json ]
|
14
16
|
end
|
15
|
-
stubs.get("/v0/
|
16
|
-
[ 200, response_headers,
|
17
|
+
stubs.get("/v0/things/foo") do |env|
|
18
|
+
[ 200, response_headers, thing_body.to_json ]
|
17
19
|
end
|
18
20
|
responses = nil
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
r[:user] = client.get(:users, "mattly")
|
23
|
-
end
|
21
|
+
responses = client.in_parallel do |r|
|
22
|
+
r[:list] = client.list(:foo)
|
23
|
+
r[:thing] = client.get(:things, "foo")
|
24
24
|
end
|
25
25
|
assert responses[:list]
|
26
26
|
assert_equal 200, responses[:list].status
|
27
|
-
|
28
|
-
|
27
|
+
assert_equal list_body, responses[:list].body
|
28
|
+
assert responses[:thing]
|
29
|
+
assert_equal 200, responses[:thing].status
|
30
|
+
assert_equal thing_body, responses[:thing].body
|
29
31
|
end
|
30
32
|
|
31
|
-
|
33
|
+
def test_ping_request_success
|
32
34
|
client, stubs = make_client_and_artifacts
|
33
35
|
stubs.head("/v0") do |env|
|
34
36
|
[ 200, response_headers, '' ]
|
@@ -36,7 +38,7 @@ describe Orchestrate::Client do
|
|
36
38
|
client.ping
|
37
39
|
end
|
38
40
|
|
39
|
-
|
41
|
+
def test_ping_request_unauthorized
|
40
42
|
client, stubs = make_client_and_artifacts
|
41
43
|
headers = response_headers
|
42
44
|
stubs.head("/v0") { [ 401, headers, '' ] }
|
@@ -0,0 +1,116 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class CollectionEnumerationTest < MiniTest::Unit::TestCase
|
4
|
+
|
5
|
+
def test_enumerates_over_all
|
6
|
+
app, stubs = make_application
|
7
|
+
stubs.get("/v0/items") do |env|
|
8
|
+
assert_equal "100", env.params['limit']
|
9
|
+
body = case env.params['afterKey']
|
10
|
+
when nil
|
11
|
+
{ "results" => 100.times.map {|x| make_kv_listing(:items, key: "key-#{x}") },
|
12
|
+
"next" => "/v0/items?afterKey=key-99&limit=100", "count" => 100 }
|
13
|
+
when 'key-99'
|
14
|
+
{ "results" => 4.times.map {|x| make_kv_listing(:items, key: "key-#{100+x}")},
|
15
|
+
"count" => 4 }
|
16
|
+
else
|
17
|
+
raise ArgumentError.new("unexpected afterKey: #{env.params['afterKey']}")
|
18
|
+
end
|
19
|
+
[ 200, response_headers, body.to_json ]
|
20
|
+
end
|
21
|
+
items = app[:items].map {|item| item }
|
22
|
+
assert_equal 104, items.length
|
23
|
+
items.each_with_index do |item, index|
|
24
|
+
assert_equal "key-#{index}", item.key
|
25
|
+
assert item.ref
|
26
|
+
assert item.reftime
|
27
|
+
assert item.value
|
28
|
+
assert_equal "key-#{index}", item[:key]
|
29
|
+
assert_in_delta Time.now.to_f, item.last_request_time.to_f, 1.1
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_enumerator_in_parallel
|
34
|
+
app, stubs = make_application({parallel:true})
|
35
|
+
stubs.get("/v0/items") do |env|
|
36
|
+
body = case env.params['afterKey']
|
37
|
+
when nil
|
38
|
+
{ "results" => 10.times.map {|x| make_kv_listing(:items, key: "key-#{x}") },
|
39
|
+
"next" => "/v0/items?afterKey=key-9", "count" => 10 }
|
40
|
+
when 'key-9'
|
41
|
+
{ "results" => 4.times.map {|x| make_kv_listing(:items, key: "key-#{10+x}")},
|
42
|
+
"count" => 4 }
|
43
|
+
else
|
44
|
+
raise ArgumentError.new("unexpected afterKey: #{env.params['afterKey']}")
|
45
|
+
end
|
46
|
+
[ 200, response_headers, body.to_json ]
|
47
|
+
end
|
48
|
+
items=nil
|
49
|
+
assert_raises Orchestrate::ResultsNotReady do
|
50
|
+
app.in_parallel { app[:items].take(5) }
|
51
|
+
end
|
52
|
+
if app[:items].respond_to?(:lazy)
|
53
|
+
app.in_parallel do
|
54
|
+
items = app[:items].lazy.map {|item| item }
|
55
|
+
end
|
56
|
+
items = items.force
|
57
|
+
assert_equal 14, items.length
|
58
|
+
items.each_with_index do |item, index|
|
59
|
+
assert_equal "key-#{index}", item.key
|
60
|
+
assert item.ref
|
61
|
+
assert item.reftime
|
62
|
+
assert item.value
|
63
|
+
assert_equal "key-#{index}", item[:key]
|
64
|
+
assert_in_delta Time.now.to_f, item.last_request_time.to_f, 1.1
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_enumerates_as_needed
|
70
|
+
app, stubs = make_application
|
71
|
+
stubs.get("/v0/items") do |env|
|
72
|
+
assert_equal "5", env.params["limit"]
|
73
|
+
if env.params['afterKey'] != nil
|
74
|
+
raise ArgumentError.new("unexpected afterKey: #{env.params['afterKey']}")
|
75
|
+
else
|
76
|
+
body = { "results" => 5.times.map {|x| make_kv_listing(:items, key: "key-#{x}")},
|
77
|
+
"next" => "/v0/items?afterKey=key-4&limit=5", "count" => 5 }
|
78
|
+
[ 200, response_headers, body.to_json ]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
items = app[:items].take(5).map {|item| item }
|
82
|
+
assert_equal 5, items.length
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_enumerates_with_range_start_and_end
|
86
|
+
keys = %w[bar bat bee cat dog ear foo]
|
87
|
+
app, stubs = make_application
|
88
|
+
stubs.get("/v0/items") do |env|
|
89
|
+
assert_equal "bar", env.params['startKey']
|
90
|
+
assert_equal "foo", env.params['endKey']
|
91
|
+
body = { "results" => keys.map {|k| make_kv_listing(:items, key: k)},
|
92
|
+
"count" => keys.length }
|
93
|
+
[ 200, response_headers, body.to_json ]
|
94
|
+
end
|
95
|
+
items = app[:items].start(:bar).end(:foo).take(5).map {|item| item.key }
|
96
|
+
assert_equal 5, items.length
|
97
|
+
assert_equal %w[bar bat bee cat dog], items
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_enumerates_with_range_after_and_before
|
101
|
+
keys = %w[bar bat bee cat dog ear foo]
|
102
|
+
app, stubs = make_application
|
103
|
+
stubs.get("/v0/items") do |env|
|
104
|
+
assert_equal "bar", env.params['afterKey']
|
105
|
+
assert_equal "goo", env.params['beforeKey']
|
106
|
+
body = { "results" => keys.drop(1).map {|k| make_kv_listing(:items, key: k)},
|
107
|
+
"count" => keys.length }
|
108
|
+
[ 200, response_headers, body.to_json ]
|
109
|
+
end
|
110
|
+
items = app[:items].after(:bar).before(:goo).take(5).map {|item| item.key }
|
111
|
+
assert_equal 5, items.length
|
112
|
+
assert_equal %w[bat bee cat dog ear], items
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
@@ -0,0 +1,145 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class Collection_KV_Accessors_Test < MiniTest::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@app, @stubs = make_application
|
6
|
+
@items = @app[:items]
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_kv_getter_when_present
|
10
|
+
body = {"hello" => "world"}
|
11
|
+
@stubs.get("/v0/items/hello") do |env|
|
12
|
+
[200, response_headers, body.to_json]
|
13
|
+
end
|
14
|
+
hello = @items[:hello]
|
15
|
+
assert_kind_of Orchestrate::KeyValue, hello
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_kv_getter_when_absent
|
19
|
+
@stubs.get("/v0/items/absent") do |env|
|
20
|
+
[404, response_headers, response_not_found('absent')]
|
21
|
+
end
|
22
|
+
assert_nil @items[:absent]
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_kv_setter
|
26
|
+
body = { "hello" => "world" }
|
27
|
+
ref = nil
|
28
|
+
@stubs.put("/v0/items/newitem") do |env|
|
29
|
+
assert_header "If-Match", nil, env
|
30
|
+
assert_header "If-None-Match", nil, env
|
31
|
+
assert_equal body, JSON.parse(env.body)
|
32
|
+
ref = make_ref
|
33
|
+
[ 201, response_headers({'Etag' => %|"#{ref}"|, 'Location' => "/v0/items/newitem/refs/#{ref}"}), '' ]
|
34
|
+
end
|
35
|
+
@items[:newitem] = body
|
36
|
+
assert ref
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_set_performs_put
|
40
|
+
body = { "hello" => "world" }
|
41
|
+
ref = nil
|
42
|
+
@stubs.put("/v0/items/newitem") do |env|
|
43
|
+
assert_header "If-Match", nil, env
|
44
|
+
assert_header "If-None-Match", nil, env
|
45
|
+
assert_equal body, JSON.parse(env.body)
|
46
|
+
ref = make_ref
|
47
|
+
[ 201, response_headers({'Etag' => %|"#{ref}"|, 'Location' => "/v0/items/newitem/refs/#{ref}"}), '' ]
|
48
|
+
end
|
49
|
+
kv = @items.set(:newitem, body)
|
50
|
+
assert_equal ref, kv.ref
|
51
|
+
assert_equal "newitem", kv.key
|
52
|
+
assert_equal body, kv.value
|
53
|
+
assert kv.loaded?
|
54
|
+
assert_in_delta Time.now.to_f, kv.last_request_time.to_f, 1.1
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_append_operator_performs_post
|
58
|
+
body = { "hello" => "world" }
|
59
|
+
key = nil
|
60
|
+
ref = nil
|
61
|
+
@stubs.post("/v0/items") do |env|
|
62
|
+
assert_header 'Content-Type', 'application/json', env
|
63
|
+
assert_equal body, JSON.parse(env.body)
|
64
|
+
ref = make_ref
|
65
|
+
key = SecureRandom.hex(16)
|
66
|
+
[ 201, response_headers({
|
67
|
+
'Etag' => %|"#{ref}"|, "Location" => "/v0/items/#{key}/refs/#{ref}"
|
68
|
+
}), '' ]
|
69
|
+
end
|
70
|
+
kv = @items << body
|
71
|
+
assert kv
|
72
|
+
assert_equal key, kv.key
|
73
|
+
assert_equal ref, kv.ref
|
74
|
+
assert_equal body, kv.value
|
75
|
+
assert kv.loaded?
|
76
|
+
assert_in_delta Time.now.to_f, kv.last_request_time.to_f, 1.1
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_create_performs_post_with_one_arg
|
80
|
+
body = { "hello" => "world" }
|
81
|
+
key = nil
|
82
|
+
ref = nil
|
83
|
+
@stubs.post("/v0/items") do |env|
|
84
|
+
assert_header 'Content-Type', 'application/json', env
|
85
|
+
assert_equal body, JSON.parse(env.body)
|
86
|
+
ref = make_ref
|
87
|
+
key = SecureRandom.hex(16)
|
88
|
+
[ 201, response_headers({
|
89
|
+
'Etag' => %|"#{ref}"|, "Location" => "/v0/items/#{key}/refs/#{ref}"
|
90
|
+
}), '' ]
|
91
|
+
end
|
92
|
+
kv = @items.create(body)
|
93
|
+
assert kv
|
94
|
+
assert_equal key, kv.key
|
95
|
+
assert_equal ref, kv.ref
|
96
|
+
assert_equal body, kv.value
|
97
|
+
assert kv.loaded?
|
98
|
+
assert_in_delta Time.now.to_f, kv.last_request_time.to_f, 1.1
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_create_performs_put_if_absent_with_two_args
|
102
|
+
body = { "hello" => "world" }
|
103
|
+
ref = nil
|
104
|
+
@stubs.put("/v0/items/newitem") do |env|
|
105
|
+
assert_header "If-Match", nil, env
|
106
|
+
assert_header "If-None-Match", '"*"', env
|
107
|
+
assert_equal body, JSON.parse(env.body)
|
108
|
+
ref = make_ref
|
109
|
+
[ 201, response_headers({"Etag" => %|"#{ref}"|, "Location" => "/v0/items/newitem/refs/#{ref}"}), '' ]
|
110
|
+
end
|
111
|
+
kv = @items.create(:newitem, body)
|
112
|
+
assert_equal @items, kv.collection
|
113
|
+
assert_equal "newitem", kv.key
|
114
|
+
assert_equal ref, kv.ref
|
115
|
+
assert_equal body, kv.value
|
116
|
+
assert kv.loaded?
|
117
|
+
assert_in_delta Time.now.to_f, kv.last_request_time.to_f, 1.1
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_create_performs_put_if_absent_with_two_args_returns_false_on_already_exists
|
121
|
+
@stubs.put("/v0/items/newitem") do |env|
|
122
|
+
assert_header "If-Match", nil, env
|
123
|
+
assert_header "If-None-Match", '"*"', env
|
124
|
+
error_response(:already_present)
|
125
|
+
end
|
126
|
+
assert_equal false, @items.create(:newitem, {"hello" => "world"})
|
127
|
+
end
|
128
|
+
|
129
|
+
def test_delete_performs_delete
|
130
|
+
@stubs.delete("/v0/items/olditem") do |env|
|
131
|
+
assert_nil env.params['purge']
|
132
|
+
[ 204, response_headers, '' ]
|
133
|
+
end
|
134
|
+
assert_equal true, @items.delete(:olditem)
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_purge_performs_purge
|
138
|
+
@stubs.delete("/v0/items/olditem") do |env|
|
139
|
+
assert_equal "true", env.params['purge']
|
140
|
+
[ 204, response_headers, '' ]
|
141
|
+
end
|
142
|
+
assert_equal true, @items.purge(:olditem)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|