diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-07-21 15:08:33 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-07-21 15:08:33 +0300 |
commit | 6c44b676312eb6cdffadef45f9ca3e29a8cc92ab (patch) | |
tree | 06666cd369ac9ad0533cec689f2c2b4fb826f797 /spec/lib | |
parent | c1cea595b6a9b4d85424e9afd2cb765101ee04bf (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/lib')
-rw-r--r-- | spec/lib/gitlab/ci/config/yaml/interpolator_spec.rb | 239 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/interpolation/inputs/base_input_spec.rb | 27 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/interpolation/inputs_spec.rb | 97 |
3 files changed, 261 insertions, 102 deletions
diff --git a/spec/lib/gitlab/ci/config/yaml/interpolator_spec.rb b/spec/lib/gitlab/ci/config/yaml/interpolator_spec.rb index b744adc570f..1621ff6655d 100644 --- a/spec/lib/gitlab/ci/config/yaml/interpolator_spec.rb +++ b/spec/lib/gitlab/ci/config/yaml/interpolator_spec.rb @@ -9,151 +9,185 @@ RSpec.describe Gitlab::Ci::Config::Yaml::Interpolator, feature_category: :pipeli subject { described_class.new(result, arguments) } - context 'when input data is valid' do - let(:header) do - { spec: { inputs: { website: nil } } } - end + # Remove shared examples when ci_interpolation_inputs_refactor is removed. + shared_examples 'interpolator' do + context 'when input data is valid' do + let(:header) do + { spec: { inputs: { website: nil } } } + end - let(:content) do - { test: 'deploy $[[ inputs.website ]]' } - end + let(:content) do + { test: 'deploy $[[ inputs.website ]]' } + end - let(:arguments) do - { website: 'gitlab.com' } - end + let(:arguments) do + { website: 'gitlab.com' } + end - it 'correctly interpolates the config' do - subject.interpolate! + it 'correctly interpolates the config' do + subject.interpolate! - expect(subject).to be_valid - expect(subject.to_hash).to eq({ test: 'deploy gitlab.com' }) + expect(subject).to be_interpolated + expect(subject).to be_valid + expect(subject.to_hash).to eq({ test: 'deploy gitlab.com' }) + end end - end - context 'when config has a syntax error' do - let(:result) { ::Gitlab::Ci::Config::Yaml::Result.new(error: 'Invalid configuration format') } + context 'when config has a syntax error' do + let(:result) { ::Gitlab::Ci::Config::Yaml::Result.new(error: 'Invalid configuration format') } - let(:arguments) do - { website: 'gitlab.com' } - end + let(:arguments) do + { website: 'gitlab.com' } + end - it 'surfaces an error about invalid config' do - subject.interpolate! + it 'surfaces an error about invalid config' do + subject.interpolate! - expect(subject).not_to be_valid - expect(subject.error_message).to eq subject.errors.first - expect(subject.errors).to include 'Invalid configuration format' + expect(subject).not_to be_valid + expect(subject.error_message).to eq subject.errors.first + expect(subject.errors).to include 'Invalid configuration format' + end end - end - context 'when spec header is invalid' do - let(:header) do - { spec: { arguments: { website: nil } } } - end + context 'when spec header is invalid' do + let(:header) do + { spec: { arguments: { website: nil } } } + end - let(:content) do - { test: 'deploy $[[ inputs.website ]]' } - end + let(:content) do + { test: 'deploy $[[ inputs.website ]]' } + end - let(:arguments) do - { website: 'gitlab.com' } - end + let(:arguments) do + { website: 'gitlab.com' } + end - it 'surfaces an error about invalid header' do - subject.interpolate! + it 'surfaces an error about invalid header' do + subject.interpolate! - expect(subject).not_to be_valid - expect(subject.error_message).to eq subject.errors.first - expect(subject.errors).to include('header:spec config contains unknown keys: arguments') + expect(subject).not_to be_valid + expect(subject.error_message).to eq subject.errors.first + expect(subject.errors).to include('header:spec config contains unknown keys: arguments') + end end - end - context 'when interpolation block is invalid' do - let(:header) do - { spec: { inputs: { website: nil } } } - end + context 'when interpolation block is invalid' do + let(:header) do + { spec: { inputs: { website: nil } } } + end - let(:content) do - { test: 'deploy $[[ inputs.abc ]]' } - end + let(:content) do + { test: 'deploy $[[ inputs.abc ]]' } + end - let(:arguments) do - { website: 'gitlab.com' } - end + let(:arguments) do + { website: 'gitlab.com' } + end - it 'correctly interpolates the config' do - subject.interpolate! + it 'correctly interpolates the config' do + subject.interpolate! - expect(subject).not_to be_valid - expect(subject.errors).to include 'unknown interpolation key: `abc`' - expect(subject.error_message).to eq 'interpolation interrupted by errors, unknown interpolation key: `abc`' + expect(subject).not_to be_valid + expect(subject.errors).to include 'unknown interpolation key: `abc`' + expect(subject.error_message).to eq 'interpolation interrupted by errors, unknown interpolation key: `abc`' + end end - end - context 'when provided interpolation argument is invalid' do - let(:header) do - { spec: { inputs: { website: nil } } } - end + context 'when multiple interpolation blocks are invalid' do + let(:header) do + { spec: { inputs: { website: nil } } } + end - let(:content) do - { test: 'deploy $[[ inputs.website ]]' } - end + let(:content) do + { test: 'deploy $[[ inputs.something.abc ]] $[[ inputs.cde ]] $[[ efg ]]' } + end - let(:arguments) do - { website: ['gitlab.com'] } - end + let(:arguments) do + { website: 'gitlab.com' } + end - it 'correctly interpolates the config' do - subject.interpolate! + it 'correctly interpolates the config' do + subject.interpolate! - expect(subject).not_to be_valid - expect(subject.error_message).to eq subject.errors.first - expect(subject.errors).to include 'unsupported value in input argument `website`' + expect(subject).not_to be_valid + expect(subject.error_message) + .to eq 'interpolation interrupted by errors, unknown interpolation key: `something`' + end end - end - context 'when multiple interpolation blocks are invalid' do - let(:header) do - { spec: { inputs: { website: nil } } } - end + describe '#to_hash' do + context 'when interpolation is not used' do + let(:result) do + ::Gitlab::Ci::Config::Yaml::Result.new(config: content) + end - let(:content) do - { test: 'deploy $[[ inputs.something.abc ]] $[[ inputs.cde ]] $[[ efg ]]' } - end + let(:content) do + { test: 'deploy production' } + end - let(:arguments) do - { website: 'gitlab.com' } - end + let(:arguments) { nil } + + it 'returns original content' do + subject.interpolate! + + expect(subject.to_hash).to eq(content) + end + end - it 'correctly interpolates the config' do - subject.interpolate! + context 'when interpolation is available' do + let(:header) do + { spec: { inputs: { website: nil } } } + end - expect(subject).not_to be_valid - expect(subject.error_message).to eq 'interpolation interrupted by errors, unknown interpolation key: `something`' + let(:content) do + { test: 'deploy $[[ inputs.website ]]' } + end + + let(:arguments) do + { website: 'gitlab.com' } + end + + it 'correctly interpolates content' do + subject.interpolate! + + expect(subject.to_hash).to eq({ test: 'deploy gitlab.com' }) + end + end end end - describe '#to_hash' do - context 'when interpolation is not used' do - let(:result) do - ::Gitlab::Ci::Config::Yaml::Result.new(config: content) + it_behaves_like 'interpolator' do + context 'when provided interpolation argument is invalid' do + let(:header) do + { spec: { inputs: { website: nil } } } end let(:content) do - { test: 'deploy production' } + { test: 'deploy $[[ inputs.website ]]' } end - let(:arguments) { nil } + let(:arguments) do + { website: ['gitlab.com'] } + end - it 'returns original content' do + it 'returns an error' do subject.interpolate! - expect(subject).not_to be_interpolated - expect(subject.to_hash).to eq(content) + expect(subject).not_to be_valid + expect(subject.error_message).to eq subject.errors.first + expect(subject.errors).to include '`website` input: provided value is not a string' end end + end - context 'when interpolation is available' do + context 'when feature flag ci_interpolation_inputs_refactor is disabled' do + before do + stub_feature_flags(ci_interpolation_inputs_refactor: false) + end + + it_behaves_like 'interpolator' + + context 'when provided interpolation argument is invalid' do let(:header) do { spec: { inputs: { website: nil } } } end @@ -163,14 +197,15 @@ RSpec.describe Gitlab::Ci::Config::Yaml::Interpolator, feature_category: :pipeli end let(:arguments) do - { website: 'gitlab.com' } + { website: ['gitlab.com'] } end - it 'correctly interpolates content' do + it 'returns an error' do subject.interpolate! - expect(subject).to be_interpolated - expect(subject.to_hash).to eq({ test: 'deploy gitlab.com' }) + expect(subject).not_to be_valid + expect(subject.error_message).to eq subject.errors.first + expect(subject.errors).to include 'unsupported value in input argument `website`' end end end diff --git a/spec/lib/gitlab/ci/interpolation/inputs/base_input_spec.rb b/spec/lib/gitlab/ci/interpolation/inputs/base_input_spec.rb new file mode 100644 index 00000000000..30dbf1ffe51 --- /dev/null +++ b/spec/lib/gitlab/ci/interpolation/inputs/base_input_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Ci::Interpolation::Inputs::BaseInput, feature_category: :pipeline_composition do + describe '.matches?' do + it 'is not implemented' do + expect { described_class.matches?(double) }.to raise_error(NotImplementedError) + end + end + + describe '.type_name' do + it 'is not implemented' do + expect { described_class.type_name }.to raise_error(NotImplementedError) + end + end + + describe '#valid_value?' do + it 'is not implemented' do + expect do + described_class.new( + name: 'website', spec: { website: nil }, value: { website: 'example.com' } + ).valid_value?('test') + end.to raise_error(NotImplementedError) + end + end +end diff --git a/spec/lib/gitlab/ci/interpolation/inputs_spec.rb b/spec/lib/gitlab/ci/interpolation/inputs_spec.rb new file mode 100644 index 00000000000..d7d7c85d04f --- /dev/null +++ b/spec/lib/gitlab/ci/interpolation/inputs_spec.rb @@ -0,0 +1,97 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Ci::Interpolation::Inputs, feature_category: :pipeline_composition do + let(:inputs) { described_class.new(specs, args) } + let(:specs) { { foo: { default: 'bar' } } } + let(:args) { {} } + + context 'when inputs are valid' do + where(:specs, :args, :merged) do + [ + [ + { foo: { default: 'bar' } }, {}, + { foo: 'bar' } + ], + [ + { foo: { default: 'bar' } }, { foo: 'test' }, + { foo: 'test' } + ], + [ + { foo: nil }, { foo: 'bar' }, + { foo: 'bar' } + ], + [ + { foo: { type: 'string' } }, { foo: 'bar' }, + { foo: 'bar' } + ], + [ + { foo: { type: 'string', default: 'bar' } }, { foo: 'test' }, + { foo: 'test' } + ], + [ + { foo: { type: 'string', default: 'bar' } }, {}, + { foo: 'bar' } + ], + [ + { foo: { default: 'bar' }, baz: nil }, { baz: 'test' }, + { foo: 'bar', baz: 'test' } + ] + ] + end + + with_them do + it 'contains the merged inputs' do + expect(inputs).to be_valid + expect(inputs.to_hash).to eq(merged) + end + end + end + + context 'when inputs are invalid' do + where(:specs, :args, :errors) do + [ + [ + { foo: nil }, { foo: 'bar', test: 'bar' }, + ['unknown input arguments: test'] + ], + [ + { foo: nil }, { test: 'bar', gitlab: '1' }, + ['unknown input arguments: test, gitlab', '`foo` input: required value has not been provided'] + ], + [ + { foo: 123 }, {}, + ['unknown input specification for `foo` (valid types: string)'] + ], + [ + { a: nil, foo: 123 }, { a: '123' }, + ['unknown input specification for `foo` (valid types: string)'] + ], + [ + { foo: nil }, {}, + ['`foo` input: required value has not been provided'] + ], + [ + { foo: { default: 123 } }, { foo: 'test' }, + ['`foo` input: default value is not a string'] + ], + [ + { foo: { default: 'test' } }, { foo: 123 }, + ['`foo` input: provided value is not a string'] + ], + [ + { foo: nil }, { foo: 123 }, + ['`foo` input: provided value is not a string'] + ] + ] + end + + with_them do + it 'contains the merged inputs', :aggregate_failures do + expect(inputs).not_to be_valid + expect(inputs.errors).to contain_exactly(*errors) + end + end + end +end |