restorm 1.0.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.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/.rspec +1 -0
- data/.rubocop.yml +31 -0
- data/.rubocop_todo.yml +232 -0
- data/.ruby-version +1 -0
- data/.travis.yml +55 -0
- data/.yardopts +2 -0
- data/CONTRIBUTING.md +26 -0
- data/Gemfile +10 -0
- data/HER_README.md +1065 -0
- data/LICENSE +7 -0
- data/README.md +7 -0
- data/Rakefile +11 -0
- data/UPGRADE.md +101 -0
- data/gemfiles/Gemfile.activemodel-4.2 +6 -0
- data/gemfiles/Gemfile.activemodel-5.0 +6 -0
- data/gemfiles/Gemfile.activemodel-5.1 +6 -0
- data/gemfiles/Gemfile.activemodel-5.2 +6 -0
- data/gemfiles/Gemfile.faraday-1.0 +6 -0
- data/lib/restorm/api.rb +121 -0
- data/lib/restorm/collection.rb +13 -0
- data/lib/restorm/errors.rb +29 -0
- data/lib/restorm/json_api/model.rb +42 -0
- data/lib/restorm/middleware/accept_json.rb +18 -0
- data/lib/restorm/middleware/first_level_parse_json.rb +37 -0
- data/lib/restorm/middleware/json_api_parser.rb +37 -0
- data/lib/restorm/middleware/parse_json.rb +22 -0
- data/lib/restorm/middleware/second_level_parse_json.rb +37 -0
- data/lib/restorm/middleware.rb +12 -0
- data/lib/restorm/model/associations/association.rb +128 -0
- data/lib/restorm/model/associations/association_proxy.rb +44 -0
- data/lib/restorm/model/associations/belongs_to_association.rb +95 -0
- data/lib/restorm/model/associations/has_many_association.rb +100 -0
- data/lib/restorm/model/associations/has_one_association.rb +79 -0
- data/lib/restorm/model/associations.rb +141 -0
- data/lib/restorm/model/attributes.rb +322 -0
- data/lib/restorm/model/base.rb +33 -0
- data/lib/restorm/model/deprecated_methods.rb +61 -0
- data/lib/restorm/model/http.rb +119 -0
- data/lib/restorm/model/introspection.rb +67 -0
- data/lib/restorm/model/nested_attributes.rb +45 -0
- data/lib/restorm/model/orm.rb +299 -0
- data/lib/restorm/model/parse.rb +223 -0
- data/lib/restorm/model/paths.rb +125 -0
- data/lib/restorm/model/relation.rb +209 -0
- data/lib/restorm/model.rb +75 -0
- data/lib/restorm/version.rb +3 -0
- data/lib/restorm.rb +19 -0
- data/restorm.gemspec +29 -0
- data/spec/api_spec.rb +120 -0
- data/spec/collection_spec.rb +41 -0
- data/spec/json_api/model_spec.rb +169 -0
- data/spec/middleware/accept_json_spec.rb +11 -0
- data/spec/middleware/first_level_parse_json_spec.rb +63 -0
- data/spec/middleware/json_api_parser_spec.rb +52 -0
- data/spec/middleware/second_level_parse_json_spec.rb +35 -0
- data/spec/model/associations/association_proxy_spec.rb +29 -0
- data/spec/model/associations_spec.rb +911 -0
- data/spec/model/attributes_spec.rb +354 -0
- data/spec/model/callbacks_spec.rb +176 -0
- data/spec/model/dirty_spec.rb +133 -0
- data/spec/model/http_spec.rb +201 -0
- data/spec/model/introspection_spec.rb +81 -0
- data/spec/model/nested_attributes_spec.rb +135 -0
- data/spec/model/orm_spec.rb +704 -0
- data/spec/model/parse_spec.rb +520 -0
- data/spec/model/paths_spec.rb +348 -0
- data/spec/model/relation_spec.rb +247 -0
- data/spec/model/validations_spec.rb +43 -0
- data/spec/model_spec.rb +45 -0
- data/spec/spec_helper.rb +25 -0
- data/spec/support/macros/her_macros.rb +17 -0
- data/spec/support/macros/model_macros.rb +36 -0
- data/spec/support/macros/request_macros.rb +27 -0
- metadata +203 -0
@@ -0,0 +1,63 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe Restorm::Middleware::FirstLevelParseJSON do
|
6
|
+
subject { described_class.new }
|
7
|
+
let(:body_without_errors) { "{\"id\": 1, \"name\": \"Tobias Fünke\", \"metadata\": 3}" }
|
8
|
+
let(:body_with_errors) { "{\"id\": 1, \"name\": \"Tobias Fünke\", \"errors\": { \"name\": [ \"not_valid\", \"should_be_present\" ] }, \"metadata\": 3}" }
|
9
|
+
let(:body_with_malformed_json) { "wut." }
|
10
|
+
let(:body_with_invalid_json) { "true" }
|
11
|
+
let(:empty_body) { "" }
|
12
|
+
let(:nil_body) { nil }
|
13
|
+
|
14
|
+
it "parses body as json" do
|
15
|
+
subject.parse(body_without_errors).tap do |json|
|
16
|
+
expect(json[:data]).to eq(id: 1, name: "Tobias Fünke")
|
17
|
+
expect(json[:metadata]).to eq(3)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it "parses :body key as json in the env hash" do
|
22
|
+
env = { body: body_without_errors }
|
23
|
+
subject.on_complete(env)
|
24
|
+
env[:body].tap do |json|
|
25
|
+
expect(json[:data]).to eq(id: 1, name: "Tobias Fünke")
|
26
|
+
expect(json[:metadata]).to eq(3)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
it "ensures the errors are a hash if there are no errors" do
|
31
|
+
expect(subject.parse(body_without_errors)[:errors]).to eq({})
|
32
|
+
end
|
33
|
+
|
34
|
+
it "ensures the errors are a hash if there are no errors" do
|
35
|
+
expect(subject.parse(body_with_errors)[:errors]).to eq(name: %w[not_valid should_be_present])
|
36
|
+
end
|
37
|
+
|
38
|
+
it "ensures that malformed JSON throws an exception" do
|
39
|
+
expect { subject.parse(body_with_malformed_json) }.to raise_error(Restorm::Errors::ParseError, 'Response from the API must behave like a Hash or an Array (last JSON response was "wut.")')
|
40
|
+
end
|
41
|
+
|
42
|
+
it "ensures that invalid JSON throws an exception" do
|
43
|
+
expect { subject.parse(body_with_invalid_json) }.to raise_error(Restorm::Errors::ParseError, 'Response from the API must behave like a Hash or an Array (last JSON response was "true")')
|
44
|
+
end
|
45
|
+
|
46
|
+
it "ensures that a nil response returns an empty hash" do
|
47
|
+
expect(subject.parse(nil_body)[:data]).to eq({})
|
48
|
+
end
|
49
|
+
|
50
|
+
it "ensures that an empty response returns an empty hash" do
|
51
|
+
expect(subject.parse(empty_body)[:data]).to eq({})
|
52
|
+
end
|
53
|
+
|
54
|
+
context "with status code 204" do
|
55
|
+
it "returns an empty body" do
|
56
|
+
env = { status: 204 }
|
57
|
+
subject.on_complete(env)
|
58
|
+
env[:body].tap do |json|
|
59
|
+
expect(json[:data]).to eq({})
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe Restorm::Middleware::JsonApiParser do
|
6
|
+
subject { described_class.new }
|
7
|
+
|
8
|
+
context "with valid JSON body" do
|
9
|
+
let(:body) { '{"data": {"type": "foo", "id": "bar", "attributes": {"baz": "qux"} }, "meta": {"api": "json api"} }' }
|
10
|
+
let(:env) { { body: body } }
|
11
|
+
|
12
|
+
it "parses body as json" do
|
13
|
+
subject.on_complete(env)
|
14
|
+
env.fetch(:body).tap do |json|
|
15
|
+
expect(json[:data]).to eql(
|
16
|
+
type: "foo",
|
17
|
+
id: "bar",
|
18
|
+
attributes: { baz: "qux" }
|
19
|
+
)
|
20
|
+
expect(json[:errors]).to eql([])
|
21
|
+
expect(json[:metadata]).to eql(api: "json api")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "with status code 204" do
|
27
|
+
it "returns an empty body" do
|
28
|
+
env = { status: 204 }
|
29
|
+
subject.on_complete(env)
|
30
|
+
env[:body].tap do |json|
|
31
|
+
expect(json[:data]).to eq({})
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'with status code 304' do
|
37
|
+
it 'returns an empty body' do
|
38
|
+
env = { :status => 304 }
|
39
|
+
subject.on_complete(env)
|
40
|
+
env[:body].tap do |json|
|
41
|
+
expect(json[:data]).to eq({})
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# context "with invalid JSON body" do
|
47
|
+
# let(:body) { '"foo"' }
|
48
|
+
# it 'ensures that invalid JSON throws an exception' do
|
49
|
+
# expect { subject.parse(body) }.to raise_error(Restorm::Errors::ParseError, 'Response from the API must behave like a Hash or an Array (last JSON response was "\"foo\"")')
|
50
|
+
# end
|
51
|
+
# end
|
52
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe Restorm::Middleware::SecondLevelParseJSON do
|
6
|
+
subject { described_class.new }
|
7
|
+
|
8
|
+
context "with valid JSON body" do
|
9
|
+
let(:body) { "{\"data\": 1, \"errors\": 2, \"metadata\": 3}" }
|
10
|
+
it "parses body as json" do
|
11
|
+
subject.parse(body).tap do |json|
|
12
|
+
expect(json[:data]).to eq(1)
|
13
|
+
expect(json[:errors]).to eq(2)
|
14
|
+
expect(json[:metadata]).to eq(3)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
it "parses :body key as json in the env hash" do
|
19
|
+
env = { body: body }
|
20
|
+
subject.on_complete(env)
|
21
|
+
env[:body].tap do |json|
|
22
|
+
expect(json[:data]).to eq(1)
|
23
|
+
expect(json[:errors]).to eq(2)
|
24
|
+
expect(json[:metadata]).to eq(3)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "with invalid JSON body" do
|
30
|
+
let(:body) { '"foo"' }
|
31
|
+
it "ensures that invalid JSON throws an exception" do
|
32
|
+
expect { subject.parse(body) }.to raise_error(Restorm::Errors::ParseError, 'Response from the API must behave like a Hash or an Array (last JSON response was "\"foo\"")')
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe Restorm::Model::Associations::AssociationProxy do
|
6
|
+
describe "proxy assignment methods" do
|
7
|
+
before do
|
8
|
+
Restorm::API.setup url: "https://api.example.com" do |builder|
|
9
|
+
builder.use Restorm::Middleware::FirstLevelParseJSON
|
10
|
+
builder.use Faraday::Request::UrlEncoded
|
11
|
+
builder.adapter :test do |stub|
|
12
|
+
stub.get("/users/1") { [200, {}, { id: 1, name: "Tobias Fünke" }.to_json] }
|
13
|
+
stub.get("/users/1/fish") { [200, {}, { id: 1, name: "Tobias's Fish" }.to_json] }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
spawn_model "User" do
|
17
|
+
has_one :fish
|
18
|
+
end
|
19
|
+
spawn_model "Fish"
|
20
|
+
end
|
21
|
+
|
22
|
+
subject { User.find(1) }
|
23
|
+
|
24
|
+
it "should assign value" do
|
25
|
+
subject.fish.name = "Fishy"
|
26
|
+
expect(subject.fish.name).to eq "Fishy"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|