File: return_spec.rb

package info (click to toggle)
puppet 5.5.22-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 21,316 kB
  • sloc: ruby: 254,925; sh: 1,608; xml: 219; makefile: 153; sql: 103
file content (105 lines) | stat: -rw-r--r-- 3,406 bytes parent folder | download | duplicates (3)
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
require 'spec_helper'

require 'puppet_spec/compiler'
require 'matchers/resource'

describe 'the return function' do
  include PuppetSpec::Compiler
  include Matchers::Resource

  context 'returns from outer function when called from nested block' do
    it 'with a given value as function result' do
      expect(compile_to_catalog(<<-CODE)).to have_resource('Notify[100]')
          function please_return() {
            [1,2,3].map |$x| { if $x == 1 { return(100) } 200 }
            300
          }
          notify { String(please_return()): }
        CODE
    end

    it 'with undef value as function result when not given an argument' do
      expect(compile_to_catalog(<<-CODE)).to have_resource('Notify[xy]')
          function please_return() {
            [1,2,3].map |$x| { if $x == 1 { return() } 200 }
            300
          }
          notify { "x${please_return}y": }
        CODE
    end
  end

  it 'can be called without parentheses around the argument' do
    expect(compile_to_catalog(<<-CODE)).to have_resource('Notify[100]')
        function please_return() {
          if 1 == 1 { return 100 }
          200
        }
        notify { String(please_return()): }
      CODE
  end

  it 'provides early exit from a class and keeps the class' do
    expect(eval_and_collect_notices(<<-CODE)).to eql(['a', 'c', 'true', 'true'])
        class notices_c { notice 'c' }
        class does_next {
          notice 'a'
          if 1 == 1 { return() } # avoid making next line statically unreachable
          notice 'b'
        }
        # include two classes to check that next does not do an early return from
        # the include function.
        include(does_next, notices_c)
        notice defined(does_next)
        notice defined(notices_c)
      CODE
  end

  it 'provides early exit from a user defined resource and keeps the resource' do
    expect(eval_and_collect_notices(<<-CODE)).to eql(['the_doer_of_next', 'copy_cat', 'true', 'true'])
        define does_next {
          notice $title
          if 1 == 1 { return() } # avoid making next line statically unreachable
          notice 'b'
        }
        define checker {
          notice defined(Does_next['the_doer_of_next'])
          notice defined(Does_next['copy_cat'])
        }
        # create two instances to ensure next does not break the entire
        # resource expression
        does_next { ['the_doer_of_next', 'copy_cat']: }
        checker { 'needed_because_evaluation_order': }
      CODE
  end

  it 'can be called when nested in a function to make that function return' do
    expect(eval_and_collect_notices(<<-CODE)).to eql(['100'])
      function nested_return() {
        with(1) |$x| { with($x) |$x| {return(100) }}
      }
      notice nested_return()
      CODE
  end

  it 'can not be called nested from top scope' do
    expect do
      compile_to_catalog(<<-CODE)
        # line 1
        # line 2
        $result = with(1) |$x| { with($x) |$x| {return(100) }}
        notice $result
      CODE
    end.to raise_error(/return\(\) from context where this is illegal \(file: unknown, line: 3\) on node.*/)
  end

  it 'can not be called from top scope' do
    expect do
      compile_to_catalog(<<-CODE)
        # line 1
        # line 2
        return()
      CODE
    end.to raise_error(/return\(\) from context where this is illegal \(file: unknown, line: 3\) on node.*/)
  end
end