2018-11-08 19:23:39 +05:30
|
|
|
require 'fast_spec_helper'
|
|
|
|
require 'rspec-parameterized'
|
2018-03-27 19:54:05 +05:30
|
|
|
|
|
|
|
describe Gitlab::Ci::Pipeline::Expression::Statement do
|
|
|
|
subject do
|
2018-05-09 12:01:36 +05:30
|
|
|
described_class.new(text, variables)
|
|
|
|
end
|
|
|
|
|
|
|
|
let(:variables) do
|
|
|
|
{ 'PRESENT_VARIABLE' => 'my variable',
|
|
|
|
EMPTY_VARIABLE: '' }
|
2018-03-27 19:54:05 +05:30
|
|
|
end
|
|
|
|
|
2018-05-09 12:01:36 +05:30
|
|
|
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
|
2018-03-27 19:54:05 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
describe '#parse_tree' do
|
|
|
|
context 'when expression is empty' do
|
|
|
|
let(:text) { '' }
|
|
|
|
|
|
|
|
it 'raises an error' do
|
|
|
|
expect { subject.parse_tree }
|
|
|
|
.to raise_error described_class::StatementError
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when expression grammar is incorrect' do
|
|
|
|
table = [
|
2018-05-09 12:01:36 +05:30
|
|
|
'$VAR "text"', # missing operator
|
|
|
|
'== "123"', # invalid left side
|
|
|
|
'"some string"', # only string provided
|
|
|
|
'$VAR ==', # invalid right side
|
2018-11-08 19:23:39 +05:30
|
|
|
'null', # missing lexemes
|
2018-05-09 12:01:36 +05:30
|
|
|
'' # empty statement
|
2018-03-27 19:54:05 +05:30
|
|
|
]
|
|
|
|
|
|
|
|
table.each do |syntax|
|
2018-05-09 12:01:36 +05:30
|
|
|
context "when expression grammar is #{syntax.inspect}" do
|
|
|
|
let(:text) { syntax }
|
|
|
|
|
2018-11-08 19:23:39 +05:30
|
|
|
it 'raises a statement error exception' do
|
2018-05-09 12:01:36 +05:30
|
|
|
expect { subject.parse_tree }
|
|
|
|
.to raise_error described_class::StatementError
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'is an invalid statement' do
|
|
|
|
expect(subject).not_to be_valid
|
|
|
|
end
|
2018-03-27 19:54:05 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when expression grammar is correct' do
|
|
|
|
context 'when using an operator' do
|
|
|
|
let(:text) { '$VAR == "value"' }
|
|
|
|
|
|
|
|
it 'returns a reverse descent parse tree' do
|
|
|
|
expect(subject.parse_tree)
|
|
|
|
.to be_a Gitlab::Ci::Pipeline::Expression::Lexeme::Equals
|
|
|
|
end
|
2018-05-09 12:01:36 +05:30
|
|
|
|
|
|
|
it 'is a valid statement' do
|
|
|
|
expect(subject).to be_valid
|
|
|
|
end
|
2018-03-27 19:54:05 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
context 'when using a single token' do
|
2018-05-09 12:01:36 +05:30
|
|
|
let(:text) { '$PRESENT_VARIABLE' }
|
2018-03-27 19:54:05 +05:30
|
|
|
|
|
|
|
it 'returns a single token instance' do
|
|
|
|
expect(subject.parse_tree)
|
|
|
|
.to be_a Gitlab::Ci::Pipeline::Expression::Lexeme::Variable
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#evaluate' do
|
2018-11-08 19:23:39 +05:30
|
|
|
using RSpec::Parameterized::TableSyntax
|
|
|
|
|
|
|
|
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 =~ /^var.*/" | false
|
|
|
|
"$EMPTY_VARIABLE =~ /var.*/" | false
|
|
|
|
"$UNDEFINED_VARIABLE =~ /var.*/" | false
|
|
|
|
"$PRESENT_VARIABLE =~ /VAR.*/i" | true
|
|
|
|
end
|
|
|
|
|
|
|
|
with_them do
|
|
|
|
let(:text) { expression }
|
|
|
|
|
|
|
|
it "evaluates to `#{params[:value].inspect}`" do
|
|
|
|
expect(subject.evaluate).to eq value
|
2018-03-27 19:54:05 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2018-05-09 12:01:36 +05:30
|
|
|
|
|
|
|
describe '#truthful?' do
|
2018-11-08 19:23:39 +05:30
|
|
|
using RSpec::Parameterized::TableSyntax
|
|
|
|
|
|
|
|
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
|
|
|
|
end
|
|
|
|
|
|
|
|
with_them do
|
|
|
|
let(:text) { expression }
|
|
|
|
|
|
|
|
it "returns `#{params[:value].inspect}`" do
|
|
|
|
expect(subject.truthful?).to eq value
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when evaluating expression raises an error' do
|
|
|
|
let(:text) { '$PRESENT_VARIABLE' }
|
|
|
|
|
|
|
|
it 'returns false' do
|
|
|
|
allow(subject).to receive(:evaluate)
|
|
|
|
.and_raise(described_class::StatementError)
|
|
|
|
|
|
|
|
expect(subject.truthful?).to be_falsey
|
2018-05-09 12:01:36 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2018-03-27 19:54:05 +05:30
|
|
|
end
|