occi-core 4.1.3 → 4.2.0

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 (125) hide show
  1. data/.gitignore +1 -0
  2. data/Gemfile +8 -0
  3. data/README.md +49 -17
  4. data/lib/occi/collection.rb +37 -21
  5. data/lib/occi/core/action.rb +5 -5
  6. data/lib/occi/core/action_instance.rb +45 -3
  7. data/lib/occi/core/actions.rb +2 -1
  8. data/lib/occi/core/attributes.rb +253 -73
  9. data/lib/occi/core/categories.rb +1 -0
  10. data/lib/occi/core/category.rb +25 -8
  11. data/lib/occi/core/entities.rb +1 -0
  12. data/lib/occi/core/entity.rb +51 -74
  13. data/lib/occi/core/kind.rb +15 -11
  14. data/lib/occi/core/kinds.rb +1 -1
  15. data/lib/occi/core/link.rb +14 -15
  16. data/lib/occi/core/links.rb +1 -1
  17. data/lib/occi/core/mixin.rb +5 -5
  18. data/lib/occi/core/mixins.rb +2 -2
  19. data/lib/occi/core/properties.rb +90 -12
  20. data/lib/occi/core/resource.rb +7 -3
  21. data/lib/occi/core/resources.rb +2 -2
  22. data/lib/occi/errors/attribute_definitions_converted_error.rb +5 -0
  23. data/lib/occi/errors/attribute_missing_error.rb +5 -0
  24. data/lib/occi/errors/attribute_name_invalid_error.rb +5 -0
  25. data/lib/occi/errors/attribute_not_defined_error.rb +5 -0
  26. data/lib/occi/errors/attribute_property_type_error.rb +5 -0
  27. data/lib/occi/errors/attribute_type_error.rb +5 -0
  28. data/lib/occi/errors/kind_not_defined_error.rb +5 -0
  29. data/lib/occi/errors/parser_input_error.rb +5 -0
  30. data/lib/occi/errors/parser_type_error.rb +5 -0
  31. data/lib/occi/errors.rb +1 -0
  32. data/lib/occi/extensions/hashie.rb +25 -0
  33. data/lib/occi/helpers/comparators/action_instance.rb +22 -0
  34. data/lib/occi/helpers/comparators/attributes.rb +22 -0
  35. data/lib/occi/helpers/comparators/categories.rb +22 -0
  36. data/lib/occi/helpers/comparators/category.rb +22 -0
  37. data/lib/occi/helpers/comparators/collection.rb +40 -0
  38. data/lib/occi/helpers/comparators/entities.rb +22 -0
  39. data/lib/occi/helpers/comparators/entity.rb +22 -0
  40. data/lib/occi/helpers/comparators/properties.rb +26 -0
  41. data/lib/occi/helpers/comparators.rb +1 -0
  42. data/lib/occi/infrastructure/compute.rb +11 -9
  43. data/lib/occi/infrastructure/network.rb +27 -27
  44. data/lib/occi/infrastructure/networkinterface.rb +22 -23
  45. data/lib/occi/infrastructure/os_tpl.rb +1 -1
  46. data/lib/occi/infrastructure/resource_tpl.rb +1 -1
  47. data/lib/occi/infrastructure/storage.rb +7 -6
  48. data/lib/occi/infrastructure/storagelink.rb +4 -4
  49. data/lib/occi/log.rb +13 -10
  50. data/lib/occi/model.rb +9 -8
  51. data/lib/occi/parser/json.rb +11 -9
  52. data/lib/occi/parser/ova.rb +12 -6
  53. data/lib/occi/parser/ovf.rb +173 -116
  54. data/lib/occi/parser/text/constants.rb +87 -0
  55. data/lib/occi/parser/text.rb +161 -200
  56. data/lib/occi/parser/xml.rb +10 -8
  57. data/lib/occi/parser.rb +100 -50
  58. data/lib/occi/settings.rb +2 -1
  59. data/lib/occi/version.rb +1 -1
  60. data/lib/occi-core.rb +6 -4
  61. data/occi-core.gemspec +0 -7
  62. data/spec/occi/collection_samples/collection1.json +1 -0
  63. data/spec/occi/collection_samples/directory2/collection2.json +1 -0
  64. data/spec/occi/collection_spec.rb +961 -31
  65. data/spec/occi/core/action_instance_spec.rb +317 -0
  66. data/spec/occi/core/action_spec.rb +71 -0
  67. data/spec/occi/core/attributes_spec.rb +582 -27
  68. data/spec/occi/core/category_spec.rb +194 -18
  69. data/spec/occi/core/entities_spec.rb +96 -0
  70. data/spec/occi/core/entity_spec.rb +317 -28
  71. data/spec/occi/core/kind_spec.rb +127 -16
  72. data/spec/occi/core/link_spec.rb +35 -0
  73. data/spec/occi/core/links_spec.rb +130 -0
  74. data/spec/occi/core/mixins_spec.rb +107 -0
  75. data/spec/occi/core/properties_spec.rb +167 -0
  76. data/spec/occi/core/resource_spec.rb +23 -9
  77. data/spec/occi/core_spec.rb +12 -0
  78. data/spec/occi/infrastructure/compute_spec.rb +218 -18
  79. data/spec/occi/infrastructure/network_spec.rb +96 -0
  80. data/spec/occi/infrastructure/networkinterface_spec.rb +96 -0
  81. data/spec/occi/infrastructure/storage_spec.rb +33 -0
  82. data/spec/occi/infrastructure/storagelink_spec.rb +45 -0
  83. data/spec/occi/log_spec.rb +104 -1
  84. data/spec/occi/model_spec.rb +251 -39
  85. data/spec/occi/{test.json → parser/json_samples/test.json} +0 -0
  86. data/spec/occi/parser/ova_samples/test.dump +0 -0
  87. data/spec/occi/{test.ova → parser/ova_samples/test.ova} +0 -0
  88. data/spec/occi/parser/ovf_samples/test.dump +0 -0
  89. data/spec/occi/{test.ovf → parser/ovf_samples/test.ovf} +0 -0
  90. data/spec/occi/parser/text_samples/occi_categories.dump +0 -0
  91. data/spec/occi/parser/text_samples/occi_categories.text +2 -0
  92. data/spec/occi/parser/text_samples/occi_compute_rocci_server.dump +0 -0
  93. data/spec/occi/parser/text_samples/occi_compute_rocci_server.resource.dump +0 -0
  94. data/spec/occi/parser/text_samples/occi_compute_rocci_server.text +10 -0
  95. data/spec/occi/parser/text_samples/occi_link_resource_instance.dump +0 -0
  96. data/spec/occi/parser/text_samples/occi_link_resource_instance.text +7 -0
  97. data/spec/occi/parser/text_samples/occi_link_simple.dump +0 -0
  98. data/spec/occi/parser/text_samples/occi_link_simple.link_string.dump +0 -0
  99. data/spec/occi/parser/text_samples/occi_link_simple.text +1 -0
  100. data/spec/occi/parser/text_samples/occi_link_w_attributes.dump +0 -0
  101. data/spec/occi/parser/text_samples/occi_link_w_attributes.text +7 -0
  102. data/spec/occi/parser/text_samples/occi_link_w_category.dump +0 -0
  103. data/spec/occi/parser/text_samples/occi_link_w_category.text +3 -0
  104. data/spec/occi/parser/text_samples/occi_model_rocci_server.dump +0 -0
  105. data/spec/occi/parser/text_samples/occi_model_rocci_server.text +51 -0
  106. data/spec/occi/parser/text_samples/occi_network_rocci_server.dump +0 -0
  107. data/spec/occi/parser/text_samples/occi_network_rocci_server.resource.dump +0 -0
  108. data/spec/occi/parser/text_samples/occi_network_rocci_server.text +11 -0
  109. data/spec/occi/parser/text_samples/occi_resource_w_attributes.dump +0 -0
  110. data/spec/occi/parser/text_samples/occi_resource_w_attributes.text +11 -0
  111. data/spec/occi/parser/text_samples/occi_resource_w_inline_links.dump +0 -0
  112. data/spec/occi/parser/text_samples/occi_resource_w_inline_links.text +16 -0
  113. data/spec/occi/parser/text_samples/occi_resource_w_inline_links_only.dump +0 -0
  114. data/spec/occi/parser/text_samples/occi_resource_w_inline_links_only.text +13 -0
  115. data/spec/occi/parser/text_samples/occi_storage_rocci_server.dump +0 -0
  116. data/spec/occi/parser/text_samples/occi_storage_rocci_server.resource.dump +0 -0
  117. data/spec/occi/parser/text_samples/occi_storage_rocci_server.text +9 -0
  118. data/spec/occi/parser/text_spec.rb +274 -78
  119. data/spec/occi/parser/xml_samples/test.xml +352 -0
  120. data/spec/occi/parser_spec.rb +255 -104
  121. data/spec/occi-core_spec.rb +31 -0
  122. data/spec/spec_helper.rb +6 -2
  123. metadata +110 -111
  124. checksums.yaml +0 -7
  125. data/spec/occi/core/attribute_spec.rb +0 -0
@@ -2,33 +2,209 @@ module Occi
2
2
  module Core
3
3
  describe Category do
4
4
 
5
- describe '.new' do
5
+ let(:category) { Category.new }
6
+ let(:category_scheme) { Category.new 'http://example.org/test#', 'category' }
7
+ let(:category_term) { Category.new 'http://schemas.ogf.org/occi/core#', 'testcat' }
8
+ let(:category_scheme_term) { Category.new *'http://schemas.ogf.org/occi/test#category1'.split('#') }
6
9
 
7
- it 'instantiates a new Category' do
8
- category = Category.new
9
- category.scheme.should == 'http://schemas.ogf.org/occi/core#'
10
- category.term.should == 'category'
11
- category.title.should be_nil
12
- category.attributes.should be_kind_of Occi::Core::Attributes
13
- category.attributes.should be_empty
10
+ context '#new' do
11
+
12
+ it 'with defaults' do
13
+ expect { Category.new }.not_to raise_error
14
+ end
15
+
16
+ it 'fails without scheme' do
17
+ expect { Category.new nil }.to raise_error(ArgumentError)
18
+ end
19
+
20
+ it 'fails without term' do
21
+ expect { Category.new 'scheme', nil }.to raise_error(ArgumentError)
22
+ end
23
+
24
+ it 'passes without attributes' do
25
+ expect { Category.new 'scheme', 'term', nil, nil }.not_to raise_error
26
+ end
27
+
28
+ end
29
+
30
+ context 'instance attributes' do
31
+
32
+ it 'default scheme is OGF OCCI Core' do
33
+ expect(category.scheme).to eq 'http://schemas.ogf.org/occi/core#'
14
34
  end
15
35
 
16
- it 'instantiates a new Category and ensures that the scheme ends with a #' do
17
- category = Category.new *'http://schemas.ogf.org/occi/core#category'.split('#')
18
- category.scheme.should == 'http://schemas.ogf.org/occi/core#'
19
- category.term.should == 'category'
20
- category.title.should be_nil
21
- category.attributes.should be_kind_of Occi::Core::Attributes
22
- category.attributes.should be_empty
36
+ it 'default term is "category"' do
37
+ expect(category.term).to eq 'category'
38
+ end
39
+
40
+ it 'default title is nil' do
41
+ expect(category.title).to be_nil
42
+ end
43
+
44
+ it 'default attributes are Occi::Core::Attributes' do
45
+ expect(category.attributes).to be_kind_of Occi::Core::Attributes
46
+ end
47
+
48
+ it 'default attributes are empty' do
49
+ expect(category.attributes).to be_empty
50
+ end
51
+
52
+ it 'scheme always ends with a #' do
53
+ expect(category_scheme_term.scheme).to eq 'http://schemas.ogf.org/occi/test#'
54
+ end
55
+
56
+ it 'term is always after the #' do
57
+ expect(category_scheme_term.term).to eq 'category1'
23
58
  end
24
59
 
25
60
  end
26
61
 
27
- describe '#type_identifier' do
62
+ context '#type_identifier' do
28
63
 
29
64
  it 'returns the type identifier of the category' do
30
- category = Category.new
31
- category.type_identifier.should == 'http://schemas.ogf.org/occi/core#category'
65
+ expect(category.type_identifier).to eq 'http://schemas.ogf.org/occi/core#category'
66
+ end
67
+
68
+ end
69
+
70
+ context '#==' do
71
+
72
+ it 'matches the same instance' do
73
+ expect(category).to eq category
74
+ end
75
+
76
+ it 'matches a clone' do
77
+ expect(category).to eq category.clone
78
+ end
79
+
80
+ it 'matches with a different title' do
81
+ changed_clone = category.clone
82
+ changed_clone.title = 'newtitle'
83
+
84
+ expect(category).to eq changed_clone
85
+ end
86
+
87
+ it 'matches with different attributes' do
88
+ changed_clone = category.clone
89
+ changed_clone.attributes = Occi::Core::Attributes.new({ "id" => '123123' })
90
+
91
+ expect(category).to eq changed_clone
92
+ end
93
+
94
+ it 'does not match a nil' do
95
+ expect(category).not_to eq nil
96
+ end
97
+
98
+ it 'does not match with a different scheme' do
99
+ expect(category).not_to eq category_scheme
100
+ end
101
+
102
+ it 'does not match with a different term' do
103
+ expect(category).not_to eq category_term
104
+ end
105
+
106
+ it 'does not match with a different scheme and term' do
107
+ expect(category).not_to eq category_scheme_term
108
+ end
109
+
110
+ end
111
+
112
+ context '#eql?' do
113
+
114
+ it 'matches the same instance' do
115
+ expect(category).to eql category
116
+ end
117
+
118
+ it 'matches a clone' do
119
+ expect(category).to eql category.clone
120
+ end
121
+
122
+ it 'matches with a different title' do
123
+ changed_clone = category.clone
124
+ changed_clone.title = 'newtitle'
125
+
126
+ expect(category).to eql changed_clone
127
+ end
128
+
129
+ it 'matches with different attributes' do
130
+ changed_clone = category.clone
131
+ changed_clone.attributes = Occi::Core::Attributes.new({ "id" => '123123' })
132
+
133
+ expect(category).to eql changed_clone
134
+ end
135
+
136
+ it 'does not match a nil' do
137
+ expect(category).not_to eql nil
138
+ end
139
+
140
+ it 'does not match with a different scheme' do
141
+ expect(category).not_to eql category_scheme
142
+ end
143
+
144
+ it 'does not match with a different term' do
145
+ expect(category).not_to eql category_term
146
+ end
147
+
148
+ it 'does not match with a different scheme and term' do
149
+ expect(category).not_to eql category_scheme_term
150
+ end
151
+
152
+ end
153
+
154
+ context '#equal?' do
155
+
156
+ it 'matches the same instance' do
157
+ expect(category).to equal category
158
+ end
159
+
160
+ it 'does not match clones' do
161
+ expect(category).not_to equal category.clone
162
+ end
163
+
164
+ end
165
+
166
+ context '#hash' do
167
+
168
+ it 'matches for clones' do
169
+ expect(category.hash).to eq category.clone.hash
170
+ end
171
+
172
+ it 'matches for the same instance' do
173
+ expect(category.hash).to eq category.hash
174
+ end
175
+
176
+ it 'does not match when term is different' do
177
+ expect(category.hash).not_to eq category_term.hash
178
+ end
179
+
180
+ it 'does not match when scheme is different' do
181
+ expect(category.hash).not_to eq category_scheme.hash
182
+ end
183
+
184
+ it 'does not match when scheme and term are different' do
185
+ expect(category.hash).not_to eq category_scheme_term
186
+ end
187
+
188
+ end
189
+
190
+ context '#empty?' do
191
+
192
+ it 'returns false for a new instance with defaults' do
193
+ expect(category.empty?).to be_false
194
+ end
195
+
196
+ it 'returns true for an instance without a term' do
197
+ cat = category.clone
198
+ cat.term = nil
199
+
200
+ expect(cat.empty?).to be_true
201
+ end
202
+
203
+ it 'returns true for an instance without a scheme' do
204
+ cat = category.clone
205
+ cat.scheme = nil
206
+
207
+ expect(cat.empty?).to be_true
32
208
  end
33
209
 
34
210
  end
@@ -0,0 +1,96 @@
1
+ module Occi
2
+ module Core
3
+ describe Entities do
4
+ let(:entities){ Occi::Core::Entities.new }
5
+ let(:entity1){ entity1 = Occi::Core::Entity.new
6
+ entity1.id = "e1testid"
7
+ entity1 }
8
+ let(:entity2){ entity2 = Occi::Core::Entity.new 'http://example.org/test/schema#entity2'
9
+ entity2.id = "e2testid"
10
+ entity2 }
11
+ let(:testaction){ Occi::Core::Action.new scheme='http://schemas.ogf.org/occi/core/entity/action#', term='testaction', title='testaction action' }
12
+
13
+ context 'populating' do
14
+
15
+ it 'is created empty' do
16
+ expect(entities.count).to eq 0
17
+ end
18
+ it 'gets entity Nos. right, 1' do
19
+ entities << entity1
20
+ expect(entities.count).to eq 1
21
+ end
22
+ it 'gets entity Nos. right, 2' do
23
+ entities << entity1
24
+ entities << entity2
25
+ expect(entities.count).to eq 2
26
+ end
27
+ it 'gets correctly-typed elements' do
28
+ entities << entity1
29
+ entities << entity2
30
+ expect(entities.first).to be_an_instance_of(Occi::Core::Entity)
31
+ end
32
+ end
33
+
34
+ context '#model' do
35
+ it 'has no model by default' do
36
+ expect(entities.model).to be nil
37
+ end
38
+ it 'can be assigned model' do
39
+ modl = Occi::Model.new
40
+ entities.model = modl
41
+ expect(entities.model).to eql modl
42
+ end
43
+ it 'uses the assigned model for new members' do
44
+ modl = Occi::Model.new
45
+ entities.model = modl
46
+ entities << entity1
47
+ expect(entities.first.model).to eql modl
48
+ end
49
+ it 'uses the assigned model for existing members' do
50
+ entities << entity1
51
+ modl = Occi::Model.new
52
+ entities.model = modl
53
+ expect(entities.first.model).to eql modl
54
+ end
55
+ it 'does not use unassigned model' do
56
+ modl = Occi::Model.new
57
+ entities << entity1
58
+ expect(entities.first.model).to_not eql modl
59
+ end
60
+ end
61
+
62
+ context '#create' do
63
+ it 'creates a new element' do
64
+ entities.create
65
+ expect(entities.first).to be_instance_of(Occi::Core::Entity)
66
+ end
67
+ it 'accepts argument' do
68
+ entities.create 'http://example.com/testnamespace#test'
69
+ expect(entities.first).to be_kind_of 'Com::Example::Testnamespace::Test'.constantize
70
+ end
71
+ end
72
+
73
+ context '#join' do
74
+ it 'joins elements correctly' do
75
+ entities << entity1
76
+ entities << entity2
77
+ expect(entities.join('|')).to eq '/entity/e1testid|/entity2/e2testid'
78
+ end
79
+ end
80
+
81
+ context '#as_json' do
82
+ it 'renders elements with various attributes' do
83
+ entity2.actions << testaction
84
+ entities << entity1
85
+ entities << entity2
86
+ expected = []
87
+ hash=Hashie::Mash.new JSON.parse('{"kind":"http://schemas.ogf.org/occi/core#entity","attributes":{"occi":{"core":{"id":"e1testid"}}},"id":"e1testid"}')
88
+ hash2= Hashie::Mash.new JSON.parse('{"kind":"http://example.org/test/schema#entity2","actions":[{"scheme":"http://schemas.ogf.org/occi/core/entity/action#","term":"testaction","title":"testaction action","attributes":{}}],"attributes":{"occi":{"core":{"id":"e2testid"}}},"id":"e2testid"}')
89
+ expected << hash
90
+ expected << hash2
91
+ expect(entities.as_json).to eql expected
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -1,44 +1,333 @@
1
1
  module Occi
2
2
  module Core
3
3
  describe Entity do
4
+ let(:entity){
5
+ entity = Occi::Core::Entity.new
6
+ entity.id = 'baf1'
7
+ entity
8
+ }
9
+ let(:testaction){ Occi::Core::Action.new scheme='http://schemas.ogf.org/occi/core/entity/action#', term='testaction', title='testaction action' }
4
10
 
5
11
  it "initializes itself successfully" do
6
- entity = Occi::Core::Entity.new
7
- entity.should be_kind_of Occi::Core::Entity
12
+ expect(entity).to be_kind_of Occi::Core::Entity
8
13
  end
9
14
 
10
- it "initializes a subclass successfully using a type identifier" do
11
- type_identifier = 'http://example.com/testnamespace#test'
12
- entity = Occi::Core::Entity.new type_identifier
13
- entity.should be_kind_of 'Com::Example::Testnamespace::Test'.constantize
14
- entity.kind.type_identifier.should == type_identifier
15
- entity.kind.related.first.should == Occi::Core::Entity.kind
15
+ context 'initializiation of a subclass using a type identifier' do
16
+ let(:type_identifier){ 'http://example.com/testnamespace#test' }
17
+ let(:typed_entity){ Occi::Core::Entity.new type_identifier }
18
+
19
+ it 'has the correct kind' do
20
+ expect(typed_entity).to be_kind_of 'Com::Example::Testnamespace::Test'.constantize
21
+ end
22
+
23
+ it 'uses the right identifier' do
24
+ expect(typed_entity.kind.type_identifier).to eq type_identifier
25
+ end
26
+
27
+ it 'relates to Entity' do
28
+ expect(typed_entity.kind.related.first).to eq Occi::Core::Entity.kind
29
+ end
16
30
  end
17
31
 
18
- it "initializes a subclass successfully using an OCCI Kind" do
19
- kind = Occi::Core::Resource.kind
20
- entity = Occi::Core::Entity.new kind
21
- entity.should be_kind_of Occi::Core::Resource
22
- entity.kind.type_identifier.should == Occi::Core::Resource.type_identifier
23
- entity.kind.related.first.should == Occi::Core::Entity.kind
32
+ context "initialization of a subclass using an OCCI Kind" do
33
+ let(:kind){ Occi::Core::Resource.kind }
34
+ let(:kind_entity){ Occi::Core::Entity.new kind }
35
+
36
+ it 'has the correct kind' do
37
+ expect(kind_entity).to be_kind_of Occi::Core::Resource
38
+ end
39
+
40
+ it 'uses the right identifier' do
41
+ expect(kind_entity.kind.type_identifier).to eq Occi::Core::Resource.type_identifier
42
+ end
43
+
44
+ it 'relates to Entity' do
45
+ expect(kind_entity.kind.related.first).to eq Occi::Core::Entity.kind
46
+ end
24
47
  end
25
48
 
26
- it "converts mixin type identifiers to objects if a mixin is added to the entities mixins" do
27
- mixin = 'http://example.com/mynamespace#mymixin'
28
- entity = Occi::Core::Entity.new
29
- entity.mixins << mixin
30
- entity.mixins.first.to_s.should == mixin
49
+ context '#kind' do
50
+ it 'accepts kind from string' do
51
+ entity.kind = 'http://example.com/testnamespace#test'
52
+ expect(entity.kind).to eql Com::Example::Testnamespace::Test
53
+ end
54
+
55
+ it 'accepts kind from class' do
56
+ entity.kind = Com::Example::Testnamespace::Test
57
+ expect(entity.kind).to eql Com::Example::Testnamespace::Test
58
+ end
31
59
  end
32
60
 
33
- # TODO: check adding of model
34
- it "checks a valid attribute value against their definition in its kind and associated mixins" do
35
- entity = Occi::Core::Entity.new
36
- expect { entity.check }.to raise_error
37
- entity.model = Occi::Model.new
38
- entity.title = 'test'
39
- uuid = UUIDTools::UUID.random_create.to_s
40
- entity.id = uuid
41
- expect { entity.check }.to_not raise_error
61
+ context '#mixins' do
62
+ let(:mixin){ 'http://example.com/mynamespace#mymixin' }
63
+
64
+ it "converts mixin type identifiers to objects if a mixin is added to the entities mixins" do
65
+ entity.mixins << mixin
66
+ expect(entity.mixins.first.to_s).to eq mixin
67
+ end
68
+ end
69
+
70
+ context 'attributes' do
71
+
72
+ context 'checking attribute validity' do
73
+ before(:each) { Occi::Settings['compatibility']=false }
74
+ after(:each) { Occi::Settings.reload! }
75
+
76
+ it 'fails check with model missing' do
77
+ expect { entity.check }.to raise_error
78
+ end
79
+
80
+ it 'runs check successfully with a model registered' do
81
+ entity.model = Occi::Model.new
82
+ entity.title = 'test'
83
+ uuid = UUIDTools::UUID.random_create.to_s
84
+ Occi::Settings['verify_attribute_pattern']=true
85
+ expect { entity.id = uuid }.to_not raise_error
86
+ end
87
+
88
+ it 'rejects values not matching pattern' do
89
+ entity.model = Occi::Model.new
90
+ entity.id = 'id with spaces'
91
+ Occi::Settings['verify_attribute_pattern']=true
92
+ expect{ entity.id = 'id with spaces' }.to raise_error Occi::Errors::AttributeTypeError
93
+ end
94
+
95
+ end
96
+
97
+ context '#location' do
98
+ it 'can be set and read' do
99
+ entity.location = 'TestLoc'
100
+ expect(entity.location).to eq 'TestLoc'
101
+ end
102
+
103
+ it 'can be constructed from id' do
104
+ entity.id = UUIDTools::UUID.random_create.to_s
105
+ expect(entity.location).to eq '/entity/' + entity.id
106
+ end
107
+ end
108
+
109
+ context '#title' do
110
+ it 'can be set and read' do
111
+ entity.title = 'TestTitle'
112
+ expect(entity.title).to eq 'TestTitle'
113
+ end
114
+ end
115
+ end
116
+
117
+ context '#actions' do
118
+ it 'can be populated through redirection' do
119
+ entity.actions << testaction
120
+ expect(entity.actions.count).to eq 1
121
+ end
122
+
123
+ it 'can be assigned through the setter method' do
124
+ acts = Occi::Core::Actions.new
125
+ acts << testaction
126
+ entity.actions=acts
127
+ expect(entity.actions.count).to eq 1
128
+ end
129
+ end
130
+
131
+ context '#to_text' do
132
+ it 'renders fresh instance in text correctly' do
133
+ expected = %Q|Category: entity;scheme="http://schemas.ogf.org/occi/core#";class="kind"
134
+ X-OCCI-Attribute: occi.core.id="baf1"|
135
+ expect(entity.to_text).to eq(expected)
136
+ end
137
+
138
+ it 'renders instance with attributes in text correctly' do
139
+ entity.actions << testaction
140
+ entity.title = 'TestTitle'
141
+ entity.location = '/TestLoc/1'
142
+ entity.mixins << 'http://example.com/mynamespace#mymixin'
143
+
144
+ expected = %Q|Category: entity;scheme="http://schemas.ogf.org/occi/core#";class="kind"
145
+ Category: mymixin;scheme="http://example.com/mynamespace#";class="mixin"
146
+ X-OCCI-Attribute: occi.core.id="baf1"
147
+ X-OCCI-Attribute: occi.core.title="TestTitle"
148
+ Link: </TestLoc/1?action=testaction>;rel=http://schemas.ogf.org/occi/core/entity/action#testaction|
149
+ expect(entity.to_text).to eq(expected)
150
+ end
151
+ end
152
+
153
+ context '#to_header' do
154
+ it 'renders fresh instance in HTTP Header correctly' do
155
+ expected = Hashie::Mash.new
156
+ expected['Category'] = 'entity;scheme="http://schemas.ogf.org/occi/core#";class="kind"'
157
+ expected['X-OCCI-Attribute'] = 'occi.core.id="baf1"'
158
+
159
+ expect(entity.to_header).to eql(expected)
160
+ end
161
+
162
+ it 'renders instance with attributes in HTTP Header correctly' do
163
+ entity.actions << testaction
164
+ entity.title = 'TestTitle'
165
+ entity.location = '/TestLoc/1'
166
+ entity.mixins << 'http://example.com/mynamespace#mymixin'
167
+
168
+ expected = Hashie::Mash.new
169
+ expected['Category'] = 'entity;scheme="http://schemas.ogf.org/occi/core#";class="kind",mymixin;scheme="http://example.com/mynamespace#";class="mixin"'
170
+ expected['X-OCCI-Attribute'] = 'occi.core.id="baf1",occi.core.title="TestTitle"'
171
+ expected['Link'] = '</TestLoc/1?action=testaction>;rel=http://schemas.ogf.org/occi/core/entity/action#testaction'
172
+
173
+ expect(entity.to_header).to eql(expected)
174
+ end
175
+ end
176
+
177
+ context '#check' do
178
+ let(:defs){
179
+ defs = Occi::Core::Attributes.new
180
+ defs['occi.core.id'] = { :type=> 'string',
181
+ :required => true }
182
+ defs['numbertype'] = { :type => 'number',
183
+ :default => 42,
184
+ :mutable => true,
185
+ :pattern => '^[0-9]+' }
186
+ defs['stringtype'] = { :type => 'string',
187
+ :pattern => '[adefltuv]+',
188
+ :default => 'defaultvalue',
189
+ :mutable => true }
190
+ defs['booleantype'] = { :type => 'boolean',
191
+ :default => true,
192
+ :mutable => true}
193
+ defs['booleantypefalse'] = { :type => 'boolean',
194
+ :default => false,
195
+ :mutable => true }
196
+ defs['booleantypepattern'] = { :type => 'boolean',
197
+ :default => true,
198
+ :mutable => true,
199
+ :pattern => true }
200
+ defs }
201
+ let(:kind){ Occi::Core::Kind.new 'http://schemas.ogf.org/occi/core#', 'testkind', 'Test Kind', defs }
202
+ let(:model){ model = Occi::Model.new
203
+ model.register(kind)
204
+ model.register(defmixin)
205
+ model }
206
+ let(:defmixin){ defmixin = Occi::Core::Mixin.new 'http://schemas.ogf.org/occi/core#', 'testmixin'
207
+ defmixin.attributes['mixinstring'] = { :type => 'string',
208
+ :pattern => '.*',
209
+ :default => 'mixdefault',
210
+ :mutable => true }
211
+ defmixin }
212
+ let(:mixin){ Occi::Core::Mixin.new 'http://schemas.ogf.org/occi/core#', 'testmixin' }
213
+
214
+ let(:entity){ entity = Occi::Core::Entity.new(kind, [], defs)
215
+ entity.model = model
216
+ entity.mixins << mixin
217
+ entity }
218
+
219
+
220
+ before(:each){ Occi::Settings['compatibility']=false
221
+ Occi::Settings['verify_attribute_pattern']=true }
222
+ after(:each) { Occi::Settings.reload! }
223
+ context 'unsupported types' do
224
+ it 'refuses unsupported type' do
225
+ expect{ entity.attributes['othertype'] = { :type => 'other', :default => 'defaultvalue' } }.to raise_exception(Occi::Errors::AttributePropertyTypeError)
226
+ end
227
+ end
228
+ context 'defaults' do
229
+ context 'setting defaults' do
230
+ it 'sets numeric default' do
231
+ entity.check(true)
232
+ expect(entity.attributes['numbertype']).to eq 42
233
+ end
234
+ it 'sets string default' do
235
+ entity.check(true)
236
+ expect(entity.attributes['stringtype']).to eq 'defaultvalue'
237
+ end
238
+ it 'sets mixin string default' do
239
+ entity.check(true)
240
+ expect(entity.attributes['mixinstring']).to eq 'mixdefault'
241
+ end
242
+ it 'sets boolean default if true' do
243
+ entity.check(true)
244
+ expect(entity.attributes['booleantype']).to eq true
245
+ end
246
+ it 'sets boolean default if false' do
247
+ entity.check(true)
248
+ expect(entity.attributes['booleantypefalse']).to eq false
249
+ end
250
+ it 'can be checked twice in a row' do
251
+ entity.check(true)
252
+ expect{ entity.check(true) }.to_not raise_exception
253
+ end
254
+ it 'skips numeric default' do
255
+ entity.attributes['numbertype'] = 12
256
+ entity.check(true)
257
+ expect(entity.attributes['numbertype']).to eq 12
258
+ end
259
+ it 'skips string default' do
260
+ entity.attributes['stringtype'] = 'fault'
261
+ entity.check(true)
262
+ expect(entity.attributes['stringtype']).to eq 'fault'
263
+ end
264
+ it 'skips boolean default if true' do
265
+ entity.attributes['booleantype'] = false
266
+ entity.check(true)
267
+ expect(entity.attributes['booleantype']).to eq false
268
+ end
269
+ it 'skips boolean default if false' do
270
+ entity.attributes['booleantypefalse'] = true
271
+ entity.check(true)
272
+ expect(entity.attributes['booleantypefalse']).to eq true
273
+ end
274
+ end
275
+
276
+ context 'patterns' do
277
+ it 'checks string pattern' do
278
+ expect{ entity.attributes['stringtype'] = 'bflmpsvz' }.to raise_exception(Occi::Errors::AttributeTypeError)
279
+ end
280
+ it 'checks numeric pattern' do
281
+ expect{ entity.attributes['numbertype'] = -32 }.to raise_exception(Occi::Errors::AttributeTypeError)
282
+ end
283
+ it 'checks boolean pattern' do
284
+ expect{ entity.attributes['booleantypepattern'] = false }.to raise_exception(Occi::Errors::AttributeTypeError)
285
+ end
286
+ end
287
+ end
288
+
289
+ context 'exceptions' do
290
+ it 'raisees exception for missing model' do
291
+ ent = Occi::Core::Entity.new(kind, [], defs)
292
+ expect{ ent.check(true) }.to raise_exception ArgumentError
293
+ end
294
+
295
+ it 'raises exception for inexistent kind' do
296
+ ent = Occi::Core::Entity.new(kind, [], defs)
297
+ mod = Occi::Model.new
298
+ ent.model = mod
299
+ expect{ ent.check(true) }.to raise_exception Occi::Errors::KindNotDefinedError
300
+ end
301
+ end
302
+ end
303
+
304
+ context '#attribute_properties' do
305
+ it 'gets attribute properties' do
306
+ properties = entity.attribute_properties
307
+ expect(properties.occi.core.count).to eql 4
308
+ end
309
+ end
310
+
311
+ context '#empty?' do
312
+
313
+ it 'returns false for a new instance with defaults' do
314
+ expect(entity.empty?).to be_false
315
+ end
316
+
317
+ it 'returns true for an instance without a kind' do
318
+ ent = entity.clone
319
+ ent.kind = nil
320
+
321
+ expect(ent.empty?).to be_true
322
+ end
323
+
324
+ it 'returns true for an instance without an identifier' do
325
+ ent = entity.clone
326
+ ent.id = nil
327
+
328
+ expect(ent.empty?).to be_true
329
+ end
330
+
42
331
  end
43
332
 
44
333
  end