cistern 2.6.0 → 2.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/CHANGELOG.md +2 -3
- data/README.md +158 -80
- data/lib/cistern/client.rb +9 -9
- data/lib/cistern/request.rb +45 -15
- data/lib/cistern/singular.rb +1 -0
- data/lib/cistern/version.rb +1 -1
- data/spec/request_spec.rb +47 -25
- data/spec/singular_spec.rb +6 -0
- data/spec/spec_helper.rb +1 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: be9990e15cdccbe77ea1c27b5a6961fecd445129
|
4
|
+
data.tar.gz: d466f0e83e49c33fc9dce01eb713b9f1062e8f7e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dd4a3d7c95873a7fb999854846db84790273ad3366a018dc0e519d7708a13ec325a3a0d1b0bb4968f28cd6260dc4d72659c513513f56dfc2ec0b52ece8a9fb9d
|
7
|
+
data.tar.gz: 68ca70761102c30cca381a029184250a1750dc01d3c63626afe8b7ecd1929839497a8c6b55f995cef40ad8d5554b534987e1447f44eae567ae6c805cce82c2b5
|
data/CHANGELOG.md
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
-
## [
|
4
|
-
|
5
|
-
[Full Changelog](https://github.com/lanej/cistern/compare/v2.5.0...HEAD)
|
3
|
+
## [v2.6.0](https://github.com/lanej/cistern/tree/v2.6.0) (2016-07-26)
|
4
|
+
[Full Changelog](https://github.com/lanej/cistern/compare/v2.5.0...v2.6.0)
|
6
5
|
|
7
6
|
**Implemented enhancements:**
|
8
7
|
|
data/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# Cistern
|
2
2
|
|
3
|
+
[](https://gitter.im/lanej/cistern?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
3
4
|
[](http://travis-ci.org/lanej/cistern)
|
4
5
|
[](https://gemnasium.com/lanej/cistern.png)
|
5
6
|
[](http://badge.fury.io/rb/cistern)
|
@@ -9,40 +10,11 @@ Cistern helps you consistently build your API clients and faciliates building mo
|
|
9
10
|
|
10
11
|
## Usage
|
11
12
|
|
12
|
-
###
|
13
|
+
### Client
|
13
14
|
|
14
|
-
|
15
|
+
This represents the remote service that you are wrapping. It defines the client's namespace and initialization parameters.
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
In cistern `~> 3.0`, the default will be for `Request`, `Collection` and `Model` classes to instead include their respective `<service>::Client` modules.
|
19
|
-
|
20
|
-
If you want to be forwards-compatible today, you can configure your client by using `Cistern::Client.with`
|
21
|
-
|
22
|
-
```ruby
|
23
|
-
class Blog
|
24
|
-
include Cistern::Client.with(interface: :module)
|
25
|
-
end
|
26
|
-
```
|
27
|
-
|
28
|
-
Now request classes would look like:
|
29
|
-
|
30
|
-
```ruby
|
31
|
-
class Blog::GetPost
|
32
|
-
include Blog::Request
|
33
|
-
|
34
|
-
def real
|
35
|
-
"post"
|
36
|
-
end
|
37
|
-
end
|
38
|
-
```
|
39
|
-
|
40
|
-
|
41
|
-
### Service
|
42
|
-
|
43
|
-
This represents the remote service that you are wrapping. If the service name is `blog` then a good name is `Blog`.
|
44
|
-
|
45
|
-
Service initialization parameters are enumerated by `requires` and `recognizes`. Parameters defined using `recognizes` are optional.
|
17
|
+
Client initialization parameters are enumerated by `requires` and `recognizes`. Parameters defined using `recognizes` are optional.
|
46
18
|
|
47
19
|
```ruby
|
48
20
|
# lib/blog.rb
|
@@ -62,8 +34,7 @@ Blog.new(hmac_id: "1", url: "http://example.org")
|
|
62
34
|
Blog.new(hmac_id: "1")
|
63
35
|
```
|
64
36
|
|
65
|
-
Cistern will define for
|
66
|
-
new service.
|
37
|
+
Cistern will define for two namespaced classes, `Blog::Mock` and `Blog::Real`. Create the corresponding files and initialzers for your new service.
|
67
38
|
|
68
39
|
```ruby
|
69
40
|
# lib/blog/real.rb
|
@@ -105,74 +76,69 @@ real.is_a?(Blog::Real) # true
|
|
105
76
|
fake.is_a?(Blog::Mock) # true
|
106
77
|
```
|
107
78
|
|
108
|
-
###
|
79
|
+
### Requests
|
109
80
|
|
110
|
-
|
81
|
+
Requests are defined by subclassing `#{service}::Request`.
|
111
82
|
|
112
|
-
|
83
|
+
* `cistern` represents the associated `Blog` instance.
|
84
|
+
* `#call` represents the primary entrypoint. Invoked when calling `client#{request_method}`.
|
85
|
+
* `#dispatch` determines which method to call. (`#mock` or `#real`)
|
86
|
+
|
87
|
+
For example:
|
113
88
|
|
114
89
|
```ruby
|
115
|
-
|
116
|
-
|
117
|
-
# within a Resource
|
118
|
-
hash_stringify_keys({a: 1, b: 2}) #=> {'a' => 1, 'b' => 2}
|
119
|
-
```
|
90
|
+
class Blog::UpdatePost
|
91
|
+
include Blog::Request
|
120
92
|
|
121
|
-
|
93
|
+
def real(id, parameters)
|
94
|
+
cistern.connection.patch("/post/#{id}", parameters)
|
95
|
+
end
|
122
96
|
|
123
|
-
|
124
|
-
|
125
|
-
Cistern::Hash.slice({a: 1, b: 2, c: 3}, :a, :c) #=> {a: 1, c: 3}
|
126
|
-
# within a Resource
|
127
|
-
hash_slice({a: 1, b: 2, c: 3}, :a, :c) #=> {a: 1, c: 3}
|
128
|
-
```
|
97
|
+
def mock(id, parameters)
|
98
|
+
post = cistern.data[:posts].fetch(id)
|
129
99
|
|
130
|
-
|
100
|
+
post.merge!(stringify_keys(parameters))
|
131
101
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
# within a Resource
|
136
|
-
hash_except({a: 1, b: 2}, :a) #=> {b: 2}
|
102
|
+
response(post: post)
|
103
|
+
end
|
104
|
+
end
|
137
105
|
```
|
138
106
|
|
107
|
+
However, if you want to add some preprocessing to your request's arguments override `#call` and call `#dispatch`. You
|
108
|
+
can also alter the response method's signatures based on the arguments provided to `#dispatch`.
|
139
109
|
|
140
|
-
**#except!**
|
141
110
|
|
142
111
|
```ruby
|
143
|
-
|
144
|
-
|
145
|
-
# within a Resource
|
146
|
-
hash_except!({:a => 1, :b => 2}, :a) #=> {:b => 2}
|
147
|
-
```
|
112
|
+
class Blog::UpdatePost
|
113
|
+
include Blog::Request
|
148
114
|
|
115
|
+
attr_reader :parameters
|
149
116
|
|
150
|
-
|
117
|
+
def call(post_id, parameters)
|
118
|
+
@parameters = stringify_keys(parameters)
|
119
|
+
dispatch(Integer(post_id))
|
120
|
+
end
|
151
121
|
|
152
|
-
|
122
|
+
def real(id)
|
123
|
+
cistern.connection.patch("/post/#{id}", parameters)
|
124
|
+
end
|
153
125
|
|
154
|
-
|
126
|
+
def mock(id)
|
127
|
+
post = cistern.data[:posts].fetch(id)
|
155
128
|
|
156
|
-
|
157
|
-
class Blog::GetPost < Blog::Request
|
158
|
-
def real(params)
|
159
|
-
# make a real request
|
160
|
-
"i'm real"
|
161
|
-
end
|
129
|
+
post.merge!(parameters)
|
162
130
|
|
163
|
-
|
164
|
-
# return a fake response
|
165
|
-
"imposter!"
|
131
|
+
response(post: post)
|
166
132
|
end
|
167
133
|
end
|
168
|
-
|
169
|
-
Blog.new.get_post # "i'm real"
|
170
134
|
```
|
171
135
|
|
172
136
|
The `#cistern_method` function allows you to specify the name of the generated method.
|
173
137
|
|
174
138
|
```ruby
|
175
|
-
class Blog::GetPosts
|
139
|
+
class Blog::GetPosts
|
140
|
+
include Blog::Request
|
141
|
+
|
176
142
|
cistern_method :get_all_the_posts
|
177
143
|
|
178
144
|
def real(params)
|
@@ -264,7 +230,8 @@ Cistern attributes are designed to make your model flexible and developer friend
|
|
264
230
|
For example:
|
265
231
|
|
266
232
|
```ruby
|
267
|
-
class Blog::Post
|
233
|
+
class Blog::Post
|
234
|
+
include Blog::Model
|
268
235
|
identity :id, type: :integer
|
269
236
|
|
270
237
|
attribute :body
|
@@ -372,7 +339,8 @@ post.data.views #=> 3
|
|
372
339
|
* `load` consumes an Array of data and constructs matching `model` instances
|
373
340
|
|
374
341
|
```ruby
|
375
|
-
class Blog::Posts
|
342
|
+
class Blog::Posts
|
343
|
+
include Blog::Collection
|
376
344
|
|
377
345
|
attribute :count, type: :integer
|
378
346
|
|
@@ -415,7 +383,9 @@ There are two types of associations available.
|
|
415
383
|
* `has_many` references a collection of resources and defines a reader / writer.
|
416
384
|
|
417
385
|
```ruby
|
418
|
-
class Blog::Tag
|
386
|
+
class Blog::Tag
|
387
|
+
include Blog::Model
|
388
|
+
|
419
389
|
identity :id
|
420
390
|
attribute :author_id
|
421
391
|
|
@@ -435,7 +405,8 @@ tag.creator = blogs.author.get(name: 'phil')
|
|
435
405
|
tag.attributes[:creator] #=> { 'id' => 2, 'name' => 'phil' }
|
436
406
|
```
|
437
407
|
|
438
|
-
Foreign keys can be updated with association
|
408
|
+
Foreign keys can be updated with with the association writer by aliasing the original writer and accessing the
|
409
|
+
underlying attributes.
|
439
410
|
|
440
411
|
```ruby
|
441
412
|
Blog::Tag.class_eval do
|
@@ -505,6 +476,48 @@ class Blog
|
|
505
476
|
end
|
506
477
|
```
|
507
478
|
|
479
|
+
### Working with data
|
480
|
+
|
481
|
+
`Cistern::Hash` contains many useful functions for working with data normalization and transformation.
|
482
|
+
|
483
|
+
**#stringify_keys**
|
484
|
+
|
485
|
+
```ruby
|
486
|
+
# anywhere
|
487
|
+
Cistern::Hash.stringify_keys({a: 1, b: 2}) #=> {'a' => 1, 'b' => 2}
|
488
|
+
# within a Resource
|
489
|
+
hash_stringify_keys({a: 1, b: 2}) #=> {'a' => 1, 'b' => 2}
|
490
|
+
```
|
491
|
+
|
492
|
+
**#slice**
|
493
|
+
|
494
|
+
```ruby
|
495
|
+
# anywhere
|
496
|
+
Cistern::Hash.slice({a: 1, b: 2, c: 3}, :a, :c) #=> {a: 1, c: 3}
|
497
|
+
# within a Resource
|
498
|
+
hash_slice({a: 1, b: 2, c: 3}, :a, :c) #=> {a: 1, c: 3}
|
499
|
+
```
|
500
|
+
|
501
|
+
**#except**
|
502
|
+
|
503
|
+
```ruby
|
504
|
+
# anywhere
|
505
|
+
Cistern::Hash.except({a: 1, b: 2}, :a) #=> {b: 2}
|
506
|
+
# within a Resource
|
507
|
+
hash_except({a: 1, b: 2}, :a) #=> {b: 2}
|
508
|
+
```
|
509
|
+
|
510
|
+
|
511
|
+
**#except!**
|
512
|
+
|
513
|
+
```ruby
|
514
|
+
# same as #except but modify specified Hash in-place
|
515
|
+
Cistern::Hash.except!({:a => 1, :b => 2}, :a) #=> {:b => 2}
|
516
|
+
# within a Resource
|
517
|
+
hash_except!({:a => 1, :b => 2}, :a) #=> {:b => 2}
|
518
|
+
```
|
519
|
+
|
520
|
+
|
508
521
|
#### Storage
|
509
522
|
|
510
523
|
Currently supported storage backends are:
|
@@ -588,10 +601,75 @@ class Blog::GetPost
|
|
588
601
|
end
|
589
602
|
```
|
590
603
|
|
604
|
+
## ~> 3.0
|
605
|
+
|
606
|
+
### Request Dispatch
|
607
|
+
|
608
|
+
Default request interface passes through `#_mock` and `#_real` depending on the client mode.
|
609
|
+
|
610
|
+
```ruby
|
611
|
+
class Blog::GetPost
|
612
|
+
include Blog::Request
|
613
|
+
|
614
|
+
def setup(post_id, parameters)
|
615
|
+
[post_id, stringify_keys(parameters)]
|
616
|
+
end
|
617
|
+
|
618
|
+
def _mock(*args)
|
619
|
+
mock(*setup(*args))
|
620
|
+
end
|
621
|
+
|
622
|
+
def _real(post_id, parameters)
|
623
|
+
real(*setup(*args))
|
624
|
+
end
|
625
|
+
end
|
626
|
+
```
|
627
|
+
|
628
|
+
In cistern 3, requests pass through `#call` in both modes. `#dispatch` is responsible for determining the mode and
|
629
|
+
calling the appropriate method.
|
630
|
+
|
631
|
+
```ruby
|
632
|
+
class Blog::GetPost
|
633
|
+
include Blog::Request
|
634
|
+
|
635
|
+
def call(post_id, parameters)
|
636
|
+
normalized_parameters = stringify_keys(parameters)
|
637
|
+
dispatch(post_id, normalized_parameters)
|
638
|
+
end
|
639
|
+
end
|
640
|
+
```
|
641
|
+
|
642
|
+
### Client definition
|
643
|
+
|
644
|
+
Default resource definition is done by inheritance.
|
645
|
+
|
646
|
+
```ruby
|
647
|
+
class Blog::Post < Blog::Model
|
648
|
+
end
|
649
|
+
```
|
650
|
+
|
651
|
+
In cistern 3, resource definition is done by module inclusion.
|
652
|
+
|
653
|
+
```ruby
|
654
|
+
class Blog::Post
|
655
|
+
include Blog::Post
|
656
|
+
end
|
657
|
+
```
|
658
|
+
|
659
|
+
Prepare for cistern 3 by using `Cistern::Client.with(interface: :module)` when defining the client.
|
660
|
+
|
661
|
+
```ruby
|
662
|
+
class Blog
|
663
|
+
include Cistern::Client.with(interface: :module)
|
664
|
+
end
|
665
|
+
```
|
666
|
+
|
591
667
|
## Examples
|
592
668
|
|
593
669
|
* [zendesk2](https://github.com/lanej/zendesk2)
|
594
670
|
* [you_track](https://github.com/lanej/you_track)
|
671
|
+
* [ey-core](https://github.com/engineyard/core-client-rb)
|
672
|
+
|
595
673
|
|
596
674
|
## Releasing
|
597
675
|
|
data/lib/cistern/client.rb
CHANGED
@@ -44,7 +44,7 @@ module Cistern::Client
|
|
44
44
|
|
45
45
|
if interface == :class
|
46
46
|
Cistern.deprecation(
|
47
|
-
%q{class' interface is deprecated. Use `include Cistern::Client.with(interface: :module). See https://github.com/lanej/cistern#custom-architecture},
|
47
|
+
%q{'class' interface is deprecated. Use `include Cistern::Client.with(interface: :module). See https://github.com/lanej/cistern#custom-architecture},
|
48
48
|
caller[2],
|
49
49
|
)
|
50
50
|
end
|
@@ -85,11 +85,19 @@ module Cistern::Client
|
|
85
85
|
class Real
|
86
86
|
def initialize(options={})
|
87
87
|
end
|
88
|
+
|
89
|
+
def mocking?
|
90
|
+
false
|
91
|
+
end
|
88
92
|
end
|
89
93
|
|
90
94
|
class Mock
|
91
95
|
def initialize(options={})
|
92
96
|
end
|
97
|
+
|
98
|
+
def mocking?
|
99
|
+
true
|
100
|
+
end
|
93
101
|
end
|
94
102
|
|
95
103
|
#{interface} #{model_class}
|
@@ -184,14 +192,6 @@ module Cistern::Client
|
|
184
192
|
|
185
193
|
super
|
186
194
|
end
|
187
|
-
|
188
|
-
def _mock(*args)
|
189
|
-
mock(*args)
|
190
|
-
end
|
191
|
-
|
192
|
-
def _real(*args)
|
193
|
-
real(*args)
|
194
|
-
end
|
195
195
|
end
|
196
196
|
EOS
|
197
197
|
|
data/lib/cistern/request.rb
CHANGED
@@ -1,22 +1,35 @@
|
|
1
1
|
module Cistern::Request
|
2
2
|
include Cistern::HashSupport
|
3
3
|
|
4
|
+
module ClassMethods
|
5
|
+
# @deprecated Use {#cistern_method} instead
|
6
|
+
def service_method(name = nil)
|
7
|
+
Cistern.deprecation(
|
8
|
+
'#service_method is deprecated. Please use #cistern_method',
|
9
|
+
caller[0]
|
10
|
+
)
|
11
|
+
@_cistern_method ||= name
|
12
|
+
end
|
13
|
+
|
14
|
+
def cistern_method(name = nil)
|
15
|
+
@_cistern_method ||= name
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
4
19
|
def self.cistern_request(cistern, klass, name)
|
5
20
|
unless klass.name || klass.cistern_method
|
6
21
|
fail ArgumentError, "can't turn anonymous class into a Cistern request"
|
7
22
|
end
|
8
23
|
|
9
|
-
|
24
|
+
method = <<-EOS
|
10
25
|
def #{name}(*args)
|
11
|
-
#{klass}.new(self).
|
26
|
+
#{klass}.new(self).call(*args)
|
12
27
|
end
|
13
28
|
EOS
|
14
29
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
19
|
-
EOS
|
30
|
+
|
31
|
+
cistern::Mock.module_eval method, __FILE__, __LINE__
|
32
|
+
cistern::Real.module_eval method, __FILE__, __LINE__
|
20
33
|
end
|
21
34
|
|
22
35
|
def self.service_request(*args)
|
@@ -41,18 +54,35 @@ module Cistern::Request
|
|
41
54
|
@cistern = cistern
|
42
55
|
end
|
43
56
|
|
44
|
-
|
45
|
-
|
46
|
-
|
57
|
+
def call(*args)
|
58
|
+
dispatch(*args)
|
59
|
+
end
|
60
|
+
|
61
|
+
def real(*)
|
62
|
+
raise NotImplementedError
|
63
|
+
end
|
64
|
+
|
65
|
+
def mock(*)
|
66
|
+
raise NotImplementedError
|
67
|
+
end
|
68
|
+
|
69
|
+
protected
|
70
|
+
|
71
|
+
# @fixme remove _{mock,real} methods and call {mock,real} directly before 3.0 release.
|
72
|
+
def dispatch(*args)
|
73
|
+
to = cistern.mocking? ? :mock : :real
|
74
|
+
|
75
|
+
legacy_method = :"_#{to}"
|
76
|
+
|
77
|
+
if respond_to?(legacy_method)
|
47
78
|
Cistern.deprecation(
|
48
|
-
'#
|
79
|
+
'#_mock is deprecated. Please use #mock and/or #call. See https://github.com/lanej/cistern#request-dispatch',
|
49
80
|
caller[0]
|
50
81
|
)
|
51
|
-
@_cistern_method ||= name
|
52
|
-
end
|
53
82
|
|
54
|
-
|
55
|
-
|
83
|
+
public_send(legacy_method, *args)
|
84
|
+
else
|
85
|
+
public_send(to, *args)
|
56
86
|
end
|
57
87
|
end
|
58
88
|
end
|
data/lib/cistern/singular.rb
CHANGED
@@ -15,6 +15,7 @@ module Cistern::Singular
|
|
15
15
|
klass.send(:extend, Cistern::Attributes::ClassMethods)
|
16
16
|
klass.send(:include, Cistern::Attributes::InstanceMethods)
|
17
17
|
klass.send(:extend, Cistern::Model::ClassMethods)
|
18
|
+
klass.send(:extend, Cistern::Associations)
|
18
19
|
end
|
19
20
|
|
20
21
|
def collection
|
data/lib/cistern/version.rb
CHANGED
data/spec/request_spec.rb
CHANGED
@@ -1,57 +1,79 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe 'Cistern::Request' do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
before {
|
5
|
+
Sample.class_eval do
|
6
|
+
recognizes :key
|
7
|
+
end
|
8
8
|
|
9
|
-
|
9
|
+
Sample::Real.class_eval do
|
10
10
|
attr_reader :service_args
|
11
11
|
|
12
12
|
def initialize(*args)
|
13
13
|
@service_args = args
|
14
14
|
end
|
15
15
|
end
|
16
|
-
|
16
|
+
}
|
17
17
|
|
18
|
-
#
|
19
|
-
|
20
|
-
|
18
|
+
describe '#cistern_method' do
|
19
|
+
it 'remaps the client request method' do
|
20
|
+
class ListSamples < Sample::Request
|
21
|
+
cistern_method :list_all_samples
|
22
|
+
end
|
21
23
|
|
22
|
-
|
23
|
-
|
24
|
+
expect(Sample.new).to respond_to(:list_all_samples)
|
25
|
+
expect(Sample.new).not_to respond_to(:list_samples)
|
24
26
|
end
|
27
|
+
end
|
25
28
|
|
26
|
-
|
27
|
-
|
29
|
+
it 'calls the appropriate method' do
|
30
|
+
class GetSamples < Sample::Request
|
31
|
+
def real(*args)
|
32
|
+
cistern.service_args + args + ['real']
|
33
|
+
end
|
34
|
+
|
35
|
+
def mock(*args)
|
36
|
+
args + ['mock']
|
37
|
+
end
|
28
38
|
end
|
29
|
-
end
|
30
39
|
|
31
|
-
|
32
|
-
expect(
|
33
|
-
expect(
|
34
|
-
expect(RequestService::Mock.new.list_all_samples('sample3')).to eq(%w(sample3 mock))
|
40
|
+
expect(Sample.new.get_samples('sample1')).to eq([{}, 'sample1', 'real'])
|
41
|
+
expect(Sample::Real.new.get_samples('sample2')).to eq(%w(sample2 real))
|
42
|
+
expect(Sample::Mock.new.get_samples('sample3')).to eq(%w(sample3 mock))
|
35
43
|
|
36
44
|
# service access
|
37
|
-
expect(
|
45
|
+
expect(Sample.new(key: 'value').get_samples('stat')).to eq([{ key: 'value' }, 'stat', 'real'])
|
38
46
|
end
|
39
47
|
|
40
48
|
describe 'deprecation', :deprecated do
|
41
|
-
|
42
|
-
|
49
|
+
it 'calls _mock and _real if present' do
|
50
|
+
class Sample::ListDeprecations < Sample::Request
|
51
|
+
def _mock
|
52
|
+
:_mock
|
53
|
+
end
|
54
|
+
|
55
|
+
def real
|
56
|
+
:real
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
actual = Sample.new.list_deprecations
|
61
|
+
expect(actual).to eq(:real)
|
62
|
+
|
63
|
+
Sample.mock!
|
64
|
+
|
65
|
+
actual = Sample.new.list_deprecations
|
66
|
+
expect(actual).to eq(:_mock)
|
43
67
|
end
|
44
68
|
|
45
69
|
it 'responds to #service' do
|
46
|
-
class ListDeprecations <
|
47
|
-
service_method :list_deprecations
|
48
|
-
|
70
|
+
class Sample::ListDeprecations < Sample::Request
|
49
71
|
def real
|
50
72
|
self
|
51
73
|
end
|
52
74
|
end
|
53
75
|
|
54
|
-
sample =
|
76
|
+
sample = Sample.new.list_deprecations
|
55
77
|
expect(sample.service).to eq(sample.cistern)
|
56
78
|
end
|
57
79
|
end
|
data/spec/singular_spec.rb
CHANGED
@@ -6,6 +6,8 @@ describe 'Cistern::Singular' do
|
|
6
6
|
attribute :name, type: :string
|
7
7
|
attribute :count, type: :number
|
8
8
|
|
9
|
+
belongs_to :entity, -> { cistern.settings(name: '1') }
|
10
|
+
|
9
11
|
def save
|
10
12
|
result = @@settings = attributes.merge(dirty_attributes)
|
11
13
|
|
@@ -32,6 +34,10 @@ describe 'Cistern::Singular' do
|
|
32
34
|
end
|
33
35
|
end
|
34
36
|
|
37
|
+
it 'allows associations' do
|
38
|
+
expect(service.settings.load.entity.name).to eq('1')
|
39
|
+
end
|
40
|
+
|
35
41
|
it 'reloads' do
|
36
42
|
singular = service.settings(count: 0)
|
37
43
|
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cistern
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josh Lane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-08-10 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: API client framework extracted from Fog
|
14
14
|
email:
|