summaryrefslogtreecommitdiff
path: root/spec/lib/gitlab/ci/pipeline/expression/statement_spec.rb
blob: 79ee4d07e3a650707ad7740d33a59fee2a0a1113 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# frozen_string_literal: true

require 'fast_spec_helper'
require 'rspec-parameterized'

describe Gitlab::Ci::Pipeline::Expression::Statement do
  subject do
    described_class.new(text, variables)
  end

  let(:variables) do
    {
      'PRESENT_VARIABLE'   => 'my variable',
      'PATH_VARIABLE'      => 'a/path/variable/value',
      'FULL_PATH_VARIABLE' => '/a/full/path/variable/value',
      'EMPTY_VARIABLE'     =>  ''
    }
  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

    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'
    end

    with_them do
      let(:text) { expression }

      it "evaluates to `#{params[:value].inspect}`" do
        expect(subject.evaluate).to eq(value)
      end
    end
  end

  describe '#truthful?' do
    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
      "$PRESENT_VARIABLE !~ /var.*/"       | false
      "$UNDEFINED_VARIABLE !~ /var.*/"     | true
    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
      end
    end
  end
end