acfs 1.4.0 → 1.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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -0
  3. data/README.md +22 -39
  4. data/acfs.gemspec +8 -14
  5. data/lib/acfs/adapter/base.rb +2 -0
  6. data/lib/acfs/adapter/typhoeus.rb +16 -11
  7. data/lib/acfs/collections/paginatable.rb +1 -1
  8. data/lib/acfs/configuration.rb +13 -3
  9. data/lib/acfs/errors.rb +41 -21
  10. data/lib/acfs/global.rb +2 -2
  11. data/lib/acfs/location.rb +26 -32
  12. data/lib/acfs/middleware/base.rb +2 -2
  13. data/lib/acfs/middleware/json.rb +4 -2
  14. data/lib/acfs/middleware/logger.rb +4 -6
  15. data/lib/acfs/middleware/serializer.rb +1 -1
  16. data/lib/acfs/operation.rb +21 -8
  17. data/lib/acfs/request/callbacks.rb +4 -4
  18. data/lib/acfs/request.rb +4 -11
  19. data/lib/acfs/resource/attributes/date_time.rb +1 -1
  20. data/lib/acfs/resource/attributes/uuid.rb +1 -1
  21. data/lib/acfs/resource/attributes.rb +16 -15
  22. data/lib/acfs/resource/dirty.rb +2 -2
  23. data/lib/acfs/resource/initialization.rb +5 -5
  24. data/lib/acfs/resource/locatable.rb +11 -8
  25. data/lib/acfs/resource/operational.rb +6 -3
  26. data/lib/acfs/resource/persistence.rb +13 -15
  27. data/lib/acfs/resource/query_methods.rb +10 -10
  28. data/lib/acfs/resource/service.rb +2 -2
  29. data/lib/acfs/resource/validation.rb +17 -7
  30. data/lib/acfs/response.rb +5 -5
  31. data/lib/acfs/runner.rb +15 -15
  32. data/lib/acfs/service.rb +16 -19
  33. data/lib/acfs/singleton_resource.rb +2 -2
  34. data/lib/acfs/stub.rb +41 -31
  35. data/lib/acfs/version.rb +2 -2
  36. data/spec/acfs/adapter/typhoeus_spec.rb +2 -2
  37. data/spec/acfs/collection_spec.rb +66 -41
  38. data/spec/acfs/configuration_spec.rb +22 -12
  39. data/spec/acfs/global_spec.rb +11 -9
  40. data/spec/acfs/location_spec.rb +2 -2
  41. data/spec/acfs/middleware/json_spec.rb +22 -8
  42. data/spec/acfs/middleware/{msgpack_spec.rb → message_pack_spec.rb} +6 -6
  43. data/spec/acfs/operation_spec.rb +3 -2
  44. data/spec/acfs/request/callbacks_spec.rb +19 -10
  45. data/spec/acfs/request_spec.rb +16 -20
  46. data/spec/acfs/resource/attributes/boolean_spec.rb +32 -32
  47. data/spec/acfs/resource/attributes/date_time_spec.rb +16 -8
  48. data/spec/acfs/resource/attributes/dict_spec.rb +15 -9
  49. data/spec/acfs/resource/attributes/float_spec.rb +20 -10
  50. data/spec/acfs/resource/attributes/integer_spec.rb +10 -5
  51. data/spec/acfs/resource/attributes/list_spec.rb +13 -8
  52. data/spec/acfs/resource/attributes/uuid_spec.rb +12 -6
  53. data/spec/acfs/resource/attributes_spec.rb +37 -38
  54. data/spec/acfs/resource/dirty_spec.rb +6 -3
  55. data/spec/acfs/resource/initialization_spec.rb +4 -5
  56. data/spec/acfs/resource/loadable_spec.rb +3 -1
  57. data/spec/acfs/resource/locatable_spec.rb +24 -18
  58. data/spec/acfs/resource/{persistance_spec.rb → persistence_spec.rb} +122 -90
  59. data/spec/acfs/resource/query_methods_spec.rb +143 -110
  60. data/spec/acfs/resource/validation_spec.rb +34 -27
  61. data/spec/acfs/response/formats_spec.rb +8 -8
  62. data/spec/acfs/response/status_spec.rb +16 -9
  63. data/spec/acfs/runner_spec.rb +10 -8
  64. data/spec/acfs/service/middleware_spec.rb +3 -3
  65. data/spec/acfs/service_spec.rb +6 -5
  66. data/spec/acfs/singleton_resource_spec.rb +2 -1
  67. data/spec/acfs/stub_spec.rb +57 -53
  68. data/spec/acfs_spec.rb +111 -93
  69. data/spec/spec_helper.rb +1 -2
  70. data/spec/support/response.rb +2 -2
  71. data/spec/support/service.rb +1 -1
  72. data/spec/support/shared/find_callbacks.rb +14 -10
  73. metadata +30 -29
data/lib/acfs/service.rb CHANGED
@@ -28,33 +28,27 @@ module Acfs
28
28
 
29
29
  # @api private
30
30
  #
31
- def initialize(options = {})
31
+ def initialize(**options)
32
32
  @options = options
33
33
  end
34
34
 
35
35
  # @api private
36
36
  # @return [Location]
37
37
  #
38
- def location(resource_class, opts = {})
39
- opts.reverse_merge! options
38
+ def location(resource_class, path: nil, action: :list, **)
39
+ path ||= options[:path]
40
40
 
41
- action = opts[:action] || :list
41
+ if path.is_a?(Hash) && path.key?(action)
42
+ path = path.fetch(action)
43
+ else
44
+ path = path.is_a?(Hash) ? path[:all].to_s : path.to_s
42
45
 
43
- path = if opts[:path].is_a?(Hash) && opts[:path].key?(action)
44
- opts[:path].fetch(action)
45
- else
46
- path = if opts[:path].is_a?(Hash)
47
- opts[:path][:all].to_s
48
- else
49
- opts[:path].to_s
50
- end
51
-
52
- if path.blank?
53
- path = (resource_class.name || 'class').pluralize.underscore
54
- end
46
+ if path.blank?
47
+ path = (resource_class.name || 'class').pluralize.underscore
48
+ end
55
49
 
56
- resource_class.location_default_path(action, path.strip)
57
- end
50
+ path = resource_class.location_default_path(action, path.strip)
51
+ end
58
52
 
59
53
  if path.nil?
60
54
  raise ArgumentError.new "Location for `#{action}' explicit disabled by set to nil."
@@ -87,7 +81,10 @@ module Acfs
87
81
  #
88
82
  def base_url
89
83
  unless (base = Acfs::Configuration.current.locate identity)
90
- raise ArgumentError.new "#{identity} not configured. Add `locate '#{identity.to_s.underscore}', 'http://service.url/'` to your configuration."
84
+ raise ArgumentError.new \
85
+ "#{identity} not configured. Add `locate '" \
86
+ "#{identity.to_s.underscore}', 'http://service.url/'` " \
87
+ 'to your configuration.'
91
88
  end
92
89
 
93
90
  base.to_s
@@ -27,10 +27,10 @@ module Acfs
27
27
  # @return [undefined]
28
28
  # @see #delete
29
29
  #
30
- def delete!(opts = {})
30
+ def delete!(**opts)
31
31
  opts[:params] ||= {}
32
32
 
33
- operation :delete, opts do |data|
33
+ operation(:delete, **opts) do |data|
34
34
  update_with data
35
35
  freeze
36
36
  end
data/lib/acfs/stub.rb CHANGED
@@ -16,16 +16,16 @@ module Acfs
16
16
  @opts[:with].stringify_keys! if @opts[:with].is_a? Hash
17
17
  @opts[:return].stringify_keys! if @opts[:return].is_a? Hash
18
18
 
19
- if @opts[:return].is_a? Array
19
+ if @opts[:return].is_a?(Array) # rubocop:disable Style/GuardClause
20
20
  @opts[:return].map! {|h| h.stringify_keys! if h.is_a? Hash }
21
21
  end
22
22
  end
23
23
 
24
- def accept?(op)
25
- return opts[:with].call op if opts[:with].respond_to? :call
24
+ def accept?(operation)
25
+ return opts[:with].call(operation) if opts[:with].respond_to?(:call)
26
26
 
27
- params = op.full_params.stringify_keys
28
- data = op.data.stringify_keys
27
+ params = operation.full_params.stringify_keys
28
+ data = operation.data.stringify_keys
29
29
  with = opts[:with]
30
30
 
31
31
  return true if with.nil?
@@ -33,10 +33,10 @@ module Acfs
33
33
  case opts.fetch(:match, :inclusion)
34
34
  when :legacy
35
35
  return true if with.empty? && params.empty? && data.empty?
36
- if with.reject {|_, v| v.nil? } == params.reject {|_, v| v.nil? }
36
+ if with.compact == params.compact
37
37
  return true
38
38
  end
39
- if with.reject {|_, v| v.nil? } == data.reject {|_, v| v.nil? }
39
+ if with.compact == data.compact
40
40
  return true
41
41
  end
42
42
 
@@ -53,28 +53,30 @@ module Acfs
53
53
  end
54
54
 
55
55
  def called?(count = nil)
56
- if count.respond_to? :count
57
- count = count.count
58
- end # For `5.times` Enumerators
56
+ count = count.count if count.respond_to?(:count)
57
+
59
58
  count.nil? ? calls.any? : calls.size == count
60
59
  end
61
60
 
62
- def call(op)
63
- calls << op
61
+ def call(operation)
62
+ calls << operation
64
63
 
65
64
  err = opts[:raise]
66
65
  data = opts[:return]
67
66
 
68
67
  if err
69
- raise_error op, err, opts[:return]
68
+ raise_error(operation, err, opts[:return])
70
69
  elsif data
71
- data = data.call(op) if data.respond_to?(:call)
70
+ data = data.call(operation) if data.respond_to?(:call)
72
71
 
73
- response = Acfs::Response.new op.request,
72
+ response = Acfs::Response.new(
73
+ operation.request,
74
74
  headers: opts[:headers] || {},
75
75
  status: opts[:status] || 200,
76
- data: data || {}
77
- op.call data, response
76
+ data: data || {},
77
+ )
78
+
79
+ operation.call(data, response)
78
80
  else
79
81
  raise ArgumentError.new 'Unsupported stub.'
80
82
  end
@@ -82,12 +84,18 @@ module Acfs
82
84
 
83
85
  private
84
86
 
85
- def raise_error(op, name, data)
87
+ def raise_error(operation, name, data)
86
88
  raise name if name.is_a? Class
87
89
 
88
- data.stringify_keys! if data.respond_to? :stringify_keys!
90
+ data.stringify_keys! if data.respond_to?(:stringify_keys!)
89
91
 
90
- op.handle_failure ::Acfs::Response.new op.request, status: Rack::Utils.status_code(name), data: data
92
+ operation.handle_failure(
93
+ ::Acfs::Response.new(
94
+ operation.request,
95
+ status: Rack::Utils.status_code(name),
96
+ data: data,
97
+ ),
98
+ )
91
99
  end
92
100
 
93
101
  class << self
@@ -137,33 +145,35 @@ module Acfs
137
145
  @stubs ||= {}
138
146
  end
139
147
 
140
- def stub_for(op)
141
- return false unless (classes = stubs[op.resource])
142
- return false unless (stubs = classes[op.action])
148
+ def stub_for(operation)
149
+ return false unless (classes = stubs[operation.resource])
150
+ return false unless (stubs = classes[operation.action])
143
151
 
144
- accepted_stubs = stubs.select {|stub| stub.accept? op }
152
+ accepted_stubs = stubs.select {|stub| stub.accept?(operation) }
145
153
 
146
154
  if accepted_stubs.size > 1
147
- raise AmbiguousStubError.new stubs: accepted_stubs, operation: op
155
+ raise AmbiguousStubError.new(stubs: accepted_stubs, operation: operation)
148
156
  end
149
157
 
150
158
  accepted_stubs.first
151
159
  end
152
160
 
153
- def stubbed(op)
154
- stub = stub_for op
161
+ def stubbed(operation)
162
+ stub = stub_for(operation)
155
163
  unless stub
156
164
  return false if allow_requests?
157
165
 
158
- raise RealRequestsNotAllowedError.new <<-MSG.strip.gsub(/^[ ]{12}/, '')
159
- No stub found for `#{op.action}' on `#{op.resource.name}' with params `#{op.full_params.inspect}', data `#{op.data.inspect}' and id `#{op.id}'.
166
+ raise RealRequestsNotAllowedError.new <<~ERROR
167
+ No stub found for `#{operation.action}' on `#{operation.resource.name}' \
168
+ with params `#{operation.full_params.inspect}', data `#{operation.data.inspect}' \
169
+ and id `#{operation.id}'.
160
170
 
161
171
  Available stubs:
162
172
  #{pretty_print}
163
- MSG
173
+ ERROR
164
174
  end
165
175
 
166
- stub.call op
176
+ stub.call(operation)
167
177
  true
168
178
  end
169
179
 
data/lib/acfs/version.rb CHANGED
@@ -3,11 +3,11 @@
3
3
  module Acfs
4
4
  module VERSION
5
5
  MAJOR = 1
6
- MINOR = 4
6
+ MINOR = 7
7
7
  PATCH = 0
8
8
  STAGE = nil
9
9
 
10
- STRING = [MAJOR, MINOR, PATCH, STAGE].reject(&:nil?).join('.')
10
+ STRING = [MAJOR, MINOR, PATCH, STAGE].compact.join('.')
11
11
 
12
12
  def self.to_s
13
13
  STRING
@@ -19,8 +19,8 @@ describe Acfs::Adapter::Typhoeus do
19
19
  adapter.queue request1
20
20
  adapter.queue request2
21
21
 
22
- expect { adapter.start }.to raise_error(/404\-[12]/)
23
- expect { adapter.start }.to_not raise_error
22
+ expect { adapter.start }.to raise_error(/404-[12]/)
23
+ expect { adapter.start }.not_to raise_error
24
24
  end
25
25
 
26
26
  it 'raises timeout' do
@@ -6,149 +6,174 @@ describe Acfs::Collection do
6
6
  let(:model) { MyUser }
7
7
 
8
8
  describe 'Pagination' do
9
+ subject do
10
+ Acfs.run
11
+ collection
12
+ end
13
+
9
14
  let(:params) { {} }
10
15
  let!(:collection) { model.all params }
11
16
 
12
- subject { Acfs.run; collection }
13
-
14
17
  context 'without explicit page parameter' do
15
18
  before do
16
19
  stub_request(:get, 'http://users.example.org/users')
17
20
  .to_return response([{id: 1, name: 'Anon', age: 12, born_at: 'Berlin'}],
18
21
  headers: {
19
22
  'X-Total-Pages' => '2',
20
- 'X-Total-Count' => '10'
21
- })
23
+ 'X-Total-Count' => '10',
24
+ },)
22
25
  end
23
26
 
24
- its(:total_pages) { should eq 2 }
25
- its(:current_page) { should eq 1 }
26
- its(:total_count) { should eq 10 }
27
+ its(:total_pages) { is_expected.to eq 2 }
28
+ its(:current_page) { is_expected.to eq 1 }
29
+ its(:total_count) { is_expected.to eq 10 }
27
30
  end
28
31
 
29
32
  context 'with page parameter' do
30
33
  let(:params) { {page: 2} }
34
+
31
35
  before do
32
36
  stub_request(:get, 'http://users.example.org/users?page=2')
33
37
  .to_return response([{id: 1, name: 'Anon', age: 12, born_at: 'Berlin'}],
34
38
  headers: {
35
39
  'X-Total-Pages' => '2',
36
- 'X-Total-Count' => '10'
37
- })
40
+ 'X-Total-Count' => '10',
41
+ },)
38
42
  end
39
43
 
40
- its(:total_pages) { should eq 2 }
41
- its(:current_page) { should eq 2 }
42
- its(:total_count) { should eq 10 }
44
+ its(:total_pages) { is_expected.to eq 2 }
45
+ its(:current_page) { is_expected.to eq 2 }
46
+ its(:total_count) { is_expected.to eq 10 }
43
47
  end
44
48
 
45
49
  context 'with non-numerical page parameter' do
46
50
  let(:params) { {page: 'e546f5'} }
51
+
47
52
  before do
48
53
  stub_request(:get, 'http://users.example.org/users?page=e546f5')
49
54
  .to_return response([{id: 1, name: 'Anon', age: 12, born_at: 'Berlin'}],
50
55
  headers: {
51
56
  'X-Total-Pages' => '2',
52
- 'X-Total-Count' => '10'
53
- })
57
+ 'X-Total-Count' => '10',
58
+ },)
54
59
  end
55
60
 
56
- its(:total_pages) { should eq 2 }
57
- its(:current_page) { should eq 'e546f5' }
58
- its(:total_count) { should eq 10 }
61
+ its(:total_pages) { is_expected.to eq 2 }
62
+ its(:current_page) { is_expected.to eq 'e546f5' }
63
+ its(:total_count) { is_expected.to eq 10 }
59
64
  end
60
65
 
61
66
  describe '#next_page' do
67
+ subject(:request_page) do
68
+ Acfs.run
69
+ collection.next_page
70
+ end
71
+
62
72
  before do
63
73
  stub_request(:get, 'http://users.example.org/users')
64
74
  .to_return response([{id: 1, name: 'Anon', age: 12, born_at: 'Berlin'}],
65
75
  headers: {
66
76
  'X-Total-Pages' => '2',
67
- 'Link' => '<http://users.example.org/users?page=2>; rel="next"'
68
- })
77
+ 'Link' => '<http://users.example.org/users?page=2>; rel="next"',
78
+ },)
69
79
  end
80
+
70
81
  let!(:req) do
71
82
  stub_request(:get, 'http://users.example.org/users?page=2').to_return response([])
72
83
  end
73
84
  let!(:collection) { model.all }
74
- subject { Acfs.run; collection.next_page }
75
85
 
76
- it { should be_a Acfs::Collection }
86
+ it { is_expected.to be_a Acfs::Collection }
77
87
 
78
- it 'should have fetched page 2' do
79
- subject
88
+ it 'has fetched page 2' do
89
+ request_page
80
90
  Acfs.run
81
91
  expect(req).to have_been_requested
82
92
  end
83
93
  end
84
94
 
85
95
  describe '#prev_page' do
96
+ subject(:request_page) do
97
+ Acfs.run
98
+ collection.prev_page
99
+ end
100
+
86
101
  before do
87
102
  stub_request(:get, 'http://users.example.org/users?page=2')
88
103
  .to_return response([{id: 2, name: 'Anno', age: 1604, born_at: 'Santa Maria'}],
89
104
  headers: {
90
105
  'X-Total-Pages' => '2',
91
- 'Link' => '<http://users.example.org/users>; rel="prev"'
92
- })
106
+ 'Link' => '<http://users.example.org/users>; rel="prev"',
107
+ },)
93
108
  end
109
+
94
110
  let!(:req) do
95
111
  stub_request(:get, 'http://users.example.org/users').to_return response([])
96
112
  end
97
113
  let!(:collection) { model.all page: 2 }
98
- subject { Acfs.run; collection.prev_page }
99
114
 
100
- it { should be_a Acfs::Collection }
115
+ it { is_expected.to be_a Acfs::Collection }
101
116
 
102
- it 'should have fetched page 1' do
103
- subject
117
+ it 'has fetched page 1' do
118
+ request_page
104
119
  Acfs.run
105
120
  expect(req).to have_been_requested
106
121
  end
107
122
  end
108
123
 
109
124
  describe '#first_page' do
125
+ subject(:request_page) do
126
+ Acfs.run
127
+ collection.first_page
128
+ end
129
+
110
130
  before do
111
131
  stub_request(:get, 'http://users.example.org/users?page=2')
112
132
  .to_return response([{id: 2, name: 'Anno', age: 1604, born_at: 'Santa Maria'}],
113
133
  headers: {
114
134
  'X-Total-Pages' => '2',
115
- 'Link' => '<http://users.example.org/users>; rel="first"'
116
- })
135
+ 'Link' => '<http://users.example.org/users>; rel="first"',
136
+ },)
117
137
  end
138
+
118
139
  let!(:req) do
119
140
  stub_request(:get, 'http://users.example.org/users').to_return response([])
120
141
  end
121
142
  let!(:collection) { model.all page: 2 }
122
- subject { Acfs.run; collection.first_page }
123
143
 
124
- it { should be_a Acfs::Collection }
144
+ it { is_expected.to be_a Acfs::Collection }
125
145
 
126
- it 'should have fetched page 1' do
127
- subject
146
+ it 'has fetched page 1' do
147
+ request_page
128
148
  Acfs.run
129
149
  expect(req).to have_been_requested
130
150
  end
131
151
  end
132
152
 
133
153
  describe '#last_page' do
154
+ subject(:request_page) do
155
+ Acfs.run
156
+ collection.last_page
157
+ end
158
+
134
159
  before do
135
160
  stub_request(:get, 'http://users.example.org/users?page=2')
136
161
  .to_return response([{id: 2, name: 'Anno', age: 1604, born_at: 'Santa Maria'}],
137
162
  headers: {
138
163
  'X-Total-Pages' => '2',
139
- 'Link' => '<http://users.example.org/users?page=12>; rel="last"'
140
- })
164
+ 'Link' => '<http://users.example.org/users?page=12>; rel="last"',
165
+ },)
141
166
  end
167
+
142
168
  let!(:req) do
143
169
  stub_request(:get, 'http://users.example.org/users?page=12').to_return response([])
144
170
  end
145
171
  let!(:collection) { model.all page: 2 }
146
- subject { Acfs.run; collection.last_page }
147
172
 
148
- it { should be_a Acfs::Collection }
173
+ it { is_expected.to be_a Acfs::Collection }
149
174
 
150
- it 'should have fetched page 1' do
151
- subject
175
+ it 'has fetched page 1' do
176
+ request_page
152
177
  Acfs.run
153
178
  expect(req).to have_been_requested
154
179
  end
@@ -4,11 +4,16 @@ require 'spec_helper'
4
4
 
5
5
  describe Acfs::Configuration do
6
6
  let(:cfg) { Acfs::Configuration.new }
7
- before { @configuration = Acfs::Configuration.current.dup }
8
- after { Acfs::Configuration.set @configuration }
7
+
8
+ around do |example|
9
+ configuration = Acfs::Configuration.current.dup
10
+ example.run
11
+ ensure
12
+ Acfs::Configuration.set(configuration)
13
+ end
9
14
 
10
15
  describe 'Acfs.configure' do
11
- it 'should invoke configure on current configuration' do
16
+ it 'invokes configure on current configuration' do
12
17
  expect(Acfs::Configuration.current).to receive(:configure).once.and_call_original
13
18
 
14
19
  Acfs.configure do |c|
@@ -18,26 +23,31 @@ describe Acfs::Configuration do
18
23
  end
19
24
 
20
25
  describe '.load' do
21
- it 'should be able to load YAML' do
26
+ it 'is able to load YAML' do
22
27
  cfg.configure do
23
28
  load 'spec/fixtures/config.yml'
24
29
  end
25
30
 
26
- expect(cfg.locate(UserService).to_s).to be == 'http://localhost:3001/'
27
- expect(cfg.locate(CommentService).to_s).to be == 'http://localhost:3002/'
31
+ expect(cfg.locate(UserService).to_s).to eq 'http://localhost:3001/'
32
+ expect(cfg.locate(CommentService).to_s).to eq 'http://localhost:3002/'
28
33
  end
29
34
 
30
35
  context 'with RACK_ENV' do
31
- before { @env = ENV['RACK_ENV']; ENV['RACK_ENV'] = 'production' }
32
- after { ENV['RACK_ENV'] = @env }
36
+ around do |example|
37
+ env = ENV['RACK_ENV']
38
+ ENV['RACK_ENV'] = 'production'
39
+ example.run
40
+ ensure
41
+ ENV['RACK_ENV'] = env
42
+ end
33
43
 
34
- it 'should load ENV block' do
44
+ it 'loads ENV block' do
35
45
  cfg.configure do
36
46
  load 'spec/fixtures/config.yml'
37
47
  end
38
48
 
39
- expect(cfg.locate(UserService).to_s).to be == 'http://user.example.org/'
40
- expect(cfg.locate(CommentService).to_s).to be == 'http://comment.example.org/'
49
+ expect(cfg.locate(UserService).to_s).to eq 'http://user.example.org/'
50
+ expect(cfg.locate(CommentService).to_s).to eq 'http://comment.example.org/'
41
51
  end
42
52
  end
43
53
  end
@@ -45,7 +55,7 @@ describe Acfs::Configuration do
45
55
  describe '#adapter' do
46
56
  let(:object) { Object.new }
47
57
 
48
- it 'should be a accessor' do
58
+ it 'is a accessor' do
49
59
  cfg.adapter = object
50
60
  expect(cfg.adapter).to eq object
51
61
  end
@@ -28,7 +28,8 @@ describe ::Acfs::Global do
28
28
  before do
29
29
  ::ActiveSupport::Notifications.subscribe 'acfs.run', collector
30
30
  end
31
- it 'should trigger event' do
31
+
32
+ it 'triggers event' do
32
33
  Acfs.run
33
34
  expect(collector.events).to have(1).items
34
35
  end
@@ -38,7 +39,8 @@ describe ::Acfs::Global do
38
39
  before do
39
40
  ::ActiveSupport::Notifications.subscribe 'acfs.reset', collector
40
41
  end
41
- it 'should trigger event' do
42
+
43
+ it 'triggers event' do
42
44
  Acfs.reset
43
45
  expect(collector.events).to have(1).items
44
46
  end
@@ -50,11 +52,11 @@ describe ::Acfs::Global do
50
52
  stub_request(:get, %r{http://users.example.org/users/\d+}).to_return(
51
53
  status: 200,
52
54
  body: '{}',
53
- headers: {'Content-Type' => 'application/json'}
55
+ headers: {'Content-Type' => 'application/json'},
54
56
  )
55
57
  end
56
58
 
57
- it 'should invoke when both resources' do
59
+ it 'invokes when both resources' do
58
60
  user1 = MyUser.find 1
59
61
  user2 = MyUser.find 2
60
62
 
@@ -64,7 +66,7 @@ describe ::Acfs::Global do
64
66
  end.to yield_with_args(user1, user2)
65
67
  end
66
68
 
67
- it 'should invoke when both resources when loaded' do
69
+ it 'invokes when both resources when loaded' do
68
70
  user1 = MyUser.find 1
69
71
  user2 = MyUser.find 2
70
72
 
@@ -82,7 +84,7 @@ describe ::Acfs::Global do
82
84
  .to_return(
83
85
  status: 200,
84
86
  body: '{}',
85
- headers: {'Content-Type' => 'application/json'}
87
+ headers: {'Content-Type' => 'application/json'},
86
88
  )
87
89
  end
88
90
 
@@ -122,10 +124,10 @@ describe ::Acfs::Global do
122
124
 
123
125
  describe '#runner' do
124
126
  it 'returns per-thread runner' do
125
- runner1 = Thread.new { acfs.runner } .value
126
- runner2 = Thread.new { acfs.runner } .value
127
+ runner1 = Thread.new { acfs.runner }.value
128
+ runner2 = Thread.new { acfs.runner }.value
127
129
 
128
- expect(runner1).to_not equal runner2
130
+ expect(runner1).not_to equal runner2
129
131
  end
130
132
 
131
133
  it 'uses configurated adapter' do
@@ -5,7 +5,7 @@ require 'spec_helper'
5
5
  describe ::Acfs::Location do
6
6
  let(:location) { described_class.new(uri, args) }
7
7
  let(:uri) { 'http://localhost/users/:id' }
8
- let(:args) { {id: 4} }
8
+ let(:args) { {'id' => 4} }
9
9
 
10
10
  describe '#str' do
11
11
  subject(:str) { location.str }
@@ -15,7 +15,7 @@ describe ::Acfs::Location do
15
15
  end
16
16
 
17
17
  context 'with special characters' do
18
- let(:args) { {id: '4 [@(\/!^$'} }
18
+ let(:args) { {'id' => '4 [@(\/!^$'} }
19
19
 
20
20
  it 'escapes special characters' do
21
21
  expect(str).to eq 'http://localhost/users/4+%5B%40%28%5C%2F%21%5E%24'
@@ -16,18 +16,32 @@ describe Acfs::Middleware::JSON do
16
16
 
17
17
  describe 'encode' do
18
18
  context 'with not serialized request' do
19
- it 'should set Content-Type' do
19
+ it 'sets Content-Type' do
20
20
  expect(request.headers['Content-Type']).to eq 'application/json'
21
21
  end
22
22
 
23
- it 'should append Accept header' do
23
+ it 'appends Accept header' do
24
24
  expect(request.headers['Accept']).to eq 'application/json;q=1'
25
25
  end
26
26
 
27
- it 'should serialize data to JSON' do
27
+ it 'serializes data to JSON' do
28
28
  expect(JSON.parse(request.body)).to eq data.map(&:stringify_keys)
29
29
  end
30
30
  end
31
+
32
+ context 'with #to_json objects' do
33
+ let(:data) do
34
+ Class.new do
35
+ def to_json(*)
36
+ '{"a": 1, "b": 2}'
37
+ end
38
+ end.new
39
+ end
40
+
41
+ it 'serializes data with #to_json' do
42
+ expect(JSON.parse(request.body)).to eq 'a' => 1, 'b' => 2
43
+ end
44
+ end
31
45
  end
32
46
 
33
47
  describe 'decode' do
@@ -35,10 +49,10 @@ describe Acfs::Middleware::JSON do
35
49
  let(:headers) { {'Content-Type' => 'application/json; charset=utf-8'} }
36
50
  let(:body) { data.to_json }
37
51
 
38
- it 'should decode body data' do
52
+ it 'decodes body data' do
39
53
  request.complete! response
40
54
 
41
- expect(response.data).to be == data.map(&:stringify_keys)
55
+ expect(response.data).to eq data.map(&:stringify_keys)
42
56
  end
43
57
  end
44
58
 
@@ -46,8 +60,8 @@ describe Acfs::Middleware::JSON do
46
60
  let(:headers) { {'Content-Type' => 'application/json'} }
47
61
  let(:body) { data.to_json[4..-4] }
48
62
 
49
- it 'should raise an error' do
50
- expect { request.complete! response }.to raise_error(MultiJson::LoadError)
63
+ it 'raises an error' do
64
+ expect { request.complete! response }.to raise_error(::JSON::ParserError)
51
65
  end
52
66
  end
53
67
 
@@ -55,7 +69,7 @@ describe Acfs::Middleware::JSON do
55
69
  let(:headers) { {'Content-Type' => 'application/text'} }
56
70
  let(:body) { data.to_json }
57
71
 
58
- it 'should not decode non-JSON encoded responses' do
72
+ it 'does not decode non-JSON encoded responses' do
59
73
  request.complete! response
60
74
 
61
75
  expect(response.data).to be_nil