gitlab-org--gitlab-foss/spec/lib/gitlab/ci/config/extendable_spec.rb

275 lines
6.2 KiB
Ruby

# frozen_string_literal: true
require 'fast_spec_helper'
RSpec.describe Gitlab::Ci::Config::Extendable do
subject { described_class.new(hash) }
describe '#each' do
context 'when there is extendable entry in the hash' do
let(:test) do
{ extends: 'something', only: %w[master] }
end
let(:hash) do
{ something: { script: 'ls' }, test: test }
end
it 'yields control' do
expect { |b| subject.each(&b) }.to yield_control
end
end
end
describe '#to_hash' do
context 'when hash does not contain extensions' do
let(:hash) do
{
test: { script: 'test' },
production: {
script: 'deploy',
only: { variables: %w[$SOMETHING] }
}
}
end
it 'does not modify the hash' do
expect(subject.to_hash).to eq hash
end
end
context 'when hash has a single simple extension' do
let(:hash) do
{
something: {
script: 'deploy',
only: { variables: %w[$SOMETHING] }
},
test: {
extends: 'something',
script: 'ls',
only: { refs: %w[master] }
}
}
end
it 'extends a hash with a deep reverse merge' do
expect(subject.to_hash).to eq(
something: {
script: 'deploy',
only: { variables: %w[$SOMETHING] }
},
test: {
extends: 'something',
script: 'ls',
only: {
refs: %w[master],
variables: %w[$SOMETHING]
}
}
)
end
end
context 'when the job tries to delete an extension key' do
let(:hash) do
{
something: {
script: 'deploy',
only: { variables: %w[$SOMETHING] }
},
test1: {
extends: 'something',
script: 'ls',
only: {}
},
test2: {
extends: 'something',
script: 'ls',
only: nil
}
}
end
it 'deletes the key if assigned to null' do
expect(subject.to_hash).to eq(
something: {
script: 'deploy',
only: { variables: %w[$SOMETHING] }
},
test1: {
extends: 'something',
script: 'ls',
only: {
variables: %w[$SOMETHING]
}
},
test2: {
extends: 'something',
script: 'ls',
only: nil
}
)
end
end
context 'when a hash uses recursive extensions' do
let(:hash) do
{
test: {
extends: 'something',
script: 'ls',
only: { refs: %w[master] }
},
build: {
extends: 'something',
stage: 'build'
},
deploy: {
stage: 'deploy',
extends: '.first'
},
something: {
extends: '.first',
script: 'exec',
only: { variables: %w[$SOMETHING] }
},
'.first': {
script: 'run',
only: { kubernetes: 'active' }
}
}
end
it 'extends a hash with a deep reverse merge' do
expect(subject.to_hash).to eq(
'.first': {
script: 'run',
only: { kubernetes: 'active' }
},
something: {
extends: '.first',
script: 'exec',
only: {
kubernetes: 'active',
variables: %w[$SOMETHING]
}
},
deploy: {
script: 'run',
stage: 'deploy',
only: { kubernetes: 'active' },
extends: '.first'
},
build: {
extends: 'something',
script: 'exec',
stage: 'build',
only: {
kubernetes: 'active',
variables: %w[$SOMETHING]
}
},
test: {
extends: 'something',
script: 'ls',
only: {
refs: %w[master],
variables: %w[$SOMETHING],
kubernetes: 'active'
}
}
)
end
end
context 'when nested circular dependecy has been detected' do
let(:hash) do
{
test: {
extends: 'something',
script: 'ls',
only: { refs: %w[master] }
},
something: {
extends: '.first',
script: 'deploy',
only: { variables: %w[$SOMETHING] }
},
'.first': {
extends: 'something',
script: 'run',
only: { kubernetes: 'active' }
}
}
end
it 'raises an error about circular dependency' do
expect { subject.to_hash }
.to raise_error(described_class::Entry::CircularDependencyError)
end
end
context 'when circular dependecy to self has been detected' do
let(:hash) do
{
test: {
extends: 'test',
script: 'ls',
only: { refs: %w[master] }
}
}
end
it 'raises an error about circular dependency' do
expect { subject.to_hash }
.to raise_error(described_class::Entry::CircularDependencyError)
end
end
context 'when invalid extends value is specified' do
let(:hash) do
{ something: { extends: 1, script: 'ls' } }
end
it 'raises an error about invalid extension' do
expect { subject.to_hash }
.to raise_error(described_class::Entry::InvalidExtensionError)
end
end
context 'when extensible entry has non-hash inheritance defined' do
let(:hash) do
{
test: {
extends: 'something',
script: 'ls',
only: { refs: %w[master] }
},
something: 'some text'
}
end
it 'raises an error about invalid base' do
expect { subject.to_hash }
.to raise_error(described_class::Entry::InvalidExtensionError)
end
end
end
end