(#8797) Merge puppetlabs-functions into puppetlabs-stdlib

It was decided that maintaining puppetlabs-functions and
puppetlabs-stdlib was duplication as both are trying to
achieve the same goal.

This patch provides a merge of the puppetlabs-functions
into the puppetlabs-stdlib repository, with history
preservation.

The following conflicts were found and resolved:

* LICENSE file from functions was used as it aligns with
  ASL usage instructions and contains relevant copyright
  information:
  http://www.apache.org/licenses/LICENSE-2.0.html
* Used spec_helper.rb from functions - this is what
  Puppet core uses and doesn't break tests.
* Merged .gitignore and spec.opts options.
This commit is contained in:
Ken Barber 2011-08-05 08:52:00 +01:00
commit aa27fc76c7
104 changed files with 3665 additions and 208 deletions

1
.gitignore vendored
View file

@ -1,3 +1,4 @@
pkg/
.DS_Store
metadata.json
coverage/

209
LICENSE
View file

@ -1,202 +1,19 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
Copyright (C) 2011 Puppet Labs Inc
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
and some parts:
1. Definitions.
Copyright (C) 2011 Krzysztof Wilczynski
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
Puppet Labs can be contacted at: info@puppetlabs.com
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

16
Rakefile Normal file
View file

@ -0,0 +1,16 @@
require 'rake'
require 'rspec/core/rake_task'
task :default => [:test]
desc 'Run RSpec'
RSpec::Core::RakeTask.new(:test) do |t|
t.pattern = 'spec/{unit}/**/*.rb'
t.rspec_opts = ['--color']
end
desc 'Generate code coverage'
RSpec::Core::RakeTask.new(:coverage) do |t|
t.rcov = true
t.rcov_opts = ['--exclude', 'spec']
end

View file

@ -0,0 +1,36 @@
#
# abs.rb
#
module Puppet::Parser::Functions
newfunction(:abs, :type => :rvalue, :doc => <<-EOS
Returns the absolute value of a number, for example -34.56 becomes
34.56. Takes a single integer and float value as an argument.
EOS
) do |arguments|
raise(Puppet::ParseError, "abs(): Wrong number of arguments " +
"given (#{arguments.size} for 1)") if arguments.size < 1
value = arguments[0]
# Numbers in Puppet are often string-encoded which is troublesome ...
if value.is_a?(String)
if value.match(/^-?(?:\d+)(?:\.\d+){1}$/)
value = value.to_f
elsif value.match(/^-?\d+$/)
value = value.to_i
else
raise(Puppet::ParseError, 'abs(): Requires float or ' +
'integer to work with')
end
end
# We have numeric value to handle ...
result = value.abs
return result
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,49 @@
#
# bool2num.rb
#
module Puppet::Parser::Functions
newfunction(:bool2num, :type => :rvalue, :doc => <<-EOS
Converts a boolean to a number. Converts the values:
false, f, 0, n, and no to 0
true, t, 1, y, and yes to 1
Requires a single boolean or string as an input.
EOS
) do |arguments|
raise(Puppet::ParseError, "bool2num(): Wrong number of arguments " +
"given (#{arguments.size} for 1)") if arguments.size < 1
value = arguments[0]
klass = value.class
# We can have either true or false, or string which resembles boolean ...
unless [FalseClass, TrueClass, String].include?(klass)
raise(Puppet::ParseError, 'bool2num(): Requires either ' +
'boolean or string to work with')
end
if value.is_a?(String)
# We consider all the yes, no, y, n and so on too ...
value = case value
#
# This is how undef looks like in Puppet ...
# We yield 0 (or false if you wish) in this case.
#
when /^$/, '' then false # Empty string will be false ...
when /^(1|t|y|true|yes)$/ then true
when /^(0|f|n|false|no)$/ then false
when /^(undef|undefined)$/ then false # This is not likely to happen ...
else
raise(Puppet::ParseError, 'bool2num(): Unknown type of boolean given')
end
end
# We have real boolean values as well ...
result = value ? 1 : 0
return result
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,34 @@
#
# capitalize.rb
#
module Puppet::Parser::Functions
newfunction(:capitalize, :type => :rvalue, :doc => <<-EOS
Capitalizes the first letter of a string or array of strings.
Requires either a single string or an array as an input.
EOS
) do |arguments|
raise(Puppet::ParseError, "capitalize(): Wrong number of arguments " +
"given (#{arguments.size} for 1)") if arguments.size < 1
value = arguments[0]
klass = value.class
unless [Array, String].include?(klass)
raise(Puppet::ParseError, 'capitalize(): Requires either ' +
'array or string to work with')
end
if value.is_a?(Array)
# Numbers in Puppet are often string-encoded which is troublesome ...
result = value.collect { |i| i.is_a?(String) ? i.capitalize : i }
else
result = value.capitalize
end
return result
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,35 @@
#
# chomp.rb
#
module Puppet::Parser::Functions
newfunction(:chomp, :type => :rvalue, :doc => <<-'EOS'
Removes the record separator from the end of a string or an array of
strings, for example `hello\n` becomes `hello`.
Requires a single string or array as an input.
EOS
) do |arguments|
raise(Puppet::ParseError, "chomp(): Wrong number of arguments " +
"given (#{arguments.size} for 1)") if arguments.size < 1
value = arguments[0]
klass = value.class
unless [Array, String].include?(klass)
raise(Puppet::ParseError, 'chomp(): Requires either ' +
'array or string to work with')
end
if value.is_a?(Array)
# Numbers in Puppet are often string-encoded which is troublesome ...
result = value.collect { |i| i.is_a?(String) ? i.chomp : i }
else
result = value.chomp
end
return result
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,37 @@
#
# chop.rb
#
module Puppet::Parser::Functions
newfunction(:chop, :type => :rvalue, :doc => <<-'EOS'
Returns a new string with the last character removed. If the string ends
with `\r\n`, both characters are removed. Applying chop to an empty
string returns an empty string. If you wish to merely remove record
separators then you should use the `chomp` function.
Requires a string or array of strings as input.
EOS
) do |arguments|
raise(Puppet::ParseError, "chop(): Wrong number of arguments " +
"given (#{arguments.size} for 1)") if arguments.size < 1
value = arguments[0]
klass = value.class
unless [Array, String].include?(klass)
raise(Puppet::ParseError, 'chop(): Requires either an ' +
'array or string to work with')
end
if value.is_a?(Array)
# Numbers in Puppet are often string-encoded which is troublesome ...
result = value.collect { |i| i.is_a?(String) ? i.chop : i }
else
result = value.chop
end
return result
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,34 @@
#
# delete.rb
#
# TODO(Krzysztof Wilczynski): We need to add support for regular expression ...
# TODO(Krzysztof Wilczynski): Support for strings and hashes too ...
module Puppet::Parser::Functions
newfunction(:delete, :type => :rvalue, :doc => <<-EOS
Deletes a selected element from an array.
*Examples:*
delete(['a','b','c'], 'b')
Would return: ['a','c']
EOS
) do |arguments|
if (arguments.size != 2) then
raise(Puppet::ParseError, "delete(): Wrong number of arguments "+
"given #{arguments.size} for 2")
end
a = arguments[0]
item = arguments[1]
a.delete(item)
a
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,49 @@
#
# delete_at.rb
#
module Puppet::Parser::Functions
newfunction(:delete_at, :type => :rvalue, :doc => <<-EOS
Deletes a determined indexed value from an array.
*Examples:*
delete_at(['a','b','c'], 1)
Would return: ['a','c']
EOS
) do |arguments|
raise(Puppet::ParseError, "delete_at(): Wrong number of arguments " +
"given (#{arguments.size} for 2)") if arguments.size < 2
array = arguments[0]
unless array.is_a?(Array)
raise(Puppet::ParseError, 'delete_at(): Requires array to work with')
end
index = arguments[1]
if index.is_a?(String) and not index.match(/^\d+$/)
raise(Puppet::ParseError, 'delete_at(): You must provide ' +
'non-negative numeric index')
end
result = array.clone
# Numbers in Puppet are often string-encoded which is troublesome ...
index = index.to_i
if index > result.size - 1 # First element is at index 0 is it not?
raise(Puppet::ParseError, 'delete_at(): Given index ' +
'exceeds size of array given')
end
result.delete_at(index) # We ignore the element that got deleted ...
return result
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,33 @@
#
# downcase.rb
#
module Puppet::Parser::Functions
newfunction(:downcase, :type => :rvalue, :doc => <<-EOS
Converts the case of a string or all strings in an array to lower case.
EOS
) do |arguments|
raise(Puppet::ParseError, "downcase(): Wrong number of arguments " +
"given (#{arguments.size} for 1)") if arguments.size < 1
value = arguments[0]
klass = value.class
unless [Array, String].include?(klass)
raise(Puppet::ParseError, 'downcase(): Requires either ' +
'array or string to work with')
end
if value.is_a?(Array)
# Numbers in Puppet are often string-encoded which is troublesome ...
result = value.collect { |i| i.is_a?(String) ? i.downcase : i }
else
result = value.downcase
end
return result
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,28 @@
#
# empty.rb
#
module Puppet::Parser::Functions
newfunction(:empty, :type => :rvalue, :doc => <<-EOS
Returns true if the variable is empty.
EOS
) do |arguments|
raise(Puppet::ParseError, "empty(): Wrong number of arguments " +
"given (#{arguments.size} for 1)") if arguments.size < 1
value = arguments[0]
klass = value.class
unless [Array, Hash, String].include?(klass)
raise(Puppet::ParseError, 'empty(): Requires either ' +
'array, hash or string to work with')
end
result = value.empty?
return result
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,33 @@
#
# flatten.rb
#
module Puppet::Parser::Functions
newfunction(:flatten, :type => :rvalue, :doc => <<-EOS
This function flattens any deeply nested arrays and returns a single flat array
as a result.
*Examples:*
flatten(['a', ['b', ['c']]])
Would return: ['a','b','c']
EOS
) do |arguments|
raise(Puppet::ParseError, "flatten(): Wrong number of arguments " +
"given (#{arguments.size} for 1)") if arguments.size < 1
array = arguments[0]
unless array.is_a?(Array)
raise(Puppet::ParseError, 'flatten(): Requires array to work with')
end
result = array.flatten
return result
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,33 @@
#
# grep.rb
#
module Puppet::Parser::Functions
newfunction(:grep, :type => :rvalue, :doc => <<-EOS
This function searches through an array and returns any elements that match
the provided regular expression.
*Examples:*
grep(['aaa','bbb','ccc','aaaddd'], 'aaa')
Would return:
['aaa','aaaddd']
EOS
) do |arguments|
if (arguments.size != 2) then
raise(Puppet::ParseError, "grep(): Wrong number of arguments "+
"given #{arguments.size} for 2")
end
a = arguments[0]
pattern = Regexp.new(arguments[1])
a.grep(pattern)
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,41 @@
#
# hash.rb
#
module Puppet::Parser::Functions
newfunction(:hash, :type => :rvalue, :doc => <<-EOS
This function converts and array into a hash.
*Examples:*
hash(['a',1,'b',2,'c',3])
Would return: {'a'=>1,'b'=>2,'c'=>3}
EOS
) do |arguments|
raise(Puppet::ParseError, "hash(): Wrong number of arguments " +
"given (#{arguments.size} for 1)") if arguments.size < 1
array = arguments[0]
unless array.is_a?(Array)
raise(Puppet::ParseError, 'hash(): Requires array to work with')
end
result = {}
begin
# This is to make it compatible with older version of Ruby ...
array = array.flatten
result = Hash[*array]
rescue Exception
raise(Puppet::ParseError, 'hash(): Unable to compute ' +
'hash from array given')
end
return result
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,22 @@
#
# is_array.rb
#
module Puppet::Parser::Functions
newfunction(:is_array, :type => :rvalue, :doc => <<-EOS
Returns true if the variable passed to this function is an array.
EOS
) do |arguments|
raise(Puppet::ParseError, "is_array(): Wrong number of arguments " +
"given (#{arguments.size} for 1)") if arguments.size < 1
type = arguments[0]
result = type.is_a?(Array)
return result
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,27 @@
#
# is_domain_name.rb
#
module Puppet::Parser::Functions
newfunction(:is_domain_name, :type => :rvalue, :doc => <<-EOS
Returns true if the string passed to this function is a valid IP address. Support for IPv4 and IPv6 address types is included.
EOS
) do |arguments|
if (arguments.size != 1) then
raise(Puppet::ParseError, "is_domain_name(): Wrong number of arguments "+
"given #{arguments.size} for 1")
end
domain = arguments[0]
if domain =~ /^(([a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])\.?$/ then
return true
else
return false
end
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,27 @@
#
# is_float.rb
#
module Puppet::Parser::Functions
newfunction(:is_float, :type => :rvalue, :doc => <<-EOS
Returns true if the variable passed to this function is a float.
EOS
) do |arguments|
if (arguments.size != 1) then
raise(Puppet::ParseError, "is_float(): Wrong number of arguments "+
"given #{arguments.size} for 1")
end
value = arguments[0]
if value != value.to_f.to_s then
return false
else
return true
end
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,22 @@
#
# is_hash.rb
#
module Puppet::Parser::Functions
newfunction(:is_hash, :type => :rvalue, :doc => <<-EOS
Returns true if the variable passed to this function is a hash.
EOS
) do |arguments|
raise(Puppet::ParseError, "is_hash(): Wrong number of arguments " +
"given (#{arguments.size} for 1)") if arguments.size != 1
type = arguments[0]
result = type.is_a?(Hash)
return result
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,27 @@
#
# is_integer.rb
#
module Puppet::Parser::Functions
newfunction(:is_integer, :type => :rvalue, :doc => <<-EOS
Returns true if the variable returned to this string is an integer.
EOS
) do |arguments|
if (arguments.size != 1) then
raise(Puppet::ParseError, "is_integer(): Wrong number of arguments "+
"given #{arguments.size} for 1")
end
value = arguments[0]
if value != value.to_i.to_s then
return false
else
return true
end
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,32 @@
#
# is_ip_address.rb
#
module Puppet::Parser::Functions
newfunction(:is_ip_address, :type => :rvalue, :doc => <<-EOS
Returns true if the string passed to this function is a valid IP address.
EOS
) do |arguments|
require 'ipaddr'
if (arguments.size != 1) then
raise(Puppet::ParseError, "is_ip_address(): Wrong number of arguments "+
"given #{arguments.size} for 1")
end
begin
ip = IPAddr.new(arguments[0])
rescue ArgumentError
return false
end
if ip.ipv4? or ip.ipv6? then
return true
else
return false
end
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,27 @@
#
# is_mac_address.rb
#
module Puppet::Parser::Functions
newfunction(:is_mac_address, :type => :rvalue, :doc => <<-EOS
Returns true if the string passed to this function is a valid mac address.
EOS
) do |arguments|
if (arguments.size != 1) then
raise(Puppet::ParseError, "is_mac_address(): Wrong number of arguments "+
"given #{arguments.size} for 1")
end
mac = arguments[0]
if /^[a-fA-F0-9]{1,2}:[a-fA-F0-9]{1,2}:[a-fA-F0-9]{1,2}:[a-fA-F0-9]{1,2}:[a-fA-F0-9]{1,2}:[a-fA-F0-9]{1,2}$/.match(mac) then
return true
else
return false
end
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,27 @@
#
# is_numeric.rb
#
module Puppet::Parser::Functions
newfunction(:is_numeric, :type => :rvalue, :doc => <<-EOS
Returns true if the variable passed to this function is a number.
EOS
) do |arguments|
if (arguments.size != 1) then
raise(Puppet::ParseError, "is_numeric(): Wrong number of arguments "+
"given #{arguments.size} for 1")
end
value = arguments[0]
if value == value.to_f.to_s or value == value.to_i.to_s then
return true
else
return false
end
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,26 @@
#
# is_string.rb
#
module Puppet::Parser::Functions
newfunction(:is_string, :type => :rvalue, :doc => <<-EOS
Returns true if the variable passed to this function is a string.
EOS
) do |arguments|
raise(Puppet::ParseError, "is_string(): Wrong number of arguments " +
"given (#{arguments.size} for 1)") if arguments.size < 1
type = arguments[0]
result = type.is_a?(String)
if result and (type == type.to_f.to_s or type == type.to_i.to_s) then
return false
end
return result
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,41 @@
#
# join.rb
#
module Puppet::Parser::Functions
newfunction(:join, :type => :rvalue, :doc => <<-EOS
This function joins an array into a string using a seperator.
*Examples:*
join(['a','b','c'], ",")
Would result in: "a,b,c"
EOS
) do |arguments|
# Technically we support two arguments but only first is mandatory ...
raise(Puppet::ParseError, "join(): Wrong number of arguments " +
"given (#{arguments.size} for 1)") if arguments.size < 1
array = arguments[0]
unless array.is_a?(Array)
raise(Puppet::ParseError, 'join(): Requires array to work with')
end
suffix = arguments[1] if arguments[1]
if suffix
unless suffix.is_a?(String)
raise(Puppet::ParseError, 'join(): Requires string to work with')
end
end
result = suffix ? array.join(suffix) : array.join
return result
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,26 @@
#
# keys.rb
#
module Puppet::Parser::Functions
newfunction(:keys, :type => :rvalue, :doc => <<-EOS
Returns the keys of a hash as an array.
EOS
) do |arguments|
raise(Puppet::ParseError, "keys(): Wrong number of arguments " +
"given (#{arguments.size} for 1)") if arguments.size < 1
hash = arguments[0]
unless hash.is_a?(Hash)
raise(Puppet::ParseError, 'keys(): Requires hash to work with')
end
result = hash.keys
return result
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,33 @@
#
# lstrip.rb
#
module Puppet::Parser::Functions
newfunction(:lstrip, :type => :rvalue, :doc => <<-EOS
Strips leading spaces to the left of a string.
EOS
) do |arguments|
raise(Puppet::ParseError, "lstrip(): Wrong number of arguments " +
"given (#{arguments.size} for 1)") if arguments.size < 1
value = arguments[0]
klass = value.class
unless [Array, String].include?(klass)
raise(Puppet::ParseError, 'lstrip(): Requires either ' +
'array or string to work with')
end
if value.is_a?(Array)
# Numbers in Puppet are often string-encoded which is troublesome ...
result = value.collect { |i| i.is_a?(String) ? i.lstrip : i }
else
result = value.lstrip
end
return result
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,44 @@
#
# member.rb
#
# TODO(Krzysztof Wilczynski): We need to add support for regular expression ...
# TODO(Krzysztof Wilczynski): Support for strings and hashes too ...
module Puppet::Parser::Functions
newfunction(:member, :type => :rvalue, :doc => <<-EOS
This function determines if a variable is a member of an array.
*Examples:*
member(['a','b'], 'b')
Would return: true
member(['a','b'], 'c')
Would return: false
EOS
) do |arguments|
raise(Puppet::ParseError, "member(): Wrong number of arguments " +
"given (#{arguments.size} for 2)") if arguments.size < 2
array = arguments[0]
unless array.is_a?(Array)
raise(Puppet::ParseError, 'member(): Requires array to work with')
end
item = arguments[1]
raise(Puppet::ParseError, 'member(): You must provide item ' +
'to search for within array given') if item.empty?
result = array.include?(item)
return result
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,40 @@
#
# num2bool.rb
#
# TODO(Krzysztof Wilczynski): We probably need to approach numeric values differently ...
module Puppet::Parser::Functions
newfunction(:num2bool, :type => :rvalue, :doc => <<-EOS
This function converts a number into a true boolean. Zero becomes false. Numbers
higher then 0 become true.
EOS
) do |arguments|
raise(Puppet::ParseError, "num2bool(): Wrong number of arguments " +
"given (#{arguments.size} for 1)") if arguments.size < 1
number = arguments[0]
# Only numbers allowed ...
unless number.match(/^\-?\d+$/)
raise(Puppet::ParseError, 'num2bool(): Requires integer to work with')
end
result = case number
when /^0$/
false
when /^\-?\d+$/
# Numbers in Puppet are often string-encoded which is troublesome ...
number = number.to_i
# We yield true for any positive number and false otherwise ...
number > 0 ? true : false
else
raise(Puppet::ParseError, 'num2bool(): Unknown numeric format given')
end
return result
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,26 @@
#
# parsejson.rb
#
module Puppet::Parser::Functions
newfunction(:parsejson, :type => :rvalue, :doc => <<-EOS
This function accepts JSON as a string and converts into the correct Puppet
structure.
EOS
) do |arguments|
if (arguments.size != 1) then
raise(Puppet::ParseError, "parsejson(): Wrong number of arguments "+
"given #{arguments.size} for 1")
end
json = arguments[0]
require 'json'
JSON.load(json)
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,24 @@
#
# parseyaml.rb
#
module Puppet::Parser::Functions
newfunction(:parseyaml, :type => :rvalue, :doc => <<-EOS
This function accepts YAML as a string and converts it into the correct
Puppet structure.
EOS
) do |arguments|
if (arguments.size != 1) then
raise(Puppet::ParseError, "parseyaml(): Wrong number of arguments "+
"given #{arguments.size} for 1")
end
require 'yaml'
YAML::load(arguments[0])
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,45 @@
#
# prefix.rb
#
module Puppet::Parser::Functions
newfunction(:prefix, :type => :rvalue, :doc => <<-EOS
This function applies a prefix to all elements in an array.
*Examles:*
prefix(['a','b','c'], 'p')
Will return: ['pa','pb','pc']
EOS
) do |arguments|
# Technically we support two arguments but only first is mandatory ...
raise(Puppet::ParseError, "prefix(): Wrong number of arguments " +
"given (#{arguments.size} for 1)") if arguments.size < 1
array = arguments[0]
unless array.is_a?(Array)
raise(Puppet::ParseError, 'prefix(): Requires array to work with')
end
prefix = arguments[1] if arguments[1]
if prefix
unless prefix.is_a?(String)
raise(Puppet::ParseError, 'prefix(): Requires string to work with')
end
end
# Turn everything into string same as join would do ...
result = array.collect do |i|
i = i.to_s
prefix ? prefix + i : i
end
return result
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,71 @@
#
# range.rb
#
# TODO(Krzysztof Wilczynski): We probably need to approach numeric values differently ...
module Puppet::Parser::Functions
newfunction(:range, :type => :rvalue, :doc => <<-EOS
When given range in the form of (start, stop) it will extrapolate a range as
an array.
*Examples:*
range("0", "9")
Will return: [0,1,2,3,4,5,6,7,8,9]
range("a", "c")
Will return: ["a","b","c"]
EOS
) do |arguments|
# We support more than one argument but at least one is mandatory ...
raise(Puppet::ParseError, "range(): Wrong number of " +
"arguments given (#{arguments.size} for 1)") if arguments.size < 1
if arguments.size > 1
start = arguments[0]
stop = arguments[1]
type = '..' # We select simplest type for Range available in Ruby ...
elsif arguments.size > 0
value = arguments[0]
if m = value.match(/^(\w+)(\.\.\.?|\-)(\w+)$/)
start = m[1]
stop = m[3]
type = m[2]
elsif value.match(/^.+$/)
raise(Puppet::ParseError, 'range(): Unable to compute range ' +
'from the value given')
else
raise(Puppet::ParseError, 'range(): Unknown format of range given')
end
end
# Check whether we have integer value if so then make it so ...
if start.match(/^\d+$/)
start = start.to_i
stop = stop.to_i
else
start = start.to_s
stop = stop.to_s
end
range = case type
when /^(\.\.|\-)$/ then (start .. stop)
when /^(\.\.\.)$/ then (start ... stop) # Exclusive of last element ...
end
result = range.collect { |i| i } # Get them all ... Pokemon ...
return result
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,28 @@
#
# reverse.rb
#
module Puppet::Parser::Functions
newfunction(:reverse, :type => :rvalue, :doc => <<-EOS
Reverses the order of a string or array.
EOS
) do |arguments|
raise(Puppet::ParseError, "reverse(): Wrong number of arguments " +
"given (#{arguments.size} for 1)") if arguments.size < 1
value = arguments[0]
klass = value.class
unless [Array, String].include?(klass)
raise(Puppet::ParseError, 'reverse(): Requires either ' +
'array or string to work with')
end
result = value.reverse
return result
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,32 @@
#
# rstrip.rb
#
module Puppet::Parser::Functions
newfunction(:rstrip, :type => :rvalue, :doc => <<-EOS
Strips leading spaces to the right of the string.
EOS
) do |arguments|
raise(Puppet::ParseError, "rstrip(): Wrong number of arguments " +
"given (#{arguments.size} for 1)") if arguments.size < 1
value = arguments[0]
klass = value.class
unless [Array, String].include?(klass)
raise(Puppet::ParseError, 'rstrip(): Requires either ' +
'array or string to work with')
end
if value.is_a?(Array)
result = value.collect { |i| i.is_a?(String) ? i.rstrip : i }
else
result = value.rstrip
end
return result
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,46 @@
#
# shuffle.rb
#
module Puppet::Parser::Functions
newfunction(:shuffle, :type => :rvalue, :doc => <<-EOS
Randomizes the order of a string or array elements.
EOS
) do |arguments|
raise(Puppet::ParseError, "shuffle(): Wrong number of arguments " +
"given (#{arguments.size} for 1)") if arguments.size < 1
value = arguments[0]
klass = value.class
unless [Array, String].include?(klass)
raise(Puppet::ParseError, 'shuffle(): Requires either ' +
'array or string to work with')
end
result = value.clone
string = value.is_a?(String) ? true : false
# Check whether it makes sense to shuffle ...
return result if result.size <= 1
# We turn any string value into an array to be able to shuffle ...
result = string ? result.split('') : result
elements = result.size
# Simple implementation of FisherYates in-place shuffle ...
elements.times do |i|
j = rand(elements - i) + i
result[j], result[i] = result[i], result[j]
end
result = string ? result.join : result
return result
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,48 @@
#
# size.rb
#
# TODO(Krzysztof Wilczynski): Support for hashes would be nice too ...
module Puppet::Parser::Functions
newfunction(:size, :type => :rvalue, :doc => <<-EOS
Returns the number of elements in a string or array.
EOS
) do |arguments|
raise(Puppet::ParseError, "size(): Wrong number of arguments " +
"given (#{arguments.size} for 1)") if arguments.size < 1
item = arguments[0]
if item.is_a?(String)
begin
#
# Check whether your item is a numeric value or not ...
# This will take care about positive and/or negative numbers
# for both integer and floating-point values ...
#
# Please note that Puppet has no notion of hexadecimal
# nor octal numbers for its DSL at this point in time ...
#
Float(item)
raise(Puppet::ParseError, 'size(): Requires either ' +
'string or array to work with')
rescue ArgumentError
result = item.size
end
elsif item.is_a?(Array)
result = item.size
else
raise(Puppet::ParseError, 'size(): Unknown type given')
end
return result
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,27 @@
#
# sort.rb
#
module Puppet::Parser::Functions
newfunction(:sort, :type => :rvalue, :doc => <<-EOS
Sorts strings and arrays lexically.
EOS
) do |arguments|
if (arguments.size != 1) then
raise(Puppet::ParseError, "sort(): Wrong number of arguments "+
"given #{arguments.size} for 1")
end
value = arguments[0]
if value.is_a?(Array) then
value.sort
elsif value.is_a?(String) then
value.split("").sort.join("")
end
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,36 @@
#
# squeeze.rb
#
module Puppet::Parser::Functions
newfunction(:squeeze, :type => :rvalue, :doc => <<-EOS
Returns a new string where runs of the same character that occur in this set are replaced by a single character.
EOS
) do |arguments|
if ((arguments.size != 2) and (arguments.size != 1)) then
raise(Puppet::ParseError, "squeeze(): Wrong number of arguments "+
"given #{arguments.size} for 2 or 1")
end
item = arguments[0]
squeezeval = arguments[1]
if item.is_a?(Array) then
if squeezeval then
item.collect { |i| i.squeeze(squeezeval) }
else
item.collect { |i| i.squeeze }
end
else
if squeezeval then
item.squeeze(squeezeval)
else
item.squeeze
end
end
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,41 @@
#
# str2bool.rb
#
module Puppet::Parser::Functions
newfunction(:str2bool, :type => :rvalue, :doc => <<-EOS
This converts a string to a boolean. This attempt to convert strings that
contain things like: y, 1, t, true to 'true' and strings that contain things
like: 0, f, n, false, no to 'false'.
EOS
) do |arguments|
raise(Puppet::ParseError, "str2bool(): Wrong number of arguments " +
"given (#{arguments.size} for 1)") if arguments.size < 1
string = arguments[0]
unless string.is_a?(String)
raise(Puppet::ParseError, 'str2bool(): Requires either ' +
'string to work with')
end
# We consider all the yes, no, y, n and so on too ...
result = case string
#
# This is how undef looks like in Puppet ...
# We yield false in this case.
#
when /^$/, '' then false # Empty string will be false ...
when /^(1|t|y|true|yes)$/ then true
when /^(0|f|n|false|no)$/ then false
when /^(undef|undefined)$/ then false # This is not likely to happen ...
else
raise(Puppet::ParseError, 'str2bool(): Unknown type of boolean given')
end
return result
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,107 @@
#
# strftime.rb
#
module Puppet::Parser::Functions
newfunction(:strftime, :type => :rvalue, :doc => <<-EOS
This function returns formatted time.
*Examples:*
To return the time since epoch:
strftime("%s")
To return the date:
strftime("%Y-%m-%d")
*Format meaning:*
%a - The abbreviated weekday name (``Sun'')
%A - The full weekday name (``Sunday'')
%b - The abbreviated month name (``Jan'')
%B - The full month name (``January'')
%c - The preferred local date and time representation
%C - Century (20 in 2009)
%d - Day of the month (01..31)
%D - Date (%m/%d/%y)
%e - Day of the month, blank-padded ( 1..31)
%F - Equivalent to %Y-%m-%d (the ISO 8601 date format)
%h - Equivalent to %b
%H - Hour of the day, 24-hour clock (00..23)
%I - Hour of the day, 12-hour clock (01..12)
%j - Day of the year (001..366)
%k - hour, 24-hour clock, blank-padded ( 0..23)
%l - hour, 12-hour clock, blank-padded ( 0..12)
%L - Millisecond of the second (000..999)
%m - Month of the year (01..12)
%M - Minute of the hour (00..59)
%n - Newline (\n)
%N - Fractional seconds digits, default is 9 digits (nanosecond)
%3N millisecond (3 digits)
%6N microsecond (6 digits)
%9N nanosecond (9 digits)
%p - Meridian indicator (``AM'' or ``PM'')
%P - Meridian indicator (``am'' or ``pm'')
%r - time, 12-hour (same as %I:%M:%S %p)
%R - time, 24-hour (%H:%M)
%s - Number of seconds since 1970-01-01 00:00:00 UTC.
%S - Second of the minute (00..60)
%t - Tab character (\t)
%T - time, 24-hour (%H:%M:%S)
%u - Day of the week as a decimal, Monday being 1. (1..7)
%U - Week number of the current year,
starting with the first Sunday as the first
day of the first week (00..53)
%v - VMS date (%e-%b-%Y)
%V - Week number of year according to ISO 8601 (01..53)
%W - Week number of the current year,
starting with the first Monday as the first
day of the first week (00..53)
%w - Day of the week (Sunday is 0, 0..6)
%x - Preferred representation for the date alone, no time
%X - Preferred representation for the time alone, no date
%y - Year without a century (00..99)
%Y - Year with century
%z - Time zone as hour offset from UTC (e.g. +0900)
%Z - Time zone name
%% - Literal ``%'' character
EOS
) do |arguments|
# Technically we support two arguments but only first is mandatory ...
raise(Puppet::ParseError, "strftime(): Wrong number of arguments " +
"given (#{arguments.size} for 1)") if arguments.size < 1
format = arguments[0]
raise(Puppet::ParseError, 'strftime(): You must provide ' +
'format for evaluation') if format.empty?
# The Time Zone argument is optional ...
time_zone = arguments[1] if arguments[1]
time = Time.new
# There is probably a better way to handle Time Zone ...
if time_zone and not time_zone.empty?
original_zone = ENV['TZ']
local_time = time.clone
local_time = local_time.utc
ENV['TZ'] = time_zone
time = local_time.localtime
ENV['TZ'] = original_zone
end
result = time.strftime(format)
return result
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,39 @@
#
# strip.rb
#
module Puppet::Parser::Functions
newfunction(:strip, :type => :rvalue, :doc => <<-EOS
This function removes leading and trailing whitespace from a string or from
every string inside an array.
*Examples:*
strip(" aaa ")
Would result in: "aaa"
EOS
) do |arguments|
raise(Puppet::ParseError, "strip(): Wrong number of arguments " +
"given (#{arguments.size} for 1)") if arguments.size < 1
value = arguments[0]
klass = value.class
unless [Array, String].include?(klass)
raise(Puppet::ParseError, 'strip(): Requires either ' +
'array or string to work with')
end
if value.is_a?(Array)
result = value.collect { |i| i.is_a?(String) ? i.strip : i }
else
result = value.strip
end
return result
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,39 @@
#
# swapcase.rb
#
module Puppet::Parser::Functions
newfunction(:swapcase, :type => :rvalue, :doc => <<-EOS
This function will swap the existing case of a string.
*Examples:*
swapcase("aBcD")
Would result in: "AbCd"
EOS
) do |arguments|
raise(Puppet::ParseError, "swapcase(): Wrong number of arguments " +
"given (#{arguments.size} for 1)") if arguments.size < 1
value = arguments[0]
klass = value.class
unless [Array, String].include?(klass)
raise(Puppet::ParseError, 'swapcase(): Requires either ' +
'array or string to work with')
end
if value.is_a?(Array)
# Numbers in Puppet are often string-encoded which is troublesome ...
result = value.collect { |i| i.is_a?(String) ? i.swapcase : i }
else
result = value.swapcase
end
return result
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,49 @@
#
# time.rb
#
module Puppet::Parser::Functions
newfunction(:time, :type => :rvalue, :doc => <<-EOS
This function will return the current time since epoch as an integer.
*Examples:*
time()
Will return something like: 1311972653
EOS
) do |arguments|
# The Time Zone argument is optional ...
time_zone = arguments[0] if arguments[0]
if (arguments.size != 0) and (arguments.size != 1) then
raise(Puppet::ParseError, "time(): Wrong number of arguments "+
"given #{arguments.size} for 0 or 1")
end
time = Time.new
# There is probably a better way to handle Time Zone ...
if time_zone and not time_zone.empty?
original_zone = ENV['TZ']
local_time = time.clone
local_time = local_time.utc
ENV['TZ'] = time_zone
time = local_time.localtime
ENV['TZ'] = original_zone
end
# Calling Time#to_i on a receiver changes it. Trust me I am the Doctor.
result = time.strftime('%s')
result = result.to_i
return result
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,50 @@
#
# type.rb
#
module Puppet::Parser::Functions
newfunction(:type, :type => :rvalue, :doc => <<-EOS
Returns the type when passed a variable. Type can be one of:
* string
* array
* hash
* float
* integer
* boolean
EOS
) do |arguments|
raise(Puppet::ParseError, "type(): Wrong number of arguments " +
"given (#{arguments.size} for 1)") if arguments.size < 1
value = arguments[0]
klass = value.class
if not [TrueClass, FalseClass, Array, Bignum, Fixnum, Float, Hash, String].include?(klass)
raise(Puppet::ParseError, 'type(): Unknown type')
end
klass = klass.to_s # Ugly ...
# We note that Integer is the parent to Bignum and Fixnum ...
result = case klass
when /^(?:Big|Fix)num$/ then 'integer'
when /^(?:True|False)Class$/ then 'boolean'
else klass
end
if result == "String" then
if value == value.to_i.to_s then
result = "Integer"
elsif value == value.to_f.to_s then
result = "Float"
end
end
return result.downcase
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,51 @@
#
# unique.rb
#
module Puppet::Parser::Functions
newfunction(:unique, :type => :rvalue, :doc => <<-EOS
This function will remove duplicates from strings and arrays.
*Examples:*
unique("aabbcc")
Will return:
abc
You can also use this with arrays:
unique(["a","a","b","b","c","c"])
This returns:
["a","b","c"]
EOS
) do |arguments|
raise(Puppet::ParseError, "unique(): Wrong number of arguments " +
"given (#{arguments.size} for 1)") if arguments.size < 1
value = arguments[0]
klass = value.class
unless [Array, String].include?(klass)
raise(Puppet::ParseError, 'unique(): Requires either ' +
'array or string to work with')
end
result = value.clone
string = value.is_a?(String) ? true : false
# We turn any string value into an array to be able to shuffle ...
result = string ? result.split('') : result
result = result.uniq # Remove duplicates ...
result = string ? result.join : result
return result
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,41 @@
#
# upcase.rb
#
module Puppet::Parser::Functions
newfunction(:upcase, :type => :rvalue, :doc => <<-EOS
Converts a string or an array of strings to uppercase.
*Examples:*
upcase("abcd")
Will return:
ASDF
EOS
) do |arguments|
raise(Puppet::ParseError, "upcase(): Wrong number of arguments " +
"given (#{arguments.size} for 1)") if arguments.size < 1
value = arguments[0]
klass = value.class
unless [Array, String].include?(klass)
raise(Puppet::ParseError, 'upcase(): Requires either ' +
'array or string to work with')
end
if value.is_a?(Array)
# Numbers in Puppet are often string-encoded which is troublesome ...
result = value.collect { |i| i.is_a?(String) ? i.upcase : i }
else
result = value.upcase
end
return result
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,39 @@
#
# values.rb
#
module Puppet::Parser::Functions
newfunction(:values, :type => :rvalue, :doc => <<-EOS
When given a hash this function will return the values of that hash.
*Examples:*
$hash = {
'a' => 1,
'b' => 2,
'c' => 3,
}
values($hash)
This example would return:
[1,2,3]
EOS
) do |arguments|
raise(Puppet::ParseError, "values(): Wrong number of arguments " +
"given (#{arguments.size} for 1)") if arguments.size < 1
hash = arguments[0]
unless hash.is_a?(Hash)
raise(Puppet::ParseError, 'values(): Requires hash to work with')
end
result = hash.values
return result
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,98 @@
#
# values_at.rb
#
module Puppet::Parser::Functions
newfunction(:values_at, :type => :rvalue, :doc => <<-EOS
Finds value inside an array based on location.
The first argument is the array you want to analyze, and the second element can
be a combination of:
* A single numeric index
* A range in the form of 'start-stop' (eg. 4-9)
* An array combining the above
*Examples*:
values_at(['a','b','c'], 2)
Would return ['c'].
values_at(['a','b','c'], ["0-1"])
Would return ['a','b'].
values_at(['a','b','c','d','e'], [0, "2-3"])
Would return ['a','c','d'].
EOS
) do |arguments|
raise(Puppet::ParseError, "values_at(): Wrong number of " +
"arguments given (#{arguments.size} for 2)") if arguments.size < 2
array = arguments.shift
unless array.is_a?(Array)
raise(Puppet::ParseError, 'values_at(): Requires array to work with')
end
indices = [arguments.shift].flatten() # Get them all ... Pokemon ...
if not indices or indices.empty?
raise(Puppet::ParseError, 'values_at(): You must provide ' +
'at least one positive index to collect')
end
result = []
indices_list = []
indices.each do |i|
if m = i.match(/^(\d+)(\.\.\.?|\-)(\d+)$/)
start = m[1].to_i
stop = m[3].to_i
type = m[2]
if start > stop
raise(Puppet::ParseError, 'values_at(): Stop index in ' +
'given indices range is smaller than the start index')
elsif stop > array.size - 1 # First element is at index 0 is it not?
raise(Puppet::ParseError, 'values_at(): Stop index in ' +
'given indices range exceeds array size')
end
range = case type
when /^(\.\.|\-)$/ then (start .. stop)
when /^(\.\.\.)$/ then (start ... stop) # Exclusive of last element ...
end
range.each { |i| indices_list << i.to_i }
else
# Only positive numbers allowed in this case ...
if not i.match(/^\d+$/)
raise(Puppet::ParseError, 'values_at(): Unknown format ' +
'of given index')
end
# In Puppet numbers are often string-encoded ...
i = i.to_i
if i > array.size - 1 # Same story. First element is at index 0 ...
raise(Puppet::ParseError, 'values_at(): Given index ' +
'exceeds array size')
end
indices_list << i
end
end
# We remove nil values as they make no sense in Puppet DSL ...
result = indices_list.collect { |i| array[i] }.compact
return result
end
end
# vim: set ts=2 sw=2 et :

View file

@ -0,0 +1,65 @@
#
# zip.rb
#
module Puppet::Parser::Functions
newfunction(:zip, :type => :rvalue, :doc => <<-EOS
Takes one element from first array and merges corresponding elements from second array. This generates a sequence of n-element arrays, where n is one more than the count of arguments.
*Example:*
zip(['1','2','3'],['4','5','6'])
Would result in:
["1", "4"], ["2", "5"], ["3", "6"]
EOS
) do |arguments|
# Technically we support three arguments but only first is mandatory ...
raise(Puppet::ParseError, "zip(): Wrong number of arguments " +
"given (#{arguments.size} for 2)") if arguments.size < 2
a = arguments[0]
b = arguments[1]
unless a.is_a?(Array) and b.is_a?(Array)
raise(Puppet::ParseError, 'zip(): Requires array to work with')
end
flatten = arguments[2] if arguments[2]
if flatten
klass = flatten.class
# We can have either true or false, or string which resembles boolean ...
unless [FalseClass, TrueClass, String].include?(klass)
raise(Puppet::ParseError, 'zip(): Requires either ' +
'boolean or string to work with')
end
if flatten.is_a?(String)
# We consider all the yes, no, y, n and so on too ...
flatten = case flatten
#
# This is how undef looks like in Puppet ...
# We yield false in this case.
#
when /^$/, '' then false # Empty string will be false ...
when /^(1|t|y|true|yes)$/ then true
when /^(0|f|n|false|no)$/ then false
when /^(undef|undefined)$/ then false # This is not likely to happen ...
else
raise(Puppet::ParseError, 'zip(): Unknown type of boolean given')
end
end
end
result = a.zip(b)
result = flatten ? result.flatten : result
return result
end
end
# vim: set ts=2 sw=2 et :

53
spec/lib/puppet_spec/files.rb Executable file
View file

@ -0,0 +1,53 @@
require 'fileutils'
require 'tempfile'
# A support module for testing files.
module PuppetSpec::Files
# This code exists only to support tests that run as root, pretty much.
# Once they have finally been eliminated this can all go... --daniel 2011-04-08
if Puppet.features.posix? then
def self.in_tmp(path)
path =~ /^\/tmp/ or path =~ /^\/var\/folders/
end
elsif Puppet.features.microsoft_windows?
def self.in_tmp(path)
tempdir = File.expand_path(File.join(Dir::LOCAL_APPDATA, "Temp"))
path =~ /^#{tempdir}/
end
else
fail "Help! Can't find in_tmp for this platform"
end
def self.cleanup
$global_tempfiles ||= []
while path = $global_tempfiles.pop do
fail "Not deleting tmpfile #{path} outside regular tmpdir" unless in_tmp(path)
begin
FileUtils.rm_r path, :secure => true
rescue Errno::ENOENT
# nothing to do
end
end
end
def tmpfile(name)
# Generate a temporary file, just for the name...
source = Tempfile.new(name)
path = source.path
source.close!
# ...record it for cleanup,
$global_tempfiles ||= []
$global_tempfiles << File.expand_path(path)
# ...and bam.
path
end
def tmpdir(name)
path = tmpfile(name)
FileUtils.mkdir_p(path)
path
end
end

View file

@ -0,0 +1,28 @@
module PuppetSpec::Fixtures
def fixtures(*rest)
File.join(PuppetSpec::FIXTURE_DIR, *rest)
end
def my_fixture_dir
callers = caller
while line = callers.shift do
next unless found = line.match(%r{/spec/(.*)_spec\.rb:})
return fixtures(found[1])
end
fail "sorry, I couldn't work out your path from the caller stack!"
end
def my_fixture(name)
file = File.join(my_fixture_dir, name)
unless File.readable? file then
fail Puppet::DevError, "fixture '#{name}' for #{my_fixture_dir} is not readable"
end
return file
end
def my_fixtures(glob = '*', flags = 0)
files = Dir.glob(File.join(my_fixture_dir, glob), flags)
unless files.length > 0 then
fail Puppet::DevError, "fixture '#{glob}' for #{my_fixture_dir} had no files!"
end
block_given? and files.each do |file| yield file end
files
end
end

View file

@ -0,0 +1,87 @@
require 'stringio'
########################################################################
# Backward compatibility for Jenkins outdated environment.
module RSpec
module Matchers
module BlockAliases
alias_method :to, :should unless method_defined? :to
alias_method :to_not, :should_not unless method_defined? :to_not
alias_method :not_to, :should_not unless method_defined? :not_to
end
end
end
########################################################################
# Custom matchers...
RSpec::Matchers.define :have_matching_element do |expected|
match do |actual|
actual.any? { |item| item =~ expected }
end
end
RSpec::Matchers.define :exit_with do |expected|
actual = nil
match do |block|
begin
block.call
rescue SystemExit => e
actual = e.status
end
actual and actual == expected
end
failure_message_for_should do |block|
"expected exit with code #{expected} but " +
(actual.nil? ? " exit was not called" : "we exited with #{actual} instead")
end
failure_message_for_should_not do |block|
"expected that exit would not be called with #{expected}"
end
description do
"expect exit with #{expected}"
end
end
RSpec::Matchers.define :have_printed do |expected|
match do |block|
$stderr = $stdout = StringIO.new
begin
block.call
ensure
$stdout.rewind
@actual = $stdout.read
$stdout = STDOUT
$stderr = STDERR
end
if @actual then
case expected
when String
@actual.include? expected
when Regexp
expected.match @actual
else
raise ArgumentError, "No idea how to match a #{@actual.class.name}"
end
end
end
failure_message_for_should do |actual|
if actual.nil? then
"expected #{expected.inspect}, but nothing was printed"
else
"expected #{expected.inspect} to be printed; got:\n#{actual}"
end
end
description do
"expect #{expected.inspect} to be printed"
end
diffable
end

View file

@ -0,0 +1,9 @@
# Support code for running stuff with warnings disabled.
module Kernel
def with_verbose_disabled
verbose, $VERBOSE = $VERBOSE, nil
result = yield
$VERBOSE = verbose
return result
end
end

View file

@ -0,0 +1,8 @@
require 'rspec'
class Object
# This is necessary because the RAL has a 'should'
# method.
alias :must :should
alias :must_not :should_not
end

View file

@ -0,0 +1,11 @@
# Some monkey-patching to allow us to test private methods.
class Class
def publicize_methods(*methods)
saved_private_instance_methods = methods.empty? ? self.private_instance_methods : methods
self.class_eval { public(*saved_private_instance_methods) }
yield
self.class_eval { private(*saved_private_instance_methods) }
end
end

View file

@ -1,18 +1,78 @@
require 'pathname'
dir = Pathname.new(__FILE__).parent
$LOAD_PATH.unshift(dir, dir + 'lib', dir + '../lib')
dir = File.expand_path(File.dirname(__FILE__))
$LOAD_PATH.unshift File.join(dir, 'lib')
p dir
# Don't want puppet getting the command line arguments for rake or autotest
ARGV.clear
require 'mocha'
require 'puppet'
gem 'rspec', '=1.2.9'
require 'spec/autorun'
require 'mocha'
gem 'rspec', '>=2.0.0'
require 'rspec/expectations'
Spec::Runner.configure do |config|
config.mock_with :mocha
# So everyone else doesn't have to include this base constant.
module PuppetSpec
FIXTURE_DIR = File.join(dir = File.expand_path(File.dirname(__FILE__)), "fixtures") unless defined?(FIXTURE_DIR)
end
# We need this because the RAL uses 'should' as a method. This
# allows us the same behaviour but with a different method name.
class Object
alias :must :should
require 'pathname'
require 'tmpdir'
require 'puppet_spec/verbose'
require 'puppet_spec/files'
require 'puppet_spec/fixtures'
require 'puppet_spec/matchers'
require 'monkey_patches/alias_should_to_must'
require 'monkey_patches/publicize_methods'
Pathname.glob("#{dir}/shared_behaviours/**/*.rb") do |behaviour|
require behaviour.relative_path_from(Pathname.new(dir))
end
RSpec.configure do |config|
include PuppetSpec::Fixtures
config.mock_with :mocha
config.before :each do
GC.disable
# these globals are set by Application
$puppet_application_mode = nil
$puppet_application_name = nil
# REVISIT: I think this conceals other bad tests, but I don't have time to
# fully diagnose those right now. When you read this, please come tell me
# I suck for letting this float. --daniel 2011-04-21
Signal.stubs(:trap)
# Set the confdir and vardir to gibberish so that tests
# have to be correctly mocked.
Puppet[:confdir] = "/dev/null"
Puppet[:vardir] = "/dev/null"
# Avoid opening ports to the outside world
Puppet.settings[:bindaddress] = "127.0.0.1"
@logs = []
Puppet::Util::Log.newdestination(Puppet::Test::LogCollector.new(@logs))
@log_level = Puppet::Util::Log.level
end
config.after :each do
Puppet.settings.clear
Puppet::Node::Environment.clear
Puppet::Util::Storage.clear
Puppet::Util::ExecutionStub.reset
PuppetSpec::Files.cleanup
@logs.clear
Puppet::Util::Log.close_all
Puppet::Util::Log.level = @log_level
GC.enable
end
end

View file

@ -0,0 +1,31 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the abs function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("abs").should == "function_abs"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_abs([]) }.should( raise_error(Puppet::ParseError))
end
it "should convert a negative number into a positive" do
result = @scope.function_abs(["-34"])
result.should(eq(34))
end
it "should do nothing with a positive number" do
result = @scope.function_abs(["5678"])
result.should(eq(5678))
end
end

View file

@ -0,0 +1,31 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the bool2num function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("bool2num").should == "function_bool2num"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_bool2num([]) }.should( raise_error(Puppet::ParseError))
end
it "should convert true to 1" do
result = @scope.function_bool2num([true])
result.should(eq(1))
end
it "should convert false to 0" do
result = @scope.function_bool2num([false])
result.should(eq(0))
end
end

View file

@ -0,0 +1,26 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the capitalize function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("capitalize").should == "function_capitalize"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_capitalize([]) }.should( raise_error(Puppet::ParseError))
end
it "should capitalize the beginning of a string" do
result = @scope.function_capitalize(["abc"])
result.should(eq("Abc"))
end
end

View file

@ -0,0 +1,26 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the chomp function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("chomp").should == "function_chomp"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_chomp([]) }.should( raise_error(Puppet::ParseError))
end
it "should chomp the end of a string" do
result = @scope.function_chomp(["abc\n"])
result.should(eq("abc"))
end
end

View file

@ -0,0 +1,26 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the chop function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("chop").should == "function_chop"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_chop([]) }.should( raise_error(Puppet::ParseError))
end
it "should chop the end of a string" do
result = @scope.function_chop(["asdf\n"])
result.should(eq("asdf"))
end
end

View file

@ -0,0 +1,26 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the delete_at function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("delete_at").should == "function_delete_at"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_delete_at([]) }.should( raise_error(Puppet::ParseError))
end
it "should delete an item at specified location from an array" do
result = @scope.function_delete_at([['a','b','c'],1])
result.should(eq(['a','c']))
end
end

View file

@ -0,0 +1,26 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the delete function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("delete").should == "function_delete"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_delete([]) }.should( raise_error(Puppet::ParseError))
end
it "should delete an item from an array" do
result = @scope.function_delete([['a','b','c'],'b'])
result.should(eq(['a','c']))
end
end

View file

@ -0,0 +1,31 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the downcase function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("downcase").should == "function_downcase"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_downcase([]) }.should( raise_error(Puppet::ParseError))
end
it "should downcase a string" do
result = @scope.function_downcase(["ASFD"])
result.should(eq("asfd"))
end
it "should do nothing to a string that is already downcase" do
result = @scope.function_downcase(["asdf asdf"])
result.should(eq("asdf asdf"))
end
end

View file

@ -0,0 +1,31 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the empty function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("empty").should == "function_empty"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_empty([]) }.should( raise_error(Puppet::ParseError))
end
it "should return a true for an empty string" do
result = @scope.function_empty([''])
result.should(eq(true))
end
it "should return a false for a non-empty string" do
result = @scope.function_empty(['asdf'])
result.should(eq(false))
end
end

View file

@ -0,0 +1,31 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the flatten function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("flatten").should == "function_flatten"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_flatten([]) }.should( raise_error(Puppet::ParseError))
end
it "should flatten a complex data structure" do
result = @scope.function_flatten([["a","b",["c",["d","e"],"f","g"]]])
result.should(eq(["a","b","c","d","e","f","g"]))
end
it "should do nothing to a structure that is already flat" do
result = @scope.function_flatten([["a","b","c","d"]])
result.should(eq(["a","b","c","d"]))
end
end

View file

@ -0,0 +1,26 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the grep function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("grep").should == "function_grep"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_grep([]) }.should( raise_error(Puppet::ParseError))
end
it "should grep contents from an array" do
result = @scope.function_grep([["aaabbb","bbbccc","dddeee"], "bbb"])
result.should(eq(["aaabbb","bbbccc"]))
end
end

View file

@ -0,0 +1,26 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the hash function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("hash").should == "function_hash"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_hash([]) }.should( raise_error(Puppet::ParseError))
end
it "should convert an array to a hash" do
result = @scope.function_hash([['a',1,'b',2,'c',3]])
result.should(eq({'a'=>1,'b'=>2,'c'=>3}))
end
end

View file

@ -0,0 +1,36 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the is_array function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("is_array").should == "function_is_array"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_is_array([]) }.should( raise_error(Puppet::ParseError))
end
it "should return true if passed an array" do
result = @scope.function_is_array([[1,2,3]])
result.should(eq(true))
end
it "should return false if passed a hash" do
result = @scope.function_is_array([{'a'=>1}])
result.should(eq(false))
end
it "should return false if passed a string" do
result = @scope.function_is_array(["asdf"])
result.should(eq(false))
end
end

View file

@ -0,0 +1,56 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the is_domain_name function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("is_domain_name").should == "function_is_domain_name"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_is_domain_name([]) }.should( raise_error(Puppet::ParseError))
end
it "should return true if a valid domain name" do
result = @scope.function_is_domain_name(["foo.bar.com"])
result.should(be_true)
end
it "should allow domain parts to start with numbers" do
result = @scope.function_is_domain_name(["3foo.2bar.com"])
result.should(be_true)
end
it "should allow domain to end with a dot" do
result = @scope.function_is_domain_name(["3foo.2bar.com."])
result.should(be_true)
end
it "should allow a single part domain" do
result = @scope.function_is_domain_name(["orange"])
result.should(be_true)
end
it "should return false if domain parts start with hyphens" do
result = @scope.function_is_domain_name(["-3foo.2bar.com"])
result.should(be_false)
end
it "should return true if domain contains hyphens" do
result = @scope.function_is_domain_name(["3foo-bar.2bar-fuzz.com"])
result.should(be_true)
end
it "should return false if domain name contains spaces" do
result = @scope.function_is_domain_name(["not valid"])
result.should(be_false)
end
end

View file

@ -0,0 +1,36 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the is_float function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("is_float").should == "function_is_float"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_is_float([]) }.should( raise_error(Puppet::ParseError))
end
it "should return true if a float" do
result = @scope.function_is_float(["0.12"])
result.should(eq(true))
end
it "should return false if a string" do
result = @scope.function_is_float(["asdf"])
result.should(eq(false))
end
it "should return false if an integer" do
result = @scope.function_is_float(["3"])
result.should(eq(false))
end
end

View file

@ -0,0 +1,36 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the is_hash function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("is_hash").should == "function_is_hash"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_is_hash([]) }.should( raise_error(Puppet::ParseError))
end
it "should return true if passed a hash" do
result = @scope.function_is_hash([{"a"=>1,"b"=>2}])
result.should(eq(true))
end
it "should return false if passed an array" do
result = @scope.function_is_hash([["a","b"]])
result.should(eq(false))
end
it "should return false if passed a string" do
result = @scope.function_is_hash(["asdf"])
result.should(eq(false))
end
end

View file

@ -0,0 +1,36 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the is_integer function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("is_integer").should == "function_is_integer"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_is_integer([]) }.should( raise_error(Puppet::ParseError))
end
it "should return true if an integer" do
result = @scope.function_is_integer(["3"])
result.should(eq(true))
end
it "should return false if a float" do
result = @scope.function_is_integer(["3.2"])
result.should(eq(false))
end
it "should return false if a string" do
result = @scope.function_is_integer(["asdf"])
result.should(eq(false))
end
end

View file

@ -0,0 +1,45 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the is_ip_address function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("is_ip_address").should == "function_is_ip_address"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_is_ip_address([]) }.should( raise_error(Puppet::ParseError))
end
it "should return true if an IPv4 address" do
result = @scope.function_is_ip_address(["1.2.3.4"])
result.should(eq(true))
end
it "should return true if a full IPv6 address" do
result = @scope.function_is_ip_address(["fe80:0000:cd12:d123:e2f8:47ff:fe09:dd74"])
result.should(eq(true))
end
it "should return true if a compressed IPv6 address" do
result = @scope.function_is_ip_address(["fe00::1"])
result.should(eq(true))
end
it "should return false if not valid" do
result = @scope.function_is_ip_address(["asdf"])
result.should(eq(false))
end
it "should return false if IP octets out of range" do
result = @scope.function_is_ip_address(["1.1.1.300"])
result.should(eq(false))
end
end

View file

@ -0,0 +1,36 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the is_mac_address function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("is_mac_address").should == "function_is_mac_address"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_is_mac_address([]) }.should( raise_error(Puppet::ParseError))
end
it "should return true if a valid mac address" do
result = @scope.function_is_mac_address(["00:a0:1f:12:7f:a0"])
result.should(eq(true))
end
it "should return false if octets are out of range" do
result = @scope.function_is_mac_address(["00:a0:1f:12:7f:g0"])
result.should(eq(false))
end
it "should return false if not valid" do
result = @scope.function_is_mac_address(["not valid"])
result.should(eq(false))
end
end

View file

@ -0,0 +1,36 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the is_numeric function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("is_numeric").should == "function_is_numeric"
end
it "should raise a ParseError if there is less than 1 argument" do
lambda { @scope.function_is_numeric([]) }.should( raise_error(Puppet::ParseError))
end
it "should return true if an integer" do
result = @scope.function_is_numeric(["3"])
result.should(eq(true))
end
it "should return true if a float" do
result = @scope.function_is_numeric(["3.2"])
result.should(eq(true))
end
it "should return false if a string" do
result = @scope.function_is_numeric(["asdf"])
result.should(eq(false))
end
end

View file

@ -0,0 +1,41 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the is_string function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("is_string").should == "function_is_string"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_is_string([]) }.should( raise_error(Puppet::ParseError))
end
it "should return true if a string" do
result = @scope.function_is_string(["asdf"])
result.should(eq(true))
end
it "should return false if an integer" do
result = @scope.function_is_string(["3"])
result.should(eq(false))
end
it "should return false if a float" do
result = @scope.function_is_string(["3.23"])
result.should(eq(false))
end
it "should return false if an array" do
result = @scope.function_is_string([["a","b","c"]])
result.should(eq(false))
end
end

View file

@ -0,0 +1,26 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the join function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("join").should == "function_join"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_join([]) }.should( raise_error(Puppet::ParseError))
end
it "should join an array into a string" do
result = @scope.function_join([["a","b","c"], ":"])
result.should(eq("a:b:c"))
end
end

View file

@ -0,0 +1,26 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the keys function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("keys").should == "function_keys"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_keys([]) }.should( raise_error(Puppet::ParseError))
end
it "should return an array of keys when given a hash" do
result = @scope.function_keys([{'a'=>1, 'b' => 2}])
result.should(eq(['a','b']))
end
end

View file

@ -0,0 +1,26 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the lstrip function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("lstrip").should == "function_lstrip"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_lstrip([]) }.should( raise_error(Puppet::ParseError))
end
it "should lstrip a string" do
result = @scope.function_lstrip([" asdf"])
result.should(eq('asdf'))
end
end

View file

@ -0,0 +1,31 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the member function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("member").should == "function_member"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_member([]) }.should( raise_error(Puppet::ParseError))
end
it "should return true if a member is in an array" do
result = @scope.function_member([["a","b","c"], "a"])
result.should(eq(true))
end
it "should return false if a member is not in an array" do
result = @scope.function_member([["a","b","c"], "d"])
result.should(eq(false))
end
end

View file

@ -0,0 +1,31 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the num2bool function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("num2bool").should == "function_num2bool"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_num2bool([]) }.should( raise_error(Puppet::ParseError))
end
it "should return true if 1" do
result = @scope.function_num2bool(["1"])
result.should(be_true)
end
it "should return false if 0" do
result = @scope.function_num2bool(["0"])
result.should(be_false)
end
end

View file

@ -0,0 +1,29 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the parsejson function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("parsejson").should == "function_parsejson"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_parsejson([]) }.should( raise_error(Puppet::ParseError))
end
it "should convert JSON to a data structure" do
json = <<-EOS
["aaa","bbb","ccc"]
EOS
result = @scope.function_parsejson([json])
result.should(eq(['aaa','bbb','ccc']))
end
end

View file

@ -0,0 +1,31 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the parseyaml function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("parseyaml").should == "function_parseyaml"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_parseyaml([]) }.should( raise_error(Puppet::ParseError))
end
it "should convert YAML to a data structure" do
yaml = <<-EOS
- aaa
- bbb
- ccc
EOS
result = @scope.function_parseyaml([yaml])
result.should(eq(['aaa','bbb','ccc']))
end
end

View file

@ -0,0 +1,26 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the prefix function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("prefix").should == "function_prefix"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_prefix([]) }.should( raise_error(Puppet::ParseError))
end
it "should return a prefixed array" do
result = @scope.function_prefix([['a','b','c'], 'p'])
result.should(eq(['pa','pb','pc']))
end
end

View file

@ -0,0 +1,31 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the range function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("range").should == "function_range"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_range([]) }.should( raise_error(Puppet::ParseError))
end
it "should return a letter range" do
result = @scope.function_range(["a","d"])
result.should(eq(['a','b','c','d']))
end
it "should return a number range" do
result = @scope.function_range(["1","4"])
result.should(eq([1,2,3,4]))
end
end

View file

@ -0,0 +1,26 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the reverse function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("reverse").should == "function_reverse"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_reverse([]) }.should( raise_error(Puppet::ParseError))
end
it "should reverse a string" do
result = @scope.function_reverse(["asdfghijkl"])
result.should(eq('lkjihgfdsa'))
end
end

View file

@ -0,0 +1,31 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the rstrip function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("rstrip").should == "function_rstrip"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_rstrip([]) }.should( raise_error(Puppet::ParseError))
end
it "should rstrip a string" do
result = @scope.function_rstrip(["asdf "])
result.should(eq('asdf'))
end
it "should rstrip each element in an array" do
result = @scope.function_rstrip([["a ","b ", "c "]])
result.should(eq(['a','b','c']))
end
end

View file

@ -0,0 +1,31 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the shuffle function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("shuffle").should == "function_shuffle"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_shuffle([]) }.should( raise_error(Puppet::ParseError))
end
it "should shuffle a string and the result should be the same size" do
result = @scope.function_shuffle(["asdf"])
result.size.should(eq(4))
end
it "should shuffle a string but the sorted contents should still be the same" do
result = @scope.function_shuffle(["adfs"])
result.split("").sort.join("").should(eq("adfs"))
end
end

View file

@ -0,0 +1,31 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the size function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("size").should == "function_size"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_size([]) }.should( raise_error(Puppet::ParseError))
end
it "should return the size of a string" do
result = @scope.function_size(["asdf"])
result.should(eq(4))
end
it "should return the size of an array" do
result = @scope.function_size([["a","b","c"]])
result.should(eq(3))
end
end

View file

@ -0,0 +1,31 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the sort function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("sort").should == "function_sort"
end
it "should raise a ParseError if there is not 1 arguments" do
lambda { @scope.function_sort(['','']) }.should( raise_error(Puppet::ParseError))
end
it "should sort an array" do
result = @scope.function_sort([["a","c","b"]])
result.should(eq(['a','b','c']))
end
it "should sort a string" do
result = @scope.function_sort(["acb"])
result.should(eq('abc'))
end
end

View file

@ -0,0 +1,31 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the squeeze function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("squeeze").should == "function_squeeze"
end
it "should raise a ParseError if there is less than 2 arguments" do
lambda { @scope.function_squeeze([]) }.should( raise_error(Puppet::ParseError))
end
it "should squeeze a string" do
result = @scope.function_squeeze(["aaabbbbcccc"])
result.should(eq('abc'))
end
it "should squeeze all elements in an array" do
result = @scope.function_squeeze([["aaabbbbcccc","dddfff"]])
result.should(eq(['abc','df']))
end
end

View file

@ -0,0 +1,31 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the str2bool function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("str2bool").should == "function_str2bool"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_str2bool([]) }.should( raise_error(Puppet::ParseError))
end
it "should convert string 'true' to true" do
result = @scope.function_str2bool(["true"])
result.should(eq(true))
end
it "should convert string 'undef' to false" do
result = @scope.function_str2bool(["undef"])
result.should(eq(false))
end
end

View file

@ -0,0 +1,36 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the strftime function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("strftime").should == "function_strftime"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_strftime([]) }.should( raise_error(Puppet::ParseError))
end
it "using %s should be higher then when I wrote this test" do
result = @scope.function_strftime(["%s"])
result.to_i.should(be > 1311953157)
end
it "using %s should be lower then 1.5 trillion" do
result = @scope.function_strftime(["%s"])
result.to_i.should(be < 1500000000)
end
it "should return a date when given %Y-%m-%d" do
result = @scope.function_strftime(["%Y-%m-%d"])
result.should =~ /^\d{4}-\d{2}-\d{2}$/
end
end

View file

@ -0,0 +1,26 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the strip function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("strip").should == "function_strip"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_strip([]) }.should( raise_error(Puppet::ParseError))
end
it "should strip a string" do
result = @scope.function_strip([" ab cd "])
result.should(eq('ab cd'))
end
end

View file

@ -0,0 +1,26 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the swapcase function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("swapcase").should == "function_swapcase"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_swapcase([]) }.should( raise_error(Puppet::ParseError))
end
it "should swapcase a string" do
result = @scope.function_swapcase(["aaBBccDD"])
result.should(eq('AAbbCCdd'))
end
end

View file

@ -0,0 +1,36 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the time function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("time").should == "function_time"
end
it "should raise a ParseError if there is more than 2 arguments" do
lambda { @scope.function_time(['','']) }.should( raise_error(Puppet::ParseError))
end
it "should return a number" do
result = @scope.function_time([])
result.class.should(eq(Fixnum))
end
it "should be higher then when I wrote this test" do
result = @scope.function_time([])
result.should(be > 1311953157)
end
it "should be lower then 1.5 trillion" do
result = @scope.function_time([])
result.should(be < 1500000000)
end
end

View file

@ -0,0 +1,51 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the type function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("type").should == "function_type"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_type([]) }.should( raise_error(Puppet::ParseError))
end
it "should return string when given a string" do
result = @scope.function_type(["aaabbbbcccc"])
result.should(eq('string'))
end
it "should return array when given an array" do
result = @scope.function_type([["aaabbbbcccc","asdf"]])
result.should(eq('array'))
end
it "should return hash when given a hash" do
result = @scope.function_type([{"a"=>1,"b"=>2}])
result.should(eq('hash'))
end
it "should return integer when given an integer" do
result = @scope.function_type(["1"])
result.should(eq('integer'))
end
it "should return float when given a float" do
result = @scope.function_type(["1.34"])
result.should(eq('float'))
end
it "should return boolean when given a boolean" do
result = @scope.function_type([true])
result.should(eq('boolean'))
end
end

View file

@ -0,0 +1,31 @@
#!/usr/bin/env rspec
require 'spec_helper'
describe "the unique function" do
before :all do
Puppet::Parser::Functions.autoloader.loadall
end
before :each do
@scope = Puppet::Parser::Scope.new
end
it "should exist" do
Puppet::Parser::Functions.function("unique").should == "function_unique"
end
it "should raise a ParseError if there is less than 1 arguments" do
lambda { @scope.function_unique([]) }.should( raise_error(Puppet::ParseError))
end
it "should remove duplicate elements in a string" do
result = @scope.function_unique(["aabbc"])
result.should(eq('abc'))
end
it "should remove duplicate elements in an array" do
result = @scope.function_unique([["a","a","b","b","c"]])
result.should(eq(['a','b','c']))
end
end

Some files were not shown because too many files have changed in this diff Show more