1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Ci::Config::Yaml::Tags::Reference do
let(:config) do
Gitlab::Ci::Config::Yaml.load!(yaml)
end
describe '.tag' do
it 'implements the tag method' do
expect(described_class.tag).to eq('!reference')
end
end
describe '#resolve' do
subject { Gitlab::Ci::Config::Yaml::Tags::Resolver.new(config).to_hash }
context 'with circular references' do
let(:yaml) do
<<~YML
a: !reference [b]
b: !reference [a]
YML
end
it 'raises CircularReferenceError' do
expect { subject }.to raise_error Gitlab::Ci::Config::Yaml::Tags::TagError, '!reference ["b"] is part of a circular chain'
end
end
context 'with nested circular references' do
let(:yaml) do
<<~YML
a: !reference [b, c]
b: { c: !reference [d, e, f] }
d: { e: { f: !reference [a] } }
YML
end
it 'raises CircularReferenceError' do
expect { subject }.to raise_error Gitlab::Ci::Config::Yaml::Tags::TagError, '!reference ["b", "c"] is part of a circular chain'
end
end
context 'with missing references' do
let(:yaml) { 'a: !reference [b]' }
it 'raises MissingReferenceError' do
expect { subject }.to raise_error Gitlab::Ci::Config::Yaml::Tags::TagError, '!reference ["b"] could not be found'
end
end
context 'with invalid references' do
using RSpec::Parameterized::TableSyntax
where(:yaml, :error_message) do
'a: !reference' | '!reference [] is not valid'
'a: !reference str' | '!reference "str" is not valid'
'a: !reference 1' | '!reference "1" is not valid'
'a: !reference [1]' | '!reference [1] is not valid'
'a: !reference { b: c }' | '!reference {"b"=>"c"} is not valid'
end
with_them do
it 'raises an error' do
expect { subject }.to raise_error Gitlab::Ci::Config::Yaml::Tags::TagError, error_message
end
end
end
context 'with arrays' do
let(:yaml) do
<<~YML
a: { b: [1, 2] }
c: { d: { e: [3, 4] } }
f: { g: [ !reference [a, b], 5, !reference [c, d, e]] }
YML
end
it { is_expected.to match(a_hash_including({ f: { g: [[1, 2], 5, [3, 4]] } })) }
end
context 'with hashes' do
context 'when referencing an entire hash' do
let(:yaml) do
<<~YML
a: { b: { c: 'c', d: 'd' } }
e: { f: !reference [a, b] }
YML
end
it { is_expected.to match(a_hash_including({ e: { f: { c: 'c', d: 'd' } } })) }
end
context 'when referencing only a hash value' do
let(:yaml) do
<<~YML
a: { b: { c: 'c', d: 'd' } }
e: { f: { g: !reference [a, b, c], h: 'h' } }
i: !reference [e, f]
YML
end
it { is_expected.to match(a_hash_including({ i: { g: 'c', h: 'h' } })) }
end
context 'when referencing a value before its definition' do
let(:yaml) do
<<~YML
a: { b: !reference [c, d] }
g: { h: { i: 'i', j: 1 } }
c: { d: { e: !reference [g, h, j], f: 'f' } }
YML
end
it { is_expected.to match(a_hash_including({ a: { b: { e: 1, f: 'f' } } })) }
end
end
end
end
|