halogen 0.0.2 → 0.0.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ecf269aadcd3040623710454934d01055e58f022
4
- data.tar.gz: c389775b46ff5daabf1bb4ccaae8b4967f4eaf89
3
+ metadata.gz: 03f1c7cbbf77576c156629d55eb72a584853202d
4
+ data.tar.gz: b58d6a047ada10cbf8420c58c5d10834a054023f
5
5
  SHA512:
6
- metadata.gz: f9ae4d73ca13c7ad45c68c718a527111b522adcc9b02772d641403edb9e642c564afd0a5172b2cb6908c034a35059a03f143555af0a812ad2a97e488529d67c9
7
- data.tar.gz: a36c479ad935f1f2d74df13f14afb7652630dc6a9ca37b652cbf64499f2198b3afc839889f4c7328f0eb154b3265180b26799f065c60827ac4a447a4e767f256
6
+ metadata.gz: c18323cfdca7e3611c12a98d90b98447554fc7910f6db87a476051e79f48bad919757b5f885c2448584178f788783cf370068216ce82ca13169d373a8f6cfccd
7
+ data.tar.gz: 7e72385b86d49fccb69ffded60a2ee5fde898423d25f4339aef5b690354e8b0ddd81e315ec3f809df0e8ee6d9c6d2014cf64bc9bfca3adfd795fb76d85b5ff62
data/Gemfile CHANGED
@@ -1,4 +1,3 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in halogen.gemspec
4
3
  gemspec
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # Halogen
2
2
 
3
3
  [![Code Climate](https://codeclimate.com/repos/552430af695680100500b659/badges/cdae8d5a10147d135be9/gpa.svg)](https://codeclimate.com/repos/552430af695680100500b659/feed)
4
+ [![Build Status](https://travis-ci.org/mode/halogen.svg?branch=master)](https://travis-ci.org/mode/halogen)
5
+ [![Gem Version](https://badge.fury.io/rb/halogen.svg)](http://badge.fury.io/rb/halogen)
4
6
 
5
7
  This library provides a framework-agnostic interface for generating
6
8
  [HAL+JSON](http://stateless.co/hal_specification.html)
@@ -30,14 +30,14 @@ module Halogen
30
30
  end
31
31
 
32
32
  module InstanceMethods # :nodoc:
33
- # Override super to ensure that the primary collection is always embedded
33
+ # Ensure that the primary collection is always embedded
34
34
  #
35
35
  # @param key [String] the embed key to check
36
36
  #
37
37
  # @return [true, false] whether the given key should be embedded
38
38
  #
39
39
  def embed?(key)
40
- super || key == self.class.collection_name
40
+ key == self.class.collection_name
41
41
  end
42
42
  end
43
43
  end
@@ -30,8 +30,6 @@ module Halogen
30
30
  #
31
31
  def embedded
32
32
  render_definitions(Definition.name) do |definition, result|
33
- next unless embed?(definition.name.to_s)
34
-
35
33
  value = instance_eval(&definition.procedure)
36
34
 
37
35
  child = embedded_child(definition.name.to_s, value)
@@ -40,8 +38,8 @@ module Halogen
40
38
  end
41
39
  end
42
40
 
43
- # @return [Hash, Array<Hash>] either a single rendered child representer
44
- # or an array of them
41
+ # @return [nil, Hash, Array<Hash>] either a single rendered child
42
+ # representer or an array of them
45
43
  #
46
44
  def embedded_child(key, value)
47
45
  return unless value
@@ -87,20 +85,10 @@ module Halogen
87
85
  # @return [Hash] hash of options with top level string keys
88
86
  #
89
87
  def embed_options
90
- options.fetch(:embed, {}).tap do |result|
88
+ @_embed_options ||= options.fetch(:embed, {}).tap do |result|
91
89
  Halogen::HashUtil.stringify_keys!(result)
92
90
  end
93
91
  end
94
-
95
- # @param key [String]
96
- #
97
- # @return [true, false] whether to embed the key
98
- #
99
- def embed?(key)
100
- return false unless embed_options.include?(key)
101
-
102
- !%w(0 false).include?(embed_options.fetch(key).to_s)
103
- end
104
92
  end
105
93
  end
106
94
  end
@@ -14,6 +14,38 @@ module Halogen
14
14
 
15
15
  fail InvalidDefinition, "Embed #{name} must be defined with a proc"
16
16
  end
17
+
18
+ # Check whether this definition should be embedded for the given instance
19
+ #
20
+ # @param instance [Object]
21
+ #
22
+ # @return [true, false]
23
+ #
24
+ def enabled?(instance)
25
+ return false unless super
26
+
27
+ if instance.respond_to?(:embed?)
28
+ instance.embed?(name.to_s)
29
+ else
30
+ embed_via_options?(instance)
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ # @param instance [Object]
37
+ #
38
+ # @return [true, false]
39
+ #
40
+ def embed_via_options?(instance)
41
+ opts = instance.embed_options
42
+
43
+ # Definition name must appear in instance embed option keys
44
+ return false unless opts.include?(name.to_s)
45
+
46
+ # Check value of embed option for definition name
47
+ !%w(0 false).include?(opts.fetch(name.to_s).to_s)
48
+ end
17
49
  end
18
50
  end
19
51
  end
data/lib/halogen/links.rb CHANGED
@@ -9,7 +9,7 @@ module Halogen
9
9
  end
10
10
 
11
11
  module ClassMethods # :nodoc:
12
- # @return [Halogen::Embeds::Definition]
12
+ # @return [Halogen::Links::Definition]
13
13
  #
14
14
  def link(name, *args, &procedure)
15
15
  definitions.add(Definition.new(name, *args, procedure))
@@ -27,11 +27,9 @@ module Halogen
27
27
  #
28
28
  def links
29
29
  render_definitions(Definition.name) do |definition, result|
30
- attrs = definition.options.fetch(:attrs, {})
30
+ value = definition.value(self)
31
31
 
32
- href = definition.value(self)
33
-
34
- result[definition.name] = attrs.merge(href: href) if href
32
+ result[definition.name] = value if value
35
33
  end
36
34
  end
37
35
  end
@@ -23,6 +23,23 @@ module Halogen
23
23
  'Link requires either procedure or explicit value'
24
24
  end
25
25
 
26
+ # @return [nil, Hash]
27
+ #
28
+ def value(_instance)
29
+ hrefs = super
30
+
31
+ attrs = options.fetch(:attrs, {})
32
+
33
+ case hrefs
34
+ when Array
35
+ hrefs.map { |href| attrs.merge(href: href) }
36
+ when nil
37
+ # no-op
38
+ else
39
+ attrs.merge(href: hrefs)
40
+ end
41
+ end
42
+
26
43
  class << self
27
44
  # Build hash of options from flexible definition arguments
28
45
  #
@@ -12,7 +12,7 @@ module Halogen
12
12
  # @param name [Symbol, String]
13
13
  # @param options [nil, Hash]
14
14
  #
15
- # @return [Halogen::Embeds::Definition]
15
+ # @return [Halogen::Properties::Definition]
16
16
  #
17
17
  def property(name, options = {}, &procedure)
18
18
  definitions.add(Definition.new(name, options, procedure))
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
  #
3
3
  module Halogen
4
- VERSION = '0.0.2' # :nodoc:
4
+ VERSION = '0.0.3' # :nodoc:
5
5
  end
@@ -44,34 +44,16 @@ describe Halogen::Collection do
44
44
 
45
45
  describe Halogen::Collection::InstanceMethods do
46
46
  describe '#embed?' do
47
- it 'returns true if super is true' do
48
- klass.collection_name = 'bar'
49
-
50
- klass.embed(:foo) { klass.new }
51
-
52
- repr = klass.new(embed: { foo: 1 })
53
-
54
- expect(repr.embed?('foo')).to eq(true)
55
- end
56
-
57
47
  it 'returns true if key matches collection name' do
58
48
  klass.collection_name = 'foo'
59
49
 
60
- klass.embed(:foo) { klass.new }
61
-
62
- repr = klass.new(embed: { foo: 0 })
63
-
64
- expect(repr.embed?('foo')).to eq(true)
50
+ expect(klass.new.embed?('foo')).to eq(true)
65
51
  end
66
52
 
67
- it 'returns false if no conditions match' do
53
+ it 'returns false if key does not match' do
68
54
  klass.collection_name = 'bar'
69
55
 
70
- klass.embed(:foo) { klass.new }
71
-
72
- repr = klass.new(embed: { foo: 0 })
73
-
74
- expect(repr.embed?('foo')).to eq(false)
56
+ expect(klass.new.embed?('foo')).to eq(false)
75
57
  end
76
58
  end
77
59
  end
@@ -20,4 +20,48 @@ describe Halogen::Embeds::Definition do
20
20
  end
21
21
  end
22
22
  end
23
+
24
+ describe '#enabled?' do
25
+ let :definition do
26
+ Halogen::Embeds::Definition.new(:name, {}, proc {})
27
+ end
28
+
29
+ it 'is true if instance rules return true' do
30
+ repr = double(:repr, embed?: true)
31
+
32
+ expect(definition.enabled?(repr)).to eq(true)
33
+ end
34
+
35
+ it 'is false if instance rules return false' do
36
+ repr = double(:repr, embed?: false)
37
+
38
+ expect(definition.enabled?(repr)).to eq(false)
39
+ end
40
+ end
41
+
42
+ describe '#embed_via_options?' do
43
+ let :klass do
44
+ Class.new { include Halogen }
45
+ end
46
+
47
+ it 'is true for expected values' do
48
+ [1, 2, true, '1', '2', 'true', 'yes'].each do |value|
49
+ repr = klass.new(embed: { foo: value })
50
+
51
+ definition = Halogen::Embeds::Definition.new(:foo, {}, proc {})
52
+
53
+ expect(definition.send(:embed_via_options?, repr)).to eq(true)
54
+ end
55
+ end
56
+
57
+ it 'is false for expected values' do
58
+ [0, false, '0', 'false'].each do |value|
59
+ repr = klass.new(embed: { foo: value })
60
+
61
+ definition = Halogen::Embeds::Definition.new(:foo, {}, proc {})
62
+
63
+ expect(definition.send(:embed_via_options?, repr)).to eq(false)
64
+ end
65
+ end
66
+ end
23
67
  end
@@ -185,23 +185,5 @@ describe Halogen::Embeds do
185
185
  expect(representer.embed_options).to eq('some' => { options: 1 })
186
186
  end
187
187
  end
188
-
189
- describe '#embed?' do
190
- it 'is true for expected values' do
191
- [1, 2, true, '1', '2', 'true', 'yes'].each do |value|
192
- representer = klass.new(embed: { foo: value })
193
-
194
- expect(representer.embed?('foo')).to eq(true)
195
- end
196
- end
197
-
198
- it 'is false for expected values' do
199
- [0, false, '0', 'false'].each do |value|
200
- representer = klass.new(embed: { foo: value })
201
-
202
- expect(representer.embed?('foo')).to eq(false)
203
- end
204
- end
205
- end
206
188
  end
207
189
  end
@@ -21,6 +21,40 @@ describe Halogen::Links::Definition do
21
21
  end
22
22
  end
23
23
 
24
+ describe '#value' do
25
+ it 'handles multiple hrefs' do
26
+ definition = Halogen::Links::Definition.new(
27
+ :name, proc { %w(first second) })
28
+
29
+ expect(definition.value(nil)).to eq([
30
+ { href: 'first' },
31
+ { href: 'second' }
32
+ ])
33
+ end
34
+
35
+ it 'handles multiple hrefs with additional attributes' do
36
+ definition = Halogen::Links::Definition.new(
37
+ :name, { attrs: { foo: 'bar' } }, proc { %w(first second) })
38
+
39
+ expect(definition.value(nil)).to eq([
40
+ { href: 'first', foo: 'bar' },
41
+ { href: 'second', foo: 'bar' }
42
+ ])
43
+ end
44
+
45
+ it 'handles single href' do
46
+ definition = Halogen::Links::Definition.new(:name, proc { 'first' })
47
+
48
+ expect(definition.value(nil)).to eq(href: 'first')
49
+ end
50
+
51
+ it 'is nil for nil href' do
52
+ definition = Halogen::Links::Definition.new(:name, proc {})
53
+
54
+ expect(definition.value(nil)).to be_nil
55
+ end
56
+ end
57
+
24
58
  describe '.build_options' do
25
59
  it 'has expected value without options hash' do
26
60
  options = Halogen::Links::Definition.build_options([])
@@ -27,6 +27,14 @@ describe Halogen::Links do
27
27
  foo: 'foo', attrs: { templated: true, bar: 'bar' })
28
28
  expect(link.procedure.call).to eq('path')
29
29
  end
30
+
31
+ it 'handles multiple values' do
32
+ klass.link(:self) { %w(foo bar) }
33
+
34
+ rendered = klass.new.render[:_links][:self]
35
+
36
+ expect(rendered).to eq([{ href: 'foo' }, { href: 'bar' }])
37
+ end
30
38
  end
31
39
 
32
40
  describe 'without procedure' do
@@ -54,6 +62,30 @@ describe Halogen::Links do
54
62
  end
55
63
  end
56
64
  end
65
+
66
+ it 'converts string rel to symbol' do
67
+ link = klass.link('ea:find', value: 'path')
68
+
69
+ expect(link.name).to eq(:'ea:find')
70
+ end
71
+ end
72
+ end
73
+
74
+ describe Halogen::Links::InstanceMethods do
75
+ describe '#links' do
76
+ let :klass do
77
+ Class.new do
78
+ include Halogen
79
+
80
+ link(:self) { nil }
81
+ end
82
+ end
83
+
84
+ it 'does not include link if value is nil' do
85
+ repr = klass.new
86
+
87
+ expect(repr.links).to eq({})
88
+ end
57
89
  end
58
90
  end
59
91
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: halogen
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
  - Heather Rivers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-07 00:00:00.000000000 Z
11
+ date: 2015-04-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json