debian-mirror-gitlab/spec/lib/gitlab/ci/pipeline/expression/statement_spec.rb
2022-07-17 14:43:12 +02:00

204 lines
9.4 KiB
Ruby

# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Ci::Pipeline::Expression::Statement do
let(:variables) do
Gitlab::Ci::Variables::Collection.new
.append(key: 'PRESENT_VARIABLE', value: 'my variable')
.append(key: 'PATH_VARIABLE', value: 'a/path/variable/value')
.append(key: 'FULL_PATH_VARIABLE', value: '/a/full/path/variable/value')
.append(key: 'EMPTY_VARIABLE', value: '')
.to_hash
end
subject(:statement) do
described_class.new(text, variables)
end
describe '.new' do
context 'when variables are not provided' do
it 'allows to properly initializes the statement' do
statement = described_class.new('$PRESENT_VARIABLE')
expect(statement.evaluate).to be_nil
end
end
end
describe '#evaluate' do
using RSpec::Parameterized::TableSyntax
subject(:evaluate) { statement.evaluate }
where(:expression, :value) do
'$PRESENT_VARIABLE == "my variable"' | true
'"my variable" == $PRESENT_VARIABLE' | true
'$PRESENT_VARIABLE == null' | false
'$EMPTY_VARIABLE == null' | false
'"" == $EMPTY_VARIABLE' | true
'$EMPTY_VARIABLE' | ''
'$UNDEFINED_VARIABLE == null' | true
'null == $UNDEFINED_VARIABLE' | true
'$PRESENT_VARIABLE' | 'my variable'
'$UNDEFINED_VARIABLE' | nil
"$PRESENT_VARIABLE =~ /var.*e$/" | true
'$PRESENT_VARIABLE =~ /va\r.*e$/' | false
'$PRESENT_VARIABLE =~ /va\/r.*e$/' | false
"$PRESENT_VARIABLE =~ /var.*e$/" | true
"$PRESENT_VARIABLE =~ /^var.*/" | false
"$EMPTY_VARIABLE =~ /var.*/" | false
"$UNDEFINED_VARIABLE =~ /var.*/" | false
"$PRESENT_VARIABLE =~ /VAR.*/i" | true
'$PATH_VARIABLE =~ /path\/variable/' | true
'$FULL_PATH_VARIABLE =~ /^\/a\/full\/path\/variable\/value$/' | true
'$FULL_PATH_VARIABLE =~ /\\/path\\/variable\\/value$/' | true
'$PRESENT_VARIABLE != "my variable"' | false
'"my variable" != $PRESENT_VARIABLE' | false
'$PRESENT_VARIABLE != null' | true
'$EMPTY_VARIABLE != null' | true
'"" != $EMPTY_VARIABLE' | false
'$UNDEFINED_VARIABLE != null' | false
'null != $UNDEFINED_VARIABLE' | false
"$PRESENT_VARIABLE !~ /var.*e$/" | false
"$PRESENT_VARIABLE !~ /^var.*/" | true
'$PRESENT_VARIABLE !~ /^v\ar.*/' | true
'$PRESENT_VARIABLE !~ /^v\/ar.*/' | true
"$EMPTY_VARIABLE !~ /var.*/" | true
"$UNDEFINED_VARIABLE !~ /var.*/" | true
"$PRESENT_VARIABLE !~ /VAR.*/i" | false
'$PRESENT_VARIABLE && "string"' | 'string'
'$PRESENT_VARIABLE && $PRESENT_VARIABLE' | 'my variable'
'$PRESENT_VARIABLE && $EMPTY_VARIABLE' | ''
'$PRESENT_VARIABLE && null' | nil
'"string" && $PRESENT_VARIABLE' | 'my variable'
'$EMPTY_VARIABLE && $PRESENT_VARIABLE' | 'my variable'
'null && $PRESENT_VARIABLE' | nil
'$EMPTY_VARIABLE && "string"' | 'string'
'$EMPTY_VARIABLE && $EMPTY_VARIABLE' | ''
'"string" && $EMPTY_VARIABLE' | ''
'"string" && null' | nil
'null && "string"' | nil
'"string" && "string"' | 'string'
'null && null' | nil
'$PRESENT_VARIABLE =~ /my var/ && $EMPTY_VARIABLE =~ /nope/' | false
'$EMPTY_VARIABLE == "" && $PRESENT_VARIABLE' | 'my variable'
'$EMPTY_VARIABLE == "" && $PRESENT_VARIABLE != "nope"' | true
'$PRESENT_VARIABLE && $EMPTY_VARIABLE' | ''
'$PRESENT_VARIABLE && $UNDEFINED_VARIABLE' | nil
'$UNDEFINED_VARIABLE && $EMPTY_VARIABLE' | nil
'$UNDEFINED_VARIABLE && $PRESENT_VARIABLE' | nil
'$FULL_PATH_VARIABLE =~ /^\/a\/full\/path\/variable\/value$/ && $PATH_VARIABLE =~ /path\/variable/' | true
'$FULL_PATH_VARIABLE =~ /^\/a\/bad\/path\/variable\/value$/ && $PATH_VARIABLE =~ /path\/variable/' | false
'$FULL_PATH_VARIABLE =~ /^\/a\/full\/path\/variable\/value$/ && $PATH_VARIABLE =~ /bad\/path\/variable/' | false
'$FULL_PATH_VARIABLE =~ /^\/a\/bad\/path\/variable\/value$/ && $PATH_VARIABLE =~ /bad\/path\/variable/' | false
'$FULL_PATH_VARIABLE =~ /^\/a\/full\/path\/variable\/value$/ || $PATH_VARIABLE =~ /path\/variable/' | true
'$FULL_PATH_VARIABLE =~ /^\/a\/bad\/path\/variable\/value$/ || $PATH_VARIABLE =~ /path\/variable/' | true
'$FULL_PATH_VARIABLE =~ /^\/a\/full\/path\/variable\/value$/ || $PATH_VARIABLE =~ /bad\/path\/variable/' | true
'$FULL_PATH_VARIABLE =~ /^\/a\/bad\/path\/variable\/value$/ || $PATH_VARIABLE =~ /bad\/path\/variable/' | false
'$PRESENT_VARIABLE =~ /my var/ || $EMPTY_VARIABLE =~ /nope/' | true
'$EMPTY_VARIABLE == "" || $PRESENT_VARIABLE' | true
'$PRESENT_VARIABLE != "nope" || $EMPTY_VARIABLE == ""' | true
'$PRESENT_VARIABLE && null || $EMPTY_VARIABLE == ""' | true
'$PRESENT_VARIABLE || $UNDEFINED_VARIABLE' | 'my variable'
'$UNDEFINED_VARIABLE || $PRESENT_VARIABLE' | 'my variable'
'$UNDEFINED_VARIABLE == null || $PRESENT_VARIABLE' | true
'$PRESENT_VARIABLE || $UNDEFINED_VARIABLE == null' | 'my variable'
'($PRESENT_VARIABLE)' | 'my variable'
'(($PRESENT_VARIABLE))' | 'my variable'
'(($PRESENT_VARIABLE && null) || $EMPTY_VARIABLE == "")' | true
'($PRESENT_VARIABLE) && (null || $EMPTY_VARIABLE == "")' | true
'("string" || "test") == "string"' | true
'(null || ("test" == "string"))' | false
'("string" == ("test" && "string"))' | true
'("string" == ("test" || "string"))' | false
'("string" == "test" || "string")' | "string"
'("string" == ("string" || (("1" == "1") && ("2" == "3"))))' | true
end
with_them do
let(:text) { expression }
it "evaluates to `#{params[:value].inspect}`" do
expect(evaluate).to eq(value)
end
end
end
describe '#truthful?' do
using RSpec::Parameterized::TableSyntax
subject(:truthful?) { statement.truthful? }
where(:expression, :value) do
'$PRESENT_VARIABLE == "my variable"' | true
"$PRESENT_VARIABLE == 'no match'" | false
'$UNDEFINED_VARIABLE == null' | true
'$PRESENT_VARIABLE' | true
'$UNDEFINED_VARIABLE' | false
'$EMPTY_VARIABLE' | false
'$INVALID = 1' | false
"$PRESENT_VARIABLE =~ /var.*/" | true
"$UNDEFINED_VARIABLE =~ /var.*/" | false
"$PRESENT_VARIABLE !~ /var.*/" | false
"$UNDEFINED_VARIABLE !~ /var.*/" | true
end
with_them do
let(:text) { expression }
it "returns `#{params[:value].inspect}`" do
expect(truthful?).to eq value
end
end
context 'when evaluating expression raises an error' do
let(:text) { '$PRESENT_VARIABLE' }
it 'returns false' do
allow(statement).to receive(:evaluate)
.and_raise(described_class::StatementError)
expect(truthful?).to be_falsey
end
end
context 'when variables have patterns' do
let(:variables) do
Gitlab::Ci::Variables::Collection.new
.append(key: 'teststring', value: 'abcde')
.append(key: 'pattern1', value: '/^ab.*/')
.append(key: 'pattern2', value: '/^at.*/')
.to_hash
end
where(:expression, :ff, :result) do
'$teststring =~ "abcde"' | true | true
'$teststring =~ "abcde"' | false | true
'$teststring =~ $teststring' | true | true
'$teststring =~ $teststring' | false | true
'$teststring =~ $pattern1' | true | true
'$teststring =~ $pattern1' | false | false
'$teststring =~ $pattern2' | true | false
'$teststring =~ $pattern2' | false | false
end
with_them do
let(:text) { expression }
before do
stub_feature_flags(ci_fix_rules_if_comparison_with_regexp_variable: ff)
end
it { is_expected.to eq(result) }
end
end
end
end