syncano 4.0.0.alpha4 → 4.0.0.pre
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/.ruby-version +1 -1
- data/README.md +1 -13
- data/circle.yml +1 -1
- data/lib/active_attr/dirty.rb +26 -0
- data/lib/active_attr/typecasting/hash_typecaster.rb +34 -0
- data/lib/active_attr/typecasting_override.rb +29 -0
- data/lib/syncano.rb +9 -55
- data/lib/syncano/api.rb +2 -20
- data/lib/syncano/connection.rb +47 -48
- data/lib/syncano/model/associations.rb +121 -0
- data/lib/syncano/model/associations/base.rb +38 -0
- data/lib/syncano/model/associations/belongs_to.rb +30 -0
- data/lib/syncano/model/associations/has_many.rb +75 -0
- data/lib/syncano/model/associations/has_one.rb +22 -0
- data/lib/syncano/model/base.rb +257 -0
- data/lib/syncano/model/callbacks.rb +49 -0
- data/lib/syncano/model/scope_builder.rb +158 -0
- data/lib/syncano/query_builder.rb +7 -11
- data/lib/syncano/resources/base.rb +66 -91
- data/lib/syncano/schema.rb +159 -10
- data/lib/syncano/schema/attribute_definition.rb +0 -75
- data/lib/syncano/schema/resource_definition.rb +2 -24
- data/lib/syncano/version.rb +1 -1
- data/spec/integration/syncano_spec.rb +26 -268
- data/spec/spec_helper.rb +1 -3
- data/spec/unit/connection_spec.rb +74 -34
- data/spec/unit/query_builder_spec.rb +2 -2
- data/spec/unit/resources_base_spec.rb +64 -125
- data/spec/unit/schema/resource_definition_spec.rb +3 -24
- data/spec/unit/schema_spec.rb +55 -5
- data/spec/unit/syncano_spec.rb +9 -45
- data/syncano.gemspec +0 -5
- metadata +14 -87
- data/lib/syncano/api/endpoints.rb +0 -17
- data/lib/syncano/poller.rb +0 -55
- data/lib/syncano/resources.rb +0 -158
- data/lib/syncano/resources/paths.rb +0 -48
- data/lib/syncano/resources/resource_invalid.rb +0 -15
- data/lib/syncano/response.rb +0 -55
- data/lib/syncano/schema/endpoints_whitelist.rb +0 -40
- data/lib/syncano/upload_io.rb +0 -7
- data/spec/unit/resources/paths_spec.rb +0 -21
- data/spec/unit/response_spec.rb +0 -75
- data/spec/unit/schema/attribute_definition_spec.rb +0 -18
@@ -1,48 +0,0 @@
|
|
1
|
-
require 'singleton'
|
2
|
-
|
3
|
-
module Syncano
|
4
|
-
module Resources
|
5
|
-
class Paths
|
6
|
-
include Singleton
|
7
|
-
|
8
|
-
attr_accessor :collections, :members
|
9
|
-
|
10
|
-
def initialize
|
11
|
-
self.collections = self.class::Collection.new
|
12
|
-
self.members = self.class::Member.new
|
13
|
-
end
|
14
|
-
|
15
|
-
private
|
16
|
-
|
17
|
-
class Collection
|
18
|
-
def initialize
|
19
|
-
@map = {}
|
20
|
-
end
|
21
|
-
|
22
|
-
def define(path, resource)
|
23
|
-
@map[Regexp.new("\\A#{path.gsub(/{[^}]*}/, '([^\/]+)')}\\z")] = resource
|
24
|
-
end
|
25
|
-
|
26
|
-
def match(path)
|
27
|
-
_, resouce = @map.find { |pattern, _| pattern =~ path }
|
28
|
-
resouce
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
class Member
|
33
|
-
def initialize
|
34
|
-
@map = {}
|
35
|
-
end
|
36
|
-
|
37
|
-
def define(path, resource)
|
38
|
-
resource_name = resource.name
|
39
|
-
@map[resource_name] = path
|
40
|
-
end
|
41
|
-
|
42
|
-
def find(resource)
|
43
|
-
@map[resource.name]
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
@@ -1,15 +0,0 @@
|
|
1
|
-
module Syncano
|
2
|
-
module Resources
|
3
|
-
class ResourceInvalid < StandardError
|
4
|
-
attr_accessor :resource
|
5
|
-
|
6
|
-
def initialize(resource)
|
7
|
-
self.resource = resource
|
8
|
-
end
|
9
|
-
|
10
|
-
def to_s
|
11
|
-
"#{self.class.name} <#{resource.class.name} #{resource.errors.full_messages}>"
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
data/lib/syncano/response.rb
DELETED
@@ -1,55 +0,0 @@
|
|
1
|
-
module Syncano
|
2
|
-
class Response
|
3
|
-
class << self
|
4
|
-
def handle(raw_response)
|
5
|
-
code = unify_code(raw_response)
|
6
|
-
|
7
|
-
case code
|
8
|
-
when Status.no_content
|
9
|
-
when Status.successful
|
10
|
-
parse_response raw_response
|
11
|
-
when Status.not_found
|
12
|
-
raise NotFound.new(raw_response.env.url, raw_response.env.method)
|
13
|
-
when Status.client_error
|
14
|
-
raise ClientError.new raw_response.body, raw_response
|
15
|
-
when Status.server_error
|
16
|
-
raise ServerError.new raw_response.body, raw_response
|
17
|
-
else
|
18
|
-
raise UnsupportedStatusError.new raw_response
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def parse_response(raw_response)
|
23
|
-
JSON.parse(raw_response.body)
|
24
|
-
end
|
25
|
-
|
26
|
-
def unify_code(raw_response)
|
27
|
-
raw_response.status.code
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
class Status
|
32
|
-
class << self
|
33
|
-
def successful
|
34
|
-
->(code) { (200...300).include? code }
|
35
|
-
end
|
36
|
-
|
37
|
-
def client_error
|
38
|
-
->(code) { (400...500).include? code }
|
39
|
-
end
|
40
|
-
|
41
|
-
def no_content
|
42
|
-
->(code) { code == 204 }
|
43
|
-
end
|
44
|
-
|
45
|
-
def server_error
|
46
|
-
->(code) { code >= 500 }
|
47
|
-
end
|
48
|
-
|
49
|
-
def not_found
|
50
|
-
->(code) { code == 404 }
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
module Syncano
|
2
|
-
class Schema
|
3
|
-
class EndpointsWhitelist
|
4
|
-
include Enumerable
|
5
|
-
|
6
|
-
class SupportedDefinitionPredicate
|
7
|
-
attr_accessor :definition
|
8
|
-
|
9
|
-
def initialize(definition)
|
10
|
-
self.definition = definition
|
11
|
-
end
|
12
|
-
|
13
|
-
def call
|
14
|
-
path =~ /\A\/v1\/instances/ && path !~ /invitation/
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
def path
|
20
|
-
definition[:collection] && definition[:collection][:path] ||
|
21
|
-
definition[:member] && definition[:member][:path]
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
SUPPORTED_DEFINITIONS = -> (definition) {
|
26
|
-
SupportedDefinitionPredicate.new(definition).call
|
27
|
-
}
|
28
|
-
|
29
|
-
def initialize(schema)
|
30
|
-
@definition = schema.definition
|
31
|
-
end
|
32
|
-
|
33
|
-
def each(&block)
|
34
|
-
@definition.select { |_name, definition|
|
35
|
-
SUPPORTED_DEFINITIONS === definition
|
36
|
-
}.each &block
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
data/lib/syncano/upload_io.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
require_relative '../../spec_helper'
|
2
|
-
|
3
|
-
describe ::Syncano::Resources::Paths do
|
4
|
-
let(:koza) { double 'KozaClass' }
|
5
|
-
|
6
|
-
context 'collections' do
|
7
|
-
subject { described_class.instance.collections }
|
8
|
-
|
9
|
-
before { subject.define '/kozas/{koza_name}/kiszkas/', koza }
|
10
|
-
|
11
|
-
specify { expect(subject.match('/kozas/mykoza/kiszkas/')).to eq(koza) }
|
12
|
-
end
|
13
|
-
|
14
|
-
context 'members' do
|
15
|
-
subject { described_class.instance.members }
|
16
|
-
|
17
|
-
before { subject.define '/kozas/{koza_name}/', koza }
|
18
|
-
|
19
|
-
xspecify { expect(subject.match('kozas/mykoza/')).to eq(koza) }
|
20
|
-
end
|
21
|
-
end
|
data/spec/unit/response_spec.rb
DELETED
@@ -1,75 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Syncano::Response do
|
4
|
-
describe '.handle' do
|
5
|
-
context 'success' do
|
6
|
-
let(:raw_response) { double :raw_response,
|
7
|
-
body: generate_body(some: 'response'),
|
8
|
-
status: status(200) }
|
9
|
-
|
10
|
-
specify do
|
11
|
-
expect(described_class.handle(raw_response)).to eq('some' => 'response')
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
context 'not found' do
|
16
|
-
let(:env) { double :env, url: 'http://path', method: :get }
|
17
|
-
let(:raw_response) { double :raw_response,
|
18
|
-
body: nil,
|
19
|
-
status: status(404),
|
20
|
-
env: env }
|
21
|
-
|
22
|
-
specify do
|
23
|
-
expect { described_class.handle(raw_response) }.to raise_error(Syncano::NotFound)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
context 'client error' do
|
28
|
-
let(:raw_response) {
|
29
|
-
double :raw_response, body: generate_body({name: ['This field can not be "koza"']}),
|
30
|
-
status: status(400)
|
31
|
-
}
|
32
|
-
|
33
|
-
specify do
|
34
|
-
expect { described_class.handle(raw_response) }.to raise_error(Syncano::ClientError)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
context 'returning a server error' do
|
39
|
-
let(:raw_response) { double :raw_response,
|
40
|
-
body: 'server error',
|
41
|
-
status: status(500) }
|
42
|
-
|
43
|
-
specify do
|
44
|
-
expect { described_class.handle(raw_response) }.
|
45
|
-
to raise_error(Syncano::ServerError)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
context 'unsupported status code' do
|
50
|
-
let(:raw_response) { double :raw_response,
|
51
|
-
body: 'fafarafa',
|
52
|
-
status: status(112) }
|
53
|
-
|
54
|
-
specify do
|
55
|
-
expect { described_class.handle(raw_response) }.to raise_error(Syncano::UnsupportedStatusError)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
context 'successful returning empty body' do
|
60
|
-
let(:raw_response) { double :raw_response, status: status(204) }
|
61
|
-
|
62
|
-
specify do
|
63
|
-
expect(described_class.handle(raw_response)).to eq(nil)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def generate_body(params)
|
69
|
-
JSON.generate params
|
70
|
-
end
|
71
|
-
|
72
|
-
def status(code)
|
73
|
-
double :status, code: code
|
74
|
-
end
|
75
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
require_relative '../../spec_helper'
|
2
|
-
|
3
|
-
describe Syncano::Schema::AttributeDefinition do
|
4
|
-
let(:name) { 'example' }
|
5
|
-
let(:raw_definition) { {} }
|
6
|
-
|
7
|
-
subject { described_class.new name, raw_definition }
|
8
|
-
|
9
|
-
specify { expect(subject.name).to eq(name) }
|
10
|
-
|
11
|
-
context 'when name is "class"' do
|
12
|
-
let(:name) { 'class' }
|
13
|
-
|
14
|
-
it 'should be named associated_class to avoid method name collision' do
|
15
|
-
expect(subject.name).to eq('associated_class')
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|