yaks 0.4.4 → 0.5.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 +4 -4
- data/.gitignore +2 -0
- data/CHANGELOG.md +44 -3
- data/README.md +90 -33
- data/Rakefile +10 -0
- data/bench/bench.rb +0 -1
- data/bench/bench_1000.rb +60 -0
- data/lib/yaks/breaking_changes.rb +22 -0
- data/lib/yaks/config/dsl.rb +114 -27
- data/lib/yaks/config.rb +39 -54
- data/lib/yaks/default_policy.rb +32 -14
- data/lib/yaks/format/collection_json.rb +4 -4
- data/lib/yaks/format/hal.rb +20 -3
- data/lib/yaks/format/json_api.rb +3 -3
- data/lib/yaks/format.rb +54 -9
- data/lib/yaks/fp/callable.rb +9 -0
- data/lib/yaks/fp/hash_updatable.rb +2 -0
- data/lib/yaks/fp/updatable.rb +2 -0
- data/lib/yaks/fp.rb +8 -0
- data/lib/yaks/mapper/link.rb +2 -2
- data/lib/yaks/mapper.rb +6 -6
- data/lib/yaks/primitivize.rb +2 -2
- data/lib/yaks/resource/link.rb +0 -4
- data/lib/yaks/runner.rb +90 -0
- data/lib/yaks/util.rb +4 -0
- data/lib/yaks/version.rb +1 -1
- data/lib/yaks.rb +3 -0
- data/spec/acceptance/acceptance_spec.rb +6 -1
- data/spec/json/confucius.collection.json +5 -16
- data/spec/json/plant_collection.collection.json +32 -0
- data/spec/spec_helper.rb +2 -1
- data/spec/support/deep_eql.rb +14 -7
- data/spec/support/pet_mapper.rb +0 -2
- data/spec/unit/yaks/collection_mapper_spec.rb +24 -2
- data/spec/unit/yaks/config/dsl_spec.rb +6 -10
- data/spec/unit/yaks/config_spec.rb +40 -99
- data/spec/unit/yaks/default_policy_spec.rb +20 -0
- data/spec/unit/yaks/format/collection_json_spec.rb +41 -0
- data/spec/unit/yaks/format/hal_spec.rb +38 -3
- data/spec/unit/yaks/format/json_api_spec.rb +2 -2
- data/spec/unit/yaks/format_spec.rb +28 -3
- data/spec/unit/yaks/fp/callable_spec.rb +13 -0
- data/spec/unit/yaks/mapper_spec.rb +226 -126
- data/spec/unit/yaks/resource/link_spec.rb +2 -3
- data/spec/unit/yaks/resource_spec.rb +15 -0
- data/spec/unit/yaks/runner_spec.rb +260 -0
- data/spec/unit/yaks/util_spec.rb +7 -1
- data/yaks.gemspec +4 -1
- metadata +72 -15
- /data/spec/json/{hal_plant_collection.json → plant_collection.hal.json} +0 -0
data/lib/yaks/default_policy.rb
CHANGED
@@ -8,23 +8,19 @@ module Yaks
|
|
8
8
|
namespace: Kernel
|
9
9
|
}
|
10
10
|
|
11
|
-
# @!attribute [r]
|
11
|
+
# @!attribute [r]
|
12
12
|
# @return [Hash]
|
13
13
|
attr_reader :options
|
14
14
|
|
15
|
-
# @param [Hash] options
|
16
|
-
# @return [Yaks::DefaultPolicy]
|
15
|
+
# @param options [Hash] options
|
17
16
|
def initialize(options = {})
|
18
17
|
@options = DEFAULTS.merge(options)
|
19
18
|
end
|
20
19
|
|
21
|
-
# @param [Object]
|
22
|
-
# @return [
|
23
|
-
# or a subclass of Yaks::Mapper of some sort.
|
24
|
-
#
|
25
|
-
# @raise [NameError] only occurs when the model
|
26
|
-
# is anything but a collection.
|
20
|
+
# @param model [Object]
|
21
|
+
# @return [Class] A mapper, typically a subclass of Yaks::Mapper
|
27
22
|
#
|
23
|
+
# @raise [NameError] only occurs when the model is anything but a collection.
|
28
24
|
def derive_mapper_from_object(model)
|
29
25
|
if model.respond_to? :to_ary
|
30
26
|
if m = model.first
|
@@ -45,14 +41,28 @@ module Yaks
|
|
45
41
|
end
|
46
42
|
end
|
47
43
|
|
48
|
-
#
|
44
|
+
# Derive the a mapper type name
|
45
|
+
#
|
46
|
+
# This returns the 'system name' for a mapper,
|
47
|
+
# e.g. ShowEventMapper => show_event.
|
48
|
+
#
|
49
|
+
# @param [Class] mapper_class
|
50
|
+
#
|
49
51
|
# @return [String]
|
50
52
|
def derive_type_from_mapper_class(mapper_class)
|
51
53
|
underscore(mapper_class.name.split('::').last.sub(/Mapper$/, ''))
|
52
54
|
end
|
53
55
|
|
54
|
-
#
|
55
|
-
#
|
56
|
+
# Derive the mapper type name from a collection
|
57
|
+
#
|
58
|
+
# This inspects the first element of the collection, so it
|
59
|
+
# requires a non-empty collection. Will return nil if the
|
60
|
+
# collection is empty.
|
61
|
+
#
|
62
|
+
# @param [#first] collection
|
63
|
+
#
|
64
|
+
# @return [String|nil]
|
65
|
+
#
|
56
66
|
# @raise [NameError]
|
57
67
|
def derive_type_from_collection(collection)
|
58
68
|
if collection.any?
|
@@ -66,16 +76,24 @@ module Yaks
|
|
66
76
|
@options[:namespace].const_get("#{camelize(association.singular_name)}Mapper")
|
67
77
|
end
|
68
78
|
|
69
|
-
# @param [Yaks::Mapper::Association]
|
79
|
+
# @param association [Yaks::Mapper::Association]
|
70
80
|
# @return [String]
|
71
81
|
def derive_rel_from_association(association)
|
72
82
|
expand_rel( association.name )
|
73
83
|
end
|
74
84
|
|
75
|
-
# @param [String]
|
85
|
+
# @param relname [String]
|
76
86
|
# @return [String]
|
77
87
|
def expand_rel(relname)
|
78
88
|
URITemplate.new(@options[:rel_template]).expand(rel: relname)
|
79
89
|
end
|
90
|
+
|
91
|
+
# @param format_class [Class]
|
92
|
+
# @return [#call] format_class
|
93
|
+
def serializer_for_format(format_class)
|
94
|
+
{
|
95
|
+
json: JSON.method(:pretty_generate)
|
96
|
+
}.fetch(format_class.serializer)
|
97
|
+
end
|
80
98
|
end
|
81
99
|
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
module Yaks
|
2
2
|
class Format
|
3
3
|
class CollectionJson < self
|
4
|
-
|
4
|
+
register :collection_json, :json, 'application/vnd.collection+json'
|
5
5
|
|
6
6
|
include FP
|
7
7
|
|
8
|
-
# @param [Yaks
|
8
|
+
# @param [Yaks::Resource] resource
|
9
9
|
# @return [Hash]
|
10
10
|
def serialize_resource(resource)
|
11
11
|
result = {
|
@@ -29,10 +29,10 @@ module Yaks
|
|
29
29
|
result = { data: attrs }
|
30
30
|
result[:href] = item.self_link.uri if item.self_link
|
31
31
|
item.links.each do |link|
|
32
|
-
next if link.rel
|
32
|
+
next if link.rel.equal? :self
|
33
33
|
result[:links] = [] unless result.key?(:links)
|
34
34
|
result[:links] << {rel: link.rel, href: link.uri}
|
35
|
-
result[:links].last[:name] = link.
|
35
|
+
result[:links].last[:name] = link.title if link.title
|
36
36
|
end
|
37
37
|
result
|
38
38
|
end
|
data/lib/yaks/format/hal.rb
CHANGED
@@ -2,8 +2,26 @@
|
|
2
2
|
|
3
3
|
module Yaks
|
4
4
|
class Format
|
5
|
+
# Hypertext Application Language (http://stateless.co/hal_specification.html)
|
6
|
+
#
|
7
|
+
# A lightweight JSON Hypermedia message format.
|
8
|
+
#
|
9
|
+
# Options: +:plural_links+ In HAL, a single rel can correspond to
|
10
|
+
# a single link, or to a list of links. Which rels are singular
|
11
|
+
# and which are plural is application-dependant. Yaks assumes all
|
12
|
+
# links are singular. If your resource might contain multiple
|
13
|
+
# links for the same rel, then configure that rel to be plural. In
|
14
|
+
# that case it will always be rendered as a collection, even when
|
15
|
+
# the resource only contains a single link.
|
16
|
+
#
|
17
|
+
# @example
|
18
|
+
#
|
19
|
+
# yaks = Yaks.new do
|
20
|
+
# format_options :hal, {plural_links: [:related_content]}
|
21
|
+
# end
|
22
|
+
#
|
5
23
|
class Hal < self
|
6
|
-
|
24
|
+
register :hal, :json, 'application/hal+json'
|
7
25
|
|
8
26
|
protected
|
9
27
|
|
@@ -14,7 +32,6 @@ module Yaks
|
|
14
32
|
# looking at client behavior (Hyperagent) it seems safer to return an empty
|
15
33
|
# resource.
|
16
34
|
#
|
17
|
-
# return nil if resource.is_a? NullResource
|
18
35
|
result = resource.attributes
|
19
36
|
result = result.merge(:_links => serialize_links(resource.links)) unless resource.links.empty?
|
20
37
|
result = result.merge(:_embedded => serialize_embedded(resource.subresources)) unless resource.subresources.empty?
|
@@ -37,7 +54,7 @@ module Yaks
|
|
37
54
|
memo[link.rel] = if singular?(link.rel)
|
38
55
|
hal_link
|
39
56
|
else
|
40
|
-
|
57
|
+
(memo[link.rel] || []) + [hal_link]
|
41
58
|
end
|
42
59
|
memo
|
43
60
|
end
|
data/lib/yaks/format/json_api.rb
CHANGED
@@ -2,8 +2,8 @@
|
|
2
2
|
|
3
3
|
module Yaks
|
4
4
|
class Format
|
5
|
-
class
|
6
|
-
|
5
|
+
class JsonAPI < self
|
6
|
+
register :json_api, :json, 'application/vnd.api+json'
|
7
7
|
|
8
8
|
include FP
|
9
9
|
|
@@ -40,7 +40,7 @@ module Yaks
|
|
40
40
|
# @return [Hash]
|
41
41
|
def serialize_links(subresources)
|
42
42
|
subresources.each_with_object({}) do |(_name, resource), hsh|
|
43
|
-
next if resource.
|
43
|
+
next if resource.instance_of? NullResource
|
44
44
|
key = resource.collection? ? pluralize(resource.type) : resource.type
|
45
45
|
hsh[key] = serialize_link(resource)
|
46
46
|
end
|
data/lib/yaks/format.rb
CHANGED
@@ -2,40 +2,85 @@ module Yaks
|
|
2
2
|
class Format
|
3
3
|
extend Forwardable
|
4
4
|
include Util
|
5
|
+
include FP::Callable
|
5
6
|
|
7
|
+
# @!attribute [r] options
|
8
|
+
# @return [Hash]
|
6
9
|
attr_reader :options
|
10
|
+
|
7
11
|
def_delegators :resource, :links, :attributes, :subresources
|
8
12
|
|
9
13
|
protected :links, :attributes, :subresources, :options
|
10
14
|
|
15
|
+
# @param [Hash] options
|
16
|
+
# @return [Hash]
|
11
17
|
def initialize(options = {})
|
12
18
|
@options = options
|
13
19
|
end
|
14
20
|
|
21
|
+
# @param [Yaks::Resource] resource
|
22
|
+
# @return [Hash]
|
15
23
|
def call(resource)
|
16
24
|
serialize_resource(resource)
|
17
25
|
end
|
18
26
|
alias serialize call
|
19
27
|
|
20
28
|
class << self
|
21
|
-
|
22
|
-
|
23
|
-
|
29
|
+
attr_reader :format_name, :serializer, :mime_type
|
30
|
+
|
31
|
+
def all
|
32
|
+
@formats ||= []
|
33
|
+
end
|
24
34
|
|
25
|
-
|
26
|
-
|
35
|
+
# @param [Constant] klass
|
36
|
+
# @param [Symbol] format_name
|
37
|
+
# @param [String] mime_type
|
38
|
+
# @return [Array]
|
39
|
+
def register(format_name, serializer, mime_type)
|
40
|
+
@format_name = format_name
|
41
|
+
@serializer = serializer
|
42
|
+
@mime_type = mime_type
|
43
|
+
|
44
|
+
Format.all << self
|
27
45
|
end
|
28
46
|
|
29
|
-
|
30
|
-
|
47
|
+
# @param [Symbol] format_name
|
48
|
+
# @return [Constant]
|
49
|
+
# @raise [KeyError]
|
50
|
+
def by_name(format_name)
|
51
|
+
find(:format_name, format_name)
|
31
52
|
end
|
32
53
|
|
54
|
+
# @param [Symbol] mime_type
|
55
|
+
# @return [Constant]
|
56
|
+
# @raise [KeyError]
|
33
57
|
def by_mime_type(mime_type)
|
34
|
-
|
58
|
+
find(:mime_type, mime_type)
|
59
|
+
end
|
60
|
+
|
61
|
+
def by_accept_header(accept_header)
|
62
|
+
mime_type = Rack::Accept::Charset.new(accept_header).best_of(mime_types.values)
|
63
|
+
if mime_type
|
64
|
+
by_mime_type(mime_type)
|
65
|
+
else
|
66
|
+
yield if block_given?
|
67
|
+
end
|
35
68
|
end
|
36
69
|
|
37
70
|
def mime_types
|
38
|
-
|
71
|
+
Format.all.each_with_object({}) do
|
72
|
+
|format, memo| memo[format.format_name] = format.mime_type
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def names
|
77
|
+
mime_types.keys
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def find(key, cond)
|
83
|
+
Format.all.detect {|format| format.send(key) == cond }
|
39
84
|
end
|
40
85
|
end
|
41
86
|
end
|
data/lib/yaks/fp/updatable.rb
CHANGED
data/lib/yaks/fp.rb
CHANGED
@@ -2,15 +2,23 @@ module Yaks
|
|
2
2
|
module FP
|
3
3
|
extend self
|
4
4
|
|
5
|
+
# @param [Symbol, String] name
|
6
|
+
# @return [Proc]
|
5
7
|
def curry_method(name)
|
6
8
|
method(name).to_proc.curry
|
7
9
|
end
|
8
10
|
|
11
|
+
|
12
|
+
# @return [Proc]
|
9
13
|
def identity_function
|
10
14
|
->(x) {x}
|
11
15
|
end
|
12
16
|
I = identity_function
|
13
17
|
|
18
|
+
# @param [Symbol] symbol
|
19
|
+
# @param [Array] args
|
20
|
+
# @param [Proc] blk
|
21
|
+
# @return [Proc]
|
14
22
|
def send_with_args(symbol, *args, &blk)
|
15
23
|
->(obj) { obj.method(symbol).(*args, &blk) }
|
16
24
|
end
|
data/lib/yaks/mapper/link.rb
CHANGED
@@ -57,7 +57,7 @@ module Yaks
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def expansion_mapping(lookup)
|
60
|
-
template_variables.
|
60
|
+
template_variables.each_with_object({}) do |name, hsh|
|
61
61
|
hsh[name] = lookup[name]
|
62
62
|
end
|
63
63
|
end
|
@@ -74,7 +74,7 @@ module Yaks
|
|
74
74
|
end
|
75
75
|
|
76
76
|
def expand_with(lookup)
|
77
|
-
return lookup[template] if template.
|
77
|
+
return lookup[template] if template.instance_of? Symbol
|
78
78
|
|
79
79
|
expand_partial(expansion_mapping(lookup)).to_s
|
80
80
|
end
|
data/lib/yaks/mapper.rb
CHANGED
@@ -55,20 +55,20 @@ module Yaks
|
|
55
55
|
private
|
56
56
|
|
57
57
|
def map_attributes(resource)
|
58
|
-
attributes.inject(resource) do |
|
59
|
-
attribute.add_to_resource(
|
58
|
+
attributes.inject(resource) do |res, attribute|
|
59
|
+
attribute.add_to_resource(res, self, context)
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
63
|
def map_links(resource)
|
64
|
-
links.inject(resource) do |
|
65
|
-
mapper_link.add_to_resource(
|
64
|
+
links.inject(resource) do |res, mapper_link|
|
65
|
+
mapper_link.add_to_resource(res, self, context)
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
69
|
def map_subresources(resource)
|
70
|
-
associations.inject(resource) do |
|
71
|
-
association.add_to_resource(
|
70
|
+
associations.inject(resource) do |res, association|
|
71
|
+
association.add_to_resource(res, self, context)
|
72
72
|
end
|
73
73
|
end
|
74
74
|
end
|
data/lib/yaks/primitivize.rb
CHANGED
@@ -22,7 +22,7 @@ module Yaks
|
|
22
22
|
|
23
23
|
def self.create
|
24
24
|
new.tap do |p|
|
25
|
-
p.map String,
|
25
|
+
p.map String, Numeric, true, false, nil do |object|
|
26
26
|
object
|
27
27
|
end
|
28
28
|
|
@@ -31,7 +31,7 @@ module Yaks
|
|
31
31
|
end
|
32
32
|
|
33
33
|
p.map Hash do |object|
|
34
|
-
object.to_enum
|
34
|
+
object.to_enum.with_object({}) do |(key, value), output|
|
35
35
|
output[call(key)] = call(value)
|
36
36
|
end
|
37
37
|
end
|
data/lib/yaks/resource/link.rb
CHANGED
data/lib/yaks/runner.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
module Yaks
|
2
|
+
class Runner
|
3
|
+
include Util
|
4
|
+
include Anima.new(:object, :config, :options)
|
5
|
+
include Adamantium::Flat
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
def_delegators :config, :policy, :default_format, :format_options, :primitivize, :serializers, :hooks
|
9
|
+
|
10
|
+
def call
|
11
|
+
steps.inject(object) {|memo, (_, step)| step.call(memo) }
|
12
|
+
end
|
13
|
+
|
14
|
+
def context
|
15
|
+
{
|
16
|
+
policy: policy,
|
17
|
+
env: env,
|
18
|
+
mapper_stack: []
|
19
|
+
}.merge(slice_hash(options, :item_mapper))
|
20
|
+
end
|
21
|
+
memoize :context, freezer: :flat
|
22
|
+
|
23
|
+
def env
|
24
|
+
options.fetch(:env, {})
|
25
|
+
end
|
26
|
+
memoize :env, freezer: :noop
|
27
|
+
|
28
|
+
# @return [Class]
|
29
|
+
def format_class
|
30
|
+
Format.by_accept_header(env['HTTP_ACCEPT']) {
|
31
|
+
Format.by_name(options.fetch(:format) { default_format })
|
32
|
+
}
|
33
|
+
end
|
34
|
+
memoize :format_class
|
35
|
+
|
36
|
+
def steps
|
37
|
+
insert_hooks(
|
38
|
+
[[ :map, mapper ],
|
39
|
+
[ :format, formatter ],
|
40
|
+
[ :primitivize, primitivize], # really a JSON-preprocessor, should be pulled out
|
41
|
+
[ :serialize, serializer ]])
|
42
|
+
end
|
43
|
+
memoize :steps
|
44
|
+
|
45
|
+
def mapper
|
46
|
+
options.fetch(:mapper) do
|
47
|
+
policy.derive_mapper_from_object(object)
|
48
|
+
end.new(context)
|
49
|
+
end
|
50
|
+
memoize :mapper, freezer: :noop
|
51
|
+
|
52
|
+
def formatter
|
53
|
+
format_class.new(format_options[format_name])
|
54
|
+
end
|
55
|
+
memoize :formatter
|
56
|
+
|
57
|
+
# @param [Hash] opts
|
58
|
+
# @return [String]
|
59
|
+
def format_name
|
60
|
+
options.fetch(:format) { default_format }
|
61
|
+
end
|
62
|
+
memoize :format_name
|
63
|
+
|
64
|
+
def serializer
|
65
|
+
serializers.fetch(format_class.serializer) do
|
66
|
+
policy.serializer_for_format(format_class)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
memoize :serializer
|
70
|
+
|
71
|
+
def insert_hooks(steps)
|
72
|
+
hooks.inject(steps) do |steps, (type, target_step, name, hook)|
|
73
|
+
steps.flat_map do |step_name, callable|
|
74
|
+
if step_name.eql? target_step
|
75
|
+
case type
|
76
|
+
when :before
|
77
|
+
[[name, hook], [step_name, callable]]
|
78
|
+
when :after
|
79
|
+
[[step_name, callable], [name, hook]]
|
80
|
+
when :around
|
81
|
+
[[step_name, ->(x) { hook.call(x, &callable) }]]
|
82
|
+
when :skip
|
83
|
+
[]
|
84
|
+
end
|
85
|
+
end || [[step_name, callable]]
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/lib/yaks/util.rb
CHANGED
@@ -18,6 +18,10 @@ module Yaks
|
|
18
18
|
.gsub!(/(?:^|_)(.)/) { $1.upcase }
|
19
19
|
end
|
20
20
|
|
21
|
+
def slice_hash(hash, *keys)
|
22
|
+
keys.each_with_object({}) {|k,dest| dest[k] = hash[k] if hash.key?(k) }
|
23
|
+
end
|
24
|
+
|
21
25
|
# Turn what is maybe a Proc into its result (or itself)
|
22
26
|
#
|
23
27
|
# When input can be either a value or a proc that returns a value,
|
data/lib/yaks/version.rb
CHANGED
data/lib/yaks.rb
CHANGED
@@ -4,6 +4,7 @@ require 'forwardable'
|
|
4
4
|
require 'set'
|
5
5
|
require 'pathname'
|
6
6
|
|
7
|
+
require 'anima'
|
7
8
|
require 'concord'
|
8
9
|
require 'inflection'
|
9
10
|
require 'uri_template'
|
@@ -13,6 +14,7 @@ require 'yaks/util'
|
|
13
14
|
require 'yaks/fp'
|
14
15
|
require 'yaks/fp/updatable'
|
15
16
|
require 'yaks/fp/hash_updatable'
|
17
|
+
require 'yaks/fp/callable'
|
16
18
|
require 'yaks/primitivize'
|
17
19
|
|
18
20
|
require 'yaks/default_policy'
|
@@ -57,3 +59,4 @@ require 'yaks/format/collection_json'
|
|
57
59
|
|
58
60
|
require 'yaks/config/dsl'
|
59
61
|
require 'yaks/config'
|
62
|
+
require 'yaks/runner'
|
@@ -7,6 +7,7 @@ RSpec.describe Yaks::Format::Hal do
|
|
7
7
|
yaks_rel_template = Yaks.new do
|
8
8
|
format_options :hal, plural_links: ['http://literature.example.com/rels/quotes']
|
9
9
|
rel_template "http://literature.example.com/rel/{association_name}"
|
10
|
+
skip :serialize
|
10
11
|
end
|
11
12
|
|
12
13
|
yaks_policy_dsl = Yaks.new do
|
@@ -14,15 +15,17 @@ RSpec.describe Yaks::Format::Hal do
|
|
14
15
|
derive_rel_from_association do |association|
|
15
16
|
"http://literature.example.com/rel/#{association.name}"
|
16
17
|
end
|
18
|
+
skip :serialize
|
17
19
|
end
|
18
20
|
|
19
21
|
include_examples 'JSON output format' , yaks_rel_template , :hal , 'confucius'
|
20
22
|
include_examples 'JSON output format' , yaks_policy_dsl , :hal , 'confucius'
|
21
23
|
end
|
22
24
|
|
23
|
-
RSpec.describe Yaks::Format::
|
25
|
+
RSpec.describe Yaks::Format::JsonAPI do
|
24
26
|
config = Yaks.new do
|
25
27
|
default_format :json_api
|
28
|
+
skip :serialize
|
26
29
|
end
|
27
30
|
|
28
31
|
include_examples 'JSON output format' , config , :json_api , 'confucius'
|
@@ -32,10 +35,12 @@ RSpec.describe Yaks::Format::CollectionJson do
|
|
32
35
|
youtypeit_yaks = Yaks.new do
|
33
36
|
default_format :collection_json
|
34
37
|
namespace Youtypeitwepostit
|
38
|
+
skip :serialize
|
35
39
|
end
|
36
40
|
|
37
41
|
confucius_yaks = Yaks.new do
|
38
42
|
default_format :collection_json
|
43
|
+
skip :serialize
|
39
44
|
end
|
40
45
|
|
41
46
|
include_examples 'JSON output format', youtypeit_yaks, :collection, 'youtypeitwepostit'
|
@@ -6,22 +6,10 @@
|
|
6
6
|
{
|
7
7
|
"href": "http://literature.example.com/authors/kongzi",
|
8
8
|
"data": [
|
9
|
-
{
|
10
|
-
|
11
|
-
|
12
|
-
}
|
13
|
-
{
|
14
|
-
"name": "name",
|
15
|
-
"value": "孔子"
|
16
|
-
},
|
17
|
-
{
|
18
|
-
"name": "pinyin",
|
19
|
-
"value": "Kongzi"
|
20
|
-
},
|
21
|
-
{
|
22
|
-
"name": "latinized",
|
23
|
-
"value": "Confucius"
|
24
|
-
}
|
9
|
+
{ "name": "id", "value": 9 },
|
10
|
+
{ "name": "name", "value": "孔子" },
|
11
|
+
{ "name": "pinyin", "value": "Kongzi" },
|
12
|
+
{ "name": "latinized", "value": "Confucius" }
|
25
13
|
],
|
26
14
|
"links": [
|
27
15
|
{
|
@@ -29,6 +17,7 @@
|
|
29
17
|
"href": "http://literature.example.com/profiles/scholar"
|
30
18
|
},
|
31
19
|
{
|
20
|
+
"name": "Search for quotes",
|
32
21
|
"rel": "http://literature.example.com/rels/quotes",
|
33
22
|
"href": "http://literature.example.com/quotes/?author=kongzi&q={query}"
|
34
23
|
}
|
@@ -0,0 +1,32 @@
|
|
1
|
+
{
|
2
|
+
"collection": {
|
3
|
+
"version": "1.0",
|
4
|
+
"href": "http://api.example.com/plants",
|
5
|
+
"items": [
|
6
|
+
{
|
7
|
+
"href": "http://api.example.com/plants/7/plain_grass",
|
8
|
+
"data": [ { "name": "name", "value": "Plain grass" },
|
9
|
+
{ "name": "type", "value": "grass" } ],
|
10
|
+
"links": [
|
11
|
+
{ "rel": "profile", "href": "http://api.example.com/doc/plant" }
|
12
|
+
]
|
13
|
+
},
|
14
|
+
{
|
15
|
+
"href": "http://api.example.com/plants/15/oak",
|
16
|
+
"data": [ { "name": "name", "value": "Oak" },
|
17
|
+
{ "name": "type", "value": "tree" } ],
|
18
|
+
"links": [
|
19
|
+
{ "rel": "profile", "href": "http://api.example.com/doc/plant" }
|
20
|
+
]
|
21
|
+
},
|
22
|
+
{
|
23
|
+
"href": "http://api.example.com/plants/33/passiflora",
|
24
|
+
"data": [ { "name": "name", "value": "Passiflora" },
|
25
|
+
{ "name": "type", "value": "flower" } ],
|
26
|
+
"links": [
|
27
|
+
{ "rel": "profile", "href": "http://api.example.com/doc/plant" }
|
28
|
+
]
|
29
|
+
}
|
30
|
+
]
|
31
|
+
}
|
32
|
+
}
|
data/spec/spec_helper.rb
CHANGED
@@ -20,10 +20,11 @@ require_relative 'support/classes_for_policy_testing'
|
|
20
20
|
RSpec.configure do |rspec|
|
21
21
|
rspec.include FixtureHelpers
|
22
22
|
rspec.backtrace_exclusion_patterns = [] if ENV['FULLSTACK']
|
23
|
-
|
23
|
+
rspec.disable_monkey_patching!
|
24
24
|
rspec.raise_errors_for_deprecations!
|
25
25
|
end
|
26
26
|
|
27
27
|
Bogus.configure do |bogus|
|
28
28
|
bogus.search_modules << Yaks
|
29
|
+
bogus.search_modules << Yaks::Mapper
|
29
30
|
end
|