diff options
Diffstat (limited to 'spec/lib/gitlab/ci/variables/collection/sort_spec.rb')
-rw-r--r-- | spec/lib/gitlab/ci/variables/collection/sort_spec.rb | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/spec/lib/gitlab/ci/variables/collection/sort_spec.rb b/spec/lib/gitlab/ci/variables/collection/sort_spec.rb new file mode 100644 index 00000000000..73cf0e19d00 --- /dev/null +++ b/spec/lib/gitlab/ci/variables/collection/sort_spec.rb @@ -0,0 +1,185 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Ci::Variables::Collection::Sort do + describe '#initialize with non-Collection value' do + context 'when FF :variable_inside_variable is disabled' do + subject { Gitlab::Ci::Variables::Collection::Sort.new([]) } + + it 'raises ArgumentError' do + expect { subject }.to raise_error(ArgumentError, /Collection object was expected/) + end + end + + context 'when FF :variable_inside_variable is enabled' do + subject { Gitlab::Ci::Variables::Collection::Sort.new([]) } + + it 'raises ArgumentError' do + expect { subject }.to raise_error(ArgumentError, /Collection object was expected/) + end + end + end + + describe '#errors' do + context 'table tests' do + using RSpec::Parameterized::TableSyntax + + where do + { + "empty array": { + variables: [], + expected_errors: nil + }, + "simple expansions": { + variables: [ + { key: 'variable', value: 'value' }, + { key: 'variable2', value: 'result' }, + { key: 'variable3', value: 'key$variable$variable2' } + ], + expected_errors: nil + }, + "cyclic dependency": { + variables: [ + { key: 'variable', value: '$variable2' }, + { key: 'variable2', value: '$variable3' }, + { key: 'variable3', value: 'key$variable$variable2' } + ], + expected_errors: 'circular variable reference detected: ["variable", "variable2", "variable3"]' + }, + "array with raw variable": { + variables: [ + { key: 'variable', value: '$variable2' }, + { key: 'variable2', value: '$variable3' }, + { key: 'variable3', value: 'key$variable$variable2', raw: true } + ], + expected_errors: nil + }, + "variable containing escaped variable reference": { + variables: [ + { key: 'variable_a', value: 'value' }, + { key: 'variable_b', value: '$$variable_a' }, + { key: 'variable_c', value: '$variable_b' } + ], + expected_errors: nil + } + } + end + + with_them do + let(:collection) { Gitlab::Ci::Variables::Collection.new(variables) } + + subject { Gitlab::Ci::Variables::Collection::Sort.new(collection) } + + it 'errors matches expected errors' do + expect(subject.errors).to eq(expected_errors) + end + + it 'valid? matches expected errors' do + expect(subject.valid?).to eq(expected_errors.nil?) + end + + it 'does not raise' do + expect { subject }.not_to raise_error + end + end + end + end + + describe '#tsort' do + context 'table tests' do + using RSpec::Parameterized::TableSyntax + + where do + { + "empty array": { + variables: [], + result: [] + }, + "simple expansions, no reordering needed": { + variables: [ + { key: 'variable', value: 'value' }, + { key: 'variable2', value: 'result' }, + { key: 'variable3', value: 'key$variable$variable2' } + ], + result: %w[variable variable2 variable3] + }, + "complex expansion, reordering needed": { + variables: [ + { key: 'variable2', value: 'key${variable}' }, + { key: 'variable', value: 'value' } + ], + result: %w[variable variable2] + }, + "unused variables": { + variables: [ + { key: 'variable', value: 'value' }, + { key: 'variable4', value: 'key$variable$variable3' }, + { key: 'variable2', value: 'result2' }, + { key: 'variable3', value: 'result3' } + ], + result: %w[variable variable3 variable4 variable2] + }, + "missing variable": { + variables: [ + { key: 'variable2', value: 'key$variable' } + ], + result: %w[variable2] + }, + "complex expansions with missing variable": { + variables: [ + { key: 'variable4', value: 'key${variable}${variable2}${variable3}' }, + { key: 'variable', value: 'value' }, + { key: 'variable3', value: 'value3' } + ], + result: %w[variable variable3 variable4] + }, + "raw variable does not get resolved": { + variables: [ + { key: 'variable', value: '$variable2' }, + { key: 'variable2', value: '$variable3' }, + { key: 'variable3', value: 'key$variable$variable2', raw: true } + ], + result: %w[variable3 variable2 variable] + }, + "variable containing escaped variable reference": { + variables: [ + { key: 'variable_c', value: '$variable_b' }, + { key: 'variable_b', value: '$$variable_a' }, + { key: 'variable_a', value: 'value' } + ], + result: %w[variable_a variable_b variable_c] + } + } + end + + with_them do + let(:collection) { Gitlab::Ci::Variables::Collection.new(variables) } + + subject { Gitlab::Ci::Variables::Collection::Sort.new(collection).tsort } + + it 'returns correctly sorted variables' do + expect(subject.pluck(:key)).to eq(result) + end + end + end + + context 'cyclic dependency' do + let(:variables) do + [ + { key: 'variable2', value: '$variable3' }, + { key: 'variable3', value: 'key$variable$variable2' }, + { key: 'variable', value: '$variable2' } + ] + end + + let(:collection) { Gitlab::Ci::Variables::Collection.new(variables) } + + subject { Gitlab::Ci::Variables::Collection::Sort.new(collection).tsort } + + it 'raises TSort::Cyclic' do + expect { subject }.to raise_error(TSort::Cyclic) + end + end + end +end |