representors 0.0.5

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