summaryrefslogtreecommitdiff
path: root/spec/unit/context_spec.rb
blob: f23774ff7e0f9179f883fe097212250410219795 (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
require 'spec_helper'

describe Puppet::Context do
  let(:context) { Puppet::Context.new({ :testing => "value" }) }

  context "with the implicit test_helper.rb pushed context" do
    it "fails to lookup a value that does not exist" do
      expect { context.lookup("a") }.to raise_error(Puppet::Context::UndefinedBindingError)
    end

    it "calls a provided block for a default value when none is found" do
      expect(context.lookup("a") { "default" }).to eq("default")
    end

    it "behaves as if pushed a {} if you push nil" do
      context.push(nil)
      expect(context.lookup(:testing)).to eq("value")
      context.pop
    end

    it "fails if you try to pop off the top of the stack" do
      expect { context.pop }.to raise_error(Puppet::Context::StackUnderflow)
    end
  end

  describe "with additional context" do
    before :each do
      context.push("a" => 1)
    end

    it "holds values for later lookup" do
      expect(context.lookup("a")).to eq(1)
    end

    it "allows rebinding values in a nested context" do
      inner = nil
      context.override("a" => 2) do
        inner = context.lookup("a")
      end

      expect(inner).to eq(2)
    end

    it "outer bindings are available in an overridden context" do
      inner_a = nil
      inner_b = nil
      context.override("b" => 2) do
        inner_a = context.lookup("a")
        inner_b = context.lookup("b")
      end

      expect(inner_a).to eq(1)
      expect(inner_b).to eq(2)
    end

    it "overridden bindings do not exist outside of the override" do
      context.override("a" => 2) do
      end

      expect(context.lookup("a")).to eq(1)
    end

    it "overridden bindings do not exist outside of the override even when leaving via an error" do
      begin
        context.override("a" => 2) do
          raise "this should still cause the bindings to leave"
        end
      rescue
      end

      expect(context.lookup("a")).to eq(1)
    end
  end

  context "a rollback" do
    it "returns to the mark" do
      context.push("a" => 1)
      context.mark("start")
      context.push("a" => 2)
      context.push("a" => 3)
      context.pop

      context.rollback("start")

      expect(context.lookup("a")).to eq(1)
    end

    it "rolls back to the mark across a scoped override" do
      context.push("a" => 1)
      context.mark("start")
      context.override("a" => 3) do

        context.rollback("start")

        expect(context.lookup("a")).to eq(1)
      end
      expect(context.lookup("a")).to eq(1)
    end

    it "fails to rollback to an unknown mark" do
      expect do
        context.rollback("unknown")
      end.to raise_error(Puppet::Context::UnknownRollbackMarkError)
    end

    it "does not allow the same mark to be set twice" do
      context.mark("duplicate")
      expect do
        context.mark("duplicate")
      end.to raise_error(Puppet::Context::DuplicateRollbackMarkError)
    end
  end

  context 'support lazy entries' do
    it 'by evaluating a bound proc' do
      result = nil
      context.override(:a => lambda {|| 'yay'}) do
        result = context.lookup(:a)
      end
      expect(result).to eq('yay')
    end

    it 'by memoizing the bound value' do
      result1 = nil
      result2 = nil
      original = 'yay'
      context.override(:a => lambda {|| tmp = original; original = 'no'; tmp}) do
        result1 = context.lookup(:a)
        result2 = context.lookup(:a)
      end
      expect(result1).to eq('yay')
      expect(original).to eq('no')
      expect(result2).to eq('yay')
    end
  end
end