summaryrefslogtreecommitdiff
path: root/spec/lib/gitlab/ci/variables/collection/sort_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/lib/gitlab/ci/variables/collection/sort_spec.rb')
-rw-r--r--spec/lib/gitlab/ci/variables/collection/sort_spec.rb185
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