shamu 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 27e560182b114ef221743131ca89ac18601cfbf7
4
- data.tar.gz: c6fd668c63413a9d45cefe73b87a587240ee5c8c
3
+ metadata.gz: 027f0ea99b484c02d9986999b39f3025dee4b4a3
4
+ data.tar.gz: 0eb00f3878a9718c979e511e8930cf81d8d708e8
5
5
  SHA512:
6
- metadata.gz: 31814221203809e5be4e532732c4f01d0f6c2583dc197bf4025efb8f1ae0e6e69c45707d5b7d553ea87e555767bf56a7efc29c910b1ea1245ac62283f3e5602d
7
- data.tar.gz: 915d74f223c593d04dc7b5d79629d7207d26fd5238956c52bf43f03cfd2bf20915ba59fedafd6249b19a0c00792952aa9e4d62638af880fe0d7e5d13702ce7aa
6
+ metadata.gz: 75946cc4efced52d7a3cf58bb673c75cdd2d9a7aee479b91f3fff4c96d485b74319f07c22345c616075a598948ee861eecd816046aefd37f9761321981c3d11e
7
+ data.tar.gz: 63784d0e8b20db671ba1563c19146ecea4e2fa3728098fc1a79db42e8ef2ebf57a7e68716c9aa349676dff841b6c92f4c73fc81f660df3bbe3fca4d1a8b953ba
data/.rubocop.yml CHANGED
@@ -79,7 +79,10 @@ Style/MultilineBlockChain:
79
79
  Enabled: false
80
80
 
81
81
  Style/OptionHash:
82
- Enabled: true
82
+ Enabled: true
83
+
84
+ Style/ParallelAssignment:
85
+ Enabled: false
83
86
 
84
87
  Style/RegexpLiteral:
85
88
  Enabled: false
@@ -111,6 +114,9 @@ Style/TrailingBlankLines:
111
114
  Style/TrailingCommaInLiteral:
112
115
  Enabled: false
113
116
 
117
+ Style/TrivialAccessors:
118
+ Enabled: false
119
+
114
120
  Style/UnneededInterpolation:
115
121
  Enabled: false
116
122
 
data/README.md CHANGED
@@ -23,8 +23,7 @@ Have a whale of a good time adding Service Oriented Architecture to your ruby pr
23
23
  - {Shamu::Auditing}
24
24
  - {Shamu::Features}
25
25
  - {Shamu::Rails}
26
-
27
-
26
+ - {Shamu::JsonApi}
28
27
 
29
28
  # Dependency Injection
30
29
 
@@ -158,7 +158,7 @@ module Shamu
158
158
 
159
159
  # @param [String] path of the default config file.
160
160
  # @return [String]
161
- def default_config_path=( path ) # rubocop:disable Style/TrivialAccessors
161
+ def default_config_path=( path )
162
162
  @default_config_path = path
163
163
  end
164
164
  end
@@ -0,0 +1 @@
1
+ http://jsonapi.org
@@ -0,0 +1,67 @@
1
+ module Shamu
2
+ module JsonApi
3
+
4
+ # Used by a {Serilaizer} to write fields and relationships
5
+ class BaseBuilder
6
+
7
+ # @param [Context] context the current serialization context.
8
+ def initialize( context )
9
+ @context = context
10
+ @output = {}
11
+ end
12
+
13
+ # @overload identifier( type, id )
14
+ # @param [String] type of the resource.
15
+ # @param [Object] id of the resource.
16
+ # @overload identifier( resource )
17
+ # @param [#json_api_type,#id] resource an object that responds to `json_api_type` and `id`
18
+ #
19
+ # Write a resource linkage info.
20
+ #
21
+ # @return [void]
22
+ def identifier( type, id = nil )
23
+ type, id = type.json_api_type, type.id if type.respond_to? :json_api_type
24
+
25
+ output[:type] = type.to_s
26
+ output[:id] = id.to_s
27
+ end
28
+
29
+ # Write a link to another resource.
30
+ #
31
+ # @param [String,Symbol] name of the link.
32
+ # @param [String] url
33
+ # @param [Hash] meta optional additional meta information.
34
+ # @return [void]
35
+ def link( name, url, meta: nil )
36
+ links = ( output[:links] ||= {} )
37
+
38
+ if meta # rubocop:disable Style/ConditionalAssignment
39
+ links[ name.to_sym ] = { href: url, meta: meta }
40
+ else
41
+ links[ name.to_sym ] = url
42
+ end
43
+ end
44
+
45
+ # Add a meta field.
46
+ # @param [String,Symbol] name of the meta field.
47
+ # @param [Object] vlaue that can be converted to a JSON primitive type.
48
+ # @return [void]
49
+ def meta( name, value )
50
+ meta = ( output[:meta] ||= {} )
51
+ meta[ name.to_sym ] = value
52
+ end
53
+
54
+ # @return [Hash] the results output as JSON safe hash.
55
+ def compile
56
+ fail JsonApi::IncompleteResourceError unless output[:type]
57
+ output
58
+ end
59
+
60
+ private
61
+
62
+ attr_reader :context
63
+ attr_reader :output
64
+
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,69 @@
1
+ module Shamu
2
+ module JsonApi
3
+ class Context
4
+
5
+ def initialize( fields: nil )
6
+ @included_resources = {}
7
+ @all_resources = Set.new
8
+ @fields = parse_fields( fields )
9
+ end
10
+
11
+ # Add an included resource for a compound response.
12
+ #
13
+ # @param [Object] resource to be serialized.
14
+ # @param [Serializer] the serializer to use to serialize the object. If
15
+ # not provided a default {Serializer} will be chosen.
16
+ # @return [resource]
17
+ # @yield (builder)
18
+ # @yieldparam [ResourceBuilder] builder to write embedded resource to.
19
+ def include_resource( resource, serializer = nil, &block )
20
+ return if all_resources.include?( resource )
21
+
22
+ all_resources << resource
23
+ included_resources[resource] ||= { serializer: serializer, block: block }
24
+ end
25
+
26
+ # Collects all the currently included resources and resets the queue.
27
+ def collect_included_resources
28
+ included = included_resources.dup
29
+ @included_resources = {}
30
+ included
31
+ end
32
+
33
+ # @return [Boolean] true if there are any pending included resources.
34
+ def included_resources?
35
+ included_resources.any?
36
+ end
37
+
38
+ # Check to see if the field should be included in the JSON API output.
39
+ #
40
+ # @param [Symbol] type the resource type in question.
41
+ # @param [Symbol] name of the field on the resouce in question.
42
+ # @return [Boolean] true if the
43
+ def include_field?( type, name )
44
+ return true unless type_fields = fields[ type ]
45
+
46
+ type_fields.include?( name )
47
+ end
48
+
49
+ private
50
+
51
+ attr_reader :all_resources
52
+ attr_reader :included_resources
53
+ attr_reader :fields
54
+
55
+ def parse_fields( raw )
56
+ return {} unless raw
57
+
58
+ raw.each_with_object( {} ) do |(type, fields), parsed|
59
+ fields = fields.split( "," ) if fields.is_a?( String )
60
+
61
+ parsed[ type.to_sym ] = fields.map do |field|
62
+ field = field.strip if field.is_a? String
63
+ field.to_sym
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,10 @@
1
+ module Shamu
2
+ module JsonApi
3
+
4
+ # A {Serializer} that can serialize all of the public attributes of an
5
+ # {Entities::Entity}.
6
+ class EntitySerializer < Serializer
7
+
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,29 @@
1
+ require "i18n"
2
+
3
+ module Shamu
4
+
5
+ module JsonApi
6
+ # A generic error class for problems with shamu JSON API.
7
+ class Error < Shamu::Error
8
+ private
9
+
10
+ def translation_scope
11
+ super.dup.insert( 1, :json_api )
12
+ end
13
+
14
+ end
15
+
16
+ # Raised if an {ResourceBuilder#identifier} was not built.
17
+ class IncompleteResourceError < Error
18
+ def initialize( message = :incomplete_resource )
19
+ super
20
+ end
21
+ end
22
+
23
+ class IdentifierRequiredError < Error
24
+ def initialize( message = :identifier_required )
25
+ super
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,78 @@
1
+ module Shamu
2
+ module JsonApi
3
+
4
+ # Build an error response object.
5
+ class ErrorBuilder
6
+
7
+ def initialize
8
+ @output = { id: SecureRandom.uuid }
9
+ end
10
+
11
+ # @param [String] id unique id for this occurrence of the error.
12
+ def id( id )
13
+ output[:id] = id
14
+ end
15
+
16
+ # Summary of the error.
17
+ # @param [Integer] http_status code.
18
+ # @param [String,Symbol] code application specific code for the error.
19
+ # @param [String] human friendly title for the error.
20
+ def summary( http_status, code, title = nil )
21
+ output[:status] = http_status.to_s
22
+ output[:code] = code.to_s
23
+ output[:title] = title || code.to_s.titleize
24
+ end
25
+
26
+ # Summarize an exception as an error.
27
+ # @param [Exception] exception
28
+ # @param [Integer] http_status code. Default 400.
29
+ def exception( exception, http_status = nil )
30
+ http_status ||= 400
31
+
32
+ name = exception.class.name.demodulize.gsub( /Error$/, "" )
33
+ summary http_status, name.underscore, name.titleize
34
+ detail exception.message
35
+ end
36
+
37
+ # @return [String] message details about the error.
38
+ def detail( message )
39
+ output[:detail] = message
40
+ end
41
+
42
+ # Write a link to error information.
43
+ #
44
+ # @param [String,Symbol] name of the link.
45
+ # @param [String] url
46
+ # @param [Hash] meta optional additional meta information.
47
+ # @return [void]
48
+ def link( name, url, meta: nil )
49
+ links = ( output[:links] ||= {} )
50
+
51
+ if meta # rubocop:disable Style/ConditionalAssignment
52
+ links[ name.to_sym ] = { href: url, meta: meta }
53
+ else
54
+ links[ name.to_sym ] = url
55
+ end
56
+ end
57
+
58
+ # Add a meta field.
59
+ # @param [String,Symbol] name of the meta field.
60
+ # @param [Object] value that can be converted to a JSON primitive type.
61
+ # @return [void]
62
+ def meta( name, value )
63
+ meta = ( output[:meta] ||= {} )
64
+ meta[ name.to_sym ] = value
65
+ end
66
+
67
+ # @return [Hash] the results output as JSON safe hash.
68
+ def compile
69
+ output
70
+ end
71
+
72
+ private
73
+
74
+ attr_reader :output
75
+
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,16 @@
1
+ require "shamu/json_api/base_builder"
2
+
3
+ module Shamu
4
+ module JsonApi
5
+
6
+ # Build a relationship from one resource to another.
7
+ class RelationshipBuilder < BaseBuilder
8
+
9
+ # (see Context#include_resource)
10
+ def include_resource( resource, serializer = nil, &block )
11
+ context.include_resource resource, serializer, &block
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,81 @@
1
+ require "shamu/json_api/base_builder"
2
+
3
+ module Shamu
4
+ module JsonApi
5
+
6
+ # Used by a {Serilaizer} to write fields and relationships
7
+ class ResourceBuilder < BaseBuilder
8
+
9
+ # @overload attribute( attributes )
10
+ # @param [Hash] attributes to write.
11
+ # @overload attribute( name, value )
12
+ # @param [String, Symbol] name of the attribute.
13
+ # @param [Object] value that can be persited to a JSON primitive value.
14
+ #
15
+ # Write one or more attributes to the output.
16
+ #
17
+ # @return [void]
18
+ def attribute( name_or_hash, value = nil )
19
+ require_identifier!
20
+
21
+ if value
22
+ add_attribute name_or_hash, value
23
+ else
24
+ name_or_hash.each do |n, v|
25
+ add_attribute n, v
26
+ end
27
+ end
28
+ end
29
+
30
+ # Build a relationship reference.
31
+ #
32
+ # ```
33
+ # relationship :author do |builder|
34
+ # builder.identifier author
35
+ # builder.link :related, author_url author
36
+ # builder.link :self, book_author_url( book, author )
37
+ # end
38
+ # ```
39
+ #
40
+ # @param [String,Symbol] name of the relationship.
41
+ # @return [void]
42
+ # @yield (builder)
43
+ # @yieldparam [RelationshipBuilder] builder used to define the properties
44
+ # of the relationship.
45
+ def relationship( name, &block )
46
+ require_identifier!
47
+
48
+ return unless context.include_field?( type, name )
49
+
50
+ builder = RelationshipBuilder.new( context )
51
+ yield builder
52
+
53
+ relationships = ( output[:relationships] ||= {} )
54
+ relationships[ name.to_sym ] = builder.compile
55
+ end
56
+
57
+ # (see BaseBuilder#identifier)
58
+ def identifier( * )
59
+ super.tap do
60
+ @type = output[:type]
61
+ end
62
+ end
63
+
64
+ private
65
+
66
+ attr_reader :type
67
+
68
+ def require_identifier!
69
+ fail IdentifierRequiredError unless @type
70
+ end
71
+
72
+ def add_attribute( name, value )
73
+ return unless context.include_field?( type, name )
74
+
75
+ attributes = ( output[:attributes] ||= {} )
76
+ attributes[ name.to_sym ] = value
77
+ end
78
+
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,99 @@
1
+ module Shamu
2
+ module JsonApi
3
+
4
+ # Build a JSON API response from one or more resources.
5
+ class Response < BaseBuilder
6
+
7
+ # Output a single resource as the response data.
8
+ # @param [Object] resource to write.
9
+ # @param [Serializer] serializer used to write the resource state.
10
+ # @yield (builder)
11
+ # @yieldparam [ResourceBuilder] builder used write the resources fields
12
+ # and meta.
13
+ #
14
+ # @return [void]
15
+ def resource( resource, serializer = nil, &block )
16
+ output[:data] = build_resource( resource, serializer, &block )
17
+ end
18
+
19
+ # Output a single resource as the response data.
20
+ #
21
+ # @param [Enumerable<Object>] resources to write.
22
+ # @param [Serializer] serializer used to write the resource state.
23
+ # @yield (builder, resource)
24
+ # @yieldparam [ResourceBuilder] builder used write the resources fields
25
+ # and meta.
26
+ # @yieldparam [Object] resource being written.
27
+ # @return [void]
28
+ def resources( collection, serializer = nil, &block )
29
+ output[:data] =
30
+ collection.map do |resource|
31
+ build_resource resource, serializer, &block
32
+ end
33
+ end
34
+
35
+ # @overload error( exception, http_status = nil )
36
+ # @param (see ErrorBuilder#exception)
37
+ # @overload error( &block )
38
+ # @yield (builder)
39
+ # @yieldparam [ErrorBuilder] builder used to describe the error.
40
+ #
41
+ # @return [void]
42
+ def error( exception = nil, http_status = nil, &block )
43
+ builder = ErrorBuilder.new
44
+
45
+ if block_given?
46
+ yield builder
47
+ else
48
+ builder.exception( exception, http_status )
49
+ end
50
+
51
+ errors = ( output[:errors] ||= [] )
52
+ errors << builder.compile
53
+ end
54
+
55
+ # (see BaseBuilder#compile)
56
+ def compile
57
+ @compiled ||= begin
58
+ compiled = output.dup
59
+ compiled[:jsonapi] = { version: "1.0" }
60
+
61
+ while context.included_resources?
62
+ included = ( compiled[ :included ] ||= [] )
63
+ context.collect_included_resources.each do |resource, options|
64
+ included << build_resource( resource, options[:serializer], &options[:block] )
65
+ end
66
+ end
67
+
68
+ compiled
69
+ end
70
+ end
71
+
72
+ def to_json
73
+ compile.to_json
74
+ end
75
+
76
+ def to_s
77
+ compile.to_s
78
+ end
79
+
80
+ private :identifier
81
+
82
+ private
83
+
84
+ def build_resource( resource, serializer, &block )
85
+ fail "A block is required if no serializer is given" if !serializer && !block_given?
86
+
87
+ builder = ResourceBuilder.new( context )
88
+ if serializer
89
+ serializer.serialize( builder )
90
+ else
91
+ yield builder
92
+ end
93
+
94
+ builder.compile
95
+ end
96
+
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,33 @@
1
+ module Shamu
2
+ module JsonApi
3
+
4
+ # Serialize an object to a JSON API stream.
5
+ class Serializer
6
+
7
+ # @param [Object] resource to be serialized.
8
+ def initialize( resource )
9
+ @resource = resource
10
+ end
11
+
12
+ # Serialize the {#resource} to the builder.
13
+ # @param [ResourceBuilder] builder to write to.
14
+ # @return [void]
15
+ def serialize( builder )
16
+ end
17
+
18
+ private
19
+
20
+ attr_reader :resource
21
+
22
+ class << self
23
+
24
+ # Find a {Serializer} that knows how to serialize the given resource.
25
+ # @param [Object] resource to serialize.
26
+ # @return [Serializer]
27
+ def find( resource )
28
+ end
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,8 @@
1
+ module Shamu
2
+ module JsonApi
3
+
4
+ # Add the ability to support JSON API serialization.
5
+ module Support
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,13 @@
1
+ module Shamu
2
+ # {include:file:lib/shamu/json_api/README.md}
3
+ module JsonApi
4
+ require "shamu/json_api/context"
5
+ require "shamu/json_api/relationship_builder"
6
+ require "shamu/json_api/resource_builder"
7
+ require "shamu/json_api/response"
8
+ require "shamu/json_api/serializer"
9
+ require "shamu/json_api/support"
10
+ require "shamu/json_api/error"
11
+ require "shamu/json_api/error_builder"
12
+ end
13
+ end
@@ -24,4 +24,9 @@ en:
24
24
 
25
25
  features:
26
26
  errors:
27
- retired_toggle_checked: "The `%{name}` toggle retired at `%{retire_at}` and cannot be checked anymore."
27
+ retired_toggle_checked: "The `%{name}` toggle retired at `%{retire_at}` and cannot be checked anymore."
28
+
29
+ json_api:
30
+ errors:
31
+ incomplete_resource: "`identifier` was not called to define the type and id of the resource"
32
+ identifier_resource: "`identifier` must be called before defining any fields"
data/lib/shamu/version.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  module Shamu
3
3
  # The primary version number
4
- VERSION_NUMBER = "0.0.2".freeze
4
+ VERSION_NUMBER = "0.0.3".freeze
5
5
 
6
6
  # Version suffix such as 'beta' or 'alpha'
7
7
  VERSION_SUFFIX = "".freeze
data/lib/shamu.rb CHANGED
@@ -15,6 +15,7 @@ module Shamu
15
15
  require "shamu/events"
16
16
  require "shamu/sessions"
17
17
  require "shamu/features"
18
+ require "shamu/json_api"
18
19
  require "shamu/to_model_id_extension"
19
20
  require "shamu/to_bool_extension"
20
21
 
@@ -0,0 +1,42 @@
1
+ require "spec_helper"
2
+
3
+ describe Shamu::JsonApi::BaseBuilder do
4
+ let( :context ) { Shamu::JsonApi::Context.new }
5
+ let( :builder ) { Shamu::JsonApi::BaseBuilder.new( context ) }
6
+
7
+ before( :each ) do
8
+ builder.identifier "example", 1
9
+ end
10
+
11
+ describe "#identifier" do
12
+ it "writes type and id" do
13
+ builder.identifier "spec", 5
14
+
15
+ expect( builder.compile ).to include type: "spec", id: "5"
16
+ end
17
+ end
18
+
19
+ describe "#link" do
20
+ it "adds a link" do
21
+ builder.link :self, "http://localhost"
22
+
23
+ expect( builder.compile ).to include links: { self: "http://localhost" }
24
+ end
25
+ end
26
+
27
+ describe "#meta" do
28
+ it "adds the meta data" do
29
+ builder.meta :updated, "today"
30
+
31
+ expect( builder.compile ).to include meta: { updated: "today" }
32
+ end
33
+ end
34
+
35
+ describe "#compile" do
36
+ it "fails if identifier has not been specified" do
37
+ expect do
38
+ Shamu::JsonApi::BaseBuilder.new( context ).compile
39
+ end.to raise_error Shamu::JsonApi::IncompleteResourceError
40
+ end
41
+ end
42
+ end
File without changes
@@ -0,0 +1,31 @@
1
+ require "spec_helper"
2
+
3
+ describe Shamu::JsonApi::Context do
4
+ it "parses comma deliminated fields" do
5
+ context = Shamu::JsonApi::Context.new fields: { "user" => "name, email," }
6
+
7
+ expect( context.send( :fields ) ).to eq user: [:name, :email]
8
+ end
9
+
10
+ it "accepts array of fields" do
11
+ context = Shamu::JsonApi::Context.new fields: { "user" => [ "name", "email" ] }
12
+
13
+ expect( context.send( :fields ) ).to eq user: [:name, :email]
14
+ end
15
+
16
+ describe "#include_field?" do
17
+ let( :context ) { Shamu::JsonApi::Context.new( fields: { "user": "name,email" } ) }
18
+
19
+ it "is true for unfiltered" do
20
+ expect( context.include_field?( :order, :number ) ).to be_truthy
21
+ end
22
+
23
+ it "is true for filtered with field" do
24
+ expect( context.include_field?( :user, :name ) ).to be_truthy
25
+ end
26
+
27
+ it "is false for filtered without field" do
28
+ expect( context.include_field?( :user, :birthdate ) ).not_to be_truthy
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,31 @@
1
+ require "spec_helper"
2
+
3
+ describe Shamu::JsonApi::ErrorBuilder do
4
+ let( :builder ) { Shamu::JsonApi::ErrorBuilder.new }
5
+
6
+ describe "#summary" do
7
+ it "infers title" do
8
+ builder.summary 422, :not_allowed
9
+
10
+ expect( builder.compile ).to include title: "Not Allowed"
11
+ end
12
+ end
13
+
14
+ describe "#exception" do
15
+ before( :each ) do
16
+ builder.exception NotImplementedError.new( "Nope, we haven't done that yet" )
17
+ end
18
+
19
+ it "applies message to details" do
20
+ expect( builder.compile ).to include detail: "Nope, we haven't done that yet"
21
+ end
22
+
23
+ it "applies class name as code" do
24
+ expect( builder.compile ).to include code: "not_implemented"
25
+ end
26
+
27
+ it "applies class name as title" do
28
+ expect( builder.compile ).to include title: "Not Implemented"
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,5 @@
1
+ require "spec_helper"
2
+
3
+ describe Shamu::JsonApi::RelationshipBuilder do
4
+
5
+ end
@@ -0,0 +1,52 @@
1
+ require "spec_helper"
2
+
3
+ describe Shamu::JsonApi::RelationshipBuilder do
4
+ let( :context ) { Shamu::JsonApi::Context.new }
5
+ let( :builder ) { Shamu::JsonApi::ResourceBuilder.new( context ) }
6
+
7
+ before( :each ) do
8
+ builder.identifier "example", 1
9
+ end
10
+
11
+ describe "#attribute" do
12
+ it "adds to the attributes node" do
13
+ builder.attribute name: "Jim"
14
+
15
+ expect( builder.compile ).to include attributes: { name: "Jim" }
16
+ end
17
+
18
+ it "adds a single name, value pair" do
19
+ builder.attribute :name, "Jim"
20
+
21
+ expect( builder.compile ).to include attributes: { name: "Jim" }
22
+ end
23
+
24
+ it "excludes filtered attributes" do
25
+ allow( context ).to receive( :include_field? ).and_return false
26
+
27
+ builder.attribute name: "Nope"
28
+ expect( builder.compile ).not_to include attributes: { name: "Nope" }
29
+ end
30
+ end
31
+
32
+ describe "#relationship" do
33
+ it "adds a relationship" do
34
+ builder.relationship :parent do |rel|
35
+ rel.identifier :example, 5
36
+ end
37
+
38
+ expect( builder.compile ).to include relationships: { parent: kind_of( Hash ) }
39
+ end
40
+
41
+ it "excludes filtered relationships" do
42
+ allow( context ).to receive( :include_field? ).and_return false
43
+
44
+ builder.relationship :parent do |rel|
45
+ rel.identifier :example, 5
46
+ end
47
+
48
+ expect( builder.compile ).not_to include relationships: { parent: kind_of( Hash ) }
49
+ end
50
+ end
51
+
52
+ end
@@ -0,0 +1,42 @@
1
+ require "spec_helper"
2
+
3
+ describe Shamu::JsonApi::Response do
4
+ let( :context ) { Shamu::JsonApi::Context.new }
5
+ let( :response ) { Shamu::JsonApi::Response.new context }
6
+
7
+ it "uses serializer if given" do
8
+ serializer = double Shamu::JsonApi::Serializer
9
+ expect( serializer ).to receive( :serialize ) do |builder|
10
+ builder.identifier :response, 9
11
+ end
12
+
13
+ response.resource double, serializer
14
+ end
15
+
16
+ it "expects a block if no serializer" do
17
+ expect do
18
+ response.resource double
19
+ end.to raise_error /block/
20
+ end
21
+
22
+ it "appends included resources" do
23
+
24
+ response.resource double do |builder|
25
+ builder.identifier :example, 4
26
+ builder.relationship :parent do |rel|
27
+ rel.identifier :suite, 10
28
+ rel.include_resource double do |res|
29
+ res.identifier :suite, 10
30
+ end
31
+ end
32
+ end
33
+
34
+ expect( response.compile ).to include included: [ hash_including( type: "suite" ) ]
35
+ end
36
+
37
+ it "includes errors" do
38
+ response.error NotImplementedError.new
39
+
40
+ expect( response.compile ).to include errors: [ hash_including( code: "not_implemented" ) ]
41
+ end
42
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shamu
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Alexander
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-17 00:00:00.000000000 Z
11
+ date: 2016-04-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -269,6 +269,18 @@ files:
269
269
  - lib/shamu/features/support.rb
270
270
  - lib/shamu/features/toggle.rb
271
271
  - lib/shamu/features/toggle_codec.rb
272
+ - lib/shamu/json_api.rb
273
+ - lib/shamu/json_api/README.md
274
+ - lib/shamu/json_api/base_builder.rb
275
+ - lib/shamu/json_api/context.rb
276
+ - lib/shamu/json_api/entity_serializer.rb
277
+ - lib/shamu/json_api/error.rb
278
+ - lib/shamu/json_api/error_builder.rb
279
+ - lib/shamu/json_api/relationship_builder.rb
280
+ - lib/shamu/json_api/resource_builder.rb
281
+ - lib/shamu/json_api/response.rb
282
+ - lib/shamu/json_api/serializer.rb
283
+ - lib/shamu/json_api/support.rb
272
284
  - lib/shamu/locale/en.yml
273
285
  - lib/shamu/logger.rb
274
286
  - lib/shamu/rack.rb
@@ -363,6 +375,13 @@ files:
363
375
  - spec/lib/shamu/features/support_spec.rb
364
376
  - spec/lib/shamu/features/toggle_codec_spec.rb
365
377
  - spec/lib/shamu/features/toggle_spec.rb
378
+ - spec/lib/shamu/json_api/base_builder_spec.rb
379
+ - spec/lib/shamu/json_api/common_builder_spec.rb
380
+ - spec/lib/shamu/json_api/context_spec.rb
381
+ - spec/lib/shamu/json_api/error_builder_spec.rb
382
+ - spec/lib/shamu/json_api/relationship_builder_spec.rb
383
+ - spec/lib/shamu/json_api/resource_builder_spec.rb
384
+ - spec/lib/shamu/json_api/response_spec.rb
366
385
  - spec/lib/shamu/rack/cookies_middleware_spec.rb
367
386
  - spec/lib/shamu/rack/cookies_spec.rb
368
387
  - spec/lib/shamu/rack/query_params_middleware_spec.rb
@@ -466,6 +485,13 @@ test_files:
466
485
  - spec/lib/shamu/features/support_spec.rb
467
486
  - spec/lib/shamu/features/toggle_codec_spec.rb
468
487
  - spec/lib/shamu/features/toggle_spec.rb
488
+ - spec/lib/shamu/json_api/base_builder_spec.rb
489
+ - spec/lib/shamu/json_api/common_builder_spec.rb
490
+ - spec/lib/shamu/json_api/context_spec.rb
491
+ - spec/lib/shamu/json_api/error_builder_spec.rb
492
+ - spec/lib/shamu/json_api/relationship_builder_spec.rb
493
+ - spec/lib/shamu/json_api/resource_builder_spec.rb
494
+ - spec/lib/shamu/json_api/response_spec.rb
469
495
  - spec/lib/shamu/rack/cookies_middleware_spec.rb
470
496
  - spec/lib/shamu/rack/cookies_spec.rb
471
497
  - spec/lib/shamu/rack/query_params_middleware_spec.rb