yaks 0.4.4 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/CHANGELOG.md +44 -3
  4. data/README.md +90 -33
  5. data/Rakefile +10 -0
  6. data/bench/bench.rb +0 -1
  7. data/bench/bench_1000.rb +60 -0
  8. data/lib/yaks/breaking_changes.rb +22 -0
  9. data/lib/yaks/config/dsl.rb +114 -27
  10. data/lib/yaks/config.rb +39 -54
  11. data/lib/yaks/default_policy.rb +32 -14
  12. data/lib/yaks/format/collection_json.rb +4 -4
  13. data/lib/yaks/format/hal.rb +20 -3
  14. data/lib/yaks/format/json_api.rb +3 -3
  15. data/lib/yaks/format.rb +54 -9
  16. data/lib/yaks/fp/callable.rb +9 -0
  17. data/lib/yaks/fp/hash_updatable.rb +2 -0
  18. data/lib/yaks/fp/updatable.rb +2 -0
  19. data/lib/yaks/fp.rb +8 -0
  20. data/lib/yaks/mapper/link.rb +2 -2
  21. data/lib/yaks/mapper.rb +6 -6
  22. data/lib/yaks/primitivize.rb +2 -2
  23. data/lib/yaks/resource/link.rb +0 -4
  24. data/lib/yaks/runner.rb +90 -0
  25. data/lib/yaks/util.rb +4 -0
  26. data/lib/yaks/version.rb +1 -1
  27. data/lib/yaks.rb +3 -0
  28. data/spec/acceptance/acceptance_spec.rb +6 -1
  29. data/spec/json/confucius.collection.json +5 -16
  30. data/spec/json/plant_collection.collection.json +32 -0
  31. data/spec/spec_helper.rb +2 -1
  32. data/spec/support/deep_eql.rb +14 -7
  33. data/spec/support/pet_mapper.rb +0 -2
  34. data/spec/unit/yaks/collection_mapper_spec.rb +24 -2
  35. data/spec/unit/yaks/config/dsl_spec.rb +6 -10
  36. data/spec/unit/yaks/config_spec.rb +40 -99
  37. data/spec/unit/yaks/default_policy_spec.rb +20 -0
  38. data/spec/unit/yaks/format/collection_json_spec.rb +41 -0
  39. data/spec/unit/yaks/format/hal_spec.rb +38 -3
  40. data/spec/unit/yaks/format/json_api_spec.rb +2 -2
  41. data/spec/unit/yaks/format_spec.rb +28 -3
  42. data/spec/unit/yaks/fp/callable_spec.rb +13 -0
  43. data/spec/unit/yaks/mapper_spec.rb +226 -126
  44. data/spec/unit/yaks/resource/link_spec.rb +2 -3
  45. data/spec/unit/yaks/resource_spec.rb +15 -0
  46. data/spec/unit/yaks/runner_spec.rb +260 -0
  47. data/spec/unit/yaks/util_spec.rb +7 -1
  48. data/yaks.gemspec +4 -1
  49. metadata +72 -15
  50. /data/spec/json/{hal_plant_collection.json → plant_collection.hal.json} +0 -0
@@ -8,23 +8,19 @@ module Yaks
8
8
  namespace: Kernel
9
9
  }
10
10
 
11
- # @!attribute [r] options
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] model
22
- # @return [Yaks::CollectionMapper, Yaks::Mapper]
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
- # @param [Class] mapper_class
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
- # @param [Yaks::Mapper::Association] association
55
- # @return [Class] of subclass Yaks::Mapper
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] 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] relname
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
- Format.register self, :collection_json, 'application/vnd.collection+json'
4
+ register :collection_json, :json, 'application/vnd.collection+json'
5
5
 
6
6
  include FP
7
7
 
8
- # @param [Yaks:Resource] resource
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 == :self
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.name if link.name
35
+ result[:links].last[:name] = link.title if link.title
36
36
  end
37
37
  result
38
38
  end
@@ -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
- Format.register self, :hal, 'application/hal+json'
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
- Array(memo[link.rel]) + [hal_link]
57
+ (memo[link.rel] || []) + [hal_link]
41
58
  end
42
59
  memo
43
60
  end
@@ -2,8 +2,8 @@
2
2
 
3
3
  module Yaks
4
4
  class Format
5
- class JsonApi < self
6
- Format.register self, :json_api, 'application/vnd.api+json'
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.is_a? NullResource
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
- def register(klass, name, mime_type)
22
- @formats ||= {}
23
- @formats[name] = klass
29
+ attr_reader :format_name, :serializer, :mime_type
30
+
31
+ def all
32
+ @formats ||= []
33
+ end
24
34
 
25
- @mime_types ||= {}
26
- @mime_types[mime_type] = [name, klass]
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
- def by_name(name)
30
- @formats.fetch(name)
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
- @mime_types.fetch(mime_type)[1]
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
- @mime_types.inject({}) {|memo, (mime_type, (name, _))| memo[name] = mime_type ; memo }
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
@@ -0,0 +1,9 @@
1
+ module Yaks
2
+ module FP
3
+ module Callable
4
+ def to_proc
5
+ method(:call).to_proc
6
+ end
7
+ end
8
+ end
9
+ end
@@ -2,6 +2,8 @@ module Yaks
2
2
  module FP
3
3
 
4
4
  class HashUpdatable < Module
5
+ # @param [Array] attributes
6
+ # @return [Symbol]
5
7
  def initialize(*attributes)
6
8
  define_method :update do |updates|
7
9
  self.class.new(
@@ -2,6 +2,8 @@ module Yaks
2
2
  module FP
3
3
 
4
4
  class Updatable < Module
5
+ # @param [Array] attributes
6
+ # @return [Symbol]
5
7
  def initialize(*attributes)
6
8
  define_method :update do |updates|
7
9
  self.class.new(
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
@@ -57,7 +57,7 @@ module Yaks
57
57
  end
58
58
 
59
59
  def expansion_mapping(lookup)
60
- template_variables.map.with_object({}) do |name, hsh|
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.is_a? Symbol
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 |resource, attribute|
59
- attribute.add_to_resource(resource, self, context)
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 |resource, mapper_link|
65
- mapper_link.add_to_resource(resource, self, context)
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 |resource, association|
71
- association.add_to_resource( resource, self, context)
70
+ associations.inject(resource) do |res, association|
71
+ association.add_to_resource(res, self, context)
72
72
  end
73
73
  end
74
74
  end
@@ -22,7 +22,7 @@ module Yaks
22
22
 
23
23
  def self.create
24
24
  new.tap do |p|
25
- p.map String, TrueClass, FalseClass, NilClass, Numeric do |object|
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(:each).with_object({}) do |(key, value), output|
34
+ object.to_enum.with_object({}) do |(key, value), output|
35
35
  output[call(key)] = call(value)
36
36
  end
37
37
  end
@@ -9,10 +9,6 @@ module Yaks
9
9
  @rel, @uri, @options = rel, uri, options
10
10
  end
11
11
 
12
- def name
13
- options[:name]
14
- end
15
-
16
12
  def title
17
13
  options[:title]
18
14
  end
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Yaks
2
- VERSION = '0.4.4'
2
+ VERSION = '0.5.0'
3
3
  end
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::JsonApi do
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
- "name": "id",
11
- "value": 9
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
- #rspec.disable_monkey_patching!
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