frenetic 0.0.20.alpha.4 → 0.0.20.alpha.5
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/README.md +37 -0
- data/lib/frenetic/concerns/member_rest_methods.rb +5 -1
- data/lib/frenetic/concerns/resource_mockery.rb +8 -0
- data/lib/frenetic/configuration.rb +5 -0
- data/lib/frenetic/resource.rb +12 -0
- data/lib/frenetic/version.rb +1 -1
- data/spec/concerns/member_rest_methods_spec.rb +22 -0
- data/spec/concerns/resource_mockery_spec.rb +9 -1
- data/spec/configuration_spec.rb +7 -0
- data/spec/resource_spec.rb +26 -0
- metadata +3 -3
data/README.md
CHANGED
@@ -402,6 +402,43 @@ end
|
|
402
402
|
As you can see, this allows you to supply some default values for the attributes
|
403
403
|
of your resource to ease object creation in testing.
|
404
404
|
|
405
|
+
|
406
|
+
|
407
|
+
### Integration Testing
|
408
|
+
|
409
|
+
When it comes time to write integration tests for your API client, you can either
|
410
|
+
stub out all of the HTTP requests with something like WebMock or VCR, or you can
|
411
|
+
use Frenetic in `test_mode`
|
412
|
+
|
413
|
+
```ruby
|
414
|
+
Frenetic.new( url:url, test_mode:true )
|
415
|
+
# ...or...
|
416
|
+
api = Frenetic.new(url:url)
|
417
|
+
api.config.test_mode = true
|
418
|
+
```
|
419
|
+
|
420
|
+
Doing so will allow `Frenetic::Resource.find` to return a mock resource instead
|
421
|
+
of querying your API for what is available.
|
422
|
+
|
423
|
+
Example:
|
424
|
+
|
425
|
+
```ruby
|
426
|
+
class MyResource < Frenetic::Resource
|
427
|
+
api_client { Frenetic.new(url) }
|
428
|
+
end
|
429
|
+
|
430
|
+
class MyMockResource < MyResource
|
431
|
+
include Frenetic::ResourceMockery
|
432
|
+
end
|
433
|
+
|
434
|
+
> MyResource.api_client.config.test_mode = true
|
435
|
+
# true
|
436
|
+
> MyResource.find(99)
|
437
|
+
# <MyMockResource id=99>
|
438
|
+
```
|
439
|
+
|
440
|
+
|
441
|
+
|
405
442
|
## Contributing
|
406
443
|
|
407
444
|
1. Fork it
|
@@ -5,15 +5,19 @@ class Frenetic
|
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
|
7
7
|
module ClassMethods
|
8
|
-
def find( params
|
8
|
+
def find( params )
|
9
9
|
params = { id:params } unless params.is_a? Hash
|
10
10
|
|
11
|
+
return as_mock(params) if test_mode?
|
12
|
+
|
11
13
|
if response = api.get( member_url(params) ) and response.success?
|
12
14
|
new response.body
|
13
15
|
end
|
14
16
|
end
|
15
17
|
|
16
18
|
def all
|
19
|
+
return [] if test_mode?
|
20
|
+
|
17
21
|
if response = api.get( collection_url ) and response.success?
|
18
22
|
Frenetic::ResourceCollection.new self, response.body
|
19
23
|
end
|
@@ -1,7 +1,15 @@
|
|
1
1
|
require 'ostruct'
|
2
|
+
require 'active_support/concern'
|
2
3
|
|
3
4
|
class Frenetic
|
4
5
|
module ResourceMockery
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
# I'm sure this violates some sort of CS principle or best practice,
|
10
|
+
# but it solves the problem for now.
|
11
|
+
superclass.send :instance_variable_set, '@mock_class', self
|
12
|
+
end
|
5
13
|
|
6
14
|
def attributes
|
7
15
|
@params
|
@@ -32,6 +32,7 @@ class Frenetic
|
|
32
32
|
headers: headers,
|
33
33
|
password: password,
|
34
34
|
ssl: ssl,
|
35
|
+
test_mode: test_mode,
|
35
36
|
url: url,
|
36
37
|
username: username
|
37
38
|
}
|
@@ -71,6 +72,10 @@ class Frenetic
|
|
71
72
|
@_cfg[:ssl] || { verify:true }
|
72
73
|
end
|
73
74
|
|
75
|
+
def test_mode
|
76
|
+
@_cfg[:test_mode] || false
|
77
|
+
end
|
78
|
+
|
74
79
|
def url
|
75
80
|
Addressable::URI.parse @_cfg[:url]
|
76
81
|
end
|
data/lib/frenetic/resource.rb
CHANGED
@@ -46,6 +46,14 @@ class Frenetic
|
|
46
46
|
(api.schema[namespace]||{})['properties'] or raise HypermediaError, %Q{Could not find schema definition for the resource "#{namespace}"}
|
47
47
|
end
|
48
48
|
|
49
|
+
def self.as_mock( params = {} )
|
50
|
+
raise Frenetic::ClientError, "Mock resource not defined for #{namespace}." \
|
51
|
+
" Subclass #{self} and mixin Frenetic::ResourceMockery" \
|
52
|
+
" to define a mock" unless @mock_class
|
53
|
+
|
54
|
+
@mock_class.new params
|
55
|
+
end
|
56
|
+
|
49
57
|
def initialize( p = {} )
|
50
58
|
build_params p
|
51
59
|
@attrs = {}
|
@@ -112,5 +120,9 @@ class Frenetic
|
|
112
120
|
self.class.properties
|
113
121
|
end
|
114
122
|
|
123
|
+
def self.test_mode?
|
124
|
+
api_client.config.test_mode
|
125
|
+
end
|
126
|
+
|
115
127
|
end
|
116
128
|
end
|
data/lib/frenetic/version.rb
CHANGED
@@ -45,6 +45,20 @@ describe Frenetic::MemberRestMethods do
|
|
45
45
|
expect{ subject }.to raise_error Frenetic::ClientError
|
46
46
|
end
|
47
47
|
end
|
48
|
+
|
49
|
+
context 'in test mode' do
|
50
|
+
let(:test_cfg) { { url:'http://example.com/api', test_mode:true } }
|
51
|
+
|
52
|
+
before do
|
53
|
+
stub_const 'MyMockResource', Class.new(MyTempResource)
|
54
|
+
|
55
|
+
MyMockResource.send :include, Frenetic::ResourceMockery
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should return a mock resource' do
|
59
|
+
expect(subject).to be_an_instance_of MyMockResource
|
60
|
+
end
|
61
|
+
end
|
48
62
|
end
|
49
63
|
|
50
64
|
describe '.all' do
|
@@ -63,5 +77,13 @@ describe Frenetic::MemberRestMethods do
|
|
63
77
|
expect(subject.first).to be_an_instance_of MyTempResource
|
64
78
|
end
|
65
79
|
end
|
80
|
+
|
81
|
+
context 'in test mode' do
|
82
|
+
let(:test_cfg) { { url:'http://example.com/api', test_mode:true } }
|
83
|
+
|
84
|
+
it 'should return an empty collection' do
|
85
|
+
expect(subject).to be_empty
|
86
|
+
end
|
87
|
+
end
|
66
88
|
end
|
67
89
|
end
|
@@ -3,8 +3,12 @@ require 'spec_helper'
|
|
3
3
|
require 'frenetic/resource_mockery'
|
4
4
|
|
5
5
|
describe Frenetic::ResourceMockery do
|
6
|
+
let(:my_temp_resource) do
|
7
|
+
Class.new(Frenetic::Resource)
|
8
|
+
end
|
9
|
+
|
6
10
|
let(:my_mocked_resource) do
|
7
|
-
Class.new(
|
11
|
+
Class.new(my_temp_resource) do
|
8
12
|
def default_attributes
|
9
13
|
{ qux:'qux' }
|
10
14
|
end
|
@@ -21,6 +25,10 @@ describe Frenetic::ResourceMockery do
|
|
21
25
|
|
22
26
|
subject { MyNamespace::MyMockedResource.new params }
|
23
27
|
|
28
|
+
it 'should violate some basic CS principles by telling the parent-class of its existence' do
|
29
|
+
expect(my_temp_resource.instance_variables).to include :@mock_class
|
30
|
+
end
|
31
|
+
|
24
32
|
describe '#properties' do
|
25
33
|
subject { super().properties }
|
26
34
|
|
data/spec/configuration_spec.rb
CHANGED
@@ -19,6 +19,7 @@ describe Frenetic::Configuration do
|
|
19
19
|
it { should include :headers }
|
20
20
|
it { should include :password }
|
21
21
|
it { should include :ssl }
|
22
|
+
it { should include :test_mode }
|
22
23
|
it { should include :url }
|
23
24
|
it { should include :username }
|
24
25
|
end
|
@@ -101,6 +102,12 @@ describe Frenetic::Configuration do
|
|
101
102
|
it { should include verify:true }
|
102
103
|
end
|
103
104
|
|
105
|
+
describe '#test_mode' do
|
106
|
+
subject { instance.test_mode }
|
107
|
+
|
108
|
+
it { should be_false }
|
109
|
+
end
|
110
|
+
|
104
111
|
describe '#url' do
|
105
112
|
let(:cfg) do
|
106
113
|
{ url:'http://example.org' }
|
data/spec/resource_spec.rb
CHANGED
@@ -152,6 +152,32 @@ describe Frenetic::Resource do
|
|
152
152
|
end
|
153
153
|
end
|
154
154
|
|
155
|
+
describe '.as_mock' do
|
156
|
+
subject { MyNamespace::MyTempResource.as_mock id:99 }
|
157
|
+
|
158
|
+
context 'without a defined Mock-class' do
|
159
|
+
it 'should raise an error' do
|
160
|
+
expect{subject}.to raise_error Frenetic::ClientError
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
context 'with a defined Mock-class' do
|
165
|
+
before do
|
166
|
+
stub_const 'MyNamespace::MyMockResource', Class.new(MyNamespace::MyTempResource)
|
167
|
+
|
168
|
+
MyNamespace::MyMockResource.send :include, Frenetic::ResourceMockery
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'should return a mock instance of the resource' do
|
172
|
+
expect(subject).to be_an_instance_of MyNamespace::MyMockResource
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'should initialize the mock with the provided values' do
|
176
|
+
expect(subject.id).to eq 99
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
155
181
|
describe '#initialize' do
|
156
182
|
before { @stubs.api_description }
|
157
183
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: frenetic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.20.alpha.
|
4
|
+
version: 0.0.20.alpha.5
|
5
5
|
prerelease: 7
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-05-
|
12
|
+
date: 2013-05-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: faraday
|
@@ -215,7 +215,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
215
215
|
version: '0'
|
216
216
|
segments:
|
217
217
|
- 0
|
218
|
-
hash: -
|
218
|
+
hash: -3382151532624258123
|
219
219
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
220
220
|
none: false
|
221
221
|
requirements:
|