occi-core 4.1.3 → 4.2.0

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