summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
Diffstat (limited to 'spec')
-rwxr-xr-xspec/lib/puppet_spec/files.rb53
-rwxr-xr-xspec/lib/puppet_spec/fixtures.rb28
-rw-r--r--spec/lib/puppet_spec/matchers.rb87
-rwxr-xr-xspec/lib/puppet_spec/verbose.rb9
-rwxr-xr-xspec/monkey_patches/alias_should_to_must.rb8
-rwxr-xr-xspec/monkey_patches/publicize_methods.rb11
-rw-r--r--spec/spec_helper.rb111
-rw-r--r--spec/unit/facter/root_home_spec.rb42
-rwxr-xr-xspec/unit/puppet/parser/functions/abs_spec.rb31
-rwxr-xr-xspec/unit/puppet/parser/functions/bool2num_spec.rb31
-rwxr-xr-xspec/unit/puppet/parser/functions/capitalize_spec.rb26
-rwxr-xr-xspec/unit/puppet/parser/functions/chomp_spec.rb26
-rwxr-xr-xspec/unit/puppet/parser/functions/chop_spec.rb26
-rwxr-xr-xspec/unit/puppet/parser/functions/delete_at_spec.rb26
-rwxr-xr-xspec/unit/puppet/parser/functions/delete_spec.rb26
-rwxr-xr-xspec/unit/puppet/parser/functions/downcase_spec.rb31
-rwxr-xr-xspec/unit/puppet/parser/functions/empty_spec.rb31
-rwxr-xr-xspec/unit/puppet/parser/functions/flatten_spec.rb31
-rwxr-xr-xspec/unit/puppet/parser/functions/grep_spec.rb26
-rw-r--r--spec/unit/puppet/parser/functions/hash_spec.rb26
-rw-r--r--spec/unit/puppet/parser/functions/is_array_spec.rb36
-rw-r--r--spec/unit/puppet/parser/functions/is_domain_name_spec.rb68
-rw-r--r--spec/unit/puppet/parser/functions/is_float_spec.rb36
-rw-r--r--spec/unit/puppet/parser/functions/is_hash_spec.rb36
-rw-r--r--spec/unit/puppet/parser/functions/is_integer_spec.rb36
-rw-r--r--spec/unit/puppet/parser/functions/is_ip_address_spec.rb45
-rw-r--r--spec/unit/puppet/parser/functions/is_mac_address_spec.rb36
-rw-r--r--spec/unit/puppet/parser/functions/is_numeric_spec.rb36
-rw-r--r--spec/unit/puppet/parser/functions/is_string_spec.rb41
-rw-r--r--spec/unit/puppet/parser/functions/join_spec.rb26
-rw-r--r--spec/unit/puppet/parser/functions/keys_spec.rb25
-rw-r--r--spec/unit/puppet/parser/functions/lstrip_spec.rb26
-rw-r--r--spec/unit/puppet/parser/functions/member_spec.rb31
-rw-r--r--spec/unit/puppet/parser/functions/num2bool_spec.rb31
-rw-r--r--spec/unit/puppet/parser/functions/parsejson_spec.rb29
-rw-r--r--spec/unit/puppet/parser/functions/parseyaml_spec.rb31
-rw-r--r--spec/unit/puppet/parser/functions/prefix_spec.rb26
-rw-r--r--spec/unit/puppet/parser/functions/range_spec.rb31
-rw-r--r--spec/unit/puppet/parser/functions/reverse_spec.rb26
-rw-r--r--spec/unit/puppet/parser/functions/rstrip_spec.rb31
-rw-r--r--spec/unit/puppet/parser/functions/shuffle_spec.rb31
-rw-r--r--spec/unit/puppet/parser/functions/size_spec.rb31
-rw-r--r--spec/unit/puppet/parser/functions/sort_spec.rb31
-rw-r--r--spec/unit/puppet/parser/functions/squeeze_spec.rb31
-rw-r--r--spec/unit/puppet/parser/functions/str2bool_spec.rb31
-rw-r--r--spec/unit/puppet/parser/functions/strftime_spec.rb36
-rw-r--r--spec/unit/puppet/parser/functions/strip_spec.rb26
-rw-r--r--spec/unit/puppet/parser/functions/swapcase_spec.rb26
-rw-r--r--spec/unit/puppet/parser/functions/time_spec.rb36
-rw-r--r--spec/unit/puppet/parser/functions/type_spec.rb51
-rw-r--r--spec/unit/puppet/parser/functions/unique_spec.rb31
-rw-r--r--spec/unit/puppet/parser/functions/upcase_spec.rb31
-rw-r--r--spec/unit/puppet/parser/functions/values_at_spec.rb45
-rw-r--r--spec/unit/puppet/parser/functions/values_spec.rb35
-rw-r--r--spec/unit/puppet/parser/functions/zip_spec.rb26
-rw-r--r--spec/watchr.rb86
56 files changed, 1941 insertions, 12 deletions
diff --git a/spec/lib/puppet_spec/files.rb b/spec/lib/puppet_spec/files.rb
new file mode 100755
index 0000000..30fb4fc
--- /dev/null
+++ b/spec/lib/puppet_spec/files.rb
@@ -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
diff --git a/spec/lib/puppet_spec/fixtures.rb b/spec/lib/puppet_spec/fixtures.rb
new file mode 100755
index 0000000..7f6bc2a
--- /dev/null
+++ b/spec/lib/puppet_spec/fixtures.rb
@@ -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
diff --git a/spec/lib/puppet_spec/matchers.rb b/spec/lib/puppet_spec/matchers.rb
new file mode 100644
index 0000000..77f5803
--- /dev/null
+++ b/spec/lib/puppet_spec/matchers.rb
@@ -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
diff --git a/spec/lib/puppet_spec/verbose.rb b/spec/lib/puppet_spec/verbose.rb
new file mode 100755
index 0000000..d9834f2
--- /dev/null
+++ b/spec/lib/puppet_spec/verbose.rb
@@ -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
diff --git a/spec/monkey_patches/alias_should_to_must.rb b/spec/monkey_patches/alias_should_to_must.rb
new file mode 100755
index 0000000..1a11117
--- /dev/null
+++ b/spec/monkey_patches/alias_should_to_must.rb
@@ -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
diff --git a/spec/monkey_patches/publicize_methods.rb b/spec/monkey_patches/publicize_methods.rb
new file mode 100755
index 0000000..b39e9c0
--- /dev/null
+++ b/spec/monkey_patches/publicize_methods.rb
@@ -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
+
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index a4aeeae..87aac34 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -1,18 +1,105 @@
-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 'facter'
+require 'mocha'
+gem 'rspec', '>=2.0.0'
+require 'rspec/expectations'
+
+# 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
-Spec::Runner.configure do |config|
- config.mock_with :mocha
+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'
+
+# JJM Hack to make the stdlib tests run in Puppet 2.6 (See puppet commit cf183534)
+if not Puppet.constants.include? "Test" then
+ module Puppet::Test
+ class LogCollector
+ def initialize(logs)
+ @logs = logs
+ end
+
+ def <<(value)
+ @logs << value
+ end
+ end
+ end
+ Puppet::Util::Log.newdesttype :log_collector do
+ match "Puppet::Test::LogCollector"
+
+ def initialize(messages)
+ @messages = messages
+ end
+
+ def handle(msg)
+ @messages << msg
+ end
+ end
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
+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 if Puppet::Util.constants.include? "ExecutionStub"
+
+ PuppetSpec::Files.cleanup
+
+ @logs.clear
+ Puppet::Util::Log.close_all
+ Puppet::Util::Log.level = @log_level
+
+ GC.enable
+ end
end
diff --git a/spec/unit/facter/root_home_spec.rb b/spec/unit/facter/root_home_spec.rb
new file mode 100644
index 0000000..8946d9d
--- /dev/null
+++ b/spec/unit/facter/root_home_spec.rb
@@ -0,0 +1,42 @@
+require 'spec_helper'
+require 'facter/root_home'
+
+describe Facter::Util::RootHome do
+ context "solaris" do
+ let(:root_ent) { "root:x:0:0:Super-User:/:/sbin/sh" }
+ let(:expected_root_home) { "/" }
+
+ it "should return /" do
+ Facter::Util::Resolution.expects(:exec).with("getent passwd root").returns(root_ent)
+ Facter::Util::RootHome.get_root_home.should == expected_root_home
+ end
+ end
+ context "linux" do
+ let(:root_ent) { "root:x:0:0:root:/root:/bin/bash" }
+ let(:expected_root_home) { "/root" }
+
+ it "should return /root" do
+ Facter::Util::Resolution.expects(:exec).with("getent passwd root").returns(root_ent)
+ Facter::Util::RootHome.get_root_home.should == expected_root_home
+ end
+ end
+ context "macosx" do
+ let(:root_ent) { "root:*:0:0:System Administrator:/var/root:/bin/sh" }
+ let(:expected_root_home) { "/var/root" }
+
+ it "should return /var/root" do
+ Facter::Util::Resolution.expects(:exec).with("getent passwd root").returns(root_ent)
+ Facter::Util::RootHome.get_root_home.should == expected_root_home
+ end
+ end
+ context "windows" do
+ let(:root_ent) { "FIXME TBD on Windows" }
+ let(:expected_root_home) { "FIXME TBD on Windows" }
+
+ it "should return FIXME TBD on windows" do
+ pending "FIXME: TBD on windows"
+ Facter::Util::Resolution.expects(:exec).with("getent passwd root").returns(root_ent)
+ Facter::Util::RootHome.get_root_home.should == expected_root_home
+ end
+ end
+end
diff --git a/spec/unit/puppet/parser/functions/abs_spec.rb b/spec/unit/puppet/parser/functions/abs_spec.rb
new file mode 100755
index 0000000..65ba2e8
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/abs_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/bool2num_spec.rb b/spec/unit/puppet/parser/functions/bool2num_spec.rb
new file mode 100755
index 0000000..d5da18c
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/bool2num_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/capitalize_spec.rb b/spec/unit/puppet/parser/functions/capitalize_spec.rb
new file mode 100755
index 0000000..1c45821
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/capitalize_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/chomp_spec.rb b/spec/unit/puppet/parser/functions/chomp_spec.rb
new file mode 100755
index 0000000..0592115
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/chomp_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/chop_spec.rb b/spec/unit/puppet/parser/functions/chop_spec.rb
new file mode 100755
index 0000000..0c456a8
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/chop_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/delete_at_spec.rb b/spec/unit/puppet/parser/functions/delete_at_spec.rb
new file mode 100755
index 0000000..27db0c8
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/delete_at_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/delete_spec.rb b/spec/unit/puppet/parser/functions/delete_spec.rb
new file mode 100755
index 0000000..fab3230
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/delete_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/downcase_spec.rb b/spec/unit/puppet/parser/functions/downcase_spec.rb
new file mode 100755
index 0000000..0bccd5f
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/downcase_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/empty_spec.rb b/spec/unit/puppet/parser/functions/empty_spec.rb
new file mode 100755
index 0000000..cb0021f
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/empty_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/flatten_spec.rb b/spec/unit/puppet/parser/functions/flatten_spec.rb
new file mode 100755
index 0000000..7bedeb2
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/flatten_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/grep_spec.rb b/spec/unit/puppet/parser/functions/grep_spec.rb
new file mode 100755
index 0000000..b1f647c
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/grep_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/hash_spec.rb b/spec/unit/puppet/parser/functions/hash_spec.rb
new file mode 100644
index 0000000..6d3d48c
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/hash_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/is_array_spec.rb b/spec/unit/puppet/parser/functions/is_array_spec.rb
new file mode 100644
index 0000000..537595c
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/is_array_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/is_domain_name_spec.rb b/spec/unit/puppet/parser/functions/is_domain_name_spec.rb
new file mode 100644
index 0000000..ccd3276
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/is_domain_name_spec.rb
@@ -0,0 +1,68 @@
+#!/usr/bin/env rspec
+require 'spec_helper'
+
+describe "the is_domain_name function" do
+ before :all do
+ Puppet::Parser::Functions.autoloader.loadall
+ end
+
+ let(:scope) { Puppet::Parser::Scope.new }
+
+ 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 short domain name" do
+ result = scope.function_is_domain_name(["x.com"])
+ result.should(be_true)
+ end
+
+ it "should return true if the domain is ." do
+ result = scope.function_is_domain_name(["."])
+ result.should(be_true)
+ end
+
+ it "should return true if the domain is x.com." do
+ result = scope.function_is_domain_name(["x.com."])
+ result.should(be_true)
+ 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
diff --git a/spec/unit/puppet/parser/functions/is_float_spec.rb b/spec/unit/puppet/parser/functions/is_float_spec.rb
new file mode 100644
index 0000000..55ba8cf
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/is_float_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/is_hash_spec.rb b/spec/unit/puppet/parser/functions/is_hash_spec.rb
new file mode 100644
index 0000000..94364f5
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/is_hash_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/is_integer_spec.rb b/spec/unit/puppet/parser/functions/is_integer_spec.rb
new file mode 100644
index 0000000..faf6f2d
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/is_integer_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/is_ip_address_spec.rb b/spec/unit/puppet/parser/functions/is_ip_address_spec.rb
new file mode 100644
index 0000000..98ce828
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/is_ip_address_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/is_mac_address_spec.rb b/spec/unit/puppet/parser/functions/is_mac_address_spec.rb
new file mode 100644
index 0000000..c9b9637
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/is_mac_address_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/is_numeric_spec.rb b/spec/unit/puppet/parser/functions/is_numeric_spec.rb
new file mode 100644
index 0000000..2191b7b
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/is_numeric_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/is_string_spec.rb b/spec/unit/puppet/parser/functions/is_string_spec.rb
new file mode 100644
index 0000000..4f3f5fd
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/is_string_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/join_spec.rb b/spec/unit/puppet/parser/functions/join_spec.rb
new file mode 100644
index 0000000..1b3dec8
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/join_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/keys_spec.rb b/spec/unit/puppet/parser/functions/keys_spec.rb
new file mode 100644
index 0000000..d928562
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/keys_spec.rb
@@ -0,0 +1,25 @@
+#!/usr/bin/env rspec
+require 'spec_helper'
+
+describe "the keys function" do
+ before :all do
+ Puppet::Parser::Functions.autoloader.loadall
+ end
+
+ let(:scope) { Puppet::Parser::Scope.new }
+
+ 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}])
+ # =~ performs 'array with same elements' (set) matching
+ # For more info see RSpec::Matchers::MatchArray
+ result.should =~ ['a','b']
+ end
+end
diff --git a/spec/unit/puppet/parser/functions/lstrip_spec.rb b/spec/unit/puppet/parser/functions/lstrip_spec.rb
new file mode 100644
index 0000000..ac331fa
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/lstrip_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/member_spec.rb b/spec/unit/puppet/parser/functions/member_spec.rb
new file mode 100644
index 0000000..2cebc0d
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/member_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/num2bool_spec.rb b/spec/unit/puppet/parser/functions/num2bool_spec.rb
new file mode 100644
index 0000000..6585273
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/num2bool_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/parsejson_spec.rb b/spec/unit/puppet/parser/functions/parsejson_spec.rb
new file mode 100644
index 0000000..26eea36
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/parsejson_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/parseyaml_spec.rb b/spec/unit/puppet/parser/functions/parseyaml_spec.rb
new file mode 100644
index 0000000..f9cb049
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/parseyaml_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/prefix_spec.rb b/spec/unit/puppet/parser/functions/prefix_spec.rb
new file mode 100644
index 0000000..a0cbcab
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/prefix_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/range_spec.rb b/spec/unit/puppet/parser/functions/range_spec.rb
new file mode 100644
index 0000000..8c2446a
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/range_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/reverse_spec.rb b/spec/unit/puppet/parser/functions/reverse_spec.rb
new file mode 100644
index 0000000..4fa50e4
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/reverse_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/rstrip_spec.rb b/spec/unit/puppet/parser/functions/rstrip_spec.rb
new file mode 100644
index 0000000..af8cc12
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/rstrip_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/shuffle_spec.rb b/spec/unit/puppet/parser/functions/shuffle_spec.rb
new file mode 100644
index 0000000..f04fda5
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/shuffle_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/size_spec.rb b/spec/unit/puppet/parser/functions/size_spec.rb
new file mode 100644
index 0000000..ccaa335
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/size_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/sort_spec.rb b/spec/unit/puppet/parser/functions/sort_spec.rb
new file mode 100644
index 0000000..fbe3073
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/sort_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/squeeze_spec.rb b/spec/unit/puppet/parser/functions/squeeze_spec.rb
new file mode 100644
index 0000000..9355ad2
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/squeeze_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/str2bool_spec.rb b/spec/unit/puppet/parser/functions/str2bool_spec.rb
new file mode 100644
index 0000000..d7f0ac9
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/str2bool_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/strftime_spec.rb b/spec/unit/puppet/parser/functions/strftime_spec.rb
new file mode 100644
index 0000000..f7a2cd9
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/strftime_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/strip_spec.rb b/spec/unit/puppet/parser/functions/strip_spec.rb
new file mode 100644
index 0000000..48a52dd
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/strip_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/swapcase_spec.rb b/spec/unit/puppet/parser/functions/swapcase_spec.rb
new file mode 100644
index 0000000..2686054
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/swapcase_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/time_spec.rb b/spec/unit/puppet/parser/functions/time_spec.rb
new file mode 100644
index 0000000..5d6cd97
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/time_spec.rb
@@ -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.should be_an(Integer)
+ 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
diff --git a/spec/unit/puppet/parser/functions/type_spec.rb b/spec/unit/puppet/parser/functions/type_spec.rb
new file mode 100644
index 0000000..e3c28ed
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/type_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/unique_spec.rb b/spec/unit/puppet/parser/functions/unique_spec.rb
new file mode 100644
index 0000000..627dc33
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/unique_spec.rb
@@ -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
diff --git a/spec/unit/puppet/parser/functions/upcase_spec.rb b/spec/unit/puppet/parser/functions/upcase_spec.rb
new file mode 100644
index 0000000..5d18846
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/upcase_spec.rb
@@ -0,0 +1,31 @@
+#!/usr/bin/env rspec
+require 'spec_helper'
+
+describe "the upcase 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("upcase").should == "function_upcase"
+ end
+
+ it "should raise a ParseError if there is less than 1 arguments" do
+ lambda { @scope.function_upcase([]) }.should( raise_error(Puppet::ParseError))
+ end
+
+ it "should upcase a string" do
+ result = @scope.function_upcase(["abc"])
+ result.should(eq('ABC'))
+ end
+
+ it "should do nothing if a string is already upcase" do
+ result = @scope.function_upcase(["ABC"])
+ result.should(eq('ABC'))
+ end
+
+end
diff --git a/spec/unit/puppet/parser/functions/values_at_spec.rb b/spec/unit/puppet/parser/functions/values_at_spec.rb
new file mode 100644
index 0000000..6c45316
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/values_at_spec.rb
@@ -0,0 +1,45 @@
+#!/usr/bin/env rspec
+require 'spec_helper'
+
+describe "the values_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("values_at").should == "function_values_at"
+ end
+
+ it "should raise a ParseError if there is less than 1 arguments" do
+ lambda { @scope.function_values_at([]) }.should( raise_error(Puppet::ParseError))
+ end
+
+ it "should raise a ParseError if you try to use a range where stop is greater then start" do
+ lambda { @scope.function_values_at([['a','b'],["3-1"]]) }.should( raise_error(Puppet::ParseError))
+ end
+
+ it "should return a value at from an array" do
+ result = @scope.function_values_at([['a','b','c'],"1"])
+ result.should(eq(['b']))
+ end
+
+ it "should return a value at from an array when passed a range" do
+ result = @scope.function_values_at([['a','b','c'],"0-1"])
+ result.should(eq(['a','b']))
+ end
+
+ it "should return chosen values from an array when passed number of indexes" do
+ result = @scope.function_values_at([['a','b','c'],["0","2"]])
+ result.should(eq(['a','c']))
+ end
+
+ it "should return chosen values from an array when passed ranges and multiple indexes" do
+ result = @scope.function_values_at([['a','b','c','d','e','f','g'],["0","2","4-5"]])
+ result.should(eq(['a','c','e','f']))
+ end
+
+end
diff --git a/spec/unit/puppet/parser/functions/values_spec.rb b/spec/unit/puppet/parser/functions/values_spec.rb
new file mode 100644
index 0000000..a5fbbd8
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/values_spec.rb
@@ -0,0 +1,35 @@
+#!/usr/bin/env rspec
+require 'spec_helper'
+
+describe "the values function" do
+ before :all do
+ Puppet::Parser::Functions.autoloader.loadall
+ end
+
+ let(:scope) { Puppet::Parser::Scope.new }
+
+ it "should exist" do
+ Puppet::Parser::Functions.function("values").should == "function_values"
+ end
+
+ it "should raise a ParseError if there is less than 1 arguments" do
+ lambda { scope.function_values([]) }.should( raise_error(Puppet::ParseError))
+ end
+
+ it "should return values from a hash" do
+ result = scope.function_values([{'a'=>'1','b'=>'2','c'=>'3'}])
+ # =~ is the RSpec::Matchers::MatchArray matcher.
+ # A.K.A. "array with same elements" (multiset) matching
+ result.should =~ %w{ 1 2 3 }
+ end
+
+ it "should return a multiset" do
+ result = scope.function_values([{'a'=>'1','b'=>'3','c'=>'3'}])
+ result.should =~ %w{ 1 3 3 }
+ result.should_not =~ %w{ 1 3 }
+ end
+
+ it "should raise a ParseError unless a Hash is provided" do
+ lambda { scope.function_values([['a','b','c']]) }.should( raise_error(Puppet::ParseError))
+ end
+end
diff --git a/spec/unit/puppet/parser/functions/zip_spec.rb b/spec/unit/puppet/parser/functions/zip_spec.rb
new file mode 100644
index 0000000..074f4df
--- /dev/null
+++ b/spec/unit/puppet/parser/functions/zip_spec.rb
@@ -0,0 +1,26 @@
+#!/usr/bin/env rspec
+require 'spec_helper'
+
+describe "the zip 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("zip").should == "function_zip"
+ end
+
+ it "should raise a ParseError if there is less than 1 arguments" do
+ lambda { @scope.function_zip([]) }.should( raise_error(Puppet::ParseError))
+ end
+
+ it "should be able to zip an array" do
+ result = @scope.function_zip([['1','2','3'],['4','5','6']])
+ result.should(eq([["1", "4"], ["2", "5"], ["3", "6"]]))
+ end
+
+end
diff --git a/spec/watchr.rb b/spec/watchr.rb
new file mode 100644
index 0000000..885ef1d
--- /dev/null
+++ b/spec/watchr.rb
@@ -0,0 +1,86 @@
+ENV['FOG_MOCK'] ||= 'true'
+ENV['AUTOTEST'] = 'true'
+ENV['WATCHR'] = '1'
+
+system 'clear'
+
+def growl(message)
+ growlnotify = `which growlnotify`.chomp
+ title = "Watchr Test Results"
+ image = case message
+ when /(\d+)\s+?(failure|error)/i
+ ($1.to_i == 0) ? "~/.watchr_images/passed.png" : "~/.watchr_images/failed.png"
+ else
+ '~/.watchr_images/unknown.png'
+ end
+ options = "-w -n Watchr --image '#{File.expand_path(image)}' -m '#{message}' '#{title}'"
+ system %(#{growlnotify} #{options} &)
+end
+
+def run(cmd)
+ puts(cmd)
+ `#{cmd}`
+end
+
+def run_spec_test(file)
+ if File.exist? file
+ result = run "rspec --format p --color #{file}"
+ growl result.split("\n").last
+ puts result
+ else
+ puts "FIXME: No test #{file} [#{Time.now}]"
+ end
+end
+
+def filter_rspec(data)
+ data.split("\n").find_all do |l|
+ l =~ /^(\d+)\s+exampl\w+.*?(\d+).*?failur\w+.*?(\d+).*?pending/
+ end.join("\n")
+end
+
+def run_all_tests
+ system('clear')
+ files = Dir.glob("spec/**/*_spec.rb").join(" ")
+ result = run "rspec #{files}"
+ growl_results = filter_rspec result
+ growl growl_results
+ puts result
+ puts "GROWL: #{growl_results}"
+end
+
+# Ctrl-\
+Signal.trap 'QUIT' do
+ puts " --- Running all tests ---\n\n"
+ run_all_tests
+end
+
+@interrupted = false
+
+# Ctrl-C
+Signal.trap 'INT' do
+ if @interrupted then
+ @wants_to_quit = true
+ abort("\n")
+ else
+ puts "Interrupt a second time to quit"
+ @interrupted = true
+ Kernel.sleep 1.5
+ # raise Interrupt, nil # let the run loop catch it
+ run_suite
+ end
+end
+
+def file2spec(file)
+ result = file.sub('lib/puppet/', 'spec/unit/puppet/').gsub(/\.rb$/, '_spec.rb')
+ result = file.sub('lib/facter/', 'spec/unit/facter/').gsub(/\.rb$/, '_spec.rb')
+end
+
+
+watch( 'spec/.*_spec\.rb' ) do |md|
+ #run_spec_test(md[0])
+ run_all_tests
+end
+watch( 'lib/.*\.rb' ) do |md|
+ # run_spec_test(file2spec(md[0]))
+ run_all_tests
+end