jsonapi-object-mapper 0.8.1 → 0.9.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 13f9a7b828f1b92f507cc28cf7eb65cbf697042669846a11ac0099aa6b6f24b6
4
- data.tar.gz: 9dfb0ad00761af92d00c87062fb60399f19989f3f13d989abd7c046676509896
3
+ metadata.gz: b23420a89f5d55965dafc872b3a84b78562d654981c7f3ff1f1524a90b42b8b7
4
+ data.tar.gz: 817b0c84ab3638e11a4b7540ccffdf3f8bd7dea40f046c884a77ada0d39712b4
5
5
  SHA512:
6
- metadata.gz: 7cd208aa8aa699060367018cd73e0c8263e3f45839de720e6983a8400c8c4056c1300e846c3933729c227f3c03e37107a02f2b829a899d84b9aa24a6f9d276fd
7
- data.tar.gz: 637cf774585df3d34fc84aa64d6f252066135c1df09316e797dbf2c71732ffbe74b98b844e7cfc7c469c9a7b8954888b6a256f310c29d7225535f730a5b8d9f5
6
+ metadata.gz: 001f695018d0ac217632c7f070789e378377b371113ec0ae13f1871cda73d088ad92d4980d28d0d5f04c23d4b3dd9f09818108a786732436cb454b560ce31273
7
+ data.tar.gz: e12ddd6228e415944ac1c8b19f62a7f64ca53ce62cf08a6e6beb77eff67a0625f968d80e4b8d6f840f8e9485a26a5340233df2eb36839051150ac26af888ae64
data/CHANGELOG.md ADDED
@@ -0,0 +1,8 @@
1
+ ## 0.9.0 - August 5th 2018
2
+ - Added document `links` support.
3
+
4
+ ## 0.0.0 to 0.8.1
5
+ - Added initial support for parsing `has_many`, `has_one` / `belongs_to` relationships into class functions
6
+ - Added initial support for parsing relationship resources with a responses `included` block. Using the `embed_with` option for relationships.
7
+ - Added initial support for parsing data attributes into class functions.
8
+ - Added Error handling support
@@ -9,7 +9,7 @@ module JsonAPIObjectMapper
9
9
  include Enumerable
10
10
  include JsonAPIObjectMapper::Parser::Errors
11
11
 
12
- attr_accessor :collection_data
12
+ attr_reader :collection_data, :links
13
13
 
14
14
  def_delegators :@collection_data, :first, :last, :[]
15
15
 
@@ -17,11 +17,12 @@ module JsonAPIObjectMapper
17
17
  raise InvalidResource unless klass.is_a?(Class)
18
18
  raise InvalidParser unless parser.is_a?(JsonAPIObjectMapper::Parser::Document)
19
19
  @errors = parser.errors
20
+ @links = parser.links
20
21
  @collection_data =
21
22
  if document_invalid?
22
23
  []
23
24
  else
24
- Array(parser.document["data"]).map do |doc|
25
+ Array(parser.document_data).map do |doc|
25
26
  klass.new(parser, document: doc)
26
27
  end
27
28
  end.freeze
@@ -29,15 +30,28 @@ module JsonAPIObjectMapper
29
30
  freeze
30
31
  end
31
32
 
32
- def to_hash
33
- @collection_data.map(&:to_hash)
34
- end
35
-
36
33
  def each
37
34
  @collection_data.each do |data|
38
35
  yield data
39
36
  end
40
37
  end
38
+
39
+ def inspect
40
+ "#<#{self.class}:0x#{object_id.to_s(16)}, "\
41
+ "@errors=#{@errors.inspect}, "\
42
+ "@links=#{@links.inspect}, "\
43
+ "@data=#{@collection_data.map(&:inspect)}>"\
44
+ end
45
+ alias to_s inspect
46
+
47
+ def to_hash
48
+ {}.tap do |hash|
49
+ hash[:data] = @collection_data.map(&:to_hash)
50
+ hash[:links] = @links.to_h unless @links.nil?
51
+ hash[:errors] = @errors unless valid?
52
+ end
53
+ end
54
+ alias to_h to_hash
41
55
  end
42
56
  end
43
57
  end
@@ -77,9 +77,13 @@ module JsonAPIObjectMapper
77
77
  end
78
78
  alias to_h to_hash
79
79
 
80
- def to_s
81
- to_hash.to_s
80
+ def inspect
81
+ "#<#{self.class}:0x#{object_id.to_s(16)}, "\
82
+ "@errors = #{@errors.inspect}, "\
83
+ "attributes = #{@_class_attributes.inspect}, "\
84
+ "relationships = #{@_class_relationships.inspect}>"
82
85
  end
86
+ alias to_s inspect
83
87
 
84
88
  protected
85
89
 
@@ -10,6 +10,8 @@ module JsonAPIObjectMapper
10
10
  include JsonAPIObjectMapper::Parser::Errors
11
11
  extend DSL
12
12
 
13
+ attr_reader :links
14
+
13
15
  class << self
14
16
  attr_accessor :rel_has_one_blocks, :rel_has_many_blocks, :rel_options, :attr_blocks, :id_block, :type_block
15
17
  end
@@ -34,7 +36,7 @@ module JsonAPIObjectMapper
34
36
 
35
37
  def self.load(document)
36
38
  parser = JsonAPIObjectMapper::Parser::Document.new(document)
37
- if parser.document["data"].is_a?(Array) || parser.invalid?
39
+ if parser.contains_data_array? || parser.invalid?
38
40
  Collection.new(parser, klass: self)
39
41
  else
40
42
  new(parser)
@@ -48,6 +50,7 @@ module JsonAPIObjectMapper
48
50
 
49
51
  if document_valid?
50
52
  @includes = parser.includes
53
+ @links = parser_links(parser)
51
54
  @data = document_data(parser, document)
52
55
  @id = @data["id"]
53
56
  @type = @data["type"]
@@ -66,7 +69,11 @@ module JsonAPIObjectMapper
66
69
  private
67
70
 
68
71
  def document_data(parser, document)
69
- document.nil? ? (parser.document["data"] || parser.document) : (document["data"] || document)
72
+ document.nil? ? parser.document_data : (document["data"] || document)
73
+ end
74
+
75
+ def parser_links(parser)
76
+ parser.links unless parser.contains_data_array?
70
77
  end
71
78
 
72
79
  def deserialize!
@@ -8,19 +8,35 @@ module JsonAPIObjectMapper
8
8
  class Document
9
9
  include Errors
10
10
 
11
- attr_accessor :document, :includes
11
+ attr_reader :document, :includes, :links
12
12
 
13
13
  def initialize(document)
14
- @document = (document.is_a?(String) ? ::Oj.load(document) : document).freeze
15
- @includes = IncludedResources.load(@document["included"])
16
- @errors = deserialize_errors!.freeze
14
+ parsed_document = (document.is_a?(String) ? ::Oj.load(document) : document)
15
+ @includes = IncludedResources.load(parsed_document.delete("included"))
16
+ @links = deserialize_links(parsed_document.delete("links")).freeze
17
+ @document = parsed_document.freeze
18
+ @errors = deserialize_errors!.freeze
17
19
  freeze
18
20
  end
19
21
 
22
+ def document_data
23
+ @document["data"] || @document
24
+ end
25
+
26
+ def contains_data_array?
27
+ document_data.is_a?(Array)
28
+ end
29
+
20
30
  def deserialize_errors!
21
31
  return [] unless @document.key?("errors")
22
32
  Set.new(@document["errors"]) { |error| OpenStruct.new(error) }
23
33
  end
34
+
35
+ def deserialize_links(links)
36
+ links&.each_with_object(OpenStruct.new) do |(key, value), struct|
37
+ struct[key.to_s.tr("-", "_")] = value
38
+ end
39
+ end
24
40
  end
25
41
  end
26
42
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JsonAPIObjectMapper
4
- VERSION = "0.8.1"
4
+ VERSION = "0.9.0"
5
5
  end
@@ -79,6 +79,25 @@ module JsonAPIObjectMapper
79
79
  expect(result.source).to include("pointer" => "name")
80
80
  end
81
81
  end
82
+
83
+ context "Links" do
84
+ let(:foo_bar_klass) { Class.new(JsonAPIObjectMapper::Deserialize::Resource) }
85
+ subject { described_class.new(parser, klass: foo_bar_klass).links }
86
+
87
+ context "Results do not include links" do
88
+ it { is_expected.to be_nil }
89
+ end
90
+
91
+ it_behaves_like "it contains links" do
92
+ let!(:payload) { payload_links.merge("data" => [{ "id" => "1", "type" => "foobar" }]) }
93
+
94
+ it "Should not include links in the children of data resources" do
95
+ results = described_class.new(parser, klass: foo_bar_klass)
96
+ expect(results.first.id).to eq("1")
97
+ expect(results.first.links).to be_nil
98
+ end
99
+ end
100
+ end
82
101
  end
83
102
  end
84
103
  end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ shared_examples_for "it contains links" do
6
+ let(:payload_links) do
7
+ {
8
+ "links" => {
9
+ "total-pages" => 14,
10
+ "self" => "https://some-random-api.com/search?name=me?page=2",
11
+ "first" => "https://some-random-api.com/search?name=me?page=1",
12
+ "last" => "https://some-random-api.com/search?name=me?page=14",
13
+ "prev" => "https://some-random-api.com/search?name=me?page=1",
14
+ "next" => "https://some-random-api.com/search?name=me?page=3",
15
+ },
16
+ }
17
+ end
18
+
19
+ let(:payload) { payload_links }
20
+
21
+ it { is_expected.to be_a(OpenStruct).and(be_frozen) }
22
+ its(:total_pages) { is_expected.to eq(14) }
23
+ its(:self) { is_expected.to eq("https://some-random-api.com/search?name=me?page=2") }
24
+ its(:first) { is_expected.to eq("https://some-random-api.com/search?name=me?page=1") }
25
+ its(:last) { is_expected.to eq("https://some-random-api.com/search?name=me?page=14") }
26
+ its(:prev) { is_expected.to eq("https://some-random-api.com/search?name=me?page=1") }
27
+ its(:next) { is_expected.to eq("https://some-random-api.com/search?name=me?page=3") }
28
+ end
@@ -191,6 +191,18 @@ module JsonAPIObjectMapper
191
191
  end
192
192
  end
193
193
  end
194
+
195
+ describe "Links" do
196
+ let(:foo_bar_klass) { Class.new(described_class) }
197
+ subject { foo_bar_klass.load(payload).links }
198
+
199
+ it_behaves_like "it contains links"
200
+
201
+ context "Response does not contain links" do
202
+ let(:payload) { {} }
203
+ it { is_expected.to be_nil }
204
+ end
205
+ end
194
206
  end
195
207
  end
196
208
  end
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "bundler/setup"
4
+ require "rspec/its"
4
5
  require "jsonapi-object-mapper"
5
6
 
6
7
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require File.expand_path(f) }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsonapi-object-mapper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - George Protacio-Karaszi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-02 00:00:00.000000000 Z
11
+ date: 2018-08-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oj
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '3.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec-its
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.2'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.2'
69
83
  description: Digests JSON-API responses to plain old ruby objects
70
84
  email:
71
85
  - georgekaraszi@gmail.com
@@ -73,6 +87,7 @@ executables: []
73
87
  extensions: []
74
88
  extra_rdoc_files: []
75
89
  files:
90
+ - CHANGELOG.md
76
91
  - README.md
77
92
  - lib/jsonapi-object-mapper.rb
78
93
  - lib/jsonapi-object-mapper/deserialize/collection.rb
@@ -84,6 +99,7 @@ files:
84
99
  - lib/jsonapi-object-mapper/parser/included_resources.rb
85
100
  - lib/jsonapi-object-mapper/version.rb
86
101
  - spec/deserialize/collection_spec.rb
102
+ - spec/deserialize/link_examples.rb
87
103
  - spec/deserialize/resource_spec.rb
88
104
  - spec/jsonapi_object_mapper_spec.rb
89
105
  - spec/spec_helper.rb
@@ -113,6 +129,7 @@ specification_version: 4
113
129
  summary: Digests JSON-API responses to plain old ruby objects
114
130
  test_files:
115
131
  - spec/deserialize/collection_spec.rb
132
+ - spec/deserialize/link_examples.rb
116
133
  - spec/deserialize/resource_spec.rb
117
134
  - spec/jsonapi_object_mapper_spec.rb
118
135
  - spec/spec_helper.rb