apitizer 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -1
  3. data/.travis.yml +6 -0
  4. data/.yardopts +6 -0
  5. data/CHANGELOG.md +10 -0
  6. data/Guardfile +11 -4
  7. data/README.md +74 -7
  8. data/apitizer.gemspec +1 -2
  9. data/lib/apitizer.rb +0 -1
  10. data/lib/apitizer/base.rb +16 -27
  11. data/lib/apitizer/connection.rb +3 -1
  12. data/lib/apitizer/connection/adaptor.rb +1 -1
  13. data/lib/apitizer/connection/adaptor/standard.rb +24 -7
  14. data/lib/apitizer/connection/dispatcher.rb +5 -12
  15. data/lib/apitizer/connection/format.rb +14 -0
  16. data/lib/apitizer/{processing/parser → connection/format}/json.rb +6 -2
  17. data/lib/apitizer/{processing/parser → connection/format}/yaml.rb +6 -2
  18. data/lib/apitizer/connection/request.rb +3 -3
  19. data/lib/apitizer/connection/response.rb +3 -3
  20. data/lib/apitizer/core.rb +4 -4
  21. data/lib/apitizer/helper.rb +38 -14
  22. data/lib/apitizer/result.rb +2 -2
  23. data/lib/apitizer/routing.rb +1 -1
  24. data/lib/apitizer/routing/{mapper.rb → map.rb} +3 -10
  25. data/lib/apitizer/routing/node.rb +0 -1
  26. data/lib/apitizer/routing/node/base.rb +15 -17
  27. data/lib/apitizer/routing/node/collection.rb +17 -16
  28. data/lib/apitizer/routing/node/operation.rb +14 -15
  29. data/lib/apitizer/routing/node/root.rb +8 -2
  30. data/lib/apitizer/routing/path.rb +16 -8
  31. data/lib/apitizer/version.rb +1 -1
  32. data/spec/apitizer/base_spec.rb +36 -28
  33. data/spec/apitizer/connection/adaptor_spec.rb +87 -11
  34. data/spec/apitizer/connection/dispatcher_spec.rb +21 -23
  35. data/spec/apitizer/connection/format_spec.rb +15 -0
  36. data/spec/apitizer/helper_spec.rb +53 -24
  37. data/spec/apitizer/result_spec.rb +5 -7
  38. data/spec/apitizer/routing/map_spec.rb +71 -0
  39. data/spec/apitizer/routing/node_spec.rb +108 -36
  40. data/spec/apitizer/routing/path_spec.rb +12 -92
  41. data/spec/spec_helper.rb +4 -6
  42. data/spec/support/factory_helper.rb +25 -5
  43. data/spec/support/resource_helper.rb +8 -0
  44. metadata +14 -15
  45. data/lib/apitizer/processing.rb +0 -8
  46. data/lib/apitizer/processing/parser.rb +0 -14
  47. data/lib/apitizer/processing/translator.rb +0 -13
  48. data/lib/apitizer/routing/node/scope.rb +0 -19
  49. data/spec/apitizer/processing/parser_spec.rb +0 -23
  50. data/spec/apitizer/routing/mapper_spec.rb +0 -80
@@ -1,102 +1,22 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Apitizer::Routing::Path do
4
- extend ResourceHelper
5
- include FactoryHelper
6
-
7
- describe '#<<' do
8
- it 'builds up addresses' do
9
- [ :articles, 'xxx', :sections, 'yyy' ].each { |step| subject << step }
10
- expect(subject.address).to eq('articles/xxx/sections/yyy')
11
- end
12
- end
3
+ RSpec.describe Apitizer::Routing::Path do
4
+ let(:subject_class) { Apitizer::Routing::Path }
13
5
 
14
6
  describe '#advance' do
15
- it 'keeps track of destinations' do
16
- nodes = [ double('articles'), double('sections') ]
17
- nodes.each { |node| subject.advance(node) }
18
- expect(subject.node).to be(nodes.last)
19
- end
20
- end
21
-
22
- an_adequate_guard = Proc.new do |only_actions = restful_actions|
23
- (restful_collection_actions & only_actions).each do |action|
24
- it "is true for #{ action } collection action" do
25
- path = root.trace(steps)
26
- expect(path.permitted?(action)).to be_true
27
- end
28
- end
29
-
30
- (restful_member_actions & only_actions).each do |action|
31
- it "is true for #{ action } member actions" do
32
- path = root.trace([ *steps, 'xxx' ])
33
- expect(path.permitted?(action)).to be_true
34
- end
35
- end
36
-
37
- (restful_collection_actions - only_actions).each do |action|
38
- it "is false for #{ action } collection action" do
39
- path = root.trace(steps)
40
- expect(path.permitted?(action)).to be_false
41
- end
42
- end
43
-
44
- (restful_member_actions - only_actions).each do |action|
45
- it "is false for #{ action } member actions" do
46
- path = root.trace([ *steps, 'xxx' ])
47
- expect(path.permitted?(action)).to be_false
48
- end
49
- end
50
-
51
- restful_member_actions.each do |action|
52
- it "is false for #{ action } actions to collections" do
53
- path = root.trace(steps)
54
- expect(path.permitted?(action)).to be_false
55
- end
56
- end
57
-
58
- restful_collection_actions.each do |action|
59
- it "is false for #{ action } actions to members" do
60
- path = root.trace([ *steps, 'xxx' ])
61
- expect(path.permitted?(action)).to be_false
62
- end
7
+ it 'builds up addresses' do
8
+ subject.advance('articles', node: double)
9
+ subject.advance('xxx', node: double)
10
+ expect(subject.address).to eq('articles/xxx')
63
11
  end
64
12
  end
65
13
 
66
- describe '#permitted?' do
67
- context 'when working with plain collections' do
68
- let(:root) { create_tree(:articles) }
69
- let(:steps) { [ :articles ] }
70
-
71
- instance_exec(&an_adequate_guard)
72
- end
73
-
74
- context 'when working with nested collections' do
75
- let(:root) { create_tree(:articles, :sections) }
76
- let(:steps) { [ :articles, 'yyy', :sections ] }
77
-
78
- instance_exec(&an_adequate_guard)
79
- end
80
-
81
- context 'when working with collections restricted to index and show' do
82
- let(:root) { create_tree([ :articles, [ :index, :show ] ]) }
83
- let(:steps) { [ :articles ] }
84
-
85
- instance_exec([ :index, :show ], &an_adequate_guard)
86
- end
87
-
88
- restful_member_actions.each do |action|
89
- it "is true for custom #{ action } operations on members" do
90
- root = create_tree(:articles, shred: action)
91
- path = root.trace([ :articles, 'xxx', :shred ])
92
- expect(path.permitted?(action)).to be_true
93
- end
94
-
95
- it "is true for custom #{ action } operations with variable names" do
96
- root = create_tree(:articles, ':paragraph' => action)
97
- path = root.trace([ :articles, 'xxx', 'zzz' ])
98
- expect(path.permitted?(action)).to be_true
99
- end
14
+ describe '#clone' do
15
+ it 'properly does its job' do
16
+ subject.advance('articles', node: double)
17
+ another = subject.clone
18
+ another.advance('xxx', node: double)
19
+ expect(subject.address).to eq('articles')
100
20
  end
101
21
  end
102
22
  end
@@ -1,11 +1,9 @@
1
- require 'support/resource_helper'
2
- require 'support/factory_helper'
3
1
  require 'webmock/rspec'
4
2
  require 'apitizer'
5
3
 
4
+ require 'support/resource_helper'
5
+ require 'support/factory_helper'
6
+
6
7
  RSpec.configure do |config|
7
- config.treat_symbols_as_metadata_keys_with_true_values = true
8
- config.run_all_when_everything_filtered = true
9
- config.filter_run :focus
10
- config.order = 'random'
8
+ config.disable_monkey_patching!
11
9
  end
@@ -1,23 +1,43 @@
1
1
  module FactoryHelper
2
+ include ResourceHelper
3
+
2
4
  def create_tree(*names)
3
5
  operations = names.last.is_a?(Hash) ? names.pop : {}
4
- root = Apitizer::Routing::Node::Root.new
6
+
7
+ root = build_root
8
+
5
9
  leaf = names.inject(root) do |parent, object|
6
10
  if object.is_a?(Array)
7
11
  name, only = *object
8
- node = Apitizer::Routing::Node::Collection.new(name, only: only)
12
+ node = build_collection(name, only: only)
9
13
  else
10
14
  name = object
11
- node = Apitizer::Routing::Node::Collection.new(name)
15
+ node = build_collection(name)
12
16
  end
13
17
  parent.append(node)
14
18
  node
15
19
  end
20
+
16
21
  operations.each do |name, action|
17
- operation = Apitizer::Routing::Node::Operation.new(
18
- name, action: action, on: :member)
22
+ on = restful_member_actions.include?(action) ? :member : :collection
23
+ operation = build_operation(name, action: action, on: on)
19
24
  leaf.append(operation)
20
25
  end
26
+
21
27
  root
22
28
  end
29
+
30
+ private
31
+
32
+ def build_root(*arguments)
33
+ Apitizer::Routing::Node::Root.new(*arguments)
34
+ end
35
+
36
+ def build_collection(*arguments)
37
+ Apitizer::Routing::Node::Collection.new(*arguments)
38
+ end
39
+
40
+ def build_operation(*arguments)
41
+ Apitizer::Routing::Node::Operation.new(*arguments)
42
+ end
23
43
  end
@@ -15,4 +15,12 @@ module ResourceHelper
15
15
  { :index => :get, :show => :get, :create => :post,
16
16
  :update => :put, :delete => :delete }
17
17
  end
18
+
19
+ def http_methods
20
+ [ :get, :post, :put, :patch, :delete ]
21
+ end
22
+
23
+ def mime_type_dictionary
24
+ { :json => 'application/json', :yaml => 'application/x-yaml' }
25
+ end
18
26
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apitizer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ivan Ukhov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-01 00:00:00.000000000 Z
11
+ date: 2014-07-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -72,14 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '2.14'
75
+ version: '3.0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '2.14'
82
+ version: '3.0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: guard-rspec
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -118,6 +118,8 @@ extra_rdoc_files: []
118
118
  files:
119
119
  - ".gitignore"
120
120
  - ".rspec"
121
+ - ".travis.yml"
122
+ - ".yardopts"
121
123
  - CHANGELOG.md
122
124
  - Gemfile
123
125
  - Guardfile
@@ -131,34 +133,31 @@ files:
131
133
  - lib/apitizer/connection/adaptor.rb
132
134
  - lib/apitizer/connection/adaptor/standard.rb
133
135
  - lib/apitizer/connection/dispatcher.rb
136
+ - lib/apitizer/connection/format.rb
137
+ - lib/apitizer/connection/format/json.rb
138
+ - lib/apitizer/connection/format/yaml.rb
134
139
  - lib/apitizer/connection/request.rb
135
140
  - lib/apitizer/connection/response.rb
136
141
  - lib/apitizer/core.rb
137
142
  - lib/apitizer/helper.rb
138
- - lib/apitizer/processing.rb
139
- - lib/apitizer/processing/parser.rb
140
- - lib/apitizer/processing/parser/json.rb
141
- - lib/apitizer/processing/parser/yaml.rb
142
- - lib/apitizer/processing/translator.rb
143
143
  - lib/apitizer/result.rb
144
144
  - lib/apitizer/routing.rb
145
- - lib/apitizer/routing/mapper.rb
145
+ - lib/apitizer/routing/map.rb
146
146
  - lib/apitizer/routing/node.rb
147
147
  - lib/apitizer/routing/node/base.rb
148
148
  - lib/apitizer/routing/node/collection.rb
149
149
  - lib/apitizer/routing/node/operation.rb
150
150
  - lib/apitizer/routing/node/root.rb
151
- - lib/apitizer/routing/node/scope.rb
152
151
  - lib/apitizer/routing/path.rb
153
152
  - lib/apitizer/routing/proxy.rb
154
153
  - lib/apitizer/version.rb
155
154
  - spec/apitizer/base_spec.rb
156
155
  - spec/apitizer/connection/adaptor_spec.rb
157
156
  - spec/apitizer/connection/dispatcher_spec.rb
157
+ - spec/apitizer/connection/format_spec.rb
158
158
  - spec/apitizer/helper_spec.rb
159
- - spec/apitizer/processing/parser_spec.rb
160
159
  - spec/apitizer/result_spec.rb
161
- - spec/apitizer/routing/mapper_spec.rb
160
+ - spec/apitizer/routing/map_spec.rb
162
161
  - spec/apitizer/routing/node_spec.rb
163
162
  - spec/apitizer/routing/path_spec.rb
164
163
  - spec/spec_helper.rb
@@ -192,10 +191,10 @@ test_files:
192
191
  - spec/apitizer/base_spec.rb
193
192
  - spec/apitizer/connection/adaptor_spec.rb
194
193
  - spec/apitizer/connection/dispatcher_spec.rb
194
+ - spec/apitizer/connection/format_spec.rb
195
195
  - spec/apitizer/helper_spec.rb
196
- - spec/apitizer/processing/parser_spec.rb
197
196
  - spec/apitizer/result_spec.rb
198
- - spec/apitizer/routing/mapper_spec.rb
197
+ - spec/apitizer/routing/map_spec.rb
199
198
  - spec/apitizer/routing/node_spec.rb
200
199
  - spec/apitizer/routing/path_spec.rb
201
200
  - spec/spec_helper.rb
@@ -1,8 +0,0 @@
1
- require_relative 'processing/parser'
2
- require_relative 'processing/translator'
3
-
4
- module Apitizer
5
- module Processing
6
- Error = Class.new(Apitizer::Error)
7
- end
8
- end
@@ -1,14 +0,0 @@
1
- require_relative 'parser/json'
2
- require_relative 'parser/yaml'
3
-
4
- module Apitizer
5
- module Processing
6
- module Parser
7
- def self.build(format)
8
- self.const_get(format.to_s.upcase).new
9
- rescue NameError
10
- raise Error, 'Unknown format'
11
- end
12
- end
13
- end
14
- end
@@ -1,13 +0,0 @@
1
- module Apitizer
2
- module Processing
3
- class Translator
4
- def initialize(format:)
5
- @parser = Parser.build(format)
6
- end
7
-
8
- def process(response)
9
- @parser.process(response.body)
10
- end
11
- end
12
- end
13
- end
@@ -1,19 +0,0 @@
1
- module Apitizer
2
- module Routing
3
- module Node
4
- class Scope < Base
5
- def initialize(steps)
6
- @steps = Array(steps)
7
- end
8
-
9
- def match(name)
10
- not lookup(name).nil?
11
- end
12
-
13
- def process(path, steps)
14
- @steps.each { |step| path << step }
15
- end
16
- end
17
- end
18
- end
19
- end
@@ -1,23 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Apitizer::Processing::Parser do
4
- let(:parent_module) { Apitizer::Processing }
5
- let(:subject_class) { parent_module::Parser }
6
-
7
- it 'supports JSON' do
8
- subject = subject_class.build(:json)
9
- result = subject.process('{ "articles": [] }')
10
- expect(result).to eq("articles" => [])
11
- end
12
-
13
- it 'supports YAML' do
14
- subject = subject_class.build(:yaml)
15
- result = subject.process("---\narticles: []")
16
- expect(result).to eq("articles" => [])
17
- end
18
-
19
- it 'does not support XML' do
20
- expect { subject_class.build(:xml) }.to \
21
- raise_error(parent_module::Error, /Unknown format/i)
22
- end
23
- end
@@ -1,80 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Apitizer::Routing::Mapper do
4
- extend ResourceHelper
5
-
6
- let(:subject_class) { Apitizer::Routing::Mapper }
7
-
8
- def create_path
9
- double(:<< => nil, :advance => nil, :permitted? => true)
10
- end
11
-
12
- def expect_steps(steps, path = create_path)
13
- Array(steps).each do |step|
14
- expect(path).to receive(:<<).once.ordered.with(step)
15
- end
16
- path
17
- end
18
-
19
- def expect_trace(mapper, steps, scope = [])
20
- mapper.trace(:arbitrary, steps, expect_steps(scope + steps))
21
- end
22
-
23
- describe '#define' do
24
- it 'declares the root address' do
25
- subject.define do
26
- address('https://service.com/api')
27
- resources(:articles)
28
- end
29
- expect_trace(subject, [ :articles, 'xxx' ], [ 'https://service.com/api' ])
30
- end
31
-
32
- it 'declares plain resources' do
33
- subject.define { resources(:articles) }
34
- expect_trace(subject, [ :articles ])
35
- end
36
-
37
- it 'declares nested resources' do
38
- subject.define { resources(:articles) { resources(:sections) } }
39
- expect_trace(subject, [ :articles, 'xxx', :sections, 'yyy' ])
40
- end
41
-
42
- it 'declares scoped resources' do
43
- subject.define do
44
- scope 'https://service.com/api' do
45
- scope [ 'v1', :json ] do
46
- resources(:articles) { resources(:sections) }
47
- end
48
- end
49
- end
50
- expect_trace(subject, [ :articles, 'xxx', :sections, 'yyy' ],
51
- [ 'https://service.com/api', 'v1', :json ])
52
- end
53
-
54
- restful_member_actions.each do |action|
55
- it "declares custom #{ action } operations on members" do
56
- subject.define do
57
- resources(:articles) { send(action, :shred, on: :member) }
58
- end
59
- expect_trace(subject, [ :articles, 'xxx', :shred ])
60
- end
61
-
62
- it 'declares custom operations with variable names' do
63
- subject.define do
64
- resources(:articles) { send(action, ':paragraph', on: :member) }
65
- end
66
- expect_trace(subject, [ :articles, 'xxx', 'zzz' ])
67
- end
68
- end
69
-
70
- it 'does not support reopening of resource declarations' do
71
- subject.define do
72
- resources(:articles)
73
- resources(:articles) { resources(:sections) }
74
- end
75
- expect do
76
- subject.trace(:arbitrary, [ :articles, 'xxx', :sections, 'yyy' ])
77
- end.to raise_error(Apitizer::Routing::Error, /Not found/i)
78
- end
79
- end
80
- end