yaks 0.4.4 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|