summaryrefslogtreecommitdiff
path: root/spec/unit/pops/evaluator/variables_spec.rb
blob: 6c1e9f821d770f0229d7ad50c832a1257ed3b433 (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
#! /usr/bin/env ruby
require 'spec_helper'
require 'puppet/pops'
require 'puppet/pops/evaluator/evaluator_impl'


# This file contains basic testing of variable references and assignments
# using a top scope and a local scope.
# It does not test variables and named scopes.
#

# relative to this spec file (./) does not work as this file is loaded by rspec
require File.join(File.dirname(__FILE__), '/evaluator_rspec_helper')

describe 'Puppet::Pops::Impl::EvaluatorImpl' do
  include EvaluatorRspecHelper

  context "When the evaluator deals with variables" do
    context "it should handle" do
      it "simple assignment and dereference" do
        evaluate_l(block( var('a').set(literal(2)+literal(2)), var('a'))).should == 4
      end

      it "local scope shadows top scope" do
        top_scope_block   = block( var('a').set(literal(2)+literal(2)), var('a'))
        local_scope_block = block( var('a').set(var('a') + literal(2)), var('a'))
        evaluate_l(top_scope_block, local_scope_block).should == 6
      end

      it "shadowed in local does not affect parent scope" do
        top_scope_block   = block( var('a').set(literal(2)+literal(2)), var('a'))
        local_scope_block = block( var('a').set(var('a') + literal(2)), var('a'))
        top_scope_again = var('a')
        evaluate_l(top_scope_block, local_scope_block, top_scope_again).should == 4
      end

      it "access to global names works in top scope" do
        top_scope_block   = block( var('a').set(literal(2)+literal(2)), var('::a'))
        evaluate_l(top_scope_block).should == 4
      end

      it "access to global names works in local scope" do
        top_scope_block     = block( var('a').set(literal(2)+literal(2)))
        local_scope_block   = block( var('a').set(var('::a')+literal(2)), var('::a'))
        evaluate_l(top_scope_block, local_scope_block).should == 6
      end

      it "can not change a variable value in same scope" do
        expect { evaluate_l(block(var('a').set(10), var('a').set(20))) }.to raise_error(/Cannot reassign variable a/)
      end

      context "access to numeric variables" do
        it "without a match" do
          evaluate_l(block(literal(2) + literal(2),
            [var(0), var(1), var(2), var(3)])).should == [nil, nil, nil, nil]
        end

        it "after a match" do
          evaluate_l(block(literal('abc') =~ literal(/(a)(b)(c)/),
            [var(0), var(1), var(2), var(3)])).should == ['abc', 'a', 'b', 'c']
        end

        it "after a failed match" do
          evaluate_l(block(literal('abc') =~ literal(/(x)(y)(z)/),
            [var(0), var(1), var(2), var(3)])).should == [nil, nil, nil, nil]
        end

        it "a failed match does not alter previous match" do
          evaluate_l(block(
            literal('abc') =~ literal(/(a)(b)(c)/),
            literal('abc') =~ literal(/(x)(y)(z)/),
            [var(0), var(1), var(2), var(3)])).should == ['abc', 'a', 'b', 'c']
        end

        it "a new match completely shadows previous match" do
          evaluate_l(block(
            literal('abc') =~ literal(/(a)(b)(c)/),
            literal('abc') =~ literal(/(a)bc/),
            [var(0), var(1), var(2), var(3)])).should == ['abc', 'a', nil, nil]
        end

        it "after a match with variable referencing a non existing group" do
          evaluate_l(block(literal('abc') =~ literal(/(a)(b)(c)/),
            [var(0), var(1), var(2), var(3), var(4)])).should == ['abc', 'a', 'b', 'c', nil]
        end
      end
    end
  end
end