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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/README.md +1 -13
  4. data/circle.yml +1 -1
  5. data/lib/active_attr/dirty.rb +26 -0
  6. data/lib/active_attr/typecasting/hash_typecaster.rb +34 -0
  7. data/lib/active_attr/typecasting_override.rb +29 -0
  8. data/lib/syncano.rb +9 -55
  9. data/lib/syncano/api.rb +2 -20
  10. data/lib/syncano/connection.rb +47 -48
  11. data/lib/syncano/model/associations.rb +121 -0
  12. data/lib/syncano/model/associations/base.rb +38 -0
  13. data/lib/syncano/model/associations/belongs_to.rb +30 -0
  14. data/lib/syncano/model/associations/has_many.rb +75 -0
  15. data/lib/syncano/model/associations/has_one.rb +22 -0
  16. data/lib/syncano/model/base.rb +257 -0
  17. data/lib/syncano/model/callbacks.rb +49 -0
  18. data/lib/syncano/model/scope_builder.rb +158 -0
  19. data/lib/syncano/query_builder.rb +7 -11
  20. data/lib/syncano/resources/base.rb +66 -91
  21. data/lib/syncano/schema.rb +159 -10
  22. data/lib/syncano/schema/attribute_definition.rb +0 -75
  23. data/lib/syncano/schema/resource_definition.rb +2 -24
  24. data/lib/syncano/version.rb +1 -1
  25. data/spec/integration/syncano_spec.rb +26 -268
  26. data/spec/spec_helper.rb +1 -3
  27. data/spec/unit/connection_spec.rb +74 -34
  28. data/spec/unit/query_builder_spec.rb +2 -2
  29. data/spec/unit/resources_base_spec.rb +64 -125
  30. data/spec/unit/schema/resource_definition_spec.rb +3 -24
  31. data/spec/unit/schema_spec.rb +55 -5
  32. data/spec/unit/syncano_spec.rb +9 -45
  33. data/syncano.gemspec +0 -5
  34. metadata +14 -87
  35. data/lib/syncano/api/endpoints.rb +0 -17
  36. data/lib/syncano/poller.rb +0 -55
  37. data/lib/syncano/resources.rb +0 -158
  38. data/lib/syncano/resources/paths.rb +0 -48
  39. data/lib/syncano/resources/resource_invalid.rb +0 -15
  40. data/lib/syncano/response.rb +0 -55
  41. data/lib/syncano/schema/endpoints_whitelist.rb +0 -40
  42. data/lib/syncano/upload_io.rb +0 -7
  43. data/spec/unit/resources/paths_spec.rb +0 -21
  44. data/spec/unit/response_spec.rb +0 -75
  45. 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
@@ -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
@@ -1,7 +0,0 @@
1
- module Syncano
2
- class UploadIO < Faraday::UploadIO
3
- def initialize(path)
4
- super path, File.mime_type?(File.new(path))
5
- end
6
- end
7
- end
@@ -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
@@ -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