[DRE-commits] [ruby-hiera] 02/04: Updated to 1.3.0
Jonas Genannt
jonas at brachium-system.net
Thu Nov 21 22:08:19 UTC 2013
This is an automated email from the git hooks/post-receive script.
hggh-guest pushed a commit to branch master
in repository ruby-hiera.
commit cb5caf835935c325a8194db2eefd7bab0c3e70c3
Author: Jonas Genannt <jonas at brachium-system.net>
Date: Thu Nov 21 22:58:46 2013 +0100
Updated to 1.3.0
---
README.md | 6 +-
bin/hiera | 3 +-
lib/hiera.rb | 8 +-
lib/hiera/backend.rb | 44 +++---
lib/hiera/backend/json_backend.rb | 2 +-
lib/hiera/backend/yaml_backend.rb | 2 +-
lib/hiera/error.rb | 4 +
lib/hiera/filecache.rb | 48 ++++---
lib/hiera/interpolate.rb | 48 +++++++
lib/hiera/recursive_guard.rb | 20 +++
lib/hiera/version.rb | 89 ++++++++++++
metadata.yml | 90 ++++++-------
spec/unit/backend/json_backend_spec.rb | 10 +-
spec/unit/backend/yaml_backend_spec.rb | 28 ++--
spec/unit/backend_spec.rb | 230 +++++++++++++++++++++++++++-----
spec/unit/filecache_spec.rb | 143 +++++++++++++++-----
spec/unit/version_spec.rb | 44 ++++++
17 files changed, 633 insertions(+), 186 deletions(-)
diff --git a/README.md b/README.md
index 968290c..38f5db1 100644
--- a/README.md
+++ b/README.md
@@ -117,7 +117,7 @@ A sample configuration file can be seen here:
:logger: console
:hierarchy:
- - "%{location}"
+ - "sites/%{location}"
- common
:yaml:
@@ -130,14 +130,14 @@ A sample configuration file can be seen here:
This configuration will require YAML files in _/etc/puppet/hieradata_ these need to contain
Hash data, sample files matching the hierarchy described in the _Why?_ section are below:
-_/etc/puppet/hieradata/dc1.yaml_:
+_/etc/puppet/hieradata/sites/dc1.yaml_:
<pre>
---
ntpserver: ntp1.dc1.example.com
sysadmin: dc1noc at example.com
</pre>
-_/etc/puppet/hieradata/dc2.yaml_:
+_/etc/puppet/hieradata/sites/dc2.yaml_:
<pre>
---
ntpserver: ntp1.dc2.example.com
diff --git a/bin/hiera b/bin/hiera
index ddd4daa..ce2875e 100755
--- a/bin/hiera
+++ b/bin/hiera
@@ -24,6 +24,7 @@ end
require 'hiera'
require 'hiera/util'
require 'optparse'
+require 'pp'
options = {
:default => nil,
@@ -222,5 +223,5 @@ ans = hiera.lookup(options[:key], options[:default], options[:scope], nil, optio
if ans.is_a?(String)
puts ans
else
- p ans
+ pp ans
end
diff --git a/lib/hiera.rb b/lib/hiera.rb
index ec9e28b..d1a8979 100644
--- a/lib/hiera.rb
+++ b/lib/hiera.rb
@@ -1,8 +1,8 @@
require 'yaml'
class Hiera
- VERSION = "1.2.1"
-
+ require "hiera/error"
+ require "hiera/version"
require "hiera/config"
require "hiera/util"
require "hiera/backend"
@@ -15,10 +15,6 @@ class Hiera
class << self
attr_reader :logger
- def version
- VERSION
- end
-
# Loggers are pluggable, just provide a class called
# Hiera::Foo_logger and respond to :warn and :debug
#
diff --git a/lib/hiera/backend.rb b/lib/hiera/backend.rb
index 9b3af5e..c04bf24 100644
--- a/lib/hiera/backend.rb
+++ b/lib/hiera/backend.rb
@@ -1,5 +1,6 @@
require 'hiera/util'
-require 'hiera/recursive_lookup'
+require 'hiera/recursive_guard'
+require 'hiera/interpolate'
begin
require 'deep_merge'
@@ -8,21 +9,25 @@ end
class Hiera
module Backend
- INTERPOLATION = /%\{([^\}]*)\}/
-
class << self
# Data lives in /var/lib/hiera by default. If a backend
# supplies a datadir in the config it will be used and
# subject to variable expansion based on scope
def datadir(backend, scope)
backend = backend.to_sym
- default = Hiera::Util.var_dir
- if Config.include?(backend)
- parse_string(Config[backend][:datadir] || default, scope)
+ if Config[backend] && Config[backend][:datadir]
+ dir = Config[backend][:datadir]
else
- parse_string(default, scope)
+ dir = Hiera::Util.var_dir
+ end
+
+ if !dir.is_a?(String)
+ raise(Hiera::InvalidConfigurationError,
+ "datadir for #{backend} cannot be an array")
end
+
+ parse_string(dir, scope)
end
# Finds the path to a datafile based on the Backend#datadir
@@ -85,22 +90,8 @@ class Hiera
#
# @api public
def parse_string(data, scope, extra_data={})
- interpolate(data, Hiera::RecursiveLookup.new(scope, extra_data))
- end
-
- def interpolate(data, values)
- if data.is_a?(String)
- data.gsub(INTERPOLATION) do
- name = $1
- values.lookup(name) do |value|
- interpolate(value, values)
- end
- end
- else
- data
- end
+ Hiera::Interpolate.interpolate(data, Hiera::RecursiveGuard.new, scope, extra_data)
end
- private :interpolate
# Parses a answer received from data files
#
@@ -114,7 +105,8 @@ class Hiera
elsif data.is_a?(Hash)
answer = {}
data.each_pair do |key, val|
- answer[key] = parse_answer(val, scope, extra_data)
+ interpolated_key = parse_string(key, scope, extra_data)
+ answer[interpolated_key] = parse_answer(val, scope, extra_data)
end
return answer
@@ -145,7 +137,7 @@ class Hiera
# Deep merge options use the Hash utility function provided by [deep_merge](https://github.com/peritor/deep_merge)
#
# :native => Native Hash.merge
- # :deep => Use Hash.deep_merge
+ # :deep => Use Hash.deep_merge
# :deeper => Use Hash.deep_merge!
#
def merge_answer(left,right)
@@ -205,6 +197,10 @@ class Hiera
return default if answer.nil?
return answer
end
+
+ def clear!
+ @backends = {}
+ end
end
end
end
diff --git a/lib/hiera/backend/json_backend.rb b/lib/hiera/backend/json_backend.rb
index 4ca9481..da78b99 100644
--- a/lib/hiera/backend/json_backend.rb
+++ b/lib/hiera/backend/json_backend.rb
@@ -21,7 +21,7 @@ class Hiera
next unless File.exist?(jsonfile)
- data = @cache.read(jsonfile, Hash, {}) do |data|
+ data = @cache.read_file(jsonfile, Hash) do |data|
JSON.parse(data)
end
diff --git a/lib/hiera/backend/yaml_backend.rb b/lib/hiera/backend/yaml_backend.rb
index 1ce6bd1..0e100c1 100644
--- a/lib/hiera/backend/yaml_backend.rb
+++ b/lib/hiera/backend/yaml_backend.rb
@@ -19,7 +19,7 @@ class Hiera
next unless File.exist?(yamlfile)
- data = @cache.read(yamlfile, Hash, {}) do |data|
+ data = @cache.read_file(yamlfile, Hash) do |data|
YAML.load(data)
end
diff --git a/lib/hiera/error.rb b/lib/hiera/error.rb
new file mode 100644
index 0000000..8ff4f3f
--- /dev/null
+++ b/lib/hiera/error.rb
@@ -0,0 +1,4 @@
+class Hiera
+ class Error < StandardError; end
+ class InvalidConfigurationError < Error; end
+end
diff --git a/lib/hiera/filecache.rb b/lib/hiera/filecache.rb
index ac46e02..f1a3d1f 100644
--- a/lib/hiera/filecache.rb
+++ b/lib/hiera/filecache.rb
@@ -24,32 +24,44 @@ class Hiera
# reading/parsing fails it will return {} instead
#
# Prior to calling this method you should be sure the file exist
- def read(path, expected_type=nil, default=nil)
- @cache[path] ||= {:data => nil, :meta => path_metadata(path)}
-
- if File.exist?(path) && !@cache[path][:data] || stale?(path)
- if block_given?
- begin
- @cache[path][:data] = yield(File.read(path))
- rescue => e
- Hiera.debug("Reading data from %s failed: %s: %S" % [path, e.class, e.to_s])
- @cache[path][:data] = default
- end
- else
- @cache[path][:data] = File.read(path)
- end
+ def read(path, expected_type = Object, default=nil, &block)
+ read_file(path, expected_type, &block)
+ rescue TypeError => detail
+ Hiera.debug("#{detail.message}, setting defaults")
+ @cache[path][:data] = default
+ rescue => detail
+ error = "Reading data from #{path} failed: #{detail.class}: #{detail}"
+ if default.nil?
+ raise detail
+ else
+ Hiera.debug(error)
+ @cache[path][:data] = default
end
+ end
- if block_given? && !expected_type.nil?
- unless @cache[path][:data].is_a?(expected_type)
- Hiera.debug("Data retrieved from %s is not a %s, setting defaults" % [path, expected_type])
- @cache[path][:data] = default
+ # Read a file when it changes. If a file is re-read and has not changed since the last time
+ # then the last, processed, contents will be returned.
+ #
+ # The processed data can also be checked against an expected type. If the
+ # type does not match a TypeError is raised.
+ #
+ # No error handling is done inside this method. Any failed reads or errors
+ # in processing will be propagated to the caller
+ def read_file(path, expected_type = Object)
+ if stale?(path)
+ data = File.read(path)
+ @cache[path][:data] = block_given? ? yield(data) : data
+
+ if !@cache[path][:data].is_a?(expected_type)
+ raise TypeError, "Data retrieved from #{path} is #{data.class} not #{expected_type}"
end
end
@cache[path][:data]
end
+ private
+
def stale?(path)
meta = path_metadata(path)
diff --git a/lib/hiera/interpolate.rb b/lib/hiera/interpolate.rb
new file mode 100644
index 0000000..b5653f2
--- /dev/null
+++ b/lib/hiera/interpolate.rb
@@ -0,0 +1,48 @@
+require 'hiera/backend'
+
+class Hiera::Interpolate
+ class << self
+ INTERPOLATION = /%\{([^\}]*)\}/
+ METHOD_INTERPOLATION = /%\{(scope|hiera)\(['"]([^"']*)["']\)\}/
+
+ def interpolate(data, recurse_guard, scope, extra_data)
+ if data.is_a?(String) && (match = data.match(INTERPOLATION))
+ interpolation_variable = match[1]
+ recurse_guard.check(interpolation_variable) do
+ interpolate_method, key = get_interpolation_method_and_key(data)
+ interpolated_data = send(interpolate_method, data, key, scope, extra_data)
+ interpolate(interpolated_data, recurse_guard, scope, extra_data)
+ end
+ else
+ data
+ end
+ end
+
+ def get_interpolation_method_and_key(data)
+ if (match = data.match(METHOD_INTERPOLATION))
+ case match[1]
+ when 'hiera' then [:hiera_interpolate, match[2]]
+ when 'scope' then [:scope_interpolate, match[2]]
+ end
+ elsif (match = data.match(INTERPOLATION))
+ [:scope_interpolate, match[1]]
+ end
+ end
+ private :get_interpolation_method_and_key
+
+ def scope_interpolate(data, key, scope, extra_data)
+ value = scope[key]
+ if value.nil? || value == :undefined
+ value = extra_data[key]
+ end
+ data.sub(INTERPOLATION, value.to_s)
+ end
+ private :scope_interpolate
+
+ def hiera_interpolate(data, key, scope, extra_data)
+ value = Hiera::Backend.lookup(key, nil, scope, nil, :priority)
+ data.sub(METHOD_INTERPOLATION, value)
+ end
+ private :hiera_interpolate
+ end
+end
diff --git a/lib/hiera/recursive_guard.rb b/lib/hiera/recursive_guard.rb
new file mode 100644
index 0000000..c68d21c
--- /dev/null
+++ b/lib/hiera/recursive_guard.rb
@@ -0,0 +1,20 @@
+# Allow for safe recursive lookup of values during variable interpolation.
+#
+# @api private
+class Hiera::InterpolationLoop < StandardError; end
+
+class Hiera::RecursiveGuard
+ def initialize
+ @seen = []
+ end
+
+ def check(value, &block)
+ if @seen.include?(value)
+ raise Hiera::InterpolationLoop, "Detected in [#{@seen.join(', ')}]"
+ end
+ @seen.push(value)
+ ret = yield
+ @seen.pop
+ ret
+ end
+end
diff --git a/lib/hiera/version.rb b/lib/hiera/version.rb
new file mode 100644
index 0000000..a5a5445
--- /dev/null
+++ b/lib/hiera/version.rb
@@ -0,0 +1,89 @@
+# The version method and constant are isolated in hiera/version.rb so that a
+# simple `require 'hiera/version'` allows a rubygems gemspec or bundler
+# Gemfile to get the hiera version of the gem install.
+#
+# The version is programatically settable because we want to allow the
+# Raketasks and such to set the version based on the output of `git describe`
+
+
+class Hiera
+ VERSION = "1.3.0"
+
+ ##
+ # version is a public API method intended to always provide a fast and
+ # lightweight way to determine the version of hiera.
+ #
+ # The intent is that software external to hiera be able to determine the
+ # hiera version with no side-effects. The expected use is:
+ #
+ # require 'hiera/version'
+ # version = Hiera.version
+ #
+ # This function has the following ordering precedence. This precedence list
+ # is designed to facilitate automated packaging tasks by simply writing to
+ # the VERSION file in the same directory as this source file.
+ #
+ # 1. If a version has been explicitly assigned using the Hiera.version=
+ # method, return that version.
+ # 2. If there is a VERSION file, read the contents, trim any
+ # trailing whitespace, and return that version string.
+ # 3. Return the value of the Hiera::VERSION constant hard-coded into
+ # the source code.
+ #
+ # If there is no VERSION file, the method must return the version string of
+ # the nearest parent version that is an officially released version. That is
+ # to say, if a branch named 3.1.x contains 25 patches on top of the most
+ # recent official release of 3.1.1, then the version method must return the
+ # string "3.1.1" if no "VERSION" file is present.
+ #
+ # By design the version identifier is _not_ intended to vary during the life
+ # a process. There is no guarantee provided that writing to the VERSION file
+ # while a Hiera process is running will cause the version string to be
+ # updated. On the contrary, the contents of the VERSION are cached to reduce
+ # filesystem accesses.
+ #
+ # The VERSION file is intended to be used by package maintainers who may be
+ # applying patches or otherwise changing the software version in a manner
+ # that warrants a different software version identifier. The VERSION file is
+ # intended to be managed and owned by the release process and packaging
+ # related tasks, and as such should not reside in version control. The
+ # VERSION constant is intended to be version controlled in history.
+ #
+ # Ideally, this behavior will allow package maintainers to precisely specify
+ # the version of the software they're packaging as in the following example:
+ #
+ # $ git describe --match "1.2.*" > lib/hiera/VERSION
+ # $ ruby -r hiera/version -e 'puts Hiera.version'
+ # 1.2.1-9-g9fda440
+ #
+ # @api public
+ #
+ # @return [String] containing the hiera version, e.g. "1.2.1"
+ def self.version
+ version_file = File.join(File.dirname(__FILE__), 'VERSION')
+ return @hiera_version if @hiera_version
+ if version = read_version_file(version_file)
+ @hiera_version = version
+ end
+ @hiera_version ||= VERSION
+ end
+
+ def self.version=(version)
+ @hiera_version = version
+ end
+
+ ##
+ # read_version_file reads the content of the "VERSION" file that lives in the
+ # same directory as this source code file.
+ #
+ # @api private
+ #
+ # @return [String] for example: "1.6.14-6-gea42046" or nil if the VERSION
+ # file does not exist.
+ def self.read_version_file(path)
+ if File.exists?(path)
+ File.read(path).chomp
+ end
+ end
+ private_class_method :read_version_file
+end
diff --git a/metadata.yml b/metadata.yml
index fb04e08..88aa39c 100644
--- a/metadata.yml
+++ b/metadata.yml
@@ -1,52 +1,49 @@
---- !ruby/object:Gem::Specification
+--- !ruby/object:Gem::Specification
name: hiera
-version: !ruby/object:Gem::Version
- hash: 29
+version: !ruby/object:Gem::Version
+ version: 1.3.0
prerelease:
- segments:
- - 1
- - 2
- - 1
- version: 1.2.1
platform: ruby
-authors:
+authors:
- Puppet Labs
autorequire:
bindir: bin
cert_chain: []
-
-date: 2013-04-18 00:00:00 Z
-dependencies:
-- !ruby/object:Gem::Dependency
+date: 2013-11-21 00:00:00.000000000 Z
+dependencies:
+- !ruby/object:Gem::Dependency
name: json_pure
- prerelease: false
- requirement: &id001 !ruby/object:Gem::Requirement
+ requirement: !ruby/object:Gem::Requirement
none: false
- requirements:
- - - ">="
- - !ruby/object:Gem::Version
- hash: 3
- segments:
- - 0
- version: "0"
+ requirements:
+ - - ! '>='
+ - !ruby/object:Gem::Version
+ version: '0'
type: :runtime
- version_requirements: *id001
+ prerelease: false
+ version_requirements: !ruby/object:Gem::Requirement
+ none: false
+ requirements:
+ - - ! '>='
+ - !ruby/object:Gem::Version
+ version: '0'
description: A pluggable data store for hierarcical data
email: info at puppetlabs.com
-executables:
+executables:
- hiera
extensions: []
-
extra_rdoc_files: []
-
-files:
+files:
- bin/hiera
- lib/hiera/puppet_logger.rb
-- lib/hiera/recursive_lookup.rb
- lib/hiera/console_logger.rb
- lib/hiera/filecache.rb
+- lib/hiera/version.rb
- lib/hiera/fallback_logger.rb
+- lib/hiera/error.rb
+- lib/hiera/interpolate.rb
- lib/hiera/util.rb
+- lib/hiera/recursive_guard.rb
- lib/hiera/backend.rb
- lib/hiera/noop_logger.rb
- lib/hiera/config.rb
@@ -58,6 +55,7 @@ files:
- LICENSE
- spec/unit/util_spec.rb
- spec/unit/puppet_logger_spec.rb
+- spec/unit/version_spec.rb
- spec/unit/config_spec.rb
- spec/unit/backend_spec.rb
- spec/unit/filecache_spec.rb
@@ -69,40 +67,32 @@ files:
- spec/spec_helper.rb
homepage: https://github.com/puppetlabs/hiera
licenses: []
-
post_install_message:
rdoc_options: []
-
-require_paths:
+require_paths:
- lib
-required_ruby_version: !ruby/object:Gem::Requirement
+required_ruby_version: !ruby/object:Gem::Requirement
none: false
- requirements:
- - - ">="
- - !ruby/object:Gem::Version
- hash: 3
- segments:
- - 0
- version: "0"
-required_rubygems_version: !ruby/object:Gem::Requirement
+ requirements:
+ - - ! '>='
+ - !ruby/object:Gem::Version
+ version: '0'
+required_rubygems_version: !ruby/object:Gem::Requirement
none: false
- requirements:
- - - ">="
- - !ruby/object:Gem::Version
- hash: 3
- segments:
- - 0
- version: "0"
+ requirements:
+ - - ! '>='
+ - !ruby/object:Gem::Version
+ version: '0'
requirements: []
-
rubyforge_project:
-rubygems_version: 1.8.24
+rubygems_version: 1.8.23
signing_key:
specification_version: 3
summary: Light weight hierarchical data store
-test_files:
+test_files:
- spec/unit/util_spec.rb
- spec/unit/puppet_logger_spec.rb
+- spec/unit/version_spec.rb
- spec/unit/config_spec.rb
- spec/unit/backend_spec.rb
- spec/unit/filecache_spec.rb
diff --git a/spec/unit/backend/json_backend_spec.rb b/spec/unit/backend/json_backend_spec.rb
index 57497de..fecc723 100644
--- a/spec/unit/backend/json_backend_spec.rb
+++ b/spec/unit/backend/json_backend_spec.rb
@@ -33,7 +33,7 @@ class Hiera
Backend.expects(:datafile).with(:json, {}, "one", "json").returns("/nonexisting/one.json").times(3)
File.stubs(:exist?).with("/nonexisting/one.json").returns(true)
- @cache.expects(:read).with("/nonexisting/one.json", Hash, {}).returns({"stringval" => "string", "boolval" => true, "numericval" => 1}).times(3)
+ @cache.expects(:read_file).with("/nonexisting/one.json", Hash).returns({"stringval" => "string", "boolval" => true, "numericval" => 1}).times(3)
@backend.lookup("stringval", {}, nil, :priority).should == "string"
@backend.lookup("boolval", {}, nil, :priority).should == true
@@ -47,7 +47,7 @@ class Hiera
Backend.expects(:datafile).with(:json, scope, "two", "json").never
File.stubs(:exist?).with("/nonexisting/one.json").returns(true)
- @cache.expects(:read).with("/nonexisting/one.json", Hash, {}).returns({"key" => "test_%{rspec}"})
+ @cache.expects(:read_file).with("/nonexisting/one.json", Hash).returns({"key" => "test_%{rspec}"})
@backend.lookup("key", scope, nil, :priority).should == "test_test"
end
@@ -63,8 +63,8 @@ class Hiera
File.expects(:exist?).with("/nonexisting/one.json").returns(true)
File.expects(:exist?).with("/nonexisting/two.json").returns(true)
- @cache.expects(:read).with("/nonexisting/one.json", Hash, {}).returns({"key" => "answer"})
- @cache.expects(:read).with("/nonexisting/two.json", Hash, {}).returns({"key" => "answer"})
+ @cache.expects(:read_file).with("/nonexisting/one.json", Hash).returns({"key" => "answer"})
+ @cache.expects(:read_file).with("/nonexisting/two.json", Hash).returns({"key" => "answer"})
@backend.lookup("key", {}, nil, :array).should == ["answer", "answer"]
end
@@ -75,7 +75,7 @@ class Hiera
Backend.expects(:datafile).with(:json, {"rspec" => "test"}, "one", "json").returns("/nonexisting/one.json")
File.expects(:exist?).with("/nonexisting/one.json").returns(true)
- @cache.expects(:read).with("/nonexisting/one.json", Hash, {}).returns({"key" => "test_%{rspec}"})
+ @cache.expects(:read_file).with("/nonexisting/one.json", Hash).returns({"key" => "test_%{rspec}"})
@backend.lookup("key", {"rspec" => "test"}, nil, :priority).should == "test_test"
end
diff --git a/spec/unit/backend/yaml_backend_spec.rb b/spec/unit/backend/yaml_backend_spec.rb
index 72048c2..2dee576 100644
--- a/spec/unit/backend/yaml_backend_spec.rb
+++ b/spec/unit/backend/yaml_backend_spec.rb
@@ -32,7 +32,7 @@ class Hiera
Backend.expects(:datasources).multiple_yields(["one"], ["two"])
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns("/nonexisting/one.yaml")
Backend.expects(:datafile).with(:yaml, {}, "two", "yaml").returns(nil).never
- @cache.expects(:read).with("/nonexisting/one.yaml", Hash, {}).returns({"key"=>"answer"})
+ @cache.expects(:read_file).with("/nonexisting/one.yaml", Hash).returns({"key"=>"answer"})
File.stubs(:exist?).with("/nonexisting/one.yaml").returns(true)
@backend.lookup("key", {}, nil, :priority).should == "answer"
@@ -50,7 +50,7 @@ class Hiera
Backend.expects(:datasources).multiple_yields(["one"])
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns("/nonexisting/one.yaml")
File.stubs(:exist?).with("/nonexisting/one.yaml").returns(true)
- @cache.expects(:read).with("/nonexisting/one.yaml", Hash, {}).returns({})
+ @cache.expects(:read_file).with("/nonexisting/one.yaml", Hash).returns({})
@backend.lookup("key", {}, nil, :priority).should be_nil
end
@@ -62,8 +62,8 @@ class Hiera
File.stubs(:exist?).with("/nonexisting/one.yaml").returns(true)
File.stubs(:exist?).with("/nonexisting/two.yaml").returns(true)
- @cache.expects(:read).with("/nonexisting/one.yaml", Hash, {}).returns({"key"=>"answer"})
- @cache.expects(:read).with("/nonexisting/two.yaml", Hash, {}).returns({"key"=>"answer"})
+ @cache.expects(:read_file).with("/nonexisting/one.yaml", Hash).returns({"key"=>"answer"})
+ @cache.expects(:read_file).with("/nonexisting/two.yaml", Hash).returns({"key"=>"answer"})
@backend.lookup("key", {}, nil, :array).should == ["answer", "answer"]
end
@@ -75,8 +75,8 @@ class Hiera
File.stubs(:exist?).with("/nonexisting/one.yaml").returns(true)
File.stubs(:exist?).with("/nonexisting/two.yaml").returns(true)
- @cache.expects(:read).with("/nonexisting/one.yaml", Hash, {}).returns({})
- @cache.expects(:read).with("/nonexisting/two.yaml", Hash, {}).returns({"key"=>{"a"=>"answer"}})
+ @cache.expects(:read_file).with("/nonexisting/one.yaml", Hash).returns({})
+ @cache.expects(:read_file).with("/nonexisting/two.yaml", Hash).returns({"key"=>{"a"=>"answer"}})
@backend.lookup("key", {}, nil, :hash).should == {"a" => "answer"}
end
@@ -88,8 +88,8 @@ class Hiera
File.stubs(:exist?).with("/nonexisting/one.yaml").returns(true)
File.stubs(:exist?).with("/nonexisting/two.yaml").returns(true)
- @cache.expects(:read).with("/nonexisting/one.yaml", Hash, {}).returns({"key"=>{"a"=>"answer"}})
- @cache.expects(:read).with("/nonexisting/two.yaml", Hash, {}).returns({"key"=>{"b"=>"answer", "a"=>"wrong"}})
+ @cache.expects(:read_file).with("/nonexisting/one.yaml", Hash).returns({"key"=>{"a"=>"answer"}})
+ @cache.expects(:read_file).with("/nonexisting/two.yaml", Hash).returns({"key"=>{"b"=>"answer", "a"=>"wrong"}})
@backend.lookup("key", {}, nil, :hash).should == {"a" => "answer", "b" => "answer"}
end
@@ -101,8 +101,8 @@ class Hiera
File.stubs(:exist?).with("/nonexisting/one.yaml").returns(true)
File.stubs(:exist?).with("/nonexisting/two.yaml").returns(true)
- @cache.expects(:read).with("/nonexisting/one.yaml", Hash, {}).returns({"key"=>["a", "answer"]})
- @cache.expects(:read).with("/nonexisting/two.yaml", Hash, {}).returns({"key"=>{"a"=>"answer"}})
+ @cache.expects(:read_file).with("/nonexisting/one.yaml", Hash).returns({"key"=>["a", "answer"]})
+ @cache.expects(:read_file).with("/nonexisting/two.yaml", Hash).returns({"key"=>{"a"=>"answer"}})
expect {@backend.lookup("key", {}, nil, :array)}.to raise_error(Exception, "Hiera type mismatch: expected Array and got Hash")
end
@@ -114,8 +114,8 @@ class Hiera
File.stubs(:exist?).with("/nonexisting/one.yaml").returns(true)
File.stubs(:exist?).with("/nonexisting/two.yaml").returns(true)
- @cache.expects(:read).with("/nonexisting/one.yaml", Hash, {}).returns({"key"=>{"a"=>"answer"}})
- @cache.expects(:read).with("/nonexisting/two.yaml", Hash, {}).returns({"key"=>["a", "wrong"]})
+ @cache.expects(:read_file).with("/nonexisting/one.yaml", Hash).returns({"key"=>{"a"=>"answer"}})
+ @cache.expects(:read_file).with("/nonexisting/two.yaml", Hash).returns({"key"=>["a", "wrong"]})
expect { @backend.lookup("key", {}, nil, :hash) }.to raise_error(Exception, "Hiera type mismatch: expected Hash and got Array")
end
@@ -125,7 +125,7 @@ class Hiera
Backend.expects(:datafile).with(:yaml, {"rspec" => "test"}, "one", "yaml").returns("/nonexisting/one.yaml")
File.stubs(:exist?).with("/nonexisting/one.yaml").returns(true)
- @cache.expects(:read).with("/nonexisting/one.yaml", Hash, {}).returns({"key"=>"test_%{rspec}"})
+ @cache.expects(:read_file).with("/nonexisting/one.yaml", Hash).returns({"key"=>"test_%{rspec}"})
@backend.lookup("key", {"rspec" => "test"}, nil, :priority).should == "test_test"
end
@@ -137,7 +137,7 @@ class Hiera
yaml = "---\nstringval: 'string'\nboolval: true\nnumericval: 1"
- @cache.expects(:read).with("/nonexisting/one.yaml", Hash, {}).times(3).returns({"boolval"=>true, "numericval"=>1, "stringval"=>"string"})
+ @cache.expects(:read_file).with("/nonexisting/one.yaml", Hash).times(3).returns({"boolval"=>true, "numericval"=>1, "stringval"=>"string"})
@backend.lookup("stringval", {}, nil, :priority).should == "string"
@backend.lookup("boolval", {}, nil, :priority).should == true
diff --git a/spec/unit/backend_spec.rb b/spec/unit/backend_spec.rb
index d5147c2..b70f87a 100644
--- a/spec/unit/backend_spec.rb
+++ b/spec/unit/backend_spec.rb
@@ -5,15 +5,30 @@ class Hiera
describe Backend do
describe "#datadir" do
it "interpolates any values in the configured value" do
- Config.load({:rspec => {:datadir => "/tmp"}})
- Backend.expects(:parse_string).with("/tmp", {})
- Backend.datadir(:rspec, {})
+ Config.load({:rspec => {:datadir => "/tmp/%{interpolate}"}})
+
+ dir = Backend.datadir(:rspec, { "interpolate" => "my_data" })
+
+ dir.should == "/tmp/my_data"
end
it "defaults to a directory in var" do
Config.load({})
- Backend.expects(:parse_string).with(Hiera::Util.var_dir, {})
- Backend.datadir(:rspec, {})
+ Backend.datadir(:rspec, {}).should == Hiera::Util.var_dir
+
+ Config.load({:rspec => nil})
+ Backend.datadir(:rspec, {}).should == Hiera::Util.var_dir
+
+ Config.load({:rspec => {}})
+ Backend.datadir(:rspec, {}).should == Hiera::Util.var_dir
+ end
+
+ it "fails when the datadir is an array" do
+ Config.load({:rspec => {:datadir => []}})
+
+ expect do
+ Backend.datadir(:rspec, {})
+ end.to raise_error(Hiera::InvalidConfigurationError, /datadir for rspec cannot be an array/)
end
end
@@ -103,11 +118,19 @@ class Hiera
Backend.parse_string(input, {}).should == input
end
- it "replaces interpolations with data looked up in the scope" do
- input = "replace %{part1} and %{part2}"
- scope = {"part1" => "value of part1", "part2" => "value of part2"}
+ @scope_interpolation_tests = {
+ "replace %{part1} and %{part2}" =>
+ "replace value of part1 and value of part2",
+ "replace %{scope('part1')} and %{scope('part2')}" =>
+ "replace value of part1 and value of part2"
+ }
+
+ @scope_interpolation_tests.each do |input, expected|
+ it "replaces interpolations with data looked up in the scope" do
+ scope = {"part1" => "value of part1", "part2" => "value of part2"}
- Backend.parse_string(input, scope).should == "replace value of part1 and value of part2"
+ Backend.parse_string(input, scope).should == expected
+ end
end
it "replaces interpolations with data looked up in extra_data when scope does not contain the value" do
@@ -120,14 +143,27 @@ class Hiera
Backend.parse_string(input, {"rspec" => "test"}, {"rspec" => "fail"}).should == "test_test_test"
end
- it "interprets nil in scope as a non-value" do
- input = "test_%{rspec}_test"
- Backend.parse_string(input, {"rspec" => nil}).should == "test__test"
+ @interprets_nil_in_scope_tests = {
+ "test_%{rspec}_test" => "test__test",
+ "test_%{scope('rspec')}_test" => "test__test"
+ }
+
+ @interprets_nil_in_scope_tests.each do |input, expected|
+ it "interprets nil in scope as a non-value" do
+ Backend.parse_string(input, {"rspec" => nil}).should == expected
+ end
end
- it "interprets false in scope as a real value" do
- input = "test_%{rspec}_test"
- Backend.parse_string(input, {"rspec" => false}).should == "test_false_test"
+ @interprets_false_in_scope_tests = {
+ "test_%{rspec}_test" => "test_false_test",
+ "test_%{scope('rspec')}_test" => "test_false_test"
+ }
+
+ @interprets_false_in_scope_tests.each do |input, expected|
+ it "interprets false in scope as a real value" do
+ input = "test_%{scope('rspec')}_test"
+ Backend.parse_string(input, {"rspec" => false}).should == expected
+ end
end
it "interprets false in extra_data as a real value" do
@@ -140,9 +176,15 @@ class Hiera
Backend.parse_string(input, {}, {"rspec" => nil}).should == "test__test"
end
- it "interprets :undefined in scope as a non-value" do
- input = "test_%{rspec}_test"
- Backend.parse_string(input, {"rspec" => :undefined}).should == "test__test"
+ @interprets_undefined_in_scope_tests = {
+ "test_%{rspec}_test" => "test__test",
+ "test_%{scope('rspec')}_test" => "test__test"
+ }
+
+ @interprets_undefined_in_scope_tests.each do |input, expected|
+ it "interprets :undefined in scope as a non-value" do
+ Backend.parse_string(input, {"rspec" => :undefined}).should == expected
+ end
end
it "uses the value from extra_data when scope is :undefined" do
@@ -150,24 +192,51 @@ class Hiera
Backend.parse_string(input, {"rspec" => :undefined}, { "rspec" => "extra" }).should == "test_extra_test"
end
- it "looks up the interpolated value exactly as it appears in the input" do
- input = "test_%{::rspec::data}_test"
- Backend.parse_string(input, {"::rspec::data" => "value"}).should == "test_value_test"
+ @exact_lookup_tests = {
+ "test_%{::rspec::data}_test" => "test_value_test",
+ "test_%{scope('::rspec::data')}_test" => "test_value_test"
+ }
+
+ @exact_lookup_tests.each do |input, expected|
+ it "looks up the interpolated value exactly as it appears in the input" do
+ Backend.parse_string(input, {"::rspec::data" => "value"}).should == expected
+ end
end
- it "does not remove any surrounding whitespace when parsing the key to lookup" do
- input = "test_%{\trspec::data }_test"
- Backend.parse_string(input, {"\trspec::data " => "value"}).should == "test_value_test"
+ @surrounding_whitespace_tests = {
+ "test_%{\trspec::data }_test" => "test_value_test",
+ "test_%{scope('\trspec::data ')}_test" => "test_value_test"
+ }
+ @surrounding_whitespace_tests.each do |input, expected|
+ it "does not remove any surrounding whitespace when parsing the key to lookup" do
+ Backend.parse_string(input, {"\trspec::data " => "value"}).should == expected
+ end
end
- it "does not try removing leading :: when a full lookup fails (#17434)" do
- input = "test_%{::rspec::data}_test"
- Backend.parse_string(input, {"rspec::data" => "value"}).should == "test__test"
+ @leading_double_colon_tests = {
+ "test_%{::rspec::data}_test" => "test__test",
+ "test_%{scope('::rspec::data')}_test" => "test__test"
+ }
+
+ @leading_double_colon_tests.each do |input, expected|
+ it "does not try removing leading :: when a full lookup fails (#17434)" do
+ Backend.parse_string(input, {"rspec::data" => "value"}).should == expected
+ end
+ end
+
+ @double_colon_key_tests = {
+ "test_%{::rspec::data}_test" => "test__test",
+ "test_%{scope('::rspec::data')}_test" => "test__test"
+ }
+ @double_colon_key_tests.each do |input, expected|
+ it "does not try removing leading sections separated by :: when a full lookup fails (#17434)" do
+ Backend.parse_string(input, {"data" => "value"}).should == expected
+ end
end
- it "does not try removing leading sections separated by :: when a full lookup fails (#17434)" do
- input = "test_%{::rspec::data}_test"
- Backend.parse_string(input, {"data" => "value"}).should == "test__test"
+ it "does not try removing unknown, preceeding characters when looking up values" do
+ input = "test_%{$var}_test"
+ Backend.parse_string(input, {"$var" => "value"}).should == "test_value_test"
end
it "looks up recursively" do
@@ -181,7 +250,17 @@ class Hiera
input = "test_%{first}_test"
expect do
Backend.parse_string(input, scope)
- end.to raise_error Exception, "Interpolation loop detected in [first, second]"
+ end.to raise_error Hiera::InterpolationLoop, "Detected in [first, second]"
+ end
+
+ it "replaces hiera interpolations with data looked up in hiera" do
+ input = "%{hiera('key1')}"
+ scope = {}
+ Config.load({:yaml => {:datadir => "/tmp"}})
+ Config.load_backends
+ Backend::Yaml_backend.any_instance.stubs(:lookup).with("key1", scope, nil, :priority).returns("answer")
+
+ Backend.parse_string(input, scope).should == "answer"
end
end
@@ -201,11 +280,93 @@ class Hiera
Backend.parse_answer(input, {"rspec" => "test"}).should == {"foo"=>"test_test_test", "bar"=>"test_test_test"}
end
+ it "interpolates string in hash keys" do
+ input = {"%{rspec}" => "test"}
+ Backend.parse_answer(input, {"rspec" => "foo"}).should == {"foo"=>"test"}
+ end
+
+ it "interpolates strings in nested hash keys" do
+ input = {"topkey" => {"%{rspec}" => "test"}}
+ Backend.parse_answer(input, {"rspec" => "foo"}).should == {"topkey"=>{"foo" => "test"}}
+ end
+
it "interpolates strings in a mixed structure of arrays and hashes" do
input = {"foo" => "test_%{rspec}_test", "bar" => ["test_%{rspec}_test", "test_%{rspec}_test"]}
Backend.parse_answer(input, {"rspec" => "test"}).should == {"foo"=>"test_test_test", "bar"=>["test_test_test", "test_test_test"]}
end
+ it "interpolates hiera lookups values in strings" do
+ input = "test_%{hiera('rspec')}_test"
+ scope = {}
+ Config.load({:yaml => {:datadir => "/tmp"}})
+ Config.load_backends
+ Backend::Yaml_backend.any_instance.stubs(:lookup).with("rspec", scope, nil, :priority).returns("test")
+ Backend.parse_answer(input, scope).should == "test_test_test"
+ end
+
+ it "interpolates hiera lookups in each string in an array" do
+ input = ["test_%{hiera('rspec')}_test", "test_%{hiera('rspec')}_test", ["test_%{hiera('rspec')}_test"]]
+ scope = {}
+ Config.load({:yaml => {:datadir => "/tmp"}})
+ Config.load_backends
+ Backend::Yaml_backend.any_instance.stubs(:lookup).with("rspec", scope, nil, :priority).returns("test")
+ Backend.parse_answer(input, scope).should == ["test_test_test", "test_test_test", ["test_test_test"]]
+ end
+
+ it "interpolates hiera lookups in each string in a hash" do
+ input = {"foo" => "test_%{hiera('rspec')}_test", "bar" => "test_%{hiera('rspec')}_test"}
+ scope = {}
+ Config.load({:yaml => {:datadir => "/tmp"}})
+ Config.load_backends
+ Backend::Yaml_backend.any_instance.stubs(:lookup).with("rspec", scope, nil, :priority).returns("test")
+ Backend.parse_answer(input, scope).should == {"foo"=>"test_test_test", "bar"=>"test_test_test"}
+ end
+
+ it "interpolates hiera lookups in string in hash keys" do
+ input = {"%{hiera('rspec')}" => "test"}
+ scope = {}
+ Config.load({:yaml => {:datadir => "/tmp"}})
+ Config.load_backends
+ Backend::Yaml_backend.any_instance.stubs(:lookup).with("rspec", scope, nil, :priority).returns("foo")
+ Backend.parse_answer(input, scope).should == {"foo"=>"test"}
+ end
+
+ it "interpolates hiera lookups in strings in nested hash keys" do
+ input = {"topkey" => {"%{hiera('rspec')}" => "test"}}
+ scope = {}
+ Config.load({:yaml => {:datadir => "/tmp"}})
+ Config.load_backends
+ Backend::Yaml_backend.any_instance.stubs(:lookup).with("rspec", scope, nil, :priority).returns("foo")
+ Backend.parse_answer(input, scope).should == {"topkey"=>{"foo" => "test"}}
+ end
+
+ it "interpolates hiera lookups in strings in a mixed structure of arrays and hashes" do
+ input = {"foo" => "test_%{hiera('rspec')}_test", "bar" => ["test_%{hiera('rspec')}_test", "test_%{hiera('rspec')}_test"]}
+ scope = {}
+ Config.load({:yaml => {:datadir => "/tmp"}})
+ Config.load_backends
+ Backend::Yaml_backend.any_instance.stubs(:lookup).with("rspec", scope, nil, :priority).returns("test")
+ Backend.parse_answer(input, scope).should == {"foo"=>"test_test_test", "bar"=>["test_test_test", "test_test_test"]}
+ end
+
+ it "interpolates hiera lookups and scope lookups in the same string" do
+ input = {"foo" => "test_%{hiera('rspec')}_test", "bar" => "test_%{rspec2}_test"}
+ scope = {"rspec2" => "scope_rspec"}
+ Config.load({:yaml => {:datadir => "/tmp"}})
+ Config.load_backends
+ Backend::Yaml_backend.any_instance.stubs(:lookup).with("rspec", scope, nil, :priority).returns("hiera_rspec")
+ Backend.parse_answer(input, scope).should == {"foo"=>"test_hiera_rspec_test", "bar"=>"test_scope_rspec_test"}
+ end
+
+ it "interpolates hiera and scope lookups with the same lookup query in a single string" do
+ input = "test_%{hiera('rspec')}_test_%{rspec}"
+ scope = {"rspec" => "scope_rspec"}
+ Config.load({:yaml => {:datadir => "/tmp"}})
+ Config.load_backends
+ Backend::Yaml_backend.any_instance.stubs(:lookup).with("rspec", scope, nil, :priority).returns("hiera_rspec")
+ Backend.parse_answer(input, scope).should == "test_hiera_rspec_test_scope_rspec"
+ end
+
it "passes integers unchanged" do
input = 1
Backend.parse_answer(input, {"rspec" => "test"}).should == 1
@@ -225,6 +386,12 @@ class Hiera
input = false
Backend.parse_answer(input, {"rspec" => "test"}).should == false
end
+
+ it "interpolates lookups using single or double quotes" do
+ input = "test_%{scope(\"rspec\")}_test_%{scope('rspec')}"
+ scope = {"rspec" => "scope_rspec"}
+ Backend.parse_answer(input, scope).should == "test_scope_rspec_test_scope_rspec"
+ end
end
describe "#resolve_answer" do
@@ -244,6 +411,7 @@ class Hiera
end
it "caches loaded backends" do
+ Backend.clear!
Hiera.expects(:debug).with(regexp_matches(/Hiera YAML backend starting/)).once
Config.load({:yaml => {:datadir => "/tmp"}})
diff --git a/spec/unit/filecache_spec.rb b/spec/unit/filecache_spec.rb
index 2a7dd72..ae9a6a7 100644
--- a/spec/unit/filecache_spec.rb
+++ b/spec/unit/filecache_spec.rb
@@ -1,62 +1,141 @@
require 'spec_helper'
+require 'tmpdir'
class Hiera
describe Filecache do
before do
- File.stubs(:exist?).returns(true)
@cache = Filecache.new
end
+ def write_file(file, contents)
+ File.open(file, 'w') do |f|
+ f.write(contents)
+ end
+ end
+
describe "#read" do
- it "should cache and read data" do
- File.expects(:read).with("/nonexisting").returns("text")
- @cache.expects(:path_metadata).returns(File.stat(__FILE__)).once
- @cache.expects(:stale?).once.returns(false)
+ it "reads data from a file" do
+ Dir.mktmpdir do |dir|
+ file = File.join(dir, "testing")
+ write_file(file, "my data")
+
+ @cache.read(file).should == "my data"
+ end
+ end
+
+ it "rereads data when the file changes" do
+ Dir.mktmpdir do |dir|
+ file = File.join(dir, "testing")
+ write_file(file, "my data")
+ @cache.read(file).should == "my data"
- @cache.read("/nonexisting").should == "text"
- @cache.read("/nonexisting").should == "text"
+ write_file(file, "changed data")
+ @cache.read(file).should == "changed data"
+ end
end
- it "should support validating return types and setting defaults" do
- File.expects(:read).with("/nonexisting").returns('{"rspec":1}')
+ it "uses the provided default when the type does not match the expected type" do
+ Hiera.expects(:debug).with(regexp_matches(/String.*not.*Hash, setting defaults/))
+ Dir.mktmpdir do |dir|
+ file = File.join(dir, "testing")
+ write_file(file, "my data")
+ data = @cache.read(file, Hash, { :testing => "hash" }) do |data|
+ "a string"
+ end
- @cache.expects(:path_metadata).returns(File.stat(__FILE__))
+ data.should == { :testing => "hash" }
+ end
+ end
- Hiera.expects(:debug).with(regexp_matches(/is not a Hash, setting defaults/))
+ it "traps any errors from the block and uses the default value" do
+ Hiera.expects(:debug).with(regexp_matches(/Reading data.*failed:.*testing error/))
+ Dir.mktmpdir do |dir|
+ file = File.join(dir, "testing")
+ write_file(file, "my data")
+ data = @cache.read(file, Hash, { :testing => "hash" }) do |data|
+ raise ArgumentError, "testing error"
+ end
- # return bogus data on purpose, triggers setting defaults
- data = @cache.read("/nonexisting", Hash, {"rspec" => 1}) do |data|
- nil
+ data.should == { :testing => "hash" }
end
+ end
- data.should == {"rspec" => 1}
+ it "raises an error when there is no default given and there is a problem" do
+ Dir.mktmpdir do |dir|
+ file = File.join(dir, "testing")
+ write_file(file, "my data")
+
+ expect do
+ @cache.read(file, Hash) do |data|
+ raise ArgumentError, "testing error"
+ end
+ end.to raise_error(ArgumentError, "testing error")
+ end
end
end
- describe "#stale?" do
- it "should return false when the file has not changed" do
- stat = File.stat(__FILE__)
+ describe "#read_file" do
+ it "reads data from a file" do
+ Dir.mktmpdir do |dir|
+ file = File.join(dir, "testing")
+ write_file(file, "my data")
- @cache.stubs(:path_metadata).returns(stat)
- @cache.stale?("/nonexisting").should == true
- @cache.stale?("/nonexisting").should == false
+ @cache.read_file(file).should == "my data"
+ end
end
- it "should update and return true when the file changed" do
- @cache.expects(:path_metadata).returns({:inode => 1, :mtime => Time.now, :size => 1})
- @cache.stale?("/nonexisting").should == true
- @cache.expects(:path_metadata).returns({:inode => 2, :mtime => Time.now, :size => 1})
- @cache.stale?("/nonexisting").should == true
+ it "rereads data when the file changes" do
+ Dir.mktmpdir do |dir|
+ file = File.join(dir, "testing")
+ write_file(file, "my data")
+ @cache.read_file(file).should == "my data"
+
+ write_file(file, "changed data")
+ @cache.read_file(file).should == "changed data"
+ end
end
- end
- describe "#path_metadata" do
- it "should return the right data" do
- stat = File.stat(__FILE__)
+ it "errors when the type does not match the expected type" do
+ Dir.mktmpdir do |dir|
+ file = File.join(dir, "testing")
+ write_file(file, "my data")
- File.expects(:stat).with("/nonexisting").returns(stat)
+ expect do
+ @cache.read_file(file, Hash) do |data|
+ "a string"
+ end
+ end.to raise_error(TypeError)
+ end
+ end
+
+ it "converts the read data using the block" do
+ Dir.mktmpdir do |dir|
+ file = File.join(dir, "testing")
+ write_file(file, "my data")
- @cache.path_metadata("/nonexisting").should == {:inode => stat.ino, :mtime => stat.mtime, :size => stat.size}
+ @cache.read_file(file, Hash) do |data|
+ { :data => data }
+ end.should == { :data => "my data" }
+ end
+ end
+
+ it "errors when the file does not exist" do
+ expect do
+ @cache.read_file("/notexist")
+ end.to raise_error(Errno::ENOENT)
+ end
+
+ it "propogates any errors from the block" do
+ Dir.mktmpdir do |dir|
+ file = File.join(dir, "testing")
+ write_file(file, "my data")
+
+ expect do
+ @cache.read_file(file) do |data|
+ raise ArgumentError, "testing error"
+ end
+ end.to raise_error(ArgumentError, "testing error")
+ end
end
end
end
diff --git a/spec/unit/version_spec.rb b/spec/unit/version_spec.rb
new file mode 100644
index 0000000..bc6e19a
--- /dev/null
+++ b/spec/unit/version_spec.rb
@@ -0,0 +1,44 @@
+require "spec_helper"
+require "hiera/version"
+require 'pathname'
+
+describe "Hiera.version Public API" do
+ subject() { Hiera }
+
+ before :each do
+ Hiera.instance_eval do
+ if @hiera_version
+ @hiera_version = nil
+ end
+ end
+ end
+
+ context "without a VERSION file" do
+ before :each do
+ subject.stubs(:read_version_file).returns(nil)
+ end
+
+ it "is Hiera::VERSION" do
+ subject.version.should == Hiera::VERSION
+ end
+ it "respects the version= setter" do
+ subject.version = '1.2.3'
+ subject.version.should == '1.2.3'
+ end
+ end
+
+ context "with a VERSION file" do
+ it "is the content of the file" do
+ subject.expects(:read_version_file).with() do |path|
+ pathname = Pathname.new(path)
+ pathname.basename.to_s == "VERSION"
+ end.returns('1.2.1-9-g9fda440')
+
+ subject.version.should == '1.2.1-9-g9fda440'
+ end
+ it "respects the version= setter" do
+ subject.version = '1.2.3'
+ subject.version.should == '1.2.3'
+ end
+ end
+end
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/ruby-hiera.git
More information about the Pkg-ruby-extras-commits
mailing list