yaks 0.7.6 → 0.7.7
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/README.md +17 -0
- data/Rakefile +58 -38
- data/lib/yaks.rb +3 -4
- data/lib/yaks/attributes.rb +23 -10
- data/lib/yaks/config.rb +4 -0
- data/lib/yaks/configurable.rb +16 -21
- data/lib/yaks/format.rb +1 -1
- data/lib/yaks/format/collection_json.rb +9 -0
- data/lib/yaks/format/halo.rb +16 -13
- data/lib/yaks/html5_forms.rb +22 -1
- data/lib/yaks/mapper.rb +5 -5
- data/lib/yaks/mapper/attribute.rb +1 -1
- data/lib/yaks/mapper/class_methods.rb +3 -1
- data/lib/yaks/mapper/config.rb +9 -16
- data/lib/yaks/mapper/form.rb +41 -0
- data/lib/yaks/mapper/form/field.rb +62 -0
- data/lib/yaks/null_resource.rb +1 -1
- data/lib/yaks/resource.rb +7 -3
- data/lib/yaks/resource/form.rb +31 -0
- data/lib/yaks/runner.rb +11 -11
- data/lib/yaks/stateful_builder.rb +11 -7
- data/lib/yaks/util.rb +3 -2
- data/lib/yaks/version.rb +1 -1
- data/spec/acceptance/models.rb +1 -1
- data/spec/json/confucius.halo.json +2 -4
- data/spec/json/plant_collection.collection.json +4 -0
- data/spec/unit/yaks/attributes_spec.rb +79 -0
- data/spec/unit/yaks/configurable_spec.rb +32 -2
- data/spec/unit/yaks/format/collection_json_spec.rb +59 -27
- data/spec/unit/yaks/format/halo_spec.rb +3 -0
- data/spec/unit/yaks/mapper/{control → form}/field_spec.rb +3 -3
- data/spec/unit/yaks/mapper/{control_spec.rb → form_spec.rb} +12 -12
- data/spec/unit/yaks/mapper_spec.rb +10 -10
- data/spec/unit/yaks/null_resource_spec.rb +50 -7
- data/spec/unit/yaks/resource_spec.rb +4 -4
- data/spec/unit/yaks/runner_spec.rb +38 -2
- data/spec/unit/yaks/util_spec.rb +42 -0
- metadata +20 -58
- data/lib/yaks/mapper/control.rb +0 -82
- data/lib/yaks/resource/control.rb +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 207388cedc68055dcef4f732bd82ce81180871c8
|
4
|
+
data.tar.gz: 97c121f6e231e8a409d1b2bca7515d75f42d261a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fd61481333faaccde1120268996ab50462dcfd2c04f0b08e9340300ad6567a7bf47d59eae2b36471d9661cb9c020304566df8267c3c19f262a77346b7924504e
|
7
|
+
data.tar.gz: 3acfcdfa41752e295833ca61052fbad706e51bae6132eb7f72350bbfd5db1e0d6fa42d1338059d6fa758396d48d417f2c699a8fcfc40888074afde7189c03dfb
|
data/README.md
CHANGED
@@ -23,6 +23,23 @@ requested. These formats are presently supported:
|
|
23
23
|
* HTML
|
24
24
|
* HALO
|
25
25
|
|
26
|
+
## State of Development
|
27
|
+
|
28
|
+
This library came into existence because we at
|
29
|
+
[Ticketsolve](https://www.ticketsolve.com) wanted to build a rich
|
30
|
+
hypermedia API, and were dissatisfied with any of the existing Ruby
|
31
|
+
solutions at the time (November 2013).
|
32
|
+
|
33
|
+
We are still actively expanding our API, and with that Yaks continues
|
34
|
+
to grow and improve. The aim is to create *the reference* for
|
35
|
+
supporting hypermedia formats in Ruby.
|
36
|
+
|
37
|
+
Yaks can be used in production today, as we do, but until 1.0 is
|
38
|
+
released there will regularly be breaking changes, as we figure out
|
39
|
+
the best way to do things. These are all documented clearly in the
|
40
|
+
[changelog](CHANGLOG.md). At this point we recommend locking to an
|
41
|
+
exact version number.
|
42
|
+
|
26
43
|
## Concepts
|
27
44
|
|
28
45
|
Yaks is a processing pipeline, you create and configure the pipeline,
|
data/Rakefile
CHANGED
@@ -2,49 +2,69 @@ load '../rakelib/shared.rake'
|
|
2
2
|
|
3
3
|
gem_tasks(:yaks)
|
4
4
|
|
5
|
-
|
6
5
|
task :mutant_chunked do
|
6
|
+
# No subjects:
|
7
|
+
# Yaks,
|
8
|
+
# Yaks::Error,
|
9
|
+
# Yaks::IllegalStateError,
|
10
|
+
# Yaks::UnsupportedOperationError,
|
11
|
+
# Yaks::PrimitivizeError,
|
12
|
+
# Yaks::Undefined,
|
13
|
+
# Yaks::HTML5Forms,
|
14
|
+
|
15
|
+
# Hangs:
|
16
|
+
# Yaks::Changelog,
|
17
|
+
|
18
|
+
# 100% verified:
|
19
|
+
# Yaks::Util,
|
20
|
+
# Yaks::Util::Deprecated,
|
21
|
+
# Yaks::FP
|
22
|
+
# Yaks::FP::Callable,
|
23
|
+
# Yaks::DefaultPolicy,
|
24
|
+
# Yaks::Mapper::HasOne,
|
25
|
+
# Yaks::Mapper::HasMany,
|
26
|
+
# Yaks::Mapper::Attribute,
|
27
|
+
# Yaks::Mapper::Config,
|
28
|
+
# Yaks::Mapper::ClassMethods,
|
29
|
+
# Yaks::Mapper::AssociationMapper,
|
30
|
+
# Yaks::Format::CollectionJson,
|
31
|
+
# Yaks::Config,
|
32
|
+
# Yaks::Config::DSL,
|
33
|
+
# Yaks::Attributes::InstanceMethods,
|
34
|
+
# Yaks::Configurable,
|
35
|
+
# Yaks::NullResource,
|
36
|
+
|
7
37
|
[
|
8
|
-
Yaks::
|
9
|
-
Yaks::
|
10
|
-
Yaks::
|
11
|
-
Yaks::
|
12
|
-
Yaks::
|
13
|
-
Yaks::
|
14
|
-
Yaks::
|
15
|
-
Yaks::
|
16
|
-
Yaks::
|
17
|
-
Yaks::
|
18
|
-
Yaks::
|
19
|
-
Yaks::
|
20
|
-
Yaks::
|
21
|
-
Yaks::
|
22
|
-
Yaks::
|
23
|
-
Yaks::
|
24
|
-
Yaks::Format::JsonAPI,
|
25
|
-
Yaks::
|
26
|
-
Yaks::
|
27
|
-
Yaks::
|
28
|
-
Yaks::Mapper::
|
29
|
-
Yaks::
|
30
|
-
Yaks::
|
31
|
-
Yaks::
|
32
|
-
Yaks::
|
33
|
-
Yaks::
|
34
|
-
Yaks::Runner,
|
35
|
-
Yaks::Mapper::Link,
|
36
|
-
Yaks::Mapper::HasMany,
|
37
|
-
Yaks::Mapper::ClassMethods,
|
38
|
-
Yaks::Mapper::Association,
|
39
|
-
Yaks::Mapper,
|
40
|
-
Yaks::Format::HTML,
|
41
|
-
Yaks::Mapper::Control,
|
42
|
-
Yaks::Mapper::Control::Field,
|
43
|
-
# Yaks::Resource::Control, #no subjects to mutate
|
44
|
-
Yaks::NullResource,
|
38
|
+
# Yaks::Resource::Form, # no explicit coverage
|
39
|
+
# Yaks::Resource::Form::Field, # no explicit coverage
|
40
|
+
# Yaks::Mapper::Form::Field::Option, # no explicit coverage
|
41
|
+
# Yaks::Format::HTML, # no explicit coverage
|
42
|
+
Yaks::Runner, # 56/509 # 89.55%
|
43
|
+
Yaks::Resource, # 35/206 # 83.01%
|
44
|
+
Yaks::StatefulBuilder, # 25/192 # 86.98%
|
45
|
+
Yaks::Format::Halo, # 24/232 # 89.66%
|
46
|
+
Yaks::Mapper, # 15/482 # 96.89%
|
47
|
+
Yaks::Resource::Link, # 13/43 # 69.77%
|
48
|
+
Yaks::Mapper::Form::Field, # 11/155 # 92.90%
|
49
|
+
Yaks::Mapper::Link, # 10/357 # 97.20%
|
50
|
+
Yaks::CollectionMapper, # 7/217 # 96.77%
|
51
|
+
Yaks::Primitivize, # 3/239 # 98.74%
|
52
|
+
Yaks::Mapper::Form, # 3/179 # 98.32%
|
53
|
+
Yaks::CollectionResource, # 3/9 # 66.67%
|
54
|
+
Yaks::Format::JsonAPI, # 3/435 # 99.31%
|
55
|
+
Yaks::Format, # 2/29 # 93.10%
|
56
|
+
Yaks::Attributes, # 1/239 # 99.57%
|
57
|
+
Yaks::StatefulBuilder::StatefulMethods, # 1/66 # 98.49%
|
58
|
+
Yaks::Mapper::Association, # 1/222 # 99.55%
|
59
|
+
Yaks::Serializer, # 1/74 # 98.65%
|
60
|
+
Yaks::Format::Hal, # 1/328 # 99.70%
|
61
|
+
# Yaks::Format::Transit, # no explicit coverage
|
62
|
+
# Yaks::Format::Transit::WriteHandler, # no explicit coverage
|
63
|
+
# Yaks::Format::Transit::ReadHandler, # no explicit coverage
|
45
64
|
].each do |space|
|
46
65
|
puts space
|
47
66
|
ENV['PATTERN'] = "#{space}"
|
48
67
|
Rake::Task["mutant"].execute
|
68
|
+
break
|
49
69
|
end
|
50
70
|
end
|
data/lib/yaks.rb
CHANGED
@@ -36,10 +36,8 @@ module Yaks
|
|
36
36
|
Yaks::Config.new(&blk)
|
37
37
|
end
|
38
38
|
end
|
39
|
-
|
40
39
|
end
|
41
40
|
|
42
|
-
|
43
41
|
require 'yaks/resource'
|
44
42
|
require 'yaks/null_resource'
|
45
43
|
require 'yaks/resource/link'
|
@@ -52,14 +50,15 @@ require 'yaks/mapper/has_one'
|
|
52
50
|
require 'yaks/mapper/has_many'
|
53
51
|
require 'yaks/mapper/attribute'
|
54
52
|
require 'yaks/mapper/link'
|
55
|
-
require 'yaks/mapper/
|
53
|
+
require 'yaks/mapper/form'
|
54
|
+
require 'yaks/mapper/form/field'
|
56
55
|
require 'yaks/mapper/config'
|
57
56
|
require 'yaks/mapper/class_methods'
|
58
57
|
require 'yaks/mapper'
|
59
58
|
require 'yaks/mapper/association_mapper'
|
60
59
|
require 'yaks/collection_mapper'
|
61
60
|
|
62
|
-
require 'yaks/resource/
|
61
|
+
require 'yaks/resource/form'
|
63
62
|
|
64
63
|
require 'yaks/serializer'
|
65
64
|
|
data/lib/yaks/attributes.rb
CHANGED
@@ -1,24 +1,24 @@
|
|
1
1
|
module Yaks
|
2
2
|
class Attributes < Module
|
3
|
-
attr_reader :defaults, :
|
3
|
+
attr_reader :defaults, :names
|
4
4
|
|
5
5
|
def initialize(*attrs)
|
6
6
|
@defaults = attrs.last.instance_of?(Hash) ? attrs.pop : {}
|
7
|
-
@
|
7
|
+
@names = (attrs + @defaults.keys).uniq
|
8
8
|
end
|
9
9
|
|
10
10
|
def add(*attrs)
|
11
11
|
defaults = attrs.last.instance_of?(Hash) ? attrs.pop : {}
|
12
|
-
self.class.new(*[*(
|
12
|
+
self.class.new(*[*(names+attrs), @defaults.merge(defaults)])
|
13
13
|
end
|
14
14
|
|
15
15
|
def included(descendant)
|
16
16
|
descendant.module_exec(self) do |this|
|
17
17
|
include InstanceMethods,
|
18
|
-
Anima.new(*this.
|
18
|
+
Anima.new(*this.names),
|
19
19
|
Anima::Update
|
20
20
|
|
21
|
-
this.
|
21
|
+
this.names.each do |attr|
|
22
22
|
define_method attr do |value = Undefined|
|
23
23
|
if value.equal? Undefined
|
24
24
|
instance_variable_get("@#{attr}")
|
@@ -45,12 +45,16 @@ module Yaks
|
|
45
45
|
indent = ->(str) { str.lines.map {|l| " #{l}"}.join }
|
46
46
|
format = ->(val) { val.respond_to?(:pp) ? val.pp : val.inspect }
|
47
47
|
|
48
|
-
|
49
|
-
|
48
|
+
defaults = self.class.attributes.defaults
|
49
|
+
values = to_h.reject do |attr, value|
|
50
|
+
value.equal?(defaults[attr])
|
51
|
+
end
|
52
|
+
|
53
|
+
fmt_attrs = values.map do |attr, value|
|
50
54
|
fmt_val = case value
|
51
55
|
when Array
|
52
56
|
if value.inspect.length < 50
|
53
|
-
value.
|
57
|
+
"[#{value.map(&format).join(", ")}]"
|
54
58
|
else
|
55
59
|
"[\n#{indent[value.map(&format).join(",\n")]}\n]"
|
56
60
|
end
|
@@ -58,9 +62,18 @@ module Yaks
|
|
58
62
|
format[value]
|
59
63
|
end
|
60
64
|
"#{attr}: #{fmt_val}"
|
61
|
-
end
|
65
|
+
end
|
66
|
+
|
67
|
+
fmt_attrs_str = fmt_attrs.join(", ")
|
62
68
|
|
63
|
-
|
69
|
+
if fmt_attrs_str.length > 50
|
70
|
+
fmt_attrs_str = fmt_attrs.join(",\n")
|
71
|
+
end
|
72
|
+
|
73
|
+
if fmt_attrs_str =~ /\n/
|
74
|
+
fmt_attrs_str = "\n#{indent[fmt_attrs_str]}\n"
|
75
|
+
end
|
76
|
+
"#{self.class.name}.new(#{fmt_attrs_str})"
|
64
77
|
end
|
65
78
|
end
|
66
79
|
end
|
data/lib/yaks/config.rb
CHANGED
data/lib/yaks/configurable.rb
CHANGED
@@ -1,27 +1,22 @@
|
|
1
1
|
module Yaks
|
2
2
|
module Configurable
|
3
|
-
def
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
def config_method(name, options)
|
4
|
+
define_method name do |*args, &block|
|
5
|
+
defaults = options.fetch(:defaults, {})
|
6
|
+
klass = options.fetch(:create)
|
7
|
+
|
8
|
+
instance = if args.length.equal?(1) && args.first.instance_of?(klass)
|
9
|
+
args.first
|
10
|
+
else
|
11
|
+
if args.last.instance_of?(Hash)
|
12
|
+
args[-1] = defaults.merge(args[-1])
|
13
|
+
else
|
14
|
+
args << defaults
|
15
|
+
end
|
16
|
+
klass.create(*args, &block)
|
17
|
+
end
|
8
18
|
|
9
|
-
|
10
|
-
def config_method(name, options)
|
11
|
-
define_method name do |*args, &block|
|
12
|
-
defaults = options[:defaults]
|
13
|
-
if defaults
|
14
|
-
if args.last.is_a? Hash
|
15
|
-
args[-1] = defaults.merge(args[-1])
|
16
|
-
else
|
17
|
-
args << defaults
|
18
|
-
end
|
19
|
-
end
|
20
|
-
append_to(
|
21
|
-
options.fetch(:append_to),
|
22
|
-
options.fetch(:create).create(*args, &block)
|
23
|
-
)
|
24
|
-
end
|
19
|
+
append_to(options.fetch(:append_to), instance)
|
25
20
|
end
|
26
21
|
end
|
27
22
|
end
|
data/lib/yaks/format.rb
CHANGED
@@ -13,6 +13,7 @@ module Yaks
|
|
13
13
|
items: serialize_items(resource)
|
14
14
|
}
|
15
15
|
result[:href] = resource.self_link.uri if resource.self_link
|
16
|
+
result[:links] = serialize_links(resource) if resource.collection? && resource.links.any?
|
16
17
|
{collection: result}
|
17
18
|
end
|
18
19
|
|
@@ -37,6 +38,14 @@ module Yaks
|
|
37
38
|
result
|
38
39
|
end
|
39
40
|
end
|
41
|
+
|
42
|
+
def serialize_links(resource)
|
43
|
+
result = []
|
44
|
+
resource.links.each do |link|
|
45
|
+
result << {href: link.uri, rel: link.rel}
|
46
|
+
end
|
47
|
+
result
|
48
|
+
end
|
40
49
|
end
|
41
50
|
end
|
42
51
|
end
|
data/lib/yaks/format/halo.rb
CHANGED
@@ -8,28 +8,31 @@ module Yaks
|
|
8
8
|
register :halo, :json, 'application/halo+json'
|
9
9
|
|
10
10
|
def serialize_resource(resource)
|
11
|
-
if resource.
|
12
|
-
super.merge(_controls:
|
11
|
+
if resource.forms.any?
|
12
|
+
super.merge(_controls: serialize_forms(resource.forms))
|
13
13
|
else
|
14
14
|
super
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
def
|
19
|
-
|
20
|
-
result[
|
18
|
+
def serialize_forms(forms)
|
19
|
+
forms.each_with_object({}) do |form, result|
|
20
|
+
result[form.name] = serialize_form(form)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
def
|
25
|
-
raw =
|
24
|
+
def serialize_form(form)
|
25
|
+
raw = form.to_h
|
26
26
|
raw[:href] = raw.delete(:action)
|
27
|
-
raw[:fields] =
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
27
|
+
raw[:fields] = form.fields.map do |field|
|
28
|
+
field.to_h.each_with_object({}) do |(attr,value), hsh|
|
29
|
+
if attr == :options
|
30
|
+
if !value.empty?
|
31
|
+
hsh[:options] = value.map(&:to_h)
|
32
|
+
end
|
33
|
+
elsif HTML5Forms::FIELD_OPTIONS[attr] != value
|
34
|
+
hsh[attr] = value
|
35
|
+
end
|
33
36
|
end
|
34
37
|
end
|
35
38
|
raw
|
data/lib/yaks/html5_forms.rb
CHANGED
@@ -28,8 +28,29 @@ module Yaks
|
|
28
28
|
:url,
|
29
29
|
:week,
|
30
30
|
|
31
|
-
:select
|
31
|
+
:select,
|
32
|
+
:textarea,
|
33
|
+
:datalist
|
32
34
|
]
|
33
35
|
|
36
|
+
FIELD_OPTIONS = {
|
37
|
+
required: false,
|
38
|
+
rows: nil,
|
39
|
+
type: nil,
|
40
|
+
value: nil,
|
41
|
+
pattern: nil,
|
42
|
+
maxlength: nil,
|
43
|
+
minlength: 0,
|
44
|
+
size: 20,
|
45
|
+
readonly: false,
|
46
|
+
multiple: false,
|
47
|
+
min: nil,
|
48
|
+
max: nil,
|
49
|
+
step: nil,
|
50
|
+
list: nil,
|
51
|
+
placeholder: nil,
|
52
|
+
checked: false
|
53
|
+
}
|
54
|
+
|
34
55
|
end
|
35
56
|
end
|
data/lib/yaks/mapper.rb
CHANGED
@@ -6,7 +6,7 @@ module Yaks
|
|
6
6
|
include Util, FP, FP::Callable
|
7
7
|
|
8
8
|
def_delegators 'self.class', :config
|
9
|
-
def_delegators :config, :attributes, :links, :associations, :
|
9
|
+
def_delegators :config, :attributes, :links, :associations, :forms
|
10
10
|
|
11
11
|
config Config.new
|
12
12
|
|
@@ -44,7 +44,7 @@ module Yaks
|
|
44
44
|
[ :map_attributes,
|
45
45
|
:map_links,
|
46
46
|
:map_subresources,
|
47
|
-
:
|
47
|
+
:map_forms
|
48
48
|
].inject(Resource.new(type: mapper_name)) do |resource, method|
|
49
49
|
send(method, resource)
|
50
50
|
end
|
@@ -100,9 +100,9 @@ module Yaks
|
|
100
100
|
end
|
101
101
|
end
|
102
102
|
|
103
|
-
def
|
104
|
-
|
105
|
-
|
103
|
+
def map_forms(resource)
|
104
|
+
forms.inject(resource) do |res, form|
|
105
|
+
form.add_to_resource(res, self, context)
|
106
106
|
end
|
107
107
|
end
|
108
108
|
end
|