Skip to content

Commit f2249f2

Browse files
author
Dmitry Ilyin
committed
[MODULES-2462] Improve parseyaml function
* Add default value support Second argument will be returned if yaml cannot be parsed instead of false value * Update tests
1 parent f820bb1 commit f2249f2

File tree

7 files changed

+169
-42
lines changed

7 files changed

+169
-42
lines changed

README.markdown

+2
Original file line numberDiff line numberDiff line change
@@ -490,10 +490,12 @@ Converts a number or a string representation of a number into a true boolean. Ze
490490
#### `parsejson`
491491

492492
Converts a string of JSON into the correct Puppet structure. *Type*: rvalue.
493+
The optional second argument will be returned if the data was not correct.
493494

494495
#### `parseyaml`
495496

496497
Converts a string of YAML into the correct Puppet structure. *Type*: rvalue.
498+
The optional second argument will be returned if the data was not correct.
497499

498500
#### `pick`
499501

lib/puppet/parser/functions/parsejson.rb

+12-11
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,22 @@
33
#
44

55
module Puppet::Parser::Functions
6-
newfunction(:parsejson, :type => :rvalue, :doc => <<-EOS
7-
This function accepts JSON as a string and converts into the correct Puppet
8-
structure.
9-
EOS
6+
newfunction(:parsejson, :type => :rvalue, :arity => -2, :doc => <<-EOS
7+
This function accepts JSON as a string and converts it into the correct
8+
Puppet structure.
9+
10+
The optional second argument can be used to pass a default value that will
11+
be returned if the parsing of YAML string have failed.
12+
EOS
1013
) do |arguments|
14+
raise ArgumentError, 'Wrong number of arguments. 1 or 2 arguments should be provided.' unless arguments.length >= 1
1115

12-
if (arguments.size != 1) then
13-
raise(Puppet::ParseError, "parsejson(): Wrong number of arguments "+
14-
"given #{arguments.size} for 1")
16+
begin
17+
PSON::load(arguments[0]) || arguments[1]
18+
rescue Exception
19+
arguments[1]
1520
end
1621

17-
json = arguments[0]
18-
19-
# PSON is natively available in puppet
20-
PSON.load(json)
2122
end
2223
end
2324

lib/puppet/parser/functions/parseyaml.rb

+11-9
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,22 @@
33
#
44

55
module Puppet::Parser::Functions
6-
newfunction(:parseyaml, :type => :rvalue, :doc => <<-EOS
6+
newfunction(:parseyaml, :type => :rvalue, :arity => -2, :doc => <<-EOS
77
This function accepts YAML as a string and converts it into the correct
88
Puppet structure.
9-
EOS
10-
) do |arguments|
11-
12-
if (arguments.size != 1) then
13-
raise(Puppet::ParseError, "parseyaml(): Wrong number of arguments "+
14-
"given #{arguments.size} for 1")
15-
end
169
10+
The optional second argument can be used to pass a default value that will
11+
be returned if the parsing of YAML string have failed.
12+
EOS
13+
) do |arguments|
14+
raise ArgumentError, 'Wrong number of arguments. 1 or 2 arguments should be provided.' unless arguments.length >= 1
1715
require 'yaml'
1816

19-
YAML::load(arguments[0])
17+
begin
18+
YAML::load(arguments[0]) || arguments[1]
19+
rescue Exception
20+
arguments[1]
21+
end
2022

2123
end
2224
end

spec/acceptance/parsejson_spec.rb

+13-4
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,28 @@
1616
end
1717
end
1818
end
19+
1920
describe 'failure' do
2021
it 'raises error on incorrect json' do
2122
pp = <<-EOS
2223
$a = '{"hunter": "washere", "tests": "passing",}'
23-
$ao = parsejson($a)
24+
$ao = parsejson($a, {'tests' => 'using the default value'})
2425
notice(inline_template('a is <%= @ao.inspect %>'))
2526
EOS
2627

27-
apply_manifest(pp, :expect_failures => true) do |r|
28-
expect(r.stderr).to match(/expected next name/)
28+
apply_manifest(pp, :catch_failures => true) do |r|
29+
expect(r.stdout).to match(/tests are "using the default value"/)
2930
end
3031
end
3132

32-
it 'raises error on incorrect number of arguments'
33+
it 'raises error on incorrect number of arguments' do
34+
pp = <<-EOS
35+
$o = parsejson()
36+
EOS
37+
38+
apply_manifest(pp, :expect_failures => true) do |r|
39+
expect(r.stderr).to match(/wrong number of arguments/i)
40+
end
41+
end
3342
end
3443
end

spec/acceptance/parseyaml_spec.rb

+14-5
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,29 @@
1616
end
1717
end
1818
end
19+
1920
describe 'failure' do
20-
it 'raises error on incorrect yaml' do
21+
it 'returns the default value on incorrect yaml' do
2122
pp = <<-EOS
2223
$a = "---\nhunter: washere\ntests: passing\n:"
23-
$o = parseyaml($a)
24+
$o = parseyaml($a, {'tests' => 'using the default value'})
2425
$tests = $o['tests']
2526
notice(inline_template('tests are <%= @tests.inspect %>'))
2627
EOS
2728

28-
apply_manifest(pp, :expect_failures => true) do |r|
29-
expect(r.stderr).to match(/(syntax error|did not find expected key)/)
29+
apply_manifest(pp, :catch_failures => true) do |r|
30+
expect(r.stdout).to match(/tests are "using the default value"/)
3031
end
3132
end
3233

33-
it 'raises error on incorrect number of arguments'
34+
it 'raises error on incorrect number of arguments' do
35+
pp = <<-EOS
36+
$o = parseyaml()
37+
EOS
38+
39+
apply_manifest(pp, :expect_failures => true) do |r|
40+
expect(r.stderr).to match(/wrong number of arguments/i)
41+
end
42+
end
3443
end
3544
end

spec/functions/parsejson_spec.rb

+60-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,64 @@
11
require 'spec_helper'
22

33
describe 'parsejson' do
4-
it { is_expected.not_to eq(nil) }
5-
it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) }
6-
it { is_expected.to run.with_params('', '').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) }
7-
it { is_expected.to run.with_params('["one"').and_raise_error(PSON::ParserError) }
8-
it { is_expected.to run.with_params('["one", "two", "three"]').and_return(['one', 'two', 'three']) }
4+
it 'should exist' do
5+
is_expected.not_to eq(nil)
6+
end
7+
8+
it 'should raise an error if called without any arguments' do
9+
is_expected.to run.with_params().
10+
and_raise_error(/wrong number of arguments/i)
11+
end
12+
13+
context 'with correct JSON data' do
14+
15+
it 'should be able to parse a JSON data with a Hash' do
16+
is_expected.to run.with_params('{"a":"1","b":"2"}').
17+
and_return({'a'=>'1', 'b'=>'2'})
18+
end
19+
20+
it 'should be able to parse a JSON data with an Array' do
21+
is_expected.to run.with_params('["a","b","c"]').
22+
and_return(['a', 'b', 'c'])
23+
end
24+
25+
it 'should be able to parse empty JSON values' do
26+
is_expected.to run.with_params('[]').
27+
and_return([])
28+
is_expected.to run.with_params('{}').
29+
and_return({})
30+
end
31+
32+
it 'should be able to parse a JSON data with a mixed structure' do
33+
is_expected.to run.with_params('{"a":"1","b":2,"c":{"d":[true,false]}}').
34+
and_return({'a' =>'1', 'b' => 2, 'c' => { 'd' => [true, false] } })
35+
end
36+
37+
it 'should not return the default value if the data was parsed correctly' do
38+
is_expected.to run.with_params('{"a":"1"}', 'default_value').
39+
and_return({'a' => '1'})
40+
end
41+
42+
end
43+
44+
context 'with incorrect YAML data' do
45+
it 'should return "nil" if a default value should be returned but is not provided' do
46+
is_expected.to run.with_params('').
47+
and_return(nil)
48+
end
49+
50+
it 'should support a structure for a default value' do
51+
is_expected.to run.with_params('', {'a' => '1'}).
52+
and_return({'a' => '1'})
53+
end
54+
55+
['', 1, 1.2, nil, true, false, [], {}, :yaml].each do |value|
56+
it "should return the default value for an incorrect #{value.inspect} (#{value.class}) parameter" do
57+
is_expected.to run.with_params(value, 'default_value').
58+
and_return('default_value')
59+
end
60+
end
61+
62+
end
63+
964
end

spec/functions/parseyaml_spec.rb

+57-8
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,63 @@
11
require 'spec_helper'
22

33
describe 'parseyaml' do
4-
it { is_expected.not_to eq(nil) }
5-
it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) }
6-
it { is_expected.to run.with_params('', '').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) }
7-
it { is_expected.to run.with_params('["one", "two", "three"]').and_return(['one', 'two', 'three']) }
8-
context 'when running on modern rubies', :unless => RUBY_VERSION == '1.8.7' do
9-
it { is_expected.to run.with_params('["one"').and_raise_error(Psych::SyntaxError) }
4+
it 'should exist' do
5+
is_expected.not_to eq(nil)
106
end
11-
context 'when running on ruby 1.8.7, which does not have Psych', :if => RUBY_VERSION == '1.8.7' do
12-
it { is_expected.to run.with_params('["one"').and_raise_error(ArgumentError) }
7+
8+
it 'should raise an error if called without any arguments' do
9+
is_expected.to run.with_params().
10+
and_raise_error(/wrong number of arguments/i)
11+
end
12+
13+
context 'with correct YAML data' do
14+
it 'should be able to parse a YAML data with a String' do
15+
is_expected.to run.with_params('--- just a string').
16+
and_return('just a string')
17+
is_expected.to run.with_params('just a string').
18+
and_return('just a string')
19+
end
20+
21+
it 'should be able to parse a YAML data with a Hash' do
22+
is_expected.to run.with_params("---\na: '1'\nb: '2'\n").
23+
and_return({'a' => '1', 'b' => '2'})
24+
end
25+
26+
it 'should be able to parse a YAML data with an Array' do
27+
is_expected.to run.with_params("---\n- a\n- b\n- c\n").
28+
and_return(['a', 'b', 'c'])
29+
end
30+
31+
it 'should be able to parse a YAML data with a mixed structure' do
32+
is_expected.to run.with_params("---\na: '1'\nb: 2\nc:\n d:\n - :a\n - true\n - false\n").
33+
and_return({'a' => '1', 'b' => 2, 'c' => { 'd' => [:a, true, false] } })
34+
end
35+
36+
it 'should not return the default value if the data was parsed correctly' do
37+
is_expected.to run.with_params("---\na: '1'\n", 'default_value').
38+
and_return({'a' => '1'})
39+
end
40+
1341
end
42+
43+
context 'with incorrect YAML data' do
44+
it 'should return "nil" if a default value should be returned but is not provided' do
45+
is_expected.to run.with_params('').
46+
and_return(nil)
47+
end
48+
49+
it 'should support a structure for a default value' do
50+
is_expected.to run.with_params('', {'a' => '1'}).
51+
and_return({'a' => '1'})
52+
end
53+
54+
['---', '...', '*8', '', 1, 1.2, nil, true, false, [], {}, :yaml].each do |value|
55+
it "should return the default value for an incorrect #{value.inspect} (#{value.class}) parameter" do
56+
is_expected.to run.with_params(value, 'default_value').
57+
and_return('default_value')
58+
end
59+
end
60+
61+
end
62+
1463
end

0 commit comments

Comments
 (0)