representors 0.0.5

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.
Files changed (73) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +18 -0
  3. data/Gemfile +3 -0
  4. data/Gemfile.lock +126 -0
  5. data/LICENSE.md +19 -0
  6. data/README.md +28 -0
  7. data/Rakefile +10 -0
  8. data/lib/representor_support/utilities.rb +39 -0
  9. data/lib/representors.rb +5 -0
  10. data/lib/representors/errors.rb +7 -0
  11. data/lib/representors/field.rb +108 -0
  12. data/lib/representors/options.rb +67 -0
  13. data/lib/representors/representor.rb +161 -0
  14. data/lib/representors/representor_builder.rb +64 -0
  15. data/lib/representors/representor_hash.rb +59 -0
  16. data/lib/representors/serialization.rb +4 -0
  17. data/lib/representors/serialization/deserializer_base.rb +29 -0
  18. data/lib/representors/serialization/deserializer_factory.rb +13 -0
  19. data/lib/representors/serialization/hal_deserializer.rb +44 -0
  20. data/lib/representors/serialization/hal_serializer.rb +91 -0
  21. data/lib/representors/serialization/hale_deserializer.rb +162 -0
  22. data/lib/representors/serialization/hale_serializer.rb +110 -0
  23. data/lib/representors/serialization/serialization_base.rb +27 -0
  24. data/lib/representors/serialization/serialization_factory_base.rb +54 -0
  25. data/lib/representors/serialization/serializer_base.rb +20 -0
  26. data/lib/representors/serialization/serializer_factory.rb +17 -0
  27. data/lib/representors/transition.rb +130 -0
  28. data/lib/representors/version.rb +4 -0
  29. data/spec/fixtures/complex_hal.json +92 -0
  30. data/spec/fixtures/complex_hale_document.json +81 -0
  31. data/spec/fixtures/drds_hash.rb +120 -0
  32. data/spec/fixtures/hale_spec_examples/basic.json +77 -0
  33. data/spec/fixtures/hale_spec_examples/complex_reference_objects.json +157 -0
  34. data/spec/fixtures/hale_spec_examples/data.json +17 -0
  35. data/spec/fixtures/hale_spec_examples/data_objects.json +96 -0
  36. data/spec/fixtures/hale_spec_examples/link_objects.json +18 -0
  37. data/spec/fixtures/hale_spec_examples/nested_ref.json +43 -0
  38. data/spec/fixtures/hale_spec_examples/reference_objects.json +89 -0
  39. data/spec/fixtures/hale_tutorial_examples/basic_links.json +85 -0
  40. data/spec/fixtures/hale_tutorial_examples/basic_links_with_orders.json +96 -0
  41. data/spec/fixtures/hale_tutorial_examples/basic_links_with_references.json +108 -0
  42. data/spec/fixtures/hale_tutorial_examples/embedded.json +182 -0
  43. data/spec/fixtures/hale_tutorial_examples/empty.json +1 -0
  44. data/spec/fixtures/hale_tutorial_examples/enctype.json +14 -0
  45. data/spec/fixtures/hale_tutorial_examples/final.json +141 -0
  46. data/spec/fixtures/hale_tutorial_examples/get_link.json +17 -0
  47. data/spec/fixtures/hale_tutorial_examples/get_link_with_data.json +29 -0
  48. data/spec/fixtures/hale_tutorial_examples/links.json +11 -0
  49. data/spec/fixtures/hale_tutorial_examples/links_only.json +3 -0
  50. data/spec/fixtures/hale_tutorial_examples/meta.json +208 -0
  51. data/spec/fixtures/hale_tutorial_examples/self_link.json +7 -0
  52. data/spec/fixtures/single_drd.rb +266 -0
  53. data/spec/lib/representors/complex_representor_spec.rb +288 -0
  54. data/spec/lib/representors/field_spec.rb +141 -0
  55. data/spec/lib/representors/representor_builder_spec.rb +223 -0
  56. data/spec/lib/representors/representor_spec.rb +285 -0
  57. data/spec/lib/representors/serialization/deserializer_factory_spec.rb +118 -0
  58. data/spec/lib/representors/serialization/hal_deserializer_spec.rb +34 -0
  59. data/spec/lib/representors/serialization/hal_serializer_spec.rb +171 -0
  60. data/spec/lib/representors/serialization/hale_deserializer_spec.rb +59 -0
  61. data/spec/lib/representors/serialization/hale_roundtrip_spec.rb +34 -0
  62. data/spec/lib/representors/serialization/hale_serializer_spec.rb +659 -0
  63. data/spec/lib/representors/serialization/serializer_factory_spec.rb +108 -0
  64. data/spec/lib/representors/transition_spec.rb +349 -0
  65. data/spec/spec_helper.rb +32 -0
  66. data/spec/support/basic-hale.json +12 -0
  67. data/spec/support/hal_representor_shared.rb +206 -0
  68. data/spec/support/helpers.rb +8 -0
  69. data/tasks/benchmark.rake +75 -0
  70. data/tasks/complex_hal_document.json +98 -0
  71. data/tasks/test_specs.rake +37 -0
  72. data/tasks/yard.rake +22 -0
  73. metadata +232 -0
@@ -0,0 +1,288 @@
1
+ require 'spec_helper'
2
+ require 'yaml'
3
+ require 'uri'
4
+ require 'fixtures/drds_hash'
5
+ require 'fixtures/single_drd'
6
+ module Representors
7
+ describe Representor do
8
+ before do
9
+ @representor_hash = ComplexRepresentor::DRDS_HASH
10
+ @representor_hash[:embedded] = {items: [ComplexRepresentor::DRD_HASH]}
11
+ end
12
+ let(:representor_hash) { @representor_hash }
13
+
14
+ let(:subject) { Representor.new(representor_hash) }
15
+
16
+ describe '.new' do
17
+ it 'returns a Representors::Representor instance' do
18
+ expect(subject).to be_an_instance_of(Representor)
19
+ end
20
+
21
+ describe '#to_s' do
22
+ it 'returns a string representation' do
23
+ expect(eval(subject.to_s)).to eq(representor_hash)
24
+ end
25
+ end
26
+
27
+ describe '#doc' do
28
+ it 'returns the same value specified under the doc element of the hash' do
29
+ doc = 'Describes the semantics, states and state transitions associated with DRDs.'
30
+ expect(subject.doc).to eq(doc)
31
+ end
32
+ end
33
+
34
+ describe '#to_hash' do
35
+ it 'returns a hash that it can be reconstructed with' do
36
+ expect(Representor.new(subject.to_hash).to_hash).to eq(@representor_hash)
37
+ end
38
+ end
39
+
40
+ describe '#to_yaml' do
41
+ it 'returns a yaml file that represents its internal hash' do
42
+ expect(YAML.load(subject.to_yaml)).to eq(YAML::load(YAML.dump(@representor_hash)))
43
+ end
44
+ end
45
+
46
+ describe '#properties' do
47
+ it 'returns a hash of attributes associated with the represented resource' do
48
+ semantic_elements_present = %w(total_count).all? do |key|
49
+ subject.properties[key] == @representor_hash[:attributes][key][:value]
50
+ end
51
+ expect(semantic_elements_present).to eq(true)
52
+ end
53
+ end
54
+
55
+ describe '#embedded' do
56
+ let(:embedded_resource) {:items}
57
+
58
+ it 'returns a set of Representor objects' do
59
+ expect(subject.embedded[embedded_resource].first).to be_an_instance_of(Representors::Representor)
60
+ end
61
+
62
+ it 'returns a Representor objects that has its data' do
63
+ doc = 'Diagnostic Repair Drones or DRDs are small robots that move around Leviathans. They are built by a Leviathan as it grows.'
64
+ embedded_objects_valid = subject.embedded[embedded_resource].all? { |embed| embed.doc == doc }
65
+ expect(embedded_objects_valid).to eq(true)
66
+ end
67
+
68
+ it 'returns the all the Representors' do
69
+ expect(subject.embedded[embedded_resource].count).to eq(@representor_hash[:embedded].count)
70
+ end
71
+ end
72
+
73
+ describe '#transitions' do
74
+ it 'returns all transitions' do
75
+ expect(subject.transitions.size).to eq(5)
76
+ has_transitions = subject.transitions.all? { |trans| trans.instance_of?(Transition) }
77
+ expect(has_transitions).to eq(true)
78
+ end
79
+ end
80
+
81
+ describe '#meta_links' do
82
+ it 'should return a list of transitions representing those links' do
83
+ expect(subject.meta_links.size).to eq(3)
84
+ has_meta_link = subject.meta_links.all? { |trans| trans.instance_of?(Transition) }
85
+ expect(has_meta_link).to eq(true)
86
+ end
87
+ end
88
+
89
+ describe '#datalists' do
90
+ let(:embedded_resource) {:items}
91
+ it 'returns all paramters and attributes that are members of a datalist' do
92
+ first_datalist = subject.embedded[embedded_resource].first.datalists
93
+ expected_datalists = ["drd_status_options", "drd_status_options", "location_options", "location_detail_options"]
94
+ has_data_list = expect(first_datalist.map { |datalist| datalist.id }).to eq(expected_datalists)
95
+ end
96
+ end
97
+
98
+ describe '.transitions' do
99
+ describe '#to_s' do
100
+ it 'returns a string representation' do
101
+ expect(subject.transitions.first.to_s).to eq(representor_hash[:transitions].first.to_s)
102
+ end
103
+ end
104
+
105
+ describe '#to_hash' do
106
+ it 'returns a hash representation' do
107
+ hashed = Hash[subject.transitions.first.to_hash.map{|(k,v)| [k.to_sym,v]}]
108
+ expect(hashed).to eq(representor_hash[:transitions].first)
109
+ end
110
+ end
111
+
112
+ describe '#[]' do
113
+ let(:key) {'href'}
114
+ let(:value) {representor_hash[:transitions].first[key.to_sym]}
115
+ it 'returns the value for the keys' do
116
+ expect(subject.transitions.first[key]).to eq(value)
117
+ end
118
+
119
+ it 'returns nil if the key is not in this transition' do
120
+ expect(subject.transitions.first['Ido not exists']).to be_nil
121
+ end
122
+
123
+ it 'has indifferent access to the hash' do
124
+ expect(subject.transitions.first[key.to_sym]).to eq(value)
125
+ expect(subject.transitions.first[key.to_s]).to eq(value)
126
+ end
127
+
128
+ end
129
+
130
+
131
+ describe '#rel' do
132
+ it 'returns the transition key' do
133
+ expect(subject.transitions.first.rel).to eq(representor_hash[:transitions].first[:rel])
134
+ end
135
+ end
136
+
137
+ describe '#interface_method' do
138
+ it 'returns the uniform interface method' do
139
+ expect(subject.transitions.first.interface_method).to eq('GET')
140
+ end
141
+ end
142
+
143
+ describe '#parameters' do
144
+ it 'returns a list of fields representing the link parameters' do
145
+ field = subject.transitions[2].parameters.first
146
+ expect(field).to be_an_instance_of(Field)
147
+ end
148
+ end
149
+
150
+ describe '#attributes' do
151
+ it 'returns a list of fields representing the link attributes' do
152
+ field = subject.transitions[3].attributes.first
153
+ expect(field).to be_an_instance_of(Field)
154
+ end
155
+ end
156
+
157
+ describe '#meta_links' do
158
+ it 'returns a list of Transitions' do
159
+ links = subject.transitions.first.meta_links.all? { |item| item.instance_of?(Transition) }
160
+ expect(links).to eq(true)
161
+ end
162
+ end
163
+
164
+ describe '#uri' do
165
+ it 'returns the bare link' do
166
+ expect(subject.transitions.first.uri).to eq('http://example.com/drds')
167
+ end
168
+ end
169
+
170
+ describe '#templated_uri' do
171
+ it 'returns the link parameterized' do
172
+ expect(subject.transitions[2].templated_uri).to eq('http://example.com/drds/search{?search_term,name}')
173
+ end
174
+ end
175
+
176
+ describe '#templated?' do
177
+ it 'returns false for the first element which has no parameters' do
178
+ expect(subject.transitions.first).not_to be_templated
179
+ end
180
+
181
+ it 'returns true for the second template which has parameters' do
182
+ expect(subject.transitions[2].templated?).to eq(true)
183
+ end
184
+ end
185
+
186
+ describe '.field' do
187
+
188
+ let(:field) { subject.transitions[3].attributes.first }
189
+ let(:field_hash) { {:name => representor_hash[:transitions].last[:descriptors][:name]} }
190
+
191
+ it 'returns a Representors::Field instance' do
192
+ expect(field).to be_an_instance_of(Representors::Field)
193
+ end
194
+
195
+ describe '#to_hash' do
196
+ it 'returns its constructor hash' do
197
+ expect(field.to_hash).to eq(field_hash)
198
+ end
199
+ end
200
+
201
+ describe '#to_yaml' do
202
+ it 'returns its constructor hash represented as a yaml document' do
203
+ expect(field.to_yaml).to eq(YAML.dump(field_hash))
204
+ end
205
+ end
206
+
207
+ describe '#name' do
208
+ it 'returns the key when requesting the name' do
209
+ expect(field.name).to eq(field_hash.keys.first)
210
+ end
211
+ end
212
+
213
+ %w(value default description type data_type).map(&:to_sym).each do |key|
214
+ describe "\##{key}" do
215
+ it "returns it's hash value" do
216
+ expect(field.send(key)).to eq(field_hash.first[1][key])
217
+ end
218
+ end
219
+ end
220
+ end
221
+ end
222
+
223
+ describe '#to_media_type' do
224
+ context 'when it serializes to hale' do
225
+ let (:hale_hash) { JSON.load(subject.to_media_type(:hale_json)) }
226
+ #TODO: Fix Hale Serializer - Complex objects not working
227
+
228
+ it 'has ths associated attributes' do
229
+ expect(hale_hash["total_count"]).to eq(subject.properties["total_count"])
230
+ end
231
+
232
+ it 'has transitions' do
233
+ expect(hale_hash["_links"]).to include("self","list","search","create")
234
+ end
235
+
236
+ it 'has meta links' do
237
+ subject.meta_links.each do |link|
238
+ expect(hale_hash["_links"][link.rel.to_s]["href"]).to eq(link.templated_uri)
239
+ end
240
+ end
241
+
242
+ it 'has embedded items' do
243
+ expect(hale_hash["_embedded"]["items"].count).to eq(@representor_hash[:embedded].count)
244
+ end
245
+
246
+ end
247
+
248
+ context 'when it serializes to hal' do
249
+ let (:hal_hash) { JSON.load(subject.to_media_type(:hal_json)) }
250
+
251
+ it 'has ths associated attributes' do
252
+ expect(hal_hash["total_count"]).to eq(subject.properties["total_count"])
253
+ end
254
+
255
+ it 'has transitions' do
256
+ subject.transitions.select { |transition| transition.rel != :items }.each do |link|
257
+ expect(hal_hash["_links"][link.rel]["href"]).to eq(link.templated_uri)
258
+ end
259
+ end
260
+
261
+ it 'has transitions for embedded resources' do
262
+ embedded_links = hal_hash["_embedded"]["items"].collect { |transition| transition["_links"]["self"]["href"] }
263
+ subject.transitions.reject { |transition| transition.rel != :items }.each do |link|
264
+ expect(embedded_links).to include(link.templated_uri)
265
+ end
266
+ end
267
+
268
+ it 'has meta links' do
269
+ subject.meta_links.each do |link|
270
+ expect(hal_hash["_links"][link.rel.to_s]["href"]).to eq(link.templated_uri)
271
+ end
272
+ end
273
+
274
+ it 'has embedded items' do
275
+ expect(hal_hash["_embedded"]["items"].count).to eq(1)
276
+ end
277
+
278
+ it 'renders a proper Hal document' do
279
+ expect(hal_hash).to eq(JSON.load(File.open(fixture_path('complex_hal.json'))))
280
+ end
281
+
282
+ end
283
+
284
+ end
285
+ end
286
+ end
287
+ end
288
+
@@ -0,0 +1,141 @@
1
+ require 'spec_helper'
2
+ require 'yaml'
3
+ require 'uri'
4
+
5
+ module Representors
6
+ describe Field do
7
+ before do
8
+ @field_hash = {
9
+ total_count: {
10
+ doc: 'The total count of DRDs.',
11
+ type: 'semantic',
12
+ profile: 'http://alps.io/schema.org/Integer',
13
+ sample: 1,
14
+ value: 2
15
+ }
16
+ }
17
+ end
18
+
19
+ let(:field_hash) { @field_hash }
20
+ let(:subject) { Field.new(field_hash) }
21
+
22
+ describe '.new' do
23
+ it 'returns a Representors::Field instance' do
24
+ expect(subject).to be_an_instance_of(Representors::Field)
25
+ end
26
+
27
+ it 'can be treated as the string of its value' do
28
+ expect(subject).to eq(subject.value.to_s)
29
+ end
30
+
31
+ it '#doc' do
32
+ expect("#{subject.doc} is #{subject}").to eq("The total count of DRDs. is 2")
33
+ end
34
+
35
+ describe '#to_hash' do
36
+ it 'returns its constructor hash' do
37
+ expect(subject.to_hash).to eq(field_hash)
38
+ end
39
+ end
40
+
41
+ describe '#to_yaml' do
42
+ it 'returns its constructor hash represented as a yaml document' do
43
+ expect(subject.to_yaml).to eq(YAML.dump(field_hash))
44
+ end
45
+ end
46
+
47
+ describe '#name' do
48
+ it 'returns the key when requesting the name' do
49
+ expect(subject.name).to eq(field_hash.keys.first)
50
+ end
51
+ end
52
+
53
+ %w(value default description type data_type).map(&:to_sym).each do |key|
54
+ describe "\##{key}" do
55
+ it "returns it's hash value" do
56
+ expect(subject.send(key)).to eq(field_hash.first[1][key])
57
+ end
58
+ end
59
+ end
60
+
61
+ describe '#options' do
62
+ it 'returns an options object' do
63
+ @field_hash[:total_count][:options] = {}
64
+
65
+ expect(subject.options).to be_an_instance_of(Options)
66
+ end
67
+
68
+ it 'works with empty options' do
69
+ @field_hash[:total_count][:options] = {}
70
+
71
+ expect(subject.options.to_hash).to eq(field_hash[:total_count][:options])
72
+ end
73
+
74
+ it 'has a list interface even when a hash' do
75
+ @field_hash[:total_count][:options] = { 'hash' => {'foo' => 'bar', 'ninja' => 'cow'} }
76
+
77
+ expect(subject.options.to_list).to eq(field_hash[:total_count][:options]['hash'].keys)
78
+ end
79
+
80
+ it 'has a values interface when a hash' do
81
+ @field_hash[:total_count][:options] = { 'hash' => {'foo' => 'bar', 'ninja' => 'cow'} }
82
+
83
+ expect(subject.options.values).to eq(field_hash[:total_count][:options]['hash'].values)
84
+ end
85
+
86
+ it 'has a hash interface even when a list' do
87
+ @field_hash[:total_count][:options] = { 'list' => ['bar', 'cow'] }
88
+
89
+ expect(subject.options.to_hash).to eq({'bar' => 'bar', 'cow' => 'cow'})
90
+ end
91
+
92
+ it 'has a hash interface when external' do
93
+ @field_hash[:total_count][:options] = { 'external' => {'source' => 'foo', 'target' => 'bar'} }
94
+
95
+ expect(subject.options.to_hash).to eq({'source' => 'foo', 'target' => 'bar'})
96
+ end
97
+
98
+ it 'defaults to a sensible id' do
99
+ @field_hash[:total_count][:options] = { 'external' => {'source' => 'foo', 'target' => 'bar'} }
100
+
101
+ expect(subject.options.id).to eq('total_count_options')
102
+ end
103
+
104
+ it 'gives back a passed in id' do
105
+ @field_hash[:total_count][:options] = { 'list' => ['bar', 'cow'], 'id' => 'fortunes grace' }
106
+
107
+ expect(subject.options.id).to eq('fortunes grace')
108
+ end
109
+
110
+ end
111
+
112
+ describe '#validators' do
113
+ it 'returns a list of hashes whose key is equal to the validator type' do
114
+ validators = [{ max_length: 8 }, :required]
115
+ @field_hash[:total_count][:validators] = validators
116
+ hash_keys = validators.map { |hs| hs.instance_of?(Symbol) ? hs : hs.keys.first }
117
+ object_keys = subject.validators.map { |hash| hash.keys.first }
118
+ expect(object_keys).to eq(hash_keys)
119
+ end
120
+
121
+ it 'returns a list of hashes whose value must be matched against' do
122
+ validators = [{max_length: 8}, :required]
123
+ @field_hash[:total_count][:validators] = validators
124
+ hash_values = validators.map { |hs| hs.instance_of?(Symbol) ? hs : hs[hs.keys.first] }
125
+ object_vals = subject.validators.map { |hash| hash[hash.keys[0]] }
126
+ expect(object_vals).to eq(hash_values)
127
+ end
128
+
129
+ it 'returns an empty list when there are no validators' do
130
+ expect(subject.validators).to eq([])
131
+ end
132
+ end
133
+
134
+ describe '#call' do
135
+ it 'returns the value when called' do
136
+ expect(subject.()).to eq(@field_hash[:total_count][:value])
137
+ end
138
+ end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,223 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ RSpec.shared_examples_for 'one attribute added' do
5
+ it 'creates a semantic key at the top level of the output' do
6
+ expect(@builder.to_representor_hash.attributes).to_not be_empty
7
+ end
8
+
9
+ it 'adds the attribute name as a key under "semantic" in the output hash' do
10
+ expect(semantic_field.has_key?(attribute_name)).to eq(true)
11
+ end
12
+
13
+ it 'adds the value under "value" in a hash which key is the attribute name' do
14
+ expect(semantic_field[attribute_name][:value]).to eq(attribute_value)
15
+ end
16
+
17
+ it 'when called twice the value is overwritten' do
18
+ new_value = 'new_value'
19
+ @builder = @builder.add_attribute(attribute_name, new_value)
20
+ expect(semantic_field[attribute_name]).to eq({value: new_value})
21
+ end
22
+ end
23
+
24
+
25
+ RSpec.shared_examples_for 'one transition added' do
26
+ it 'creates a transition key at the top level of the output' do
27
+ expect(@builder.to_representor_hash.transitions).to_not be_empty
28
+ end
29
+
30
+ it 'adds an array under "transitions" ' do
31
+ expect(transitions_field).to be_instance_of(Array)
32
+ end
33
+
34
+ it 'the members of the transitions has a href' do
35
+ expect(transitions_field.first[:href]).to eq(transition_href)
36
+ end
37
+ it 'the members of the transitions has a rel' do
38
+ expect(transitions_field.first[:rel]).to eq(transition_name)
39
+ end
40
+ end
41
+
42
+ RSpec.shared_examples_for 'one embedded added' do
43
+ it 'creates a transition key at the top level of the output' do
44
+ expect(@builder.to_representor_hash.embedded).to_not be_empty
45
+ end
46
+
47
+ it 'adds a hash under "embedded" ' do
48
+ expect(embedded_field).to be_instance_of(Hash)
49
+ end
50
+
51
+ it 'creates an embedded resource inside its own hash' do
52
+ expect(embedded_field[embedded_name]).to eq(embedded_value)
53
+ end
54
+
55
+ end
56
+
57
+ RSpec.shared_examples_for 'it can reconstruct itself' do
58
+ it 'can be constructed with the hash' do
59
+ expect(
60
+ Representors::RepresentorBuilder.new(@builder.to_representor_hash).to_representor_hash
61
+ ).to eq(@builder.to_representor_hash)
62
+ end
63
+ end
64
+
65
+ RSpec.describe Representors::RepresentorBuilder do
66
+ let(:semantic_field) {@builder.to_representor_hash.attributes}
67
+ let(:transitions_field) {@builder.to_representor_hash.transitions}
68
+ let(:embedded_field) {@builder.to_representor_hash.embedded}
69
+
70
+ before do
71
+ @builder = Representors::RepresentorBuilder.new
72
+ end
73
+
74
+ context 'empty builder' do
75
+ it "returns an empty representor hash" do
76
+ empty_hash = {:id=>nil, :doc=>nil, :href=>nil, :protocol=>nil, :attributes=>{}, :embedded=>{}, :links=>{}, :transitions=>[]}
77
+ expect(@builder.to_representor_hash.to_h).to eq(empty_hash)
78
+ end
79
+ end
80
+
81
+ describe '#add_attribute' do
82
+ let(:attribute_name) {'some_name'}
83
+ let(:attribute_value) {'cool_value'}
84
+
85
+ context 'Added an attribute without extra options' do
86
+ before do
87
+ @builder = @builder.add_attribute(attribute_name, attribute_value)
88
+ end
89
+
90
+ it_behaves_like 'one attribute added'
91
+ end
92
+
93
+ context 'Added an attribute with no specified extra options' do
94
+ before do
95
+ @builder = @builder.add_attribute(attribute_name, attribute_value)
96
+ end
97
+
98
+ it_behaves_like 'one attribute added'
99
+ end
100
+
101
+ context 'Added an attribute with empty extra options' do
102
+ before do
103
+ @builder = @builder.add_attribute(attribute_name, attribute_value, {})
104
+ end
105
+
106
+ it_behaves_like 'one attribute added'
107
+ end
108
+
109
+ context 'Added an attribute with extra options' do
110
+ let(:extra_key) {'doc'}
111
+ let(:extra_value) {'Some documentation'}
112
+ let(:extra_options) { {extra_key => extra_value} }
113
+
114
+ before do
115
+ @builder = @builder.add_attribute(attribute_name, attribute_value, extra_options)
116
+ end
117
+
118
+ it_behaves_like 'one attribute added'
119
+
120
+ it_behaves_like 'it can reconstruct itself'
121
+
122
+ it 'adds any extra options as keys under the attribute name hash' do
123
+ expect(semantic_field[attribute_name].has_key?(extra_key)).to eq(true)
124
+ end
125
+
126
+ it 'adds the correct value for the extra options' do
127
+ expect(semantic_field[attribute_name][extra_key]).to eq(extra_value)
128
+ end
129
+ end
130
+
131
+ end
132
+
133
+ describe '#add_transition' do
134
+ let(:transition_name) {'trusmis'}
135
+ let(:transition_href) {'/path_to_there'}
136
+
137
+ context 'Added a transition without extra options' do
138
+ before do
139
+ @builder = @builder.add_transition(transition_name, transition_href)
140
+ end
141
+
142
+ it_behaves_like 'one transition added'
143
+
144
+ it_behaves_like 'it can reconstruct itself'
145
+ end
146
+
147
+ context 'Added a transition with extra options' do
148
+ let(:extra_key) {:doc}
149
+ let(:extra_value) {'Some documentation'}
150
+ let(:extra_options) { {extra_key => extra_value} }
151
+
152
+ before do
153
+ @builder = @builder.add_transition(transition_name, transition_href, extra_options)
154
+ end
155
+
156
+ it_behaves_like 'one transition added'
157
+
158
+ it 'adds any extra options as keys under the attribute name hash' do
159
+ expect(transitions_field.first.has_key?(extra_key)).to eq(true)
160
+ end
161
+
162
+ it 'adds the correct value for the extra options' do
163
+ expect(transitions_field.first[extra_key]).to eq(extra_value)
164
+ end
165
+
166
+ it_behaves_like 'it can reconstruct itself'
167
+ end
168
+ end
169
+
170
+ describe '#add_transition_array' do
171
+ let(:transition_name) {'mumismo'}
172
+ let(:transition_href) {'/path_to_there'}
173
+ let(:transition_array) { [{hello: 'world', :href => transition_href}, {count: 10, href: '/another_path'}]}
174
+
175
+ before do
176
+ @builder = @builder.add_transition_array(transition_name, transition_array)
177
+ end
178
+
179
+ it 'creates two elements under transitions' do
180
+ expect(transitions_field.size).to eq(2)
181
+ end
182
+
183
+ it_behaves_like 'one transition added'
184
+
185
+ it_behaves_like 'it can reconstruct itself'
186
+ end
187
+
188
+
189
+ describe '#add_embedded' do
190
+ let(:embedded_name) {'trusmis'}
191
+ let(:embedded_value) { { 'data' => 'here'}}
192
+
193
+ context 'Added an embedded' do
194
+ before do
195
+ @builder = @builder.add_embedded(embedded_name, embedded_value)
196
+ end
197
+
198
+ it_behaves_like 'one embedded added'
199
+
200
+ it_behaves_like 'it can reconstruct itself'
201
+ end
202
+ end
203
+
204
+ context 'Reconstructing the Complex Hash Fixture' do
205
+ #TODO: Reconstructing the Complex Hash Fixture with Builder - Builder Needs Work
206
+ it 'accepts basic attributes' do
207
+ representor = Representors::Representor.new({protocol: 'http', # The protocol we're using
208
+ href: 'www.example.com/drds', # Crichton needs to say where we are
209
+ id: 'DRDs', # ID from desrciptor
210
+ doc: 'Describes the semantics, states and state transitions associated with DRDs.'
211
+ }) do |builder|
212
+ builder = builder.add_attribute('total_count', 2, { #semantic key
213
+ doc: 'The total count of DRDs.', # Descriptor semantic doc
214
+ type: 'semantic', # Descriptor semantic type
215
+ profile: 'http://alps.io/schema.org/Integer', # same as 'href' in Descriptor file
216
+ sample: 1, # same as sample in descriptor
217
+ },)
218
+ end # Doc from descriptor
219
+ expect(representor.properties["total_count"]).to eq(2)
220
+ end
221
+ end
222
+
223
+ end