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.
- data/.gitignore +1 -0
- data/Gemfile +8 -0
- data/README.md +49 -17
- data/lib/occi/collection.rb +37 -21
- data/lib/occi/core/action.rb +5 -5
- data/lib/occi/core/action_instance.rb +45 -3
- data/lib/occi/core/actions.rb +2 -1
- data/lib/occi/core/attributes.rb +253 -73
- data/lib/occi/core/categories.rb +1 -0
- data/lib/occi/core/category.rb +25 -8
- data/lib/occi/core/entities.rb +1 -0
- data/lib/occi/core/entity.rb +51 -74
- data/lib/occi/core/kind.rb +15 -11
- data/lib/occi/core/kinds.rb +1 -1
- data/lib/occi/core/link.rb +14 -15
- data/lib/occi/core/links.rb +1 -1
- data/lib/occi/core/mixin.rb +5 -5
- data/lib/occi/core/mixins.rb +2 -2
- data/lib/occi/core/properties.rb +90 -12
- data/lib/occi/core/resource.rb +7 -3
- data/lib/occi/core/resources.rb +2 -2
- data/lib/occi/errors/attribute_definitions_converted_error.rb +5 -0
- data/lib/occi/errors/attribute_missing_error.rb +5 -0
- data/lib/occi/errors/attribute_name_invalid_error.rb +5 -0
- data/lib/occi/errors/attribute_not_defined_error.rb +5 -0
- data/lib/occi/errors/attribute_property_type_error.rb +5 -0
- data/lib/occi/errors/attribute_type_error.rb +5 -0
- data/lib/occi/errors/kind_not_defined_error.rb +5 -0
- data/lib/occi/errors/parser_input_error.rb +5 -0
- data/lib/occi/errors/parser_type_error.rb +5 -0
- data/lib/occi/errors.rb +1 -0
- data/lib/occi/extensions/hashie.rb +25 -0
- data/lib/occi/helpers/comparators/action_instance.rb +22 -0
- data/lib/occi/helpers/comparators/attributes.rb +22 -0
- data/lib/occi/helpers/comparators/categories.rb +22 -0
- data/lib/occi/helpers/comparators/category.rb +22 -0
- data/lib/occi/helpers/comparators/collection.rb +40 -0
- data/lib/occi/helpers/comparators/entities.rb +22 -0
- data/lib/occi/helpers/comparators/entity.rb +22 -0
- data/lib/occi/helpers/comparators/properties.rb +26 -0
- data/lib/occi/helpers/comparators.rb +1 -0
- data/lib/occi/infrastructure/compute.rb +11 -9
- data/lib/occi/infrastructure/network.rb +27 -27
- data/lib/occi/infrastructure/networkinterface.rb +22 -23
- data/lib/occi/infrastructure/os_tpl.rb +1 -1
- data/lib/occi/infrastructure/resource_tpl.rb +1 -1
- data/lib/occi/infrastructure/storage.rb +7 -6
- data/lib/occi/infrastructure/storagelink.rb +4 -4
- data/lib/occi/log.rb +13 -10
- data/lib/occi/model.rb +9 -8
- data/lib/occi/parser/json.rb +11 -9
- data/lib/occi/parser/ova.rb +12 -6
- data/lib/occi/parser/ovf.rb +173 -116
- data/lib/occi/parser/text/constants.rb +87 -0
- data/lib/occi/parser/text.rb +161 -200
- data/lib/occi/parser/xml.rb +10 -8
- data/lib/occi/parser.rb +100 -50
- data/lib/occi/settings.rb +2 -1
- data/lib/occi/version.rb +1 -1
- data/lib/occi-core.rb +6 -4
- data/occi-core.gemspec +0 -7
- data/spec/occi/collection_samples/collection1.json +1 -0
- data/spec/occi/collection_samples/directory2/collection2.json +1 -0
- data/spec/occi/collection_spec.rb +961 -31
- data/spec/occi/core/action_instance_spec.rb +317 -0
- data/spec/occi/core/action_spec.rb +71 -0
- data/spec/occi/core/attributes_spec.rb +582 -27
- data/spec/occi/core/category_spec.rb +194 -18
- data/spec/occi/core/entities_spec.rb +96 -0
- data/spec/occi/core/entity_spec.rb +317 -28
- data/spec/occi/core/kind_spec.rb +127 -16
- data/spec/occi/core/link_spec.rb +35 -0
- data/spec/occi/core/links_spec.rb +130 -0
- data/spec/occi/core/mixins_spec.rb +107 -0
- data/spec/occi/core/properties_spec.rb +167 -0
- data/spec/occi/core/resource_spec.rb +23 -9
- data/spec/occi/core_spec.rb +12 -0
- data/spec/occi/infrastructure/compute_spec.rb +218 -18
- data/spec/occi/infrastructure/network_spec.rb +96 -0
- data/spec/occi/infrastructure/networkinterface_spec.rb +96 -0
- data/spec/occi/infrastructure/storage_spec.rb +33 -0
- data/spec/occi/infrastructure/storagelink_spec.rb +45 -0
- data/spec/occi/log_spec.rb +104 -1
- data/spec/occi/model_spec.rb +251 -39
- data/spec/occi/{test.json → parser/json_samples/test.json} +0 -0
- data/spec/occi/parser/ova_samples/test.dump +0 -0
- data/spec/occi/{test.ova → parser/ova_samples/test.ova} +0 -0
- data/spec/occi/parser/ovf_samples/test.dump +0 -0
- data/spec/occi/{test.ovf → parser/ovf_samples/test.ovf} +0 -0
- data/spec/occi/parser/text_samples/occi_categories.dump +0 -0
- data/spec/occi/parser/text_samples/occi_categories.text +2 -0
- data/spec/occi/parser/text_samples/occi_compute_rocci_server.dump +0 -0
- data/spec/occi/parser/text_samples/occi_compute_rocci_server.resource.dump +0 -0
- data/spec/occi/parser/text_samples/occi_compute_rocci_server.text +10 -0
- data/spec/occi/parser/text_samples/occi_link_resource_instance.dump +0 -0
- data/spec/occi/parser/text_samples/occi_link_resource_instance.text +7 -0
- data/spec/occi/parser/text_samples/occi_link_simple.dump +0 -0
- data/spec/occi/parser/text_samples/occi_link_simple.link_string.dump +0 -0
- data/spec/occi/parser/text_samples/occi_link_simple.text +1 -0
- data/spec/occi/parser/text_samples/occi_link_w_attributes.dump +0 -0
- data/spec/occi/parser/text_samples/occi_link_w_attributes.text +7 -0
- data/spec/occi/parser/text_samples/occi_link_w_category.dump +0 -0
- data/spec/occi/parser/text_samples/occi_link_w_category.text +3 -0
- data/spec/occi/parser/text_samples/occi_model_rocci_server.dump +0 -0
- data/spec/occi/parser/text_samples/occi_model_rocci_server.text +51 -0
- data/spec/occi/parser/text_samples/occi_network_rocci_server.dump +0 -0
- data/spec/occi/parser/text_samples/occi_network_rocci_server.resource.dump +0 -0
- data/spec/occi/parser/text_samples/occi_network_rocci_server.text +11 -0
- data/spec/occi/parser/text_samples/occi_resource_w_attributes.dump +0 -0
- data/spec/occi/parser/text_samples/occi_resource_w_attributes.text +11 -0
- data/spec/occi/parser/text_samples/occi_resource_w_inline_links.dump +0 -0
- data/spec/occi/parser/text_samples/occi_resource_w_inline_links.text +16 -0
- data/spec/occi/parser/text_samples/occi_resource_w_inline_links_only.dump +0 -0
- data/spec/occi/parser/text_samples/occi_resource_w_inline_links_only.text +13 -0
- data/spec/occi/parser/text_samples/occi_storage_rocci_server.dump +0 -0
- data/spec/occi/parser/text_samples/occi_storage_rocci_server.resource.dump +0 -0
- data/spec/occi/parser/text_samples/occi_storage_rocci_server.text +9 -0
- data/spec/occi/parser/text_spec.rb +274 -78
- data/spec/occi/parser/xml_samples/test.xml +352 -0
- data/spec/occi/parser_spec.rb +255 -104
- data/spec/occi-core_spec.rb +31 -0
- data/spec/spec_helper.rb +6 -2
- metadata +110 -111
- checksums.yaml +0 -7
- data/spec/occi/core/attribute_spec.rb +0 -0
data/spec/occi/core/kind_spec.rb
CHANGED
|
@@ -4,21 +4,33 @@ module Occi
|
|
|
4
4
|
|
|
5
5
|
describe '#get_class' do
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
scheme
|
|
9
|
-
term
|
|
10
|
-
klass
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
context 'OCCI Resource class' do
|
|
8
|
+
let(:scheme){ 'http://schemas.ogf.org/occi/core' }
|
|
9
|
+
let(:term){ 'resource' }
|
|
10
|
+
let(:klass){ Occi::Core::Kind.get_class scheme, term }
|
|
11
|
+
|
|
12
|
+
it 'gets OCCI Resource class by term term and scheme' do
|
|
13
|
+
expect(klass).to be Occi::Core::Resource
|
|
14
|
+
end
|
|
15
|
+
it 'also gets the superclass' do
|
|
16
|
+
expect(klass.superclass).to be Occi::Core::Entity
|
|
17
|
+
#TODO: Possibly move this test to resource_spec?
|
|
18
|
+
end
|
|
13
19
|
end
|
|
14
20
|
|
|
15
|
-
|
|
16
|
-
scheme
|
|
17
|
-
term
|
|
18
|
-
related
|
|
19
|
-
klass
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
context 'non-predefined OCCI class' do
|
|
22
|
+
let(:scheme){ 'http://example.com/occi' }
|
|
23
|
+
let(:term){ 'test' }
|
|
24
|
+
let(:related){ ['http://schemas.ogf.org/occi/core#resource'] }
|
|
25
|
+
let(:klass){ Occi::Core::Kind.get_class scheme, term, related }
|
|
26
|
+
|
|
27
|
+
it 'gets non predefined OCCI class by term, scheme and related class' do
|
|
28
|
+
expect(klass).to be Com::Example::Occi::Test
|
|
29
|
+
end
|
|
30
|
+
it 'also gets the superclass' do
|
|
31
|
+
expect(klass.superclass).to be Occi::Core::Resource
|
|
32
|
+
#TODO: Possibly move this test to resource_spec?
|
|
33
|
+
end
|
|
22
34
|
end
|
|
23
35
|
|
|
24
36
|
it 'does not get OCCI class by term and scheme if it relates to existing class not derived from OCCI Entity' do
|
|
@@ -28,17 +40,116 @@ module Occi
|
|
|
28
40
|
expect { Occi::Core::Kind.get_class scheme, term, related }.to raise_error
|
|
29
41
|
end
|
|
30
42
|
|
|
43
|
+
context 'in case of improper input' do
|
|
44
|
+
|
|
45
|
+
it 'handles parent overriden with nil' do
|
|
46
|
+
expect(Occi::Core::Kind.get_class 'http://schemas.ogf.org/occi/core', 'resource', nil).to eq Occi::Core::Resource
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it 'copes with invalid characters in scheme' do
|
|
50
|
+
expect{Occi::Core::Kind.get_class 'http://schemas ogf.org/occi/core', 'resource'}.to raise_error(URI::InvalidURIError)
|
|
51
|
+
end
|
|
52
|
+
it 'copes with non-URI-like structure of the scheme' do
|
|
53
|
+
expect{Occi::Core::Kind.get_class 'doesnotexist', 'resource'}.to raise_error(StandardError)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
context 'handling invalid characters in term' do
|
|
57
|
+
after { Occi::Settings.reload! }
|
|
58
|
+
it 'copes with compatibility on' do
|
|
59
|
+
Occi::Settings['compatibility'] = true
|
|
60
|
+
expect(Occi::Core::Kind.get_class 'http://schemas.ogf.org/occi/core', '# #resource$').to eq Occi::Core::Resource
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it 'copes with compatibility off' do
|
|
64
|
+
Occi::Settings['compatibility'] = false
|
|
65
|
+
expect{Occi::Core::Kind.get_class 'http://schemas.ogf.org/occi/core', '# #resource$'}.to raise_error(ArgumentError)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it 'handles nil scheme' do
|
|
70
|
+
expect{Occi::Core::Kind.get_class nil, 'resource'}.to raise_error(ArgumentError)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it 'handles nil resource' do
|
|
74
|
+
expect{Occi::Core::Kind.get_class 'http://schemas.ogf.org/occi/core', nil}.to raise_error(ArgumentError)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it 'copes with invalid parent' do
|
|
78
|
+
expect{Occi::Core::Kind.get_class 'http://example.com/occi', 'test', 'http://s chemas.ogf.org/occi/core#resource'}.to raise_error(URI::InvalidURIError)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it 'copes with parent missing term' do
|
|
82
|
+
expect{Occi::Core::Kind.get_class 'http://example.com/occi', 'test', 'http://s chemas.ogf.org/occi/core'}.to raise_error(ArgumentError)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
end
|
|
86
|
+
|
|
31
87
|
end
|
|
32
88
|
|
|
33
89
|
describe '#related_to?' do
|
|
90
|
+
let(:base){ Occi::Core::Kind.new 'http://occi.test.case/core/kind', 'base' }
|
|
91
|
+
let(:related){ Occi::Core::Kind.new 'http://occi.test.case/core/kind/base', 'related', 'title', Occi::Core::Attributes.new, base }
|
|
92
|
+
let(:unrelated){ Occi::Core::Kind.new 'http://occi.test.case/core/kind', 'unrelated' }
|
|
93
|
+
|
|
94
|
+
it 'recognizes existing relationship' do
|
|
95
|
+
expect(related.related_to?(base)).to eq true
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it 'does not give false positives on non-existent relationship' do
|
|
99
|
+
expect(base.related_to?(unrelated)).to eq false
|
|
100
|
+
end
|
|
34
101
|
|
|
35
|
-
it '
|
|
36
|
-
|
|
37
|
-
|
|
102
|
+
it 'recognizes transitive relationships' #do #TODO This test actually works, but fails because te feature is not yet implemented
|
|
103
|
+
# grandchild = Occi::Core::Kind.new 'http://occi.test.case/core/kind/base', 'related', 'title', Occi::Core::Attributes.new, related
|
|
104
|
+
# expect(grandchild.related_to?(base)).to eq true
|
|
105
|
+
# end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
describe '#as_json' do
|
|
109
|
+
let(:kind){ Occi::Core::Kind.new }
|
|
110
|
+
|
|
111
|
+
it 'renders JSON correctly from freshly initialized object' do
|
|
112
|
+
expected = '{"location":"/kind/","term":"kind","scheme":"http://schemas.ogf.org/occi/core#","attributes":{}}'
|
|
113
|
+
hash=Hashie::Mash.new(JSON.parse(expected))
|
|
114
|
+
expect(kind.as_json).to eql(hash)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
it 'renders JSON correctly with optional attributes' do
|
|
118
|
+
kind.title = "test title"
|
|
119
|
+
expected = '{"location":"/kind/","term":"kind","scheme":"http://schemas.ogf.org/occi/core#","title":"test title","attributes":{}}'
|
|
120
|
+
hash=Hashie::Mash.new(JSON.parse(expected))
|
|
121
|
+
expect(kind.as_json).to eql(hash)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it 'renders JSON correctly with special characters' do
|
|
125
|
+
kind.title = "Some special characters @#\$%"
|
|
126
|
+
expected = '{"location":"/kind/","term":"kind","scheme":"http://schemas.ogf.org/occi/core#","title":"Some special characters @#\$%","attributes":{}}'
|
|
127
|
+
hash=Hashie::Mash.new(JSON.parse(expected))
|
|
128
|
+
expect(kind.as_json).to eql(hash)
|
|
38
129
|
end
|
|
39
130
|
|
|
40
131
|
end
|
|
41
132
|
|
|
133
|
+
describe '#to_string' do
|
|
134
|
+
let(:kind){ Occi::Core::Kind.new }
|
|
135
|
+
|
|
136
|
+
it 'produces a string correctly from freshly initialized object' do
|
|
137
|
+
expected = ('scheme="http://schemas.ogf.org/occi/core#";class="kind";location="/kind/";kind').split(/;/)
|
|
138
|
+
actual = kind.to_string.split(/;/)
|
|
139
|
+
expect(actual).to match_array(expected)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
it 'produces a string correctly with optional attributes' do
|
|
143
|
+
kind.title = "test title"
|
|
144
|
+
expected = ('scheme="http://schemas.ogf.org/occi/core#";class="kind";location="/kind/";kind;title="test title"').split(/;/)
|
|
145
|
+
actual = kind.to_string.split(/;/)
|
|
146
|
+
expect(actual).to match_array(expected)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# TODO: Optional attributes, special characters
|
|
150
|
+
|
|
151
|
+
end
|
|
152
|
+
|
|
42
153
|
end
|
|
43
154
|
end
|
|
44
155
|
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Occi
|
|
2
|
+
module Core
|
|
3
|
+
describe Link do
|
|
4
|
+
# XXX This is a poor man's spec file, by no means exhaustive
|
|
5
|
+
# XXX So far it is only used to cover code otherwise not
|
|
6
|
+
# XXX covered by calls from other specs
|
|
7
|
+
|
|
8
|
+
context '#check' do
|
|
9
|
+
let(:defs){
|
|
10
|
+
defs = Occi::Core::Attributes.new
|
|
11
|
+
defs['occi.core.id'] = { :type=> 'string', :required => true }
|
|
12
|
+
defs['stringtype'] = { :type => 'string', :pattern => '[adefltuv]+',
|
|
13
|
+
:default => 'defaultforlink', :mutable => true, :required => true }
|
|
14
|
+
defs }
|
|
15
|
+
|
|
16
|
+
it 'sets default for required attribute' do
|
|
17
|
+
link = Occi::Core::Link.new
|
|
18
|
+
link.kind.attributes.merge!(defs)
|
|
19
|
+
model = Occi::Model.new
|
|
20
|
+
model.register(link.kind)
|
|
21
|
+
link.model = model
|
|
22
|
+
|
|
23
|
+
link.check
|
|
24
|
+
expect(link.attributes['stringtype']).to eql 'defaultforlink'
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'raises error if no relationship is set' do
|
|
28
|
+
norel = Occi::Core::Link.new
|
|
29
|
+
norel.instance_eval { @rel=nil }
|
|
30
|
+
expect{ norel.check }.to raise_exception ArgumentError
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
module Occi
|
|
2
|
+
module Core
|
|
3
|
+
describe Links do
|
|
4
|
+
|
|
5
|
+
context '.initialize' do
|
|
6
|
+
it 'initializes an empty Links set' do
|
|
7
|
+
links = Occi::Core::Links.new
|
|
8
|
+
expect(links).to eql []
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
context 'with multiple members' do
|
|
12
|
+
let(:link1){ Occi::Core::Link.new }
|
|
13
|
+
let(:link2){ Occi::Core::Link.new }
|
|
14
|
+
let(:links){ Occi::Core::Links.new [link1,link2] }
|
|
15
|
+
let(:expected){ expected = []
|
|
16
|
+
links.each { |ln| expected << ln.id }
|
|
17
|
+
expected }
|
|
18
|
+
|
|
19
|
+
it 'produces the right number of members' do
|
|
20
|
+
expect(links.count).to eql 2
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it 'has the first link' do
|
|
24
|
+
expect(link1.id).to satisfy { |id| expected.include?(id) }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'has the second link' do
|
|
28
|
+
expect(link2.id).to satisfy { |id| expected.include?(id) }
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
context 'with strings' do
|
|
33
|
+
it 'produces the right number of members, strings only' do
|
|
34
|
+
links = Occi::Core::Links.new ["target1","target2"]
|
|
35
|
+
expect(links.count).to eql 2
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it 'populates target in the link' do
|
|
39
|
+
links = Occi::Core::Links.new ["target1"]
|
|
40
|
+
expect(links.first.target).to eql "target1"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it 'produces the right number of members, string/link combination' do
|
|
44
|
+
link2 = Occi::Core::Link.new
|
|
45
|
+
links = Occi::Core::Links.new ["target1",link2]
|
|
46
|
+
expect(links.count).to eql 2
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
context '<<' do
|
|
54
|
+
context 'into an empty set' do
|
|
55
|
+
let(:link1){ Occi::Core::Link.new }
|
|
56
|
+
let(:links){ links = Occi::Core::Links.new
|
|
57
|
+
links << link1
|
|
58
|
+
links }
|
|
59
|
+
|
|
60
|
+
it 'produces the right number of members' do
|
|
61
|
+
expect(links.count).to eql 1
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it 'has the link' do
|
|
65
|
+
expect(links.first.id).to eql link1.id
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
context 'into a populated set' do
|
|
70
|
+
let(:link1){ Occi::Core::Link.new }
|
|
71
|
+
let(:link2){ Occi::Core::Link.new }
|
|
72
|
+
let(:links){ links = Occi::Core::Links.new [link2]
|
|
73
|
+
links << link1
|
|
74
|
+
links }
|
|
75
|
+
let(:expected){ expected = []
|
|
76
|
+
links.each { |ln| expected << ln.id }
|
|
77
|
+
expected }
|
|
78
|
+
|
|
79
|
+
it 'produces the right number of members' do
|
|
80
|
+
expect(links.count).to eql 2
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it 'has the first link' do
|
|
84
|
+
expect(link1.id).to satisfy { |id| expected.include?(id) }
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it 'has the second link' do
|
|
88
|
+
expect(link2.id).to satisfy { |id| expected.include?(id) }
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
context '.create' do
|
|
94
|
+
context 'in an empty set' do
|
|
95
|
+
let!(:links){ Occi::Core::Links.new }
|
|
96
|
+
let!(:link1){ links.create }
|
|
97
|
+
|
|
98
|
+
it 'produces the right number of members' do
|
|
99
|
+
expect(links.count).to eql 1
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
it 'has the link' do
|
|
103
|
+
expect(links.first.id).to eql link1.id
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
context 'in a populated set' do
|
|
108
|
+
let(:link2){ Occi::Core::Link.new }
|
|
109
|
+
let!(:links){ Occi::Core::Links.new [link2] }
|
|
110
|
+
let!(:link1){ links.create }
|
|
111
|
+
let!(:expected){ expected = []
|
|
112
|
+
links.each { |ln| expected << ln.id }
|
|
113
|
+
expected }
|
|
114
|
+
|
|
115
|
+
it 'produces the right number of members' do
|
|
116
|
+
expect(links.count).to eql 2
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it 'has the first link' do
|
|
120
|
+
expect(link1.id).to satisfy { |id| expected.include?(id) }
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it 'has the second link' do
|
|
124
|
+
expect(link2.id).to satisfy { |id| expected.include?(id) }
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
module Occi
|
|
2
|
+
module Core
|
|
3
|
+
describe Mixins do
|
|
4
|
+
|
|
5
|
+
context '#entity=' do
|
|
6
|
+
let(:ent){ Occi::Core::Entity.new }
|
|
7
|
+
let(:mixins){ Occi::Core::Mixins.new }
|
|
8
|
+
|
|
9
|
+
context 'assignment with mixins set empty' do
|
|
10
|
+
let(:mixin){ Occi::Core::Mixin.new }
|
|
11
|
+
it 'assigns entity to an empty mixin' do
|
|
12
|
+
mixins.entity = ent
|
|
13
|
+
expect(mixins.entity).to eql ent
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
context 'converting attributes form members into the assigned entity' do
|
|
18
|
+
let(:mixin){ mixin = Occi::Core::Mixin.new
|
|
19
|
+
mixin.attributes['stringtype'] = { :type => 'string',
|
|
20
|
+
:pattern => '[adefltuv]+',
|
|
21
|
+
:default => 'defaultvalue',
|
|
22
|
+
:mutable => true }
|
|
23
|
+
mixin.attributes['stringtype'] = 'flute'
|
|
24
|
+
mixin }
|
|
25
|
+
|
|
26
|
+
before(:each) {
|
|
27
|
+
mixins << mixin
|
|
28
|
+
mixins.entity = ent }
|
|
29
|
+
|
|
30
|
+
it 'removes assigned values' do
|
|
31
|
+
expect(mixins.entity.attributes['stringtype']).to eql nil
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'preserves attribute properties' do
|
|
35
|
+
expect(mixins.entity.attributes['_stringtype']).to_not eql nil
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
context '<<' do
|
|
41
|
+
let!(:mixins){ Occi::Core::Mixins.new }
|
|
42
|
+
|
|
43
|
+
it 'adds a mixin to an empty set' do
|
|
44
|
+
mixins << Occi::Infrastructure::OsTpl.mixin
|
|
45
|
+
expect(mixins.include?(Occi::Infrastructure::OsTpl.mixin)).to eql true
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it 'adds a mixin to an empty set' do
|
|
49
|
+
mixins << Occi::Infrastructure::OsTpl.mixin
|
|
50
|
+
mixins << Occi::Infrastructure::ResourceTpl.mixin
|
|
51
|
+
expect(mixins.include?(Occi::Infrastructure::ResourceTpl.mixin)).to eql true
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it 'only adds the supplied mixin' do
|
|
55
|
+
mixins << Occi::Infrastructure::OsTpl.mixin
|
|
56
|
+
expect(mixins.include?(Occi::Infrastructure::ResourceTpl.mixin)).to eql false
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it 'adds mixin from string' do
|
|
60
|
+
mixins << "http://schemas.ogf.org/occi/core#testmixin"
|
|
61
|
+
expect(mixins.first.term).to eql "testmixin"
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
context '#remove' do
|
|
66
|
+
let!(:mixins){ Occi::Core::Mixins.new }
|
|
67
|
+
|
|
68
|
+
it 'removes last mixin from the set' do
|
|
69
|
+
mixins << Occi::Infrastructure::OsTpl.mixin
|
|
70
|
+
mixins.remove(Occi::Infrastructure::OsTpl.mixin)
|
|
71
|
+
expect(mixins.include?(Occi::Infrastructure::OsTpl.mixin)).to eql false
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it 'removes mixin from among multiple members' do
|
|
75
|
+
mixins << Occi::Infrastructure::OsTpl.mixin
|
|
76
|
+
mixins << Occi::Infrastructure::ResourceTpl.mixin
|
|
77
|
+
mixins.remove(Occi::Infrastructure::OsTpl.mixin)
|
|
78
|
+
expect(mixins.include?(Occi::Infrastructure::OsTpl.mixin)).to eql false
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it 'leaves other unaffected' do
|
|
82
|
+
mixins << Occi::Infrastructure::OsTpl.mixin
|
|
83
|
+
mixins << Occi::Infrastructure::ResourceTpl.mixin
|
|
84
|
+
mixins.remove(Occi::Infrastructure::OsTpl.mixin)
|
|
85
|
+
expect(mixins.include?(Occi::Infrastructure::ResourceTpl.mixin)).to eql true
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it 'removes attributes from the entity attribute' do
|
|
89
|
+
ent = Occi::Core::Entity.new
|
|
90
|
+
mixin = Occi::Core::Mixin.new
|
|
91
|
+
mixin.attributes['stringtype'] = { :type => 'string', :pattern => '[adefltuv]+', :default => 'defaultvalue', :mutable => true }
|
|
92
|
+
mixin.attributes['stringtype'] = 'flute'
|
|
93
|
+
|
|
94
|
+
mixins << mixin
|
|
95
|
+
mixins.entity = ent
|
|
96
|
+
|
|
97
|
+
mixins.remove(mixin)
|
|
98
|
+
|
|
99
|
+
expect(mixins.entity.attributes['_stringtype']).to eql nil
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
context '#convert' do
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
module Occi
|
|
2
|
+
module Core
|
|
3
|
+
describe Properties do
|
|
4
|
+
|
|
5
|
+
context '#type=' do
|
|
6
|
+
let(:properties){ Occi::Core::Properties.new }
|
|
7
|
+
it 'accepts string' do
|
|
8
|
+
expect{ properties.type = 'string' }.to_not raise_exception
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it 'accepts number' do
|
|
12
|
+
expect{ properties.type = 'number' }.to_not raise_exception
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it 'accepts boolean' do
|
|
16
|
+
expect{ properties.type = 'boolean' }.to_not raise_exception
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'rejects another string' do
|
|
20
|
+
expect{ properties.type = 'other' }.to raise_exception Occi::Errors::AttributePropertyTypeError
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
context '#check_value_for_type' do
|
|
26
|
+
context 'string' do
|
|
27
|
+
let(:properties){ properties = Occi::Core::Properties.new
|
|
28
|
+
properties.type = 'string'
|
|
29
|
+
properties }
|
|
30
|
+
|
|
31
|
+
it 'permits string' do
|
|
32
|
+
expect{ properties.check_value_for_type("string") }.to_not raise_exception
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it 'rejects nil' do
|
|
36
|
+
expect{ properties.check_value_for_type(nil) }.to raise_exception(Occi::Errors::AttributeTypeError)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'rejects another class' do
|
|
40
|
+
expect{ properties.check_value_for_type(true) }.to raise_exception(Occi::Errors::AttributeTypeError)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
context 'number' do
|
|
45
|
+
let(:properties){ properties = Occi::Core::Properties.new
|
|
46
|
+
properties.type = 'number'
|
|
47
|
+
properties }
|
|
48
|
+
|
|
49
|
+
it 'permits number' do
|
|
50
|
+
expect{ properties.check_value_for_type(42) }.to_not raise_exception
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it 'rejects nil' do
|
|
54
|
+
expect{ properties.check_value_for_type(nil) }.to raise_exception(Occi::Errors::AttributeTypeError)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it 'rejects another class' do
|
|
58
|
+
expect{ properties.check_value_for_type("string") }.to raise_exception(Occi::Errors::AttributeTypeError)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
context 'boolean' do
|
|
63
|
+
let(:properties){ properties = Occi::Core::Properties.new
|
|
64
|
+
properties.type = 'boolean'
|
|
65
|
+
properties }
|
|
66
|
+
|
|
67
|
+
it 'permits true' do
|
|
68
|
+
expect{ properties.check_value_for_type(true) }.to_not raise_exception
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it 'permits false' do
|
|
72
|
+
expect{ properties.check_value_for_type(false) }.to_not raise_exception
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it 'rejects nil' do
|
|
76
|
+
expect{ properties.check_value_for_type(nil) }.to raise_exception(Occi::Errors::AttributeTypeError)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it 'rejects another class' do
|
|
80
|
+
expect{ properties.check_value_for_type(0) }.to raise_exception(Occi::Errors::AttributeTypeError)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
context 'rendering' do
|
|
86
|
+
let(:properties) { properties = Occi::Core::Properties.new
|
|
87
|
+
properties.type = "string"
|
|
88
|
+
properties.required = true
|
|
89
|
+
properties.mutable = true
|
|
90
|
+
properties.default = "defaultvalue"
|
|
91
|
+
properties.description = "Required string value"
|
|
92
|
+
properties.pattern = "[adefltuv]+"
|
|
93
|
+
properties }
|
|
94
|
+
|
|
95
|
+
context '#to_hash' do
|
|
96
|
+
it 'makes a correct rendering' do
|
|
97
|
+
expected = Hash.new
|
|
98
|
+
expected["description"] = "Required string value"
|
|
99
|
+
expected["mutable"] = true
|
|
100
|
+
expected["pattern"] = "[adefltuv]+"
|
|
101
|
+
expected["required"] = true
|
|
102
|
+
expected["type"] = "string"
|
|
103
|
+
|
|
104
|
+
expect(properties.to_hash).to eql expected
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
context '#as_json' do
|
|
109
|
+
it 'makes a correct rendering' do
|
|
110
|
+
expected = Hash.new
|
|
111
|
+
expected["description"] = "Required string value"
|
|
112
|
+
expected["mutable"] = true
|
|
113
|
+
expected["pattern"] = "[adefltuv]+"
|
|
114
|
+
expected["required"] = true
|
|
115
|
+
expected["type"] = "string"
|
|
116
|
+
|
|
117
|
+
expect(properties.to_hash).to eql expected
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
it 'makes a correct rendering of empty props' do
|
|
121
|
+
empty = Occi::Core::Properties.new
|
|
122
|
+
expected = Hash.new
|
|
123
|
+
expected["mutable"] = false
|
|
124
|
+
expected["pattern"] = ".*"
|
|
125
|
+
expected["required"] = false
|
|
126
|
+
expected["type"] = "string"
|
|
127
|
+
|
|
128
|
+
expect(empty.to_hash).to eql expected
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
context '#to_json' do
|
|
134
|
+
it 'makes a correct rendering' do
|
|
135
|
+
expected = '{"type":"string","required":true,"mutable":true,"pattern":"[adefltuv]+","description":"Required string value"}'
|
|
136
|
+
expect(properties.to_json).to eql expected
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
context '#empty?' do
|
|
142
|
+
let(:properties) { properties = Occi::Core::Properties.new
|
|
143
|
+
properties.type = "string"
|
|
144
|
+
properties.required = true
|
|
145
|
+
properties.mutable = true
|
|
146
|
+
properties.default = "defaultvalue"
|
|
147
|
+
properties.description = "Required string value"
|
|
148
|
+
properties.pattern = "[adefltuv]+"
|
|
149
|
+
properties }
|
|
150
|
+
|
|
151
|
+
it 'Returns false for non-empty props' do
|
|
152
|
+
expect(properties.empty?).to be false
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
it 'Returns true for empty props' do
|
|
156
|
+
empty = Occi::Core::Properties.new
|
|
157
|
+
empty.mutable = nil
|
|
158
|
+
empty.pattern = nil
|
|
159
|
+
empty.required = nil
|
|
160
|
+
empty.instance_eval { @type=nil }
|
|
161
|
+
|
|
162
|
+
expect(empty.empty?).to be true
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
@@ -1,18 +1,32 @@
|
|
|
1
1
|
module Occi
|
|
2
2
|
module Core
|
|
3
3
|
describe Resource do
|
|
4
|
-
|
|
5
|
-
it "links another resource succesfully" do
|
|
6
|
-
resource = Occi::Core::Resource.new
|
|
7
|
-
target = Occi::Core::Resource.new
|
|
8
|
-
# create a random ID as the resource must already exist and therefore must have an ID assigned
|
|
9
|
-
target.id = UUIDTools::UUID.random_create.to_s
|
|
4
|
+
let(:resource){ resource = Occi::Core::Resource.new
|
|
10
5
|
resource.link target
|
|
11
|
-
resource.
|
|
12
|
-
resource
|
|
13
|
-
|
|
6
|
+
resource.attributes.occi!.core!.summary = "Resource Summary"
|
|
7
|
+
resource }
|
|
8
|
+
let(:target){ target = Occi::Core::Resource.new }
|
|
9
|
+
|
|
10
|
+
context '#link' do
|
|
11
|
+
it "creates the appropriate No. of links" do
|
|
12
|
+
expect(resource.links).to have(1).link
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "has the correct kind" do
|
|
16
|
+
expect(resource.links.first).to be_kind_of Occi::Core::Link
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'sets the right target' do
|
|
20
|
+
expect(resource.links.first.target).to eql target
|
|
21
|
+
end
|
|
14
22
|
end
|
|
15
23
|
|
|
24
|
+
context '#summary' do
|
|
25
|
+
it 'gets the summary attribute corectly' do
|
|
26
|
+
expected = "Resource Summary"
|
|
27
|
+
expect(resource.summary).to eql expected
|
|
28
|
+
end
|
|
29
|
+
end
|
|
16
30
|
end
|
|
17
31
|
end
|
|
18
32
|
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module Occi
|
|
2
|
+
describe Core do
|
|
3
|
+
|
|
4
|
+
context ".kinds" do
|
|
5
|
+
it 'initializes kinds' do
|
|
6
|
+
kinds = Occi::Core.kinds
|
|
7
|
+
expected = Occi::Core::Kinds.new << Occi::Core::Entity.kind << Occi::Core::Link.kind << Occi::Core::Resource.kind
|
|
8
|
+
expect(kinds).to eql expected
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|