summaryrefslogtreecommitdiffstats
path: root/spec
diff options
context:
space:
mode:
authorLuke Kanies <luke@madstop.com>2008-03-31 23:56:09 -0500
committerLuke Kanies <luke@madstop.com>2008-03-31 23:56:09 -0500
commit88dc49cb7b0efe757c92ce28c807b91335acb07a (patch)
tree13fe4561f1f524f97a8bb2c1ff84c1ef981d0241 /spec
parent4165edaeb71ee2883b1bb85ff39a52d5628b259f (diff)
parenta8592f1009040ebf30a98268610915cc33bb3f63 (diff)
Merge branch 'master' into master_no_global_resources
Conflicts: lib/puppet/node/catalog.rb lib/puppet/type/pfile.rb lib/puppet/type/pfilebucket.rb lib/puppet/util/filetype.rb spec/unit/node/catalog.rb spec/unit/other/transbucket.rb spec/unit/ral/provider/mount/parsed.rb spec/unit/ral/types/file.rb spec/unit/ral/types/interface.rb spec/unit/ral/types/mount.rb spec/unit/ral/types/package.rb spec/unit/ral/types/schedule.rb spec/unit/ral/types/service.rb test/language/compile.rb test/language/lexer.rb test/language/snippets.rb test/lib/puppettest.rb test/ral/types/basic.rb test/ral/types/cron.rb test/ral/types/exec.rb test/ral/types/file.rb test/ral/types/file/target.rb test/ral/types/filebucket.rb test/ral/types/fileignoresource.rb test/ral/types/filesources.rb test/ral/types/group.rb test/ral/types/host.rb test/ral/types/parameter.rb test/ral/types/sshkey.rb test/ral/types/tidy.rb test/ral/types/user.rb test/ral/types/yumrepo.rb
Diffstat (limited to 'spec')
-rw-r--r--spec/Rakefile12
-rwxr-xr-xspec/bin/spec4
-rwxr-xr-xspec/integration/file_serving/configuration.rb4
-rwxr-xr-xspec/integration/node.rb8
-rw-r--r--spec/lib/autotest/discover.rb9
-rw-r--r--spec/lib/autotest/puppet_rspec.rb46
-rw-r--r--spec/lib/autotest/rspec.rb95
-rw-r--r--spec/lib/monkey_patches/add_confine_and_runnable_to_rspec_dsl.rb31
-rw-r--r--spec/lib/spec.rb13
-rw-r--r--spec/lib/spec/dsl.rb11
-rw-r--r--spec/lib/spec/dsl/behaviour.rb221
-rw-r--r--spec/lib/spec/dsl/behaviour_callbacks.rb82
-rw-r--r--spec/lib/spec/dsl/behaviour_eval.rb231
-rwxr-xr-xspec/lib/spec/dsl/behaviour_factory.rb42
-rw-r--r--spec/lib/spec/dsl/composite_proc_builder.rb33
-rwxr-xr-xspec/lib/spec/dsl/configuration.rb135
-rwxr-xr-xspec/lib/spec/dsl/description.rb76
-rw-r--r--spec/lib/spec/dsl/errors.rb9
-rw-r--r--spec/lib/spec/dsl/example.rb135
-rwxr-xr-xspec/lib/spec/dsl/example_matcher.rb40
-rw-r--r--spec/lib/spec/dsl/example_should_raise_handler.rb74
-rw-r--r--spec/lib/spec/expectations.rb56
-rw-r--r--spec/lib/spec/expectations/differs/default.rb61
-rw-r--r--spec/lib/spec/expectations/errors.rb6
-rw-r--r--spec/lib/spec/expectations/extensions.rb2
-rw-r--r--spec/lib/spec/expectations/extensions/object.rb66
-rw-r--r--spec/lib/spec/expectations/extensions/string_and_symbol.rb17
-rw-r--r--spec/lib/spec/expectations/handler.rb43
-rwxr-xr-xspec/lib/spec/extensions.rb1
-rwxr-xr-xspec/lib/spec/extensions/object.rb6
-rw-r--r--spec/lib/spec/matchers.rb166
-rw-r--r--spec/lib/spec/matchers/be.rb206
-rw-r--r--spec/lib/spec/matchers/be_close.rb37
-rw-r--r--spec/lib/spec/matchers/change.rb120
-rw-r--r--spec/lib/spec/matchers/eql.rb43
-rw-r--r--spec/lib/spec/matchers/equal.rb43
-rw-r--r--spec/lib/spec/matchers/has.rb44
-rw-r--r--spec/lib/spec/matchers/have.rb142
-rw-r--r--spec/lib/spec/matchers/include.rb70
-rw-r--r--spec/lib/spec/matchers/match.rb41
-rwxr-xr-xspec/lib/spec/matchers/operator_matcher.rb72
-rw-r--r--spec/lib/spec/matchers/raise_error.rb105
-rw-r--r--spec/lib/spec/matchers/respond_to.rb45
-rw-r--r--spec/lib/spec/matchers/satisfy.rb47
-rw-r--r--spec/lib/spec/matchers/throw_symbol.rb72
-rw-r--r--spec/lib/spec/mocks.rb208
-rw-r--r--spec/lib/spec/mocks/argument_constraint_matchers.rb27
-rw-r--r--spec/lib/spec/mocks/argument_expectation.rb183
-rw-r--r--spec/lib/spec/mocks/error_generator.rb84
-rw-r--r--spec/lib/spec/mocks/errors.rb10
-rw-r--r--spec/lib/spec/mocks/extensions/object.rb3
-rw-r--r--spec/lib/spec/mocks/message_expectation.rb242
-rw-r--r--spec/lib/spec/mocks/methods.rb39
-rw-r--r--spec/lib/spec/mocks/mock.rb29
-rw-r--r--spec/lib/spec/mocks/order_group.rb29
-rw-r--r--spec/lib/spec/mocks/proxy.rb167
-rw-r--r--spec/lib/spec/mocks/space.rb28
-rw-r--r--spec/lib/spec/mocks/spec_methods.rb30
-rw-r--r--spec/lib/spec/rake/spectask.rb217
-rw-r--r--spec/lib/spec/rake/verify_rcov.rb52
-rw-r--r--spec/lib/spec/runner.rb165
-rw-r--r--spec/lib/spec/runner/backtrace_tweaker.rb57
-rw-r--r--spec/lib/spec/runner/behaviour_runner.rb123
-rw-r--r--spec/lib/spec/runner/command_line.rb22
-rw-r--r--spec/lib/spec/runner/drb_command_line.rb21
-rw-r--r--spec/lib/spec/runner/extensions/kernel.rb50
-rw-r--r--spec/lib/spec/runner/extensions/object.rb32
-rw-r--r--spec/lib/spec/runner/formatter.rb9
-rw-r--r--spec/lib/spec/runner/formatter/base_formatter.rb76
-rw-r--r--spec/lib/spec/runner/formatter/base_text_formatter.rb130
-rw-r--r--spec/lib/spec/runner/formatter/failing_behaviours_formatter.rb29
-rw-r--r--spec/lib/spec/runner/formatter/failing_examples_formatter.rb22
-rw-r--r--spec/lib/spec/runner/formatter/html_formatter.rb323
-rw-r--r--spec/lib/spec/runner/formatter/progress_bar_formatter.rb31
-rw-r--r--spec/lib/spec/runner/formatter/rdoc_formatter.rb24
-rw-r--r--spec/lib/spec/runner/formatter/snippet_extractor.rb52
-rw-r--r--spec/lib/spec/runner/formatter/specdoc_formatter.rb29
-rw-r--r--spec/lib/spec/runner/heckle_runner.rb72
-rw-r--r--spec/lib/spec/runner/heckle_runner_unsupported.rb10
-rw-r--r--spec/lib/spec/runner/option_parser.rb227
-rw-r--r--spec/lib/spec/runner/options.rb175
-rw-r--r--spec/lib/spec/runner/reporter.rb125
-rw-r--r--spec/lib/spec/runner/spec_parser.rb50
-rwxr-xr-xspec/lib/spec/test_case_adapter.rb10
-rw-r--r--spec/lib/spec/translator.rb114
-rw-r--r--spec/lib/spec/version.rb23
-rw-r--r--spec/monkey_patches/add_confine_and_runnable_to_rspec_dsl.rb43
-rw-r--r--spec/plugins/mock_frameworks/flexmock.rb23
-rw-r--r--spec/plugins/mock_frameworks/mocha.rb19
-rw-r--r--spec/plugins/mock_frameworks/rr.rb21
-rw-r--r--spec/plugins/mock_frameworks/rspec.rb18
-rw-r--r--spec/shared_behaviours/file_server_terminus.rb (renamed from spec/lib/shared_behaviours/file_server_terminus.rb)0
-rw-r--r--spec/shared_behaviours/file_serving.rb (renamed from spec/lib/shared_behaviours/file_serving.rb)0
-rw-r--r--spec/spec.opts4
-rw-r--r--spec/spec_helper.rb32
-rwxr-xr-xspec/unit/file_serving/configuration.rb389
-rwxr-xr-xspec/unit/file_serving/configuration/parser.rb175
-rwxr-xr-xspec/unit/file_serving/file_base.rb125
-rwxr-xr-xspec/unit/file_serving/metadata.rb74
-rwxr-xr-xspec/unit/indirector/catalog/compiler.rb6
-rwxr-xr-xspec/unit/indirector/checksum/file.rb176
-rwxr-xr-xspec/unit/indirector/direct_file_server.rb107
-rwxr-xr-xspec/unit/indirector/facts/facter.rb55
-rwxr-xr-xspec/unit/indirector/file.rb200
-rwxr-xr-xspec/unit/indirector/file_server.rb223
-rwxr-xr-xspec/unit/indirector/indirection.rb459
-rwxr-xr-xspec/unit/indirector/module_files.rb376
-rwxr-xr-xspec/unit/indirector/node/exec.rb89
-rwxr-xr-xspec/unit/indirector/node/ldap.rb292
-rwxr-xr-xspec/unit/indirector/node/plain.rb6
-rwxr-xr-xspec/unit/indirector/rest.rb2
-rwxr-xr-xspec/unit/indirector/terminus.rb255
-rwxr-xr-xspec/unit/indirector/yaml.rb124
-rw-r--r--spec/unit/network/client.rb43
-rwxr-xr-xspec/unit/network/http_pool.rb257
-rw-r--r--spec/unit/network/server.rb8
-rwxr-xr-xspec/unit/node.rb20
-rwxr-xr-xspec/unit/node/catalog.rb271
-rwxr-xr-xspec/unit/other/pgraph.rb35
-rwxr-xr-xspec/unit/other/transaction.rb7
-rwxr-xr-xspec/unit/other/transbucket.rb30
-rwxr-xr-xspec/unit/parser/ast/definition.rb158
-rwxr-xr-xspec/unit/parser/ast/hostclass.rb135
-rwxr-xr-xspec/unit/parser/ast/node.rb125
-rwxr-xr-xspec/unit/parser/collector.rb60
-rwxr-xr-xspec/unit/parser/compile.rb281
-rwxr-xr-xspec/unit/parser/compiler.rb532
-rwxr-xr-xspec/unit/parser/interpreter.rb285
-rwxr-xr-xspec/unit/parser/lexer.rb465
-rwxr-xr-xspec/unit/parser/resource.rb332
-rwxr-xr-xspec/unit/parser/resource/reference.rb8
-rwxr-xr-xspec/unit/ral/provider/interface/redhat.rb3
-rwxr-xr-xspec/unit/ral/provider/mount.rb172
-rwxr-xr-xspec/unit/ral/provider/mount/parsed.rb151
-rwxr-xr-xspec/unit/ral/type.rb4
-rwxr-xr-xspec/unit/ral/type/exec.rb (renamed from spec/unit/ral/types/exec.rb)0
-rwxr-xr-xspec/unit/ral/type/file.rb96
-rwxr-xr-xspec/unit/ral/type/interface.rb (renamed from spec/unit/ral/types/interface.rb)0
-rwxr-xr-xspec/unit/ral/type/mount.rb184
-rwxr-xr-xspec/unit/ral/type/nagios.rb (renamed from spec/unit/ral/types/nagios.rb)0
-rwxr-xr-xspec/unit/ral/type/noop_metaparam.rb38
-rwxr-xr-xspec/unit/ral/type/package.rb (renamed from spec/unit/ral/types/package.rb)186
-rwxr-xr-xspec/unit/ral/type/schedule.rb335
-rwxr-xr-xspec/unit/ral/type/service.rb (renamed from spec/unit/ral/types/service.rb)15
-rwxr-xr-xspec/unit/ral/type/user.rb (renamed from spec/unit/ral/types/user.rb)0
-rwxr-xr-xspec/unit/ral/types/file.rb28
-rwxr-xr-xspec/unit/ral/types/mount.rb187
-rwxr-xr-xspec/unit/ral/types/schedule.rb370
-rwxr-xr-xspec/unit/resource_reference.rb6
-rwxr-xr-xspec/unit/simple_graph.rb75
-rwxr-xr-xspec/unit/util/checksums.rb99
-rwxr-xr-xspec/unit/util/constant_inflector.rb70
-rwxr-xr-xspec/unit/util/settings.rb75
-rwxr-xr-xspec/unit/util/tagging.rb92
154 files changed, 5262 insertions, 9440 deletions
diff --git a/spec/Rakefile b/spec/Rakefile
index 8b45eff89..e2996f64f 100644
--- a/spec/Rakefile
+++ b/spec/Rakefile
@@ -7,10 +7,12 @@ puppetlibdir = File.join(basedir, "../lib")
puppettestlibdir = File.join(basedir, "../test/lib")
speclibdir = File.join(basedir, "lib")
-desc "Run all spec unit tests"
-Spec::Rake::SpecTask.new('unit') do |t|
- t.spec_files = FileList['unit/**/*.rb', 'integration/**/*.rb']
- t.libs = [puppetlibdir, puppettestlibdir, speclibdir]
+libs = [puppetlibdir, puppettestlibdir, speclibdir]
+desc "Run all specs"
+Spec::Rake::SpecTask.new('all') do |t|
+ t.spec_files = FileList['integration/**/*.rb', 'unit/**/*.rb']
+ t.libs = libs
+ t.spec_opts = ['--options', 'spec.opts']
end
-task :default => [:unit]
+task :default => [:all]
diff --git a/spec/bin/spec b/spec/bin/spec
deleted file mode 100755
index aaf320f34..000000000
--- a/spec/bin/spec
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/usr/bin/env ruby
-$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib"))
-require 'spec'
-::Spec::Runner::CommandLine.run(ARGV, STDERR, STDOUT, true, true)
diff --git a/spec/integration/file_serving/configuration.rb b/spec/integration/file_serving/configuration.rb
index b6505f096..6975594a8 100755
--- a/spec/integration/file_serving/configuration.rb
+++ b/spec/integration/file_serving/configuration.rb
@@ -12,8 +12,6 @@ describe Puppet::FileServing::Configuration, " when finding files with Puppet::F
# Just in case it already exists.
Puppet::FileServing::Configuration.clear_cache
- @config = Puppet::FileServing::Configuration.create
-
@mount = Puppet::FileServing::Mount.new("mymount")
FileTest.stubs(:exists?).with("/my/path").returns(true)
FileTest.stubs(:readable?).with("/my/path").returns(true)
@@ -25,6 +23,8 @@ describe Puppet::FileServing::Configuration, " when finding files with Puppet::F
@parser.stubs(:parse).returns("mymount" => @mount)
@parser.stubs(:changed?).returns(true)
Puppet::FileServing::Configuration::Parser.stubs(:new).returns(@parser)
+
+ @config = Puppet::FileServing::Configuration.create
end
it "should return nil if the file does not exist" do
diff --git a/spec/integration/node.rb b/spec/integration/node.rb
index e4a311998..631d4403e 100755
--- a/spec/integration/node.rb
+++ b/spec/integration/node.rb
@@ -10,7 +10,9 @@ require 'puppet/node'
describe Puppet::Node, " when using the memory terminus" do
before do
@name = "me"
- Puppet::Node.terminus_class = :memory
+ @old_terminus = Puppet::Node.indirection.terminus_class
+ @terminus = Puppet::Node.indirection.terminus(:memory)
+ Puppet::Node.indirection.stubs(:terminus).returns @terminus
@node = Puppet::Node.new(@name)
end
@@ -39,8 +41,4 @@ describe Puppet::Node, " when using the memory terminus" do
it "should fail when asked to destroy a node that does not exist" do
proc { Puppet::Node.destroy(@node) }.should raise_error(ArgumentError)
end
-
- after do
- Puppet.settings.clear
- end
end
diff --git a/spec/lib/autotest/discover.rb b/spec/lib/autotest/discover.rb
deleted file mode 100644
index 0ac563724..000000000
--- a/spec/lib/autotest/discover.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-require 'autotest'
-
-Autotest.add_discovery do
- "rspec"
-end
-
-Autotest.add_discovery do
- "puppet"
-end
diff --git a/spec/lib/autotest/puppet_rspec.rb b/spec/lib/autotest/puppet_rspec.rb
deleted file mode 100644
index 8536f3912..000000000
--- a/spec/lib/autotest/puppet_rspec.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-require 'autotest'
-require 'autotest/rspec'
-
-class Autotest::PuppetRspec < Autotest::Rspec
- def initialize # :nodoc:
- super
- @test_mappings = {
- # the libraries under lib/puppet
- %r%^lib/puppet/(.*)\.rb$% => proc { |filename, m|
- files_matching %r!spec/(unit|integration)/#{m[1]}.rb!
- },
-
- # the actual spec files themselves
- %r%^spec/(unit|integration)/.*\.rb$% => proc { |filename, _|
- filename
- },
-
- # force a complete re-run for all of these:
-
- # main puppet lib
- %r!^lib/puppet\.rb$! => proc { |filename, _|
- files_matching %r!spec/(unit|integration)/.*\.rb!
- },
-
- # the spec_helper
- %r!^spec/spec_helper\.rb$! => proc { |filename, _|
- files_matching %r!spec/(unit|integration)/.*\.rb!
- },
-
- # the puppet test libraries
- %r!^test/lib/puppettest/.*! => proc { |filename, _|
- files_matching %r!spec/(unit|integration)/.*\.rb!
- },
-
- # the puppet spec libraries
- %r!^spec/lib/spec.*! => proc { |filename, _|
- files_matching %r!spec/(unit|integration)/.*\.rb!
- },
-
- # the monkey patches for rspec
- %r!^spec/lib/monkey_patches/.*! => proc { |filename, _|
- files_matching %r!spec/(unit|integration)/.*\.rb!
- },
- }
- end
-end
diff --git a/spec/lib/autotest/rspec.rb b/spec/lib/autotest/rspec.rb
deleted file mode 100644
index d4b77ea6b..000000000
--- a/spec/lib/autotest/rspec.rb
+++ /dev/null
@@ -1,95 +0,0 @@
-require 'autotest'
-
-class RspecCommandError < StandardError; end
-
-class Autotest::Rspec < Autotest
-
- def initialize(kernel=Kernel, separator=File::SEPARATOR, alt_separator=File::ALT_SEPARATOR) # :nodoc:
- super()
- @kernel, @separator, @alt_separator = kernel, separator, alt_separator
- @spec_command = spec_command
-
- # watch out: Ruby bug (1.8.6):
- # %r(/) != /\//
- # since Ruby compares the REGEXP source, not the resulting pattern
- @test_mappings = {
- %r%^spec/.*\.rb$% => kernel.proc { |filename, _|
- filename
- },
- %r%^lib/(.*)\.rb$% => kernel.proc { |_, m|
- ["spec/#{m[1]}_spec.rb"]
- },
- %r%^spec/(spec_helper|shared/.*)\.rb$% => kernel.proc {
- files_matching %r%^spec/.*_spec\.rb$%
- }
- }
- end
-
- def tests_for_file(filename)
- super.select { |f| @files.has_key? f }
- end
-
- alias :specs_for_file :tests_for_file
-
- def failed_results(results)
- results.scan(/^\d+\)\n(?:\e\[\d*m)?(?:.*?Error in )?'([^\n]*)'(?: FAILED)?(?:\e\[\d*m)?\n(.*?)\n\n/m)
- end
-
- def handle_results(results)
- @files_to_test = consolidate_failures failed_results(results)
- unless @files_to_test.empty? then
- hook :red
- else
- hook :green
- end unless $TESTING
- @tainted = true unless @files_to_test.empty?
- end
-
- def consolidate_failures(failed)
- filters = Hash.new { |h,k| h[k] = [] }
- failed.each do |spec, failed_trace|
- @files.keys.select{|f| f =~ /spec\//}.each do |f|
- if failed_trace =~ Regexp.new(f)
- filters[f] << spec
- break
- end
- end
- end
- return filters
- end
-
- def make_test_cmd(files_to_test)
- return "#{ruby} -S #{@spec_command} #{add_options_if_present} #{files_to_test.keys.flatten.join(' ')}"
- end
-
- def add_options_if_present
- File.exist?("spec/spec.opts") ? "-O spec/spec.opts " : ""
- end
-
- # Finds the proper spec command to use. Precendence
- # is set in the lazily-evaluated method spec_commands. Alias + Override
- # that in ~/.autotest to provide a different spec command
- # then the default paths provided.
- def spec_command
- spec_commands.each do |command|
- if File.exists?(command)
- return @alt_separator ? (command.gsub @separator, @alt_separator) : command
- end
- end
-
- raise RspecCommandError, "No spec command could be found!"
- end
-
- # Autotest will look for spec commands in the following
- # locations, in this order:
- #
- # * bin/spec
- # * default spec bin/loader installed in Rubygems
- def spec_commands
- [
- File.join('bin', 'spec'),
- File.join(Config::CONFIG['bindir'], 'spec')
- ]
- end
-
-end
diff --git a/spec/lib/monkey_patches/add_confine_and_runnable_to_rspec_dsl.rb b/spec/lib/monkey_patches/add_confine_and_runnable_to_rspec_dsl.rb
deleted file mode 100644
index bfa2a0c3c..000000000
--- a/spec/lib/monkey_patches/add_confine_and_runnable_to_rspec_dsl.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-dir = File.expand_path(File.dirname(__FILE__))
-[ "#{dir}/../../lib", "#{dir}/../../../lib", "#{dir}/../../../test/lib"].each do |dir|
- fulldir = File.expand_path(dir)
- $LOAD_PATH.unshift(fulldir) unless $LOAD_PATH.include?(fulldir)
-end
-
-require 'spec'
-require 'puppettest'
-require 'puppettest/runnable_test'
-
-module Spec
- module Runner
- class BehaviourRunner
- def run_behaviours
- @behaviours.each do |behaviour|
- # LAK:NOTE: this 'runnable' test is Puppet-specific.
- next unless behaviour.runnable?
- behaviour.run(@options.reporter, @options.dry_run, @options.reverse, @options.timeout)
- end
- end
- end
- end
-end
-
-module Spec
- module DSL
- class EvalModule < Module
- include PuppetTest::RunnableTest
- end
- end
-end
diff --git a/spec/lib/spec.rb b/spec/lib/spec.rb
deleted file mode 100644
index 48c12595c..000000000
--- a/spec/lib/spec.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-require 'spec/extensions'
-require 'spec/version'
-require 'spec/matchers'
-require 'spec/expectations'
-require 'spec/translator'
-require 'spec/dsl'
-require 'spec/runner'
-
-class Object
- def metaclass
- class << self; self; end
- end
-end
diff --git a/spec/lib/spec/dsl.rb b/spec/lib/spec/dsl.rb
deleted file mode 100644
index f960eb907..000000000
--- a/spec/lib/spec/dsl.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-require 'spec/dsl/description'
-require 'spec/dsl/errors'
-require 'spec/dsl/configuration'
-require 'spec/dsl/behaviour_callbacks'
-require 'spec/dsl/behaviour'
-require 'spec/dsl/behaviour_eval'
-require 'spec/dsl/composite_proc_builder'
-require 'spec/dsl/example'
-require 'spec/dsl/example_matcher'
-require 'spec/dsl/example_should_raise_handler'
-require 'spec/dsl/behaviour_factory'
diff --git a/spec/lib/spec/dsl/behaviour.rb b/spec/lib/spec/dsl/behaviour.rb
deleted file mode 100644
index cc71ccffe..000000000
--- a/spec/lib/spec/dsl/behaviour.rb
+++ /dev/null
@@ -1,221 +0,0 @@
-require(File.expand_path(File.dirname(__FILE__) + '../../../../../test/lib/puppettest/runnable_test.rb'))
-
-module Spec
- module DSL
- class Behaviour
- extend BehaviourCallbacks
-
- class << self
- def add_shared_behaviour(behaviour)
- return if behaviour.equal?(found_behaviour = find_shared_behaviour(behaviour.description))
- return if found_behaviour and File.expand_path(behaviour.description[:spec_path]) == File.expand_path(found_behaviour.description[:spec_path])
- raise ArgumentError.new("Shared Behaviour '#{behaviour.description}' already exists") if found_behaviour
- shared_behaviours << behaviour
- end
-
- def find_shared_behaviour(behaviour_description)
- shared_behaviours.find { |b| b.description == behaviour_description }
- end
-
- def shared_behaviours
- # TODO - this needs to be global, or at least accessible from
- # from subclasses of Behaviour in a centralized place. I'm not loving
- # this as a solution, but it works for now.
- $shared_behaviours ||= []
- end
- end
-
- def initialize(*args, &behaviour_block)
- init_description(*args)
- init_eval_module
- before_eval
- eval_behaviour(&behaviour_block)
- end
-
- private
-
- def init_description(*args)
- unless self.class == Behaviour
- args << {} unless Hash === args.last
- args.last[:behaviour_class] = self.class
- end
- @description = Description.new(*args)
- end
-
- def init_eval_module
- @eval_module = EvalModule.new
- @eval_module.extend BehaviourEval::ModuleMethods
- @eval_module.include BehaviourEval::InstanceMethods
- @eval_module.include described_type if described_type.class == Module
- @eval_module.behaviour = self
- @eval_module.description = @description
- end
-
- def eval_behaviour(&behaviour_block)
- @eval_module.class_eval(&behaviour_block)
- end
-
- protected
-
- def before_eval
- end
-
- public
-
- def run(reporter, dry_run=false, reverse=false, timeout=nil)
- raise "shared behaviours should never run" if shared?
- # TODO - change add_behaviour to add_description ??????
- reporter.add_behaviour(@description)
- prepare_execution_context_class
- before_all_errors = run_before_all(reporter, dry_run)
-
- exs = reverse ? examples.reverse : examples
- example_execution_context = nil
-
- if before_all_errors.empty?
- exs.each do |example|
- example_execution_context = execution_context(example)
- example_execution_context.copy_instance_variables_from(@before_and_after_all_context_instance) unless before_all_proc(behaviour_type).nil?
-
- befores = before_each_proc(behaviour_type) {|e| raise e}
- afters = after_each_proc(behaviour_type)
- example.run(reporter, befores, afters, dry_run, example_execution_context, timeout)
- end
- end
-
- @before_and_after_all_context_instance.copy_instance_variables_from(example_execution_context) unless after_all_proc(behaviour_type).nil?
- run_after_all(reporter, dry_run)
- end
-
- def number_of_examples
- examples.length
- end
-
- def matches?(specified_examples)
- matcher ||= ExampleMatcher.new(description)
-
- examples.each do |example|
- return true if example.matches?(matcher, specified_examples)
- end
- return false
- end
-
- def shared?
- @description[:shared]
- end
-
- def retain_examples_matching!(specified_examples)
- return if specified_examples.index(description)
- matcher = ExampleMatcher.new(description)
- examples.reject! do |example|
- !example.matches?(matcher, specified_examples)
- end
- end
-
- def methods
- my_methods = super
- my_methods |= @eval_module.methods
- my_methods
- end
-
- # Includes modules in the Behaviour (the <tt>describe</tt> block).
- def include(*args)
- @eval_module.include(*args)
- end
-
- def behaviour_type #:nodoc:
- @description[:behaviour_type]
- end
-
- # Sets the #number on each Example and returns the next number
- def set_sequence_numbers(number, reverse) #:nodoc:
- exs = reverse ? examples.reverse : examples
- exs.each do |example|
- example.number = number
- number += 1
- end
- number
- end
-
- protected
-
- # Messages that this class does not understand
- # are passed directly to the @eval_module.
- def method_missing(sym, *args, &block)
- @eval_module.send(sym, *args, &block)
- end
-
- def prepare_execution_context_class
- plugin_mock_framework
- weave_in_included_modules
- define_predicate_matchers #this is in behaviour_eval
- execution_context_class
- end
-
- def weave_in_included_modules
- mods = [@eval_module]
- mods << included_modules.dup
- mods << Spec::Runner.configuration.modules_for(behaviour_type)
- execution_context_class.class_eval do
- # WARNING - the following can be executed in the context of any
- # class, and should never pass more than one module to include
- # even though we redefine include in this class. This is NOT
- # tested anywhere, hence this comment.
- mods.flatten.each {|mod| include mod}
- end
- end
-
- def execution_context(example)
- execution_context_class.new(example)
- end
-
- def run_before_all(reporter, dry_run)
- errors = []
- unless dry_run
- begin
- @before_and_after_all_context_instance = execution_context(nil)
- @before_and_after_all_context_instance.instance_eval(&before_all_proc(behaviour_type))
- rescue Exception => e
- errors << e
- location = "before(:all)"
- # The easiest is to report this as an example failure. We don't have an Example
- # at this point, so we'll just create a placeholder.
- reporter.example_finished(Example.new(location), e, location) if reporter
- end
- end
- errors
- end
-
- def run_after_all(reporter, dry_run)
- unless dry_run
- begin
- @before_and_after_all_context_instance ||= execution_context(nil)
- @before_and_after_all_context_instance.instance_eval(&after_all_proc(behaviour_type))
- rescue Exception => e
- location = "after(:all)"
- reporter.example_finished(Example.new(location), e, location) if reporter
- end
- end
- end
-
- def plugin_mock_framework
- case mock_framework = Spec::Runner.configuration.mock_framework
- when Module
- include mock_framework
- else
- require Spec::Runner.configuration.mock_framework
- include Spec::Plugins::MockFramework
- end
- end
-
- def description
- @description.to_s
- end
-
- def described_type
- @description.described_type
- end
-
- end
- end
-end
diff --git a/spec/lib/spec/dsl/behaviour_callbacks.rb b/spec/lib/spec/dsl/behaviour_callbacks.rb
deleted file mode 100644
index 8b69ad9e5..000000000
--- a/spec/lib/spec/dsl/behaviour_callbacks.rb
+++ /dev/null
@@ -1,82 +0,0 @@
-module Spec
- module DSL
- # See http://rspec.rubyforge.org/documentation/before_and_after.html
- module BehaviourCallbacks
- def prepend_before(*args, &block)
- scope, options = scope_and_options(*args)
- add(scope, options, :before, :unshift, &block)
- end
- def append_before(*args, &block)
- scope, options = scope_and_options(*args)
- add(scope, options, :before, :<<, &block)
- end
- alias_method :before, :append_before
-
- def prepend_after(*args, &block)
- scope, options = scope_and_options(*args)
- add(scope, options, :after, :unshift, &block)
- end
- alias_method :after, :prepend_after
- def append_after(*args, &block)
- scope, options = scope_and_options(*args)
- add(scope, options, :after, :<<, &block)
- end
-
- def scope_and_options(*args)
- args, options = args_and_options(*args)
- scope = (args[0] || :each), options
- end
-
- def add(scope, options, where, how, &block)
- scope ||= :each
- options ||= {}
- behaviour_type = options[:behaviour_type]
- case scope
- when :each; self.__send__("#{where}_each_parts", behaviour_type).__send__(how, block)
- when :all; self.__send__("#{where}_all_parts", behaviour_type).__send__(how, block)
- end
- end
-
- def remove_after(scope, &block)
- after_each_parts.delete(block)
- end
-
- # Deprecated. Use before(:each)
- def setup(&block)
- before(:each, &block)
- end
-
- # Deprecated. Use after(:each)
- def teardown(&block)
- after(:each, &block)
- end
-
- def before_all_parts(behaviour_type=nil) # :nodoc:
- @before_all_parts ||= {}
- @before_all_parts[behaviour_type] ||= []
- end
-
- def after_all_parts(behaviour_type=nil) # :nodoc:
- @after_all_parts ||= {}
- @after_all_parts[behaviour_type] ||= []
- end
-
- def before_each_parts(behaviour_type=nil) # :nodoc:
- @before_each_parts ||= {}
- @before_each_parts[behaviour_type] ||= []
- end
-
- def after_each_parts(behaviour_type=nil) # :nodoc:
- @after_each_parts ||= {}
- @after_each_parts[behaviour_type] ||= []
- end
-
- def clear_before_and_after! # :nodoc:
- @before_all_parts = nil
- @after_all_parts = nil
- @before_each_parts = nil
- @after_each_parts = nil
- end
- end
- end
-end
diff --git a/spec/lib/spec/dsl/behaviour_eval.rb b/spec/lib/spec/dsl/behaviour_eval.rb
deleted file mode 100644
index 9f7b8281e..000000000
--- a/spec/lib/spec/dsl/behaviour_eval.rb
+++ /dev/null
@@ -1,231 +0,0 @@
-module Spec
- module DSL
- module BehaviourEval
- module ModuleMethods
- include BehaviourCallbacks
-
- attr_writer :behaviour
- attr_accessor :description
-
- # RSpec runs every example in a new instance of Object, mixing in
- # the behaviour necessary to run examples. Because this behaviour gets
- # mixed in, it can get mixed in to an instance of any class at all.
- #
- # This is something that you would hardly ever use, but there is one
- # common use case for it - inheriting from Test::Unit::TestCase. RSpec's
- # Rails plugin uses this feature to provide access to all of the features
- # that are available for Test::Unit within RSpec examples.
- def inherit(klass)
- raise ArgumentError.new("Shared behaviours cannot inherit from classes") if @behaviour.shared?
- @behaviour_superclass = klass
- derive_execution_context_class_from_behaviour_superclass
- end
-
- # You can pass this one or many modules. Each module will subsequently
- # be included in the each object in which an example is run. Use this
- # to provide global helper methods to your examples.
- #
- # == Example
- #
- # module HelperMethods
- # def helper_method
- # ...
- # end
- # end
- #
- # describe Thing do
- # include HelperMethods
- # it "should do stuff" do
- # helper_method
- # end
- # end
- def include(*mods)
- mods.each do |mod|
- included_modules << mod
- mod.send :included, self
- end
- end
-
- # Use this to pull in examples from shared behaviours.
- # See Spec::Runner for information about shared behaviours.
- def it_should_behave_like(behaviour_description)
- behaviour = @behaviour.class.find_shared_behaviour(behaviour_description)
- if behaviour.nil?
- raise RuntimeError.new("Shared Behaviour '#{behaviour_description}' can not be found")
- end
- behaviour.copy_to(self)
- end
-
- def copy_to(eval_module) # :nodoc:
- examples.each { |e| eval_module.examples << e; }
- before_each_parts.each { |p| eval_module.before_each_parts << p }
- after_each_parts.each { |p| eval_module.after_each_parts << p }
- before_all_parts.each { |p| eval_module.before_all_parts << p }
- after_all_parts.each { |p| eval_module.after_all_parts << p }
- included_modules.each { |m| eval_module.included_modules << m }
- eval_module.included_modules << self
- end
-
- # :call-seq:
- # predicate_matchers[matcher_name] = method_on_object
- # predicate_matchers[matcher_name] = [method1_on_object, method2_on_object]
- #
- # Dynamically generates a custom matcher that will match
- # a predicate on your class. RSpec provides a couple of these
- # out of the box:
- #
- # exist (or state expectations)
- # File.should exist("path/to/file")
- #
- # an_instance_of (for mock argument constraints)
- # mock.should_receive(:message).with(an_instance_of(String))
- #
- # == Examples
- #
- # class Fish
- # def can_swim?
- # true
- # end
- # end
- #
- # describe Fish do
- # predicate_matchers[:swim] = :can_swim?
- # it "should swim" do
- # Fish.new.should swim
- # end
- # end
- def predicate_matchers
- @predicate_matchers ||= {:exist => :exist?, :an_instance_of => :is_a?}
- end
-
- def define_predicate_matchers(hash=nil) # :nodoc:
- if hash.nil?
- define_predicate_matchers(predicate_matchers)
- define_predicate_matchers(Spec::Runner.configuration.predicate_matchers)
- else
- hash.each_pair do |matcher_method, method_on_object|
- define_method matcher_method do |*args|
- eval("be_#{method_on_object.to_s.gsub('?','')}(*args)")
- end
- end
- end
- end
-
- # Creates an instance of Spec::DSL::Example and adds
- # it to a collection of examples of the current behaviour.
- def it(description=:__generate_description, opts={}, &block)
- examples << Example.new(description, opts, &block)
- end
-
- # Alias for it.
- def specify(description=:__generate_description, opts={}, &block)
- it(description, opts, &block)
- end
-
- def methods # :nodoc:
- my_methods = super
- my_methods |= behaviour_superclass.methods
- my_methods
- end
-
- protected
-
- def method_missing(method_name, *args)
- if behaviour_superclass.respond_to?(method_name)
- return execution_context_class.send(method_name, *args)
- end
- super
- end
-
- def before_each_proc(behaviour_type, &error_handler)
- parts = []
- parts.push(*Behaviour.before_each_parts(nil))
- parts.push(*Behaviour.before_each_parts(behaviour_type)) unless behaviour_type.nil?
- parts.push(*before_each_parts(nil))
- parts.push(*before_each_parts(behaviour_type)) unless behaviour_type.nil?
- CompositeProcBuilder.new(parts).proc(&error_handler)
- end
-
- def before_all_proc(behaviour_type, &error_handler)
- parts = []
- parts.push(*Behaviour.before_all_parts(nil))
- parts.push(*Behaviour.before_all_parts(behaviour_type)) unless behaviour_type.nil?
- parts.push(*before_all_parts(nil))
- parts.push(*before_all_parts(behaviour_type)) unless behaviour_type.nil?
- CompositeProcBuilder.new(parts).proc(&error_handler)
- end
-
- def after_all_proc(behaviour_type)
- parts = []
- parts.push(*after_all_parts(behaviour_type)) unless behaviour_type.nil?
- parts.push(*after_all_parts(nil))
- parts.push(*Behaviour.after_all_parts(behaviour_type)) unless behaviour_type.nil?
- parts.push(*Behaviour.after_all_parts(nil))
- CompositeProcBuilder.new(parts).proc
- end
-
- def after_each_proc(behaviour_type)
- parts = []
- parts.push(*after_each_parts(behaviour_type)) unless behaviour_type.nil?
- parts.push(*after_each_parts(nil))
- parts.push(*Behaviour.after_each_parts(behaviour_type)) unless behaviour_type.nil?
- parts.push(*Behaviour.after_each_parts(nil))
- CompositeProcBuilder.new(parts).proc
- end
-
- private
-
- def execution_context_class
- @execution_context_class ||= derive_execution_context_class_from_behaviour_superclass
- end
-
- def derive_execution_context_class_from_behaviour_superclass
- @execution_context_class = Class.new(behaviour_superclass)
- behaviour_superclass.spec_inherited(self) if behaviour_superclass.respond_to?(:spec_inherited)
- @execution_context_class
- end
-
- def behaviour_superclass
- @behaviour_superclass ||= Object
- end
-
- protected
- def included_modules
- @included_modules ||= [::Spec::Matchers]
- end
-
- def examples
- @examples ||= []
- end
- end
-
- module InstanceMethods
- def initialize(*args, &block) #:nodoc:
- # TODO - inheriting from TestUnit::TestCase fails without this
- # - let's figure out why and move this somewhere else
- end
-
- def violated(message="")
- raise Spec::Expectations::ExpectationNotMetError.new(message)
- end
-
- def inspect
- "[RSpec example]"
- end
-
- def pending(message)
- if block_given?
- begin
- yield
- rescue Exception => e
- raise Spec::DSL::ExamplePendingError.new(message)
- end
- raise Spec::DSL::PendingFixedError.new("Expected pending '#{message}' to fail. No Error was raised.")
- else
- raise Spec::DSL::ExamplePendingError.new(message)
- end
- end
- end
- end
- end
-end
diff --git a/spec/lib/spec/dsl/behaviour_factory.rb b/spec/lib/spec/dsl/behaviour_factory.rb
deleted file mode 100755
index 44b60c641..000000000
--- a/spec/lib/spec/dsl/behaviour_factory.rb
+++ /dev/null
@@ -1,42 +0,0 @@
-module Spec
- module DSL
- class BehaviourFactory
-
- class << self
-
- BEHAVIOUR_CLASSES = {:default => Spec::DSL::Behaviour}
-
- # Registers a behaviour class +klass+ with the symbol
- # +behaviour_type+. For example:
- #
- # Spec::DSL::BehaviourFactory.add_behaviour_class(:farm, Spec::Farm::DSL::FarmBehaviour)
- #
- # This will cause Kernel#describe from a file living in
- # <tt>spec/farm</tt> to create behaviour instances of type
- # Spec::Farm::DSL::FarmBehaviour.
- def add_behaviour_class(behaviour_type, klass)
- BEHAVIOUR_CLASSES[behaviour_type] = klass
- end
-
- def remove_behaviour_class(behaviour_type)
- BEHAVIOUR_CLASSES.delete(behaviour_type)
- end
-
- def create(*args, &block)
- opts = Hash === args.last ? args.last : {}
- if opts[:shared]
- behaviour_type = :default
- elsif opts[:behaviour_type]
- behaviour_type = opts[:behaviour_type]
- elsif opts[:spec_path] =~ /spec(\\|\/)(#{BEHAVIOUR_CLASSES.keys.join('|')})/
- behaviour_type = $2.to_sym
- else
- behaviour_type = :default
- end
- return BEHAVIOUR_CLASSES[behaviour_type].new(*args, &block)
- end
-
- end
- end
- end
-end
diff --git a/spec/lib/spec/dsl/composite_proc_builder.rb b/spec/lib/spec/dsl/composite_proc_builder.rb
deleted file mode 100644
index 373f44953..000000000
--- a/spec/lib/spec/dsl/composite_proc_builder.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-module Spec
- module DSL
- class CompositeProcBuilder < Array
- def initialize(callbacks=[])
- push(*callbacks)
- end
-
- def proc(&error_handler)
- parts = self
- errors = []
- Proc.new do
- result = parts.collect do |part|
- begin
- if part.is_a?(UnboundMethod)
- part.bind(self).call
- else
- instance_eval(&part)
- end
- rescue Exception => e
- if error_handler
- error_handler.call(e)
- else
- errors << e
- end
- end
- end
- raise errors.first unless errors.empty?
- result
- end
- end
- end
- end
-end
diff --git a/spec/lib/spec/dsl/configuration.rb b/spec/lib/spec/dsl/configuration.rb
deleted file mode 100755
index 709574ded..000000000
--- a/spec/lib/spec/dsl/configuration.rb
+++ /dev/null
@@ -1,135 +0,0 @@
-module Spec
- module DSL
- class Configuration
-
- # Chooses what mock framework to use. Example:
- #
- # Spec::Runner.configure do |config|
- # config.mock_with :rspec, :mocha, :flexmock, or :rr
- # end
- #
- # To use any other mock framework, you'll have to provide
- # your own adapter. This is simply a module that responds to
- # setup_mocks_for_rspec, verify_mocks_for_rspec and teardown_mocks_for_rspec.
- # These are your hooks into the lifecycle of a given example. RSpec will
- # call setup_mocks_for_rspec before running anything else in each Example.
- # After executing the #after methods, RSpec will then call verify_mocks_for_rspec
- # and teardown_mocks_for_rspec (this is guaranteed to run even if there are
- # failures in verify_mocks_for_rspec).
- #
- # Once you've defined this module, you can pass that to mock_with:
- #
- # Spec::Runner.configure do |config|
- # config.mock_with MyMockFrameworkAdapter
- # end
- #
- def mock_with(mock_framework)
- @mock_framework = case mock_framework
- when Symbol
- mock_framework_path(mock_framework.to_s)
- else
- mock_framework
- end
- end
-
- def mock_framework # :nodoc:
- @mock_framework ||= mock_framework_path("rspec")
- end
-
- # Declares modules to be included in all behaviours (<tt>describe</tt> blocks).
- #
- # config.include(My::Bottle, My::Cup)
- #
- # If you want to restrict the inclusion to a subset of all the behaviours then
- # specify this in a Hash as the last argument:
- #
- # config.include(My::Pony, My::Horse, :behaviour_type => :farm)
- #
- # Only behaviours that have that type will get the modules included:
- #
- # describe "Downtown", :behaviour_type => :city do
- # # Will *not* get My::Pony and My::Horse included
- # end
- #
- # describe "Old Mac Donald", :behaviour_type => :farm do
- # # *Will* get My::Pony and My::Horse included
- # end
- #
- def include(*args)
- args << {} unless Hash === args.last
- modules, options = args_and_options(*args)
- required_behaviour_type = options[:behaviour_type]
- required_behaviour_type = required_behaviour_type.to_sym unless required_behaviour_type.nil?
- @modules ||= {}
- @modules[required_behaviour_type] ||= []
- @modules[required_behaviour_type] += modules
- end
-
- def modules_for(required_behaviour_type) #:nodoc:
- @modules ||= {}
- modules = @modules[nil] || [] # general ones
- modules << @modules[required_behaviour_type.to_sym] unless required_behaviour_type.nil?
- modules.uniq.compact
- end
-
- # This is just for cleanup in RSpec's own examples
- def exclude(*modules) #:nodoc:
- @modules.each do |behaviour_type, mods|
- modules.each{|m| mods.delete(m)}
- end
- end
-
- # Defines global predicate matchers. Example:
- #
- # config.predicate_matchers[:swim] = :can_swim?
- #
- # This makes it possible to say:
- #
- # person.should swim # passes if person.should_swim? returns true
- #
- def predicate_matchers
- @predicate_matchers ||= {}
- end
-
- # Prepends a global <tt>before</tt> block to all behaviours.
- # See #append_before for filtering semantics.
- def prepend_before(*args, &proc)
- Behaviour.prepend_before(*args, &proc)
- end
- # Appends a global <tt>before</tt> block to all behaviours.
- #
- # If you want to restrict the block to a subset of all the behaviours then
- # specify this in a Hash as the last argument:
- #
- # config.prepend_before(:all, :behaviour_type => :farm)
- #
- # or
- #
- # config.prepend_before(:behaviour_type => :farm)
- #
- def append_before(*args, &proc)
- Behaviour.append_before(*args, &proc)
- end
- alias_method :before, :append_before
-
- # Prepends a global <tt>after</tt> block to all behaviours.
- # See #append_before for filtering semantics.
- def prepend_after(*args, &proc)
- Behaviour.prepend_after(*args, &proc)
- end
- alias_method :after, :prepend_after
- # Appends a global <tt>after</tt> block to all behaviours.
- # See #append_before for filtering semantics.
- def append_after(*args, &proc)
- Behaviour.append_after(*args, &proc)
- end
-
- private
-
- def mock_framework_path(framework_name)
- File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "plugins", "mock_frameworks", framework_name))
- end
-
- end
- end
-end
diff --git a/spec/lib/spec/dsl/description.rb b/spec/lib/spec/dsl/description.rb
deleted file mode 100755
index fe8c9b0c9..000000000
--- a/spec/lib/spec/dsl/description.rb
+++ /dev/null
@@ -1,76 +0,0 @@
-module Spec
- module DSL
- class Description
- module ClassMethods
- def generate_description(*args)
- description = args.shift.to_s
- unless args.empty?
- suffix = args.shift.to_s
- description << " " unless suffix =~ /^\s|\.|#/
- description << suffix
- end
- description
- end
- end
- extend ClassMethods
-
- attr_reader :description, :described_type
-
- def initialize(*args)
- args, @options = args_and_options(*args)
- init_behaviour_type(@options)
- init_spec_path(@options)
- init_described_type(args)
- init_description(*args)
- end
-
- def [](key)
- @options[key]
- end
-
- def []=(key, value)
- @options[key] = value
- end
-
- def to_s; @description; end
-
- def ==(value)
- case value
- when Description
- @description == value.description
- else
- @description == value
- end
- end
-
- private
- def init_behaviour_type(options)
- # NOTE - BE CAREFUL IF CHANGING THIS NEXT LINE:
- # this line is as it is to satisfy JRuby - the original version
- # read, simply: "if options[:behaviour_class]", which passed against ruby, but failed against jruby
- if options[:behaviour_class] && options[:behaviour_class].ancestors.include?(Behaviour)
- options[:behaviour_type] = parse_behaviour_type(@options[:behaviour_class])
- end
- end
-
- def init_spec_path(options)
- if options.has_key?(:spec_path)
- options[:spec_path] = File.expand_path(@options[:spec_path])
- end
- end
-
- def init_description(*args)
- @description = self.class.generate_description(*args)
- end
-
- def init_described_type(args)
- @described_type = args.first unless args.first.is_a?(String)
- end
-
- def parse_behaviour_type(behaviour_class)
- behaviour_class.to_s.split("::").reverse[0].gsub!('Behaviour', '').downcase.to_sym
- end
-
- end
- end
-end
diff --git a/spec/lib/spec/dsl/errors.rb b/spec/lib/spec/dsl/errors.rb
deleted file mode 100644
index ba7046a89..000000000
--- a/spec/lib/spec/dsl/errors.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-module Spec
- module DSL
- class ExamplePendingError < StandardError
- end
-
- class PendingFixedError < StandardError
- end
- end
-end
diff --git a/spec/lib/spec/dsl/example.rb b/spec/lib/spec/dsl/example.rb
deleted file mode 100644
index d04073f7e..000000000
--- a/spec/lib/spec/dsl/example.rb
+++ /dev/null
@@ -1,135 +0,0 @@
-require 'timeout'
-
-module Spec
- module DSL
- class Example
- # The global sequence number of this example
- attr_accessor :number
-
- def initialize(description, options={}, &example_block)
- @from = caller(0)[3]
- @options = options
- @example_block = example_block
- @description = description
- @description_generated_proc = lambda { |desc| @generated_description = desc }
- end
-
- def run(reporter, before_each_block, after_each_block, dry_run, execution_context, timeout=nil)
- @dry_run = dry_run
- reporter.example_started(self)
- return reporter.example_finished(self) if dry_run
-
- errors = []
- location = nil
- Timeout.timeout(timeout) do
- before_each_ok = before_example(execution_context, errors, &before_each_block)
- example_ok = run_example(execution_context, errors) if before_each_ok
- after_each_ok = after_example(execution_context, errors, &after_each_block)
- location = failure_location(before_each_ok, example_ok, after_each_ok)
- end
-
- ExampleShouldRaiseHandler.new(@from, @options).handle(errors)
- reporter.example_finished(self, errors.first, location, @example_block.nil?) if reporter
- end
-
- def matches?(matcher, specified_examples)
- matcher.example_desc = description
- matcher.matches?(specified_examples)
- end
-
- def description
- @description == :__generate_description ? generated_description : @description
- end
-
- def to_s
- description
- end
-
- private
-
- def generated_description
- return @generated_description if @generated_description
- if @dry_run
- "NO NAME (Because of --dry-run)"
- else
- if @failed
- "NO NAME (Because of Error raised in matcher)"
- else
- "NO NAME (Because there were no expectations)"
- end
- end
- end
-
- def before_example(execution_context, errors, &behaviour_before_block)
- setup_mocks(execution_context)
- Spec::Matchers.description_generated(@description_generated_proc)
-
- builder = CompositeProcBuilder.new
- before_proc = builder.proc(&append_errors(errors))
- execution_context.instance_eval(&before_proc)
-
- execution_context.instance_eval(&behaviour_before_block) if behaviour_before_block
- return errors.empty?
- rescue Exception => e
- @failed = true
- errors << e
- return false
- end
-
- def run_example(execution_context, errors)
- begin
- execution_context.instance_eval(&@example_block) if @example_block
- return true
- rescue Exception => e
- @failed = true
- errors << e
- return false
- end
- end
-
- def after_example(execution_context, errors, &behaviour_after_each)
- execution_context.instance_eval(&behaviour_after_each) if behaviour_after_each
-
- begin
- verify_mocks(execution_context)
- ensure
- teardown_mocks(execution_context)
- end
-
- Spec::Matchers.unregister_description_generated(@description_generated_proc)
-
- builder = CompositeProcBuilder.new
- after_proc = builder.proc(&append_errors(errors))
- execution_context.instance_eval(&after_proc)
-
- return errors.empty?
- rescue Exception => e
- @failed = true
- errors << e
- return false
- end
-
- def setup_mocks(execution_context)
- execution_context.setup_mocks_for_rspec if execution_context.respond_to?(:setup_mocks_for_rspec)
- end
-
- def verify_mocks(execution_context)
- execution_context.verify_mocks_for_rspec if execution_context.respond_to?(:verify_mocks_for_rspec)
- end
-
- def teardown_mocks(execution_context)
- execution_context.teardown_mocks_for_rspec if execution_context.respond_to?(:teardown_mocks_for_rspec)
- end
-
- def append_errors(errors)
- proc {|error| errors << error}
- end
-
- def failure_location(before_each_ok, example_ok, after_each_ok)
- return 'before(:each)' unless before_each_ok
- return description unless example_ok
- return 'after(:each)' unless after_each_ok
- end
- end
- end
-end
diff --git a/spec/lib/spec/dsl/example_matcher.rb b/spec/lib/spec/dsl/example_matcher.rb
deleted file mode 100755
index 18cc47409..000000000
--- a/spec/lib/spec/dsl/example_matcher.rb
+++ /dev/null
@@ -1,40 +0,0 @@
-module Spec
- module DSL
- class ExampleMatcher
-
- attr_writer :example_desc
- def initialize(behaviour_desc, example_desc=nil)
- @behaviour_desc = behaviour_desc
- @example_desc = example_desc
- end
-
- def matches?(specified_examples)
- specified_examples.each do |specified_example|
- return true if matches_literal_example?(specified_example) || matches_example_not_considering_modules?(specified_example)
- end
- false
- end
-
- private
- def matches_literal_example?(specified_example)
- specified_example =~ /(^#{context_regexp} #{example_regexp}$|^#{context_regexp}$|^#{example_regexp}$)/
- end
-
- def matches_example_not_considering_modules?(specified_example)
- specified_example =~ /(^#{context_regexp_not_considering_modules} #{example_regexp}$|^#{context_regexp_not_considering_modules}$|^#{example_regexp}$)/
- end
-
- def context_regexp
- Regexp.escape(@behaviour_desc)
- end
-
- def context_regexp_not_considering_modules
- Regexp.escape(@behaviour_desc.split('::').last)
- end
-
- def example_regexp
- Regexp.escape(@example_desc)
- end
- end
- end
-end
diff --git a/spec/lib/spec/dsl/example_should_raise_handler.rb b/spec/lib/spec/dsl/example_should_raise_handler.rb
deleted file mode 100644
index 942327317..000000000
--- a/spec/lib/spec/dsl/example_should_raise_handler.rb
+++ /dev/null
@@ -1,74 +0,0 @@
-module Spec
- module DSL
- class ExampleShouldRaiseHandler
- def initialize(file_and_line_number, opts)
- @file_and_line_number = file_and_line_number
- @options = opts
- @expected_error_class = determine_error_class(opts)
- @expected_error_message = determine_error_message(opts)
- end
-
- def determine_error_class(opts)
- if candidate = opts[:should_raise]
- if candidate.is_a?(Class)
- return candidate
- elsif candidate.is_a?(Array)
- return candidate[0]
- else
- return Exception
- end
- end
- end
-
- def determine_error_message(opts)
- if candidate = opts[:should_raise]
- if candidate.is_a?(Array)
- return candidate[1]
- end
- end
- return nil
- end
-
- def build_message(exception=nil)
- if @expected_error_message.nil?
- message = "example block expected #{@expected_error_class.to_s}"
- else
- message = "example block expected #{@expected_error_class.new(@expected_error_message.to_s).inspect}"
- end
- message << " but raised #{exception.inspect}" if exception
- message << " but nothing was raised" unless exception
- message << "\n"
- message << @file_and_line_number
- end
-
- def error_matches?(error)
- return false unless error.kind_of?(@expected_error_class)
- unless @expected_error_message.nil?
- if @expected_error_message.is_a?(Regexp)
- return false unless error.message =~ @expected_error_message
- else
- return false unless error.message == @expected_error_message
- end
- end
- return true
- end
-
- def handle(errors)
- if @expected_error_class
- if errors.empty?
- errors << Spec::Expectations::ExpectationNotMetError.new(build_message)
- else
- error_to_remove = errors.detect do |error|
- error_matches?(error)
- end
- if error_to_remove.nil?
- errors.insert(0,Spec::Expectations::ExpectationNotMetError.new(build_message(errors[0])))
- else
- errors.delete(error_to_remove)
- end
- end
- end
- end
- end
- end
-end
diff --git a/spec/lib/spec/expectations.rb b/spec/lib/spec/expectations.rb
deleted file mode 100644
index 65ea47425..000000000
--- a/spec/lib/spec/expectations.rb
+++ /dev/null
@@ -1,56 +0,0 @@
-require 'spec/matchers'
-require 'spec/expectations/errors'
-require 'spec/expectations/extensions'
-require 'spec/expectations/handler'
-
-module Spec
-
- # Spec::Expectations lets you set expectations on your objects.
- #
- # result.should == 37
- # team.should have(11).players_on_the_field
- #
- # == How Expectations work.
- #
- # Spec::Expectations adds two methods to Object:
- #
- # should(matcher=nil)
- # should_not(matcher=nil)
- #
- # Both methods take an optional Expression Matcher (See Spec::Matchers).
- #
- # When +should+ receives an Expression Matcher, it calls <tt>matches?(self)</tt>. If
- # it returns +true+, the spec passes and execution continues. If it returns
- # +false+, then the spec fails with the message returned by <tt>matcher.failure_message</tt>.
- #
- # Similarly, when +should_not+ receives a matcher, it calls <tt>matches?(self)</tt>. If
- # it returns +false+, the spec passes and execution continues. If it returns
- # +true+, then the spec fails with the message returned by <tt>matcher.negative_failure_message</tt>.
- #
- # RSpec ships with a standard set of useful matchers, and writing your own
- # matchers is quite simple. See Spec::Matchers for details.
- module Expectations
- class << self
- attr_accessor :differ
-
- # raises a Spec::Expectations::ExpectationNotMetError with message
- #
- # When a differ has been assigned and fail_with is passed
- # <code>expected</code> and <code>target</code>, passes them
- # to the differ to append a diff message to the failure message.
- def fail_with(message, expected=nil, target=nil) # :nodoc:
- if Array === message && message.length == 3
- message, expected, target = message[0], message[1], message[2]
- end
- unless (differ.nil? || expected.nil? || target.nil?)
- if expected.is_a?(String)
- message << "\nDiff:" << self.differ.diff_as_string(target.to_s, expected)
- elsif !target.is_a?(Proc)
- message << "\nDiff:" << self.differ.diff_as_object(target, expected)
- end
- end
- Kernel::raise(Spec::Expectations::ExpectationNotMetError.new(message))
- end
- end
- end
-end
diff --git a/spec/lib/spec/expectations/differs/default.rb b/spec/lib/spec/expectations/differs/default.rb
deleted file mode 100644
index 87e59b3a6..000000000
--- a/spec/lib/spec/expectations/differs/default.rb
+++ /dev/null
@@ -1,61 +0,0 @@
-begin
- require 'rubygems'
- require 'diff/lcs' #necessary due to loading bug on some machines - not sure why - DaC
- require 'diff/lcs/hunk'
-rescue LoadError ; raise "You must gem install diff-lcs to use diffing" ; end
-
-require 'pp'
-
-module Spec
- module Expectations
- module Differs
-
- # TODO add some rdoc
- class Default
- def initialize(format=:unified,context_lines=nil,colour=nil)
-
- context_lines ||= 3
- colour ||= false
-
- @format,@context_lines,@colour = format,context_lines,colour
- end
-
- # This is snagged from diff/lcs/ldiff.rb (which is a commandline tool)
- def diff_as_string(data_old, data_new)
- data_old = data_old.split(/\n/).map! { |e| e.chomp }
- data_new = data_new.split(/\n/).map! { |e| e.chomp }
- output = ""
- diffs = Diff::LCS.diff(data_old, data_new)
- return output if diffs.empty?
- oldhunk = hunk = nil
- file_length_difference = 0
- diffs.each do |piece|
- begin
- hunk = Diff::LCS::Hunk.new(data_old, data_new, piece, @context_lines,
- file_length_difference)
- file_length_difference = hunk.file_length_difference
- next unless oldhunk
- # Hunks may overlap, which is why we need to be careful when our
- # diff includes lines of context. Otherwise, we might print
- # redundant lines.
- if (@context_lines > 0) and hunk.overlaps?(oldhunk)
- hunk.unshift(oldhunk)
- else
- output << oldhunk.diff(@format)
- end
- ensure
- oldhunk = hunk
- output << "\n"
- end
- end
- #Handle the last remaining hunk
- output << oldhunk.diff(@format) << "\n"
- end
-
- def diff_as_object(target,expected)
- diff_as_string(PP.pp(target,""), PP.pp(expected,""))
- end
- end
- end
- end
-end
diff --git a/spec/lib/spec/expectations/errors.rb b/spec/lib/spec/expectations/errors.rb
deleted file mode 100644
index 03e81a064..000000000
--- a/spec/lib/spec/expectations/errors.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-module Spec
- module Expectations
- class ExpectationNotMetError < StandardError
- end
- end
-end
diff --git a/spec/lib/spec/expectations/extensions.rb b/spec/lib/spec/expectations/extensions.rb
deleted file mode 100644
index 60c9b9e7d..000000000
--- a/spec/lib/spec/expectations/extensions.rb
+++ /dev/null
@@ -1,2 +0,0 @@
-require 'spec/expectations/extensions/object'
-require 'spec/expectations/extensions/string_and_symbol'
diff --git a/spec/lib/spec/expectations/extensions/object.rb b/spec/lib/spec/expectations/extensions/object.rb
deleted file mode 100644
index f59af722e..000000000
--- a/spec/lib/spec/expectations/extensions/object.rb
+++ /dev/null
@@ -1,66 +0,0 @@
-module Spec
- module Expectations
- # rspec adds #should and #should_not to every Object (and,
- # implicitly, every Class).
- module ObjectExpectations
-
- # :call-seq:
- # should(matcher)
- # should == expected
- # should === expected
- # should =~ expected
- #
- # receiver.should(matcher)
- # => Passes if matcher.matches?(receiver)
- #
- # receiver.should == expected #any value
- # => Passes if (receiver == expected)
- #
- # receiver.should === expected #any value
- # => Passes if (receiver === expected)
- #
- # receiver.should =~ regexp
- # => Passes if (receiver =~ regexp)
- #
- # See Spec::Matchers for more information about matchers
- #
- # == Warning
- #
- # NOTE that this does NOT support receiver.should != expected.
- # Instead, use receiver.should_not == expected
- def should(matcher=nil, &block)
- return ExpectationMatcherHandler.handle_matcher(self, matcher, &block) if matcher
- Spec::Matchers::PositiveOperatorMatcher.new(self)
- end
-
- # :call-seq:
- # should_not(matcher)
- # should_not == expected
- # should_not === expected
- # should_not =~ expected
- #
- # receiver.should_not(matcher)
- # => Passes unless matcher.matches?(receiver)
- #
- # receiver.should_not == expected
- # => Passes unless (receiver == expected)
- #
- # receiver.should_not === expected
- # => Passes unless (receiver === expected)
- #
- # receiver.should_not =~ regexp
- # => Passes unless (receiver =~ regexp)
- #
- # See Spec::Matchers for more information about matchers
- def should_not(matcher=nil, &block)
- return NegativeExpectationMatcherHandler.handle_matcher(self, matcher, &block) if matcher
- Spec::Matchers::NegativeOperatorMatcher.new(self)
- end
-
- end
- end
-end
-
-class Object
- include Spec::Expectations::ObjectExpectations
-end
diff --git a/spec/lib/spec/expectations/extensions/string_and_symbol.rb b/spec/lib/spec/expectations/extensions/string_and_symbol.rb
deleted file mode 100644
index 29cfbddfa..000000000
--- a/spec/lib/spec/expectations/extensions/string_and_symbol.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-module Spec
- module Expectations
- module StringHelpers
- def starts_with?(prefix)
- to_s[0..(prefix.to_s.length - 1)] == prefix.to_s
- end
- end
- end
-end
-
-class String
- include Spec::Expectations::StringHelpers
-end
-
-class Symbol
- include Spec::Expectations::StringHelpers
-end
diff --git a/spec/lib/spec/expectations/handler.rb b/spec/lib/spec/expectations/handler.rb
deleted file mode 100644
index 4caa321e4..000000000
--- a/spec/lib/spec/expectations/handler.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-module Spec
- module Expectations
-
- module MatcherHandlerHelper
- def describe(matcher)
- matcher.respond_to?(:description) ? matcher.description : "[#{matcher.class.name} does not provide a description]"
- end
- end
-
- class ExpectationMatcherHandler
- class << self
- include MatcherHandlerHelper
- def handle_matcher(actual, matcher, &block)
- match = matcher.matches?(actual, &block)
- ::Spec::Matchers.generated_description = "should #{describe(matcher)}"
- Spec::Expectations.fail_with(matcher.failure_message) unless match
- end
- end
- end
-
- class NegativeExpectationMatcherHandler
- class << self
- include MatcherHandlerHelper
- def handle_matcher(actual, matcher, &block)
- unless matcher.respond_to?(:negative_failure_message)
- Spec::Expectations.fail_with(
-<<-EOF
-Matcher does not support should_not.
-See Spec::Matchers for more information
-about matchers.
-EOF
-)
- end
- match = matcher.matches?(actual, &block)
- ::Spec::Matchers.generated_description = "should not #{describe(matcher)}"
- Spec::Expectations.fail_with(matcher.negative_failure_message) if match
- end
- end
- end
-
- end
-end
-
diff --git a/spec/lib/spec/extensions.rb b/spec/lib/spec/extensions.rb
deleted file mode 100755
index 824f03bfb..000000000
--- a/spec/lib/spec/extensions.rb
+++ /dev/null
@@ -1 +0,0 @@
-require 'spec/extensions/object'
diff --git a/spec/lib/spec/extensions/object.rb b/spec/lib/spec/extensions/object.rb
deleted file mode 100755
index 6218aa770..000000000
--- a/spec/lib/spec/extensions/object.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-class Object
- def args_and_options(*args)
- options = Hash === args.last ? args.pop : {}
- return args, options
- end
-end
diff --git a/spec/lib/spec/matchers.rb b/spec/lib/spec/matchers.rb
deleted file mode 100644
index fd208d628..000000000
--- a/spec/lib/spec/matchers.rb
+++ /dev/null
@@ -1,166 +0,0 @@
-require 'spec/matchers/be'
-require 'spec/matchers/be_close'
-require 'spec/matchers/change'
-require 'spec/matchers/eql'
-require 'spec/matchers/equal'
-require 'spec/matchers/has'
-require 'spec/matchers/have'
-require 'spec/matchers/include'
-require 'spec/matchers/match'
-require 'spec/matchers/raise_error'
-require 'spec/matchers/respond_to'
-require 'spec/matchers/satisfy'
-require 'spec/matchers/throw_symbol'
-require 'spec/matchers/operator_matcher'
-
-module Spec
-
- # RSpec ships with a number of useful Expression Matchers. An Expression Matcher
- # is any object that responds to the following methods:
- #
- # matches?(actual)
- # failure_message
- # negative_failure_message #optional
- # description #optional
- #
- # See Spec::Expectations to learn how to use these as Expectation Matchers.
- # See Spec::Mocks to learn how to use them as Mock Argument Constraints.
- #
- # == Predicates
- #
- # In addition to those Expression Matchers that are defined explicitly, RSpec will
- # create custom Matchers on the fly for any arbitrary predicate, giving your specs
- # a much more natural language feel.
- #
- # A Ruby predicate is a method that ends with a "?" and returns true or false.
- # Common examples are +empty?+, +nil?+, and +instance_of?+.
- #
- # All you need to do is write +should be_+ followed by the predicate without
- # the question mark, and RSpec will figure it out from there. For example:
- #
- # [].should be_empty => [].empty? #passes
- # [].should_not be_empty => [].empty? #fails
- #
- # In addtion to prefixing the predicate matchers with "be_", you can also use "be_a_"
- # and "be_an_", making your specs read much more naturally:
- #
- # "a string".should be_an_instance_of(String) =>"a string".instance_of?(String) #passes
- #
- # 3.should be_a_kind_of(Fixnum) => 3.kind_of?(Numeric) #passes
- # 3.should be_a_kind_of(Numeric) => 3.kind_of?(Numeric) #passes
- # 3.should be_an_instance_of(Fixnum) => 3.instance_of?(Fixnum) #passes
- # 3.should_not be_instance_of(Numeric) => 3.instance_of?(Numeric) #fails
- #
- # RSpec will also create custom matchers for predicates like +has_key?+. To
- # use this feature, just state that the object should have_key(:key) and RSpec will
- # call has_key?(:key) on the target. For example:
- #
- # {:a => "A"}.should have_key(:a) => {:a => "A"}.has_key?(:a) #passes
- # {:a => "A"}.should have_key(:b) => {:a => "A"}.has_key?(:b) #fails
- #
- # You can use this feature to invoke any predicate that begins with "has_", whether it is
- # part of the Ruby libraries (like +Hash#has_key?+) or a method you wrote on your own class.
- #
- # == Custom Expectation Matchers
- #
- # When you find that none of the stock Expectation Matchers provide a natural
- # feeling expectation, you can very easily write your own.
- #
- # For example, imagine that you are writing a game in which players can
- # be in various zones on a virtual board. To specify that bob should
- # be in zone 4, you could say:
- #
- # bob.current_zone.should eql(Zone.new("4"))
- #
- # But you might find it more expressive to say:
- #
- # bob.should be_in_zone("4")
- #
- # and/or
- #
- # bob.should_not be_in_zone("3")
- #
- # To do this, you would need to write a class like this:
- #
- # class BeInZone
- # def initialize(expected)
- # @expected = expected
- # end
- # def matches?(target)
- # @target = target
- # @target.current_zone.eql?(Zone.new(@expected))
- # end
- # def failure_message
- # "expected #{@target.inspect} to be in Zone #{@expected}"
- # end
- # def negative_failure_message
- # "expected #{@target.inspect} not to be in Zone #{@expected}"
- # end
- # end
- #
- # ... and a method like this:
- #
- # def be_in_zone(expected)
- # BeInZone.new(expected)
- # end
- #
- # And then expose the method to your specs. This is normally done
- # by including the method and the class in a module, which is then
- # included in your spec:
- #
- # module CustomGameMatchers
- # class BeInZone
- # ...
- # end
- #
- # def be_in_zone(expected)
- # ...
- # end
- # end
- #
- # describe "Player behaviour" do
- # include CustomGameMatchers
- # ...
- # end
- #
- # or you can include in globally in a spec_helper.rb file <tt>require</tt>d
- # from your spec file(s):
- #
- # Spec::Runner.configure do |config|
- # config.include(CustomGameMatchers)
- # end
- #
- module Matchers
- module ModuleMethods
- def description_generated(callback)
- description_generated_callbacks << callback
- end
-
- def unregister_description_generated(callback)
- description_generated_callbacks.delete(callback)
- end
-
- def generated_description=(name)
- description_generated_callbacks.each do |callback|
- callback.call(name)
- end
- end
-
- private
- def description_generated_callbacks
- @description_generated_callbacks ||= []
- end
- end
- extend ModuleMethods
-
- def method_missing(sym, *args, &block) # :nodoc:
- return Matchers::Be.new(sym, *args) if sym.starts_with?("be_")
- return Matchers::Has.new(sym, *args) if sym.starts_with?("have_")
- super
- end
-
- class MatcherError < StandardError
- end
-
- end
-end
diff --git a/spec/lib/spec/matchers/be.rb b/spec/lib/spec/matchers/be.rb
deleted file mode 100644
index 0eb1629a6..000000000
--- a/spec/lib/spec/matchers/be.rb
+++ /dev/null
@@ -1,206 +0,0 @@
-module Spec
- module Matchers
-
- class Be #:nodoc:
- def initialize(*args)
- @expected = parse_expected(args.shift)
- @args = args
- @comparison = ""
- end
-
- def matches?(actual)
- @actual = actual
- return true if match_or_compare unless handling_predicate?
- if handling_predicate?
- begin
- return @result = actual.__send__(predicate, *@args)
- rescue => predicate_error
- # This clause should be empty, but rcov will not report it as covered
- # unless something (anything) is executed within the clause
- rcov_error_report = "http://eigenclass.org/hiki.rb?rcov-0.8.0"
- end
-
- # This supports should_exist > target.exists? in the old world.
- # We should consider deprecating that ability as in the new world
- # you can't write "should exist" unless you have your own custom matcher.
- begin
- return @result = actual.__send__(present_tense_predicate, *@args)
- rescue
- raise predicate_error
- end
- end
- return false
- end
-
- def failure_message
- return "expected #{@comparison}#{expected}, got #{@actual.inspect}" unless handling_predicate?
- return "expected #{predicate}#{args_to_s} to return true, got #{@result.inspect}"
- end
-
- def negative_failure_message
- return "expected not #{expected}, got #{@actual.inspect}" unless handling_predicate?
- return "expected #{predicate}#{args_to_s} to return false, got #{@result.inspect}"
- end
-
- def expected
- return true if @expected == :true
- return false if @expected == :false
- return "nil" if @expected == :nil
- return @expected.inspect
- end
-
- def match_or_compare
- return @actual == true if @expected == :true
- return @actual == false if @expected == :false
- return @actual.nil? if @expected == :nil
- return @actual < @expected if @less_than
- return @actual <= @expected if @less_than_or_equal
- return @actual >= @expected if @greater_than_or_equal
- return @actual > @expected if @greater_than
- return @actual == @expected if @double_equal
- return @actual === @expected if @triple_equal
- return @actual.equal?(@expected)
- end
-
- def ==(expected)
- @double_equal = true
- @comparison = "== "
- @expected = expected
- self
- end
-
- def ===(expected)
- @triple_equal = true
- @comparison = "=== "
- @expected = expected
- self
- end
-
- def <(expected)
- @less_than = true
- @comparison = "< "
- @expected = expected
- self
- end
-
- def <=(expected)
- @less_than_or_equal = true
- @comparison = "<= "
- @expected = expected
- self
- end
-
- def >=(expected)
- @greater_than_or_equal = true
- @comparison = ">= "
- @expected = expected
- self
- end
-
- def >(expected)
- @greater_than = true
- @comparison = "> "
- @expected = expected
- self
- end
-
- def description
- "#{prefix_to_sentence}#{comparison}#{expected_to_sentence}#{args_to_sentence}"
- end
-
- private
- def parse_expected(expected)
- if Symbol === expected
- @handling_predicate = true
- ["be_an_","be_a_","be_"].each do |@prefix|
- return "#{expected.to_s.sub(@prefix,"")}".to_sym if expected.starts_with?(@prefix)
- end
- end
- @prefix = "be "
- return expected
- end
-
- def handling_predicate?
- return false if [:true, :false, :nil].include?(@expected)
- return @handling_predicate
- end
-
- def predicate
- "#{@expected.to_s}?".to_sym
- end
-
- def present_tense_predicate
- "#{@expected.to_s}s?".to_sym
- end
-
- def args_to_s
- return "" if @args.empty?
- inspected_args = @args.collect{|a| a.inspect}
- return "(#{inspected_args.join(', ')})"
- end
-
- def comparison
- @comparison
- end
-
- def expected_to_sentence
- split_words(@expected)
- end
-
- def prefix_to_sentence
- split_words(@prefix)
- end
-
- def split_words(sym)
- sym.to_s.gsub(/_/,' ')
- end
-
- def args_to_sentence
- case @args.length
- when 0
- ""
- when 1
- " #{@args[0]}"
- else
- " #{@args[0...-1].join(', ')} and #{@args[-1]}"
- end
- end
-
- end
-
- # :call-seq:
- # should be_true
- # should be_false
- # should be_nil
- # should be_arbitrary_predicate(*args)
- # should_not be_nil
- # should_not be_arbitrary_predicate(*args)
- #
- # Given true, false, or nil, will pass if actual is
- # true, false or nil (respectively).
- #
- # Predicates are any Ruby method that ends in a "?" and returns true or false.
- # Given be_ followed by arbitrary_predicate (without the "?"), RSpec will match
- # convert that into a query against the target object.
- #
- # The arbitrary_predicate feature will handle any predicate
- # prefixed with "be_an_" (e.g. be_an_instance_of), "be_a_" (e.g. be_a_kind_of)
- # or "be_" (e.g. be_empty), letting you choose the prefix that best suits the predicate.
- #
- # == Examples
- #
- # target.should be_true
- # target.should be_false
- # target.should be_nil
- # target.should_not be_nil
- #
- # collection.should be_empty #passes if target.empty?
- # "this string".should be_an_intance_of(String)
- #
- # target.should_not be_empty #passes unless target.empty?
- # target.should_not be_old_enough(16) #passes unless target.old_enough?(16)
- def be(*args)
- Matchers::Be.new(*args)
- end
- end
-end
diff --git a/spec/lib/spec/matchers/be_close.rb b/spec/lib/spec/matchers/be_close.rb
deleted file mode 100644
index 7763eb97e..000000000
--- a/spec/lib/spec/matchers/be_close.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-module Spec
- module Matchers
-
- class BeClose #:nodoc:
- def initialize(expected, delta)
- @expected = expected
- @delta = delta
- end
-
- def matches?(actual)
- @actual = actual
- (@actual - @expected).abs < @delta
- end
-
- def failure_message
- "expected #{@expected} +/- (< #{@delta}), got #{@actual}"
- end
-
- def description
- "be close to #{@expected} (within +- #{@delta})"
- end
- end
-
- # :call-seq:
- # should be_close(expected, delta)
- # should_not be_close(expected, delta)
- #
- # Passes if actual == expected +/- delta
- #
- # == Example
- #
- # result.should be_close(3.0, 0.5)
- def be_close(expected, delta)
- Matchers::BeClose.new(expected, delta)
- end
- end
-end
diff --git a/spec/lib/spec/matchers/change.rb b/spec/lib/spec/matchers/change.rb
deleted file mode 100644
index 41a718aca..000000000
--- a/spec/lib/spec/matchers/change.rb
+++ /dev/null
@@ -1,120 +0,0 @@
-module Spec
- module Matchers
-
- #Based on patch from Wilson Bilkovich
- class Change #:nodoc:
- def initialize(receiver=nil, message=nil, &block)
- @receiver = receiver
- @message = message
- @block = block
- end
-
- def matches?(target, &block)
- if block
- raise MatcherError.new(<<-EOF
-block passed to should or should_not change must use {} instead of do/end
-EOF
-)
- end
- @target = target
- execute_change
- return false if @from && (@from != @before)
- return false if @to && (@to != @after)
- return (@before + @amount == @after) if @amount
- return @before != @after
- end
-
- def execute_change
- @before = @block.nil? ? @receiver.send(@message) : @block.call
- @target.call
- @after = @block.nil? ? @receiver.send(@message) : @block.call
- end
-
- def failure_message
- if @to
- "#{result} should have been changed to #{@to.inspect}, but is now #{@after.inspect}"
- elsif @from
- "#{result} should have initially been #{@from.inspect}, but was #{@before.inspect}"
- elsif @amount
- "#{result} should have been changed by #{@amount.inspect}, but was changed by #{actual_delta.inspect}"
- else
- "#{result} should have changed, but is still #{@before.inspect}"
- end
- end
-
- def result
- @message || "result"
- end
-
- def actual_delta
- @after - @before
- end
-
- def negative_failure_message
- "#{result} should not have changed, but did change from #{@before.inspect} to #{@after.inspect}"
- end
-
- def by(amount)
- @amount = amount
- self
- end
-
- def to(to)
- @to = to
- self
- end
-
- def from (from)
- @from = from
- self
- end
- end
-
- # :call-seq:
- # should change(receiver, message, &block)
- # should change(receiver, message, &block).by(value)
- # should change(receiver, message, &block).from(old).to(new)
- # should_not change(receiver, message, &block)
- #
- # Allows you to specify that a Proc will cause some value to change.
- #
- # == Examples
- #
- # lambda {
- # team.add_player(player)
- # }.should change(roster, :count)
- #
- # lambda {
- # team.add_player(player)
- # }.should change(roster, :count).by(1)
- #
- # string = "string"
- # lambda {
- # string.reverse
- # }.should change { string }.from("string").to("gnirts")
- #
- # lambda {
- # person.happy_birthday
- # }.should change(person, :birthday).from(32).to(33)
- #
- # lambda {
- # employee.develop_great_new_social_networking_app
- # }.should change(employee, :title).from("Mail Clerk").to("CEO")
- #
- # Evaluates +receiver.message+ or +block+ before and
- # after it evaluates the c object (generated by the lambdas in the examples above).
- #
- # Then compares the values before and after the +receiver.message+ and
- # evaluates the difference compared to the expected difference.
- #
- # == Warning
- # +should_not+ +change+ only supports the form with no subsequent calls to
- # +be+, +to+ or +from+.
- #
- # blocks passed to +should+ +change+ and +should_not+ +change+
- # must use the <tt>{}</tt> form (<tt>do/end</tt> is not supported)
- def change(target=nil, message=nil, &block)
- Matchers::Change.new(target, message, &block)
- end
- end
-end
diff --git a/spec/lib/spec/matchers/eql.rb b/spec/lib/spec/matchers/eql.rb
deleted file mode 100644
index 280ca5454..000000000
--- a/spec/lib/spec/matchers/eql.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-module Spec
- module Matchers
-
- class Eql #:nodoc:
- def initialize(expected)
- @expected = expected
- end
-
- def matches?(actual)
- @actual = actual
- @actual.eql?(@expected)
- end
-
- def failure_message
- return "expected #{@expected.inspect}, got #{@actual.inspect} (using .eql?)", @expected, @actual
- end
-
- def negative_failure_message
- return "expected #{@actual.inspect} not to equal #{@expected.inspect} (using .eql?)", @expected, @actual
- end
-
- def description
- "eql #{@expected.inspect}"
- end
- end
-
- # :call-seq:
- # should eql(expected)
- # should_not eql(expected)
- #
- # Passes if actual and expected are of equal value, but not necessarily the same object.
- #
- # See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more information about equality in Ruby.
- #
- # == Examples
- #
- # 5.should eql(5)
- # 5.should_not eql(3)
- def eql(expected)
- Matchers::Eql.new(expected)
- end
- end
-end
diff --git a/spec/lib/spec/matchers/equal.rb b/spec/lib/spec/matchers/equal.rb
deleted file mode 100644
index 4bfc74951..000000000
--- a/spec/lib/spec/matchers/equal.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-module Spec
- module Matchers
-
- class Equal #:nodoc:
- def initialize(expected)
- @expected = expected
- end
-
- def matches?(actual)
- @actual = actual
- @actual.equal?(@expected)
- end
-
- def failure_message
- return "expected #{@expected.inspect}, got #{@actual.inspect} (using .equal?)", @expected, @actual
- end
-
- def negative_failure_message
- return "expected #{@actual.inspect} not to equal #{@expected.inspect} (using .equal?)", @expected, @actual
- end
-
- def description
- "equal #{@expected.inspect}"
- end
- end
-
- # :call-seq:
- # should equal(expected)
- # should_not equal(expected)
- #
- # Passes if actual and expected are the same object (object identity).
- #
- # See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more information about equality in Ruby.
- #
- # == Examples
- #
- # 5.should equal(5) #Fixnums are equal
- # "5".should_not equal("5") #Strings that look the same are not the same object
- def equal(expected)
- Matchers::Equal.new(expected)
- end
- end
-end
diff --git a/spec/lib/spec/matchers/has.rb b/spec/lib/spec/matchers/has.rb
deleted file mode 100644
index cc5a250b8..000000000
--- a/spec/lib/spec/matchers/has.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-module Spec
- module Matchers
-
- class Has #:nodoc:
- def initialize(sym, *args)
- @sym = sym
- @args = args
- end
-
- def matches?(target)
- @target = target
- begin
- return target.send(predicate, *@args)
- rescue => @error
- # This clause should be empty, but rcov will not report it as covered
- # unless something (anything) is executed within the clause
- rcov_error_report = "http://eigenclass.org/hiki.rb?rcov-0.8.0"
- end
- return false
- end
-
- def failure_message
- raise @error if @error
- "expected ##{predicate}(#{@args[0].inspect}) to return true, got false"
- end
-
- def negative_failure_message
- raise @error if @error
- "expected ##{predicate}(#{@args[0].inspect}) to return false, got true"
- end
-
- def description
- "have key #{@args[0].inspect}"
- end
-
- private
- def predicate
- "#{@sym.to_s.sub("have_","has_")}?".to_sym
- end
-
- end
-
- end
-end
diff --git a/spec/lib/spec/matchers/have.rb b/spec/lib/spec/matchers/have.rb
deleted file mode 100644
index f28b86ad3..000000000
--- a/spec/lib/spec/matchers/have.rb
+++ /dev/null
@@ -1,142 +0,0 @@
-module Spec
- module Matchers
-
- class Have #:nodoc:
- def initialize(expected, relativity=:exactly)
- @expected = (expected == :no ? 0 : expected)
- @relativity = relativity
- end
-
- def relativities
- @relativities ||= {
- :exactly => "",
- :at_least => "at least ",
- :at_most => "at most "
- }
- end
-
- def method_missing(sym, *args, &block)
- @collection_name = sym
- @args = args
- @block = block
- self
- end
-
- def matches?(collection_owner)
- if collection_owner.respond_to?(@collection_name)
- collection = collection_owner.send(@collection_name, *@args, &@block)
- elsif (collection_owner.respond_to?(:length) || collection_owner.respond_to?(:size))
- collection = collection_owner
- else
- collection_owner.send(@collection_name, *@args, &@block)
- end
- @actual = collection.size if collection.respond_to?(:size)
- @actual = collection.length if collection.respond_to?(:length)
- raise not_a_collection if @actual.nil?
- return @actual >= @expected if @relativity == :at_least
- return @actual <= @expected if @relativity == :at_most
- return @actual == @expected
- end
-
- def not_a_collection
- "expected #{@collection_name} to be a collection but it does not respond to #length or #size"
- end
-
- def failure_message
- "expected #{relative_expectation} #{@collection_name}, got #{@actual}"
- end
-
- def negative_failure_message
- if @relativity == :exactly
- return "expected target not to have #{@expected} #{@collection_name}, got #{@actual}"
- elsif @relativity == :at_most
- return <<-EOF
-Isn't life confusing enough?
-Instead of having to figure out the meaning of this:
- should_not have_at_most(#{@expected}).#{@collection_name}
-We recommend that you use this instead:
- should have_at_least(#{@expected + 1}).#{@collection_name}
-EOF
- elsif @relativity == :at_least
- return <<-EOF
-Isn't life confusing enough?
-Instead of having to figure out the meaning of this:
- should_not have_at_least(#{@expected}).#{@collection_name}
-We recommend that you use this instead:
- should have_at_most(#{@expected - 1}).#{@collection_name}
-EOF
- end
- end
-
- def description
- "have #{relative_expectation} #{@collection_name}"
- end
-
- private
-
- def relative_expectation
- "#{relativities[@relativity]}#{@expected}"
- end
- end
-
- # :call-seq:
- # should have(number).named_collection__or__sugar
- # should_not have(number).named_collection__or__sugar
- #
- # Passes if receiver is a collection with the submitted
- # number of items OR if the receiver OWNS a collection
- # with the submitted number of items.
- #
- # If the receiver OWNS the collection, you must use the name
- # of the collection. So if a <tt>Team</tt> instance has a
- # collection named <tt>#players</tt>, you must use that name
- # to set the expectation.
- #
- # If the receiver IS the collection, you can use any name
- # you like for <tt>named_collection</tt>. We'd recommend using
- # either "elements", "members", or "items" as these are all
- # standard ways of describing the things IN a collection.
- #
- # This also works for Strings, letting you set an expectation
- # about its length
- #
- # == Examples
- #
- # # Passes if team.players.size == 11
- # team.should have(11).players
- #
- # # Passes if [1,2,3].length == 3
- # [1,2,3].should have(3).items #"items" is pure sugar
- #
- # # Passes if "this string".length == 11
- # "this string".should have(11).characters #"characters" is pure sugar
- def have(n)
- Matchers::Have.new(n)
- end
- alias :have_exactly :have
-
- # :call-seq:
- # should have_at_least(number).items
- #
- # Exactly like have() with >=.
- #
- # == Warning
- #
- # +should_not+ +have_at_least+ is not supported
- def have_at_least(n)
- Matchers::Have.new(n, :at_least)
- end
-
- # :call-seq:
- # should have_at_most(number).items
- #
- # Exactly like have() with <=.
- #
- # == Warning
- #
- # +should_not+ +have_at_most+ is not supported
- def have_at_most(n)
- Matchers::Have.new(n, :at_most)
- end
- end
-end
diff --git a/spec/lib/spec/matchers/include.rb b/spec/lib/spec/matchers/include.rb
deleted file mode 100644
index 5476f97d8..000000000
--- a/spec/lib/spec/matchers/include.rb
+++ /dev/null
@@ -1,70 +0,0 @@
-module Spec
- module Matchers
-
- class Include #:nodoc:
-
- def initialize(*expecteds)
- @expecteds = expecteds
- end
-
- def matches?(actual)
- @actual = actual
- @expecteds.each do |expected|
- return false unless actual.include?(expected)
- end
- true
- end
-
- def failure_message
- _message
- end
-
- def negative_failure_message
- _message("not ")
- end
-
- def description
- "include #{_pretty_print(@expecteds)}"
- end
-
- private
- def _message(maybe_not="")
- "expected #{@actual.inspect} #{maybe_not}to include #{_pretty_print(@expecteds)}"
- end
-
- def _pretty_print(array)
- result = ""
- array.each_with_index do |item, index|
- if index < (array.length - 2)
- result << "#{item.inspect}, "
- elsif index < (array.length - 1)
- result << "#{item.inspect} and "
- else
- result << "#{item.inspect}"
- end
- end
- result
- end
- end
-
- # :call-seq:
- # should include(expected)
- # should_not include(expected)
- #
- # Passes if actual includes expected. This works for
- # collections and Strings. You can also pass in multiple args
- # and it will only pass if all args are found in collection.
- #
- # == Examples
- #
- # [1,2,3].should include(3)
- # [1,2,3].should include(2,3) #would pass
- # [1,2,3].should include(2,3,4) #would fail
- # [1,2,3].should_not include(4)
- # "spread".should include("read")
- # "spread".should_not include("red")
- def include(*expected)
- Matchers::Include.new(*expected)
- end
- end
-end
diff --git a/spec/lib/spec/matchers/match.rb b/spec/lib/spec/matchers/match.rb
deleted file mode 100644
index 61ab52429..000000000
--- a/spec/lib/spec/matchers/match.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-module Spec
- module Matchers
-
- class Match #:nodoc:
- def initialize(expected)
- @expected = expected
- end
-
- def matches?(actual)
- @actual = actual
- return true if actual =~ @expected
- return false
- end
-
- def failure_message
- return "expected #{@actual.inspect} to match #{@expected.inspect}", @expected, @actual
- end
-
- def negative_failure_message
- return "expected #{@actual.inspect} not to match #{@expected.inspect}", @expected, @actual
- end
-
- def description
- "match #{@expected.inspect}"
- end
- end
-
- # :call-seq:
- # should match(regexp)
- # should_not match(regexp)
- #
- # Given a Regexp, passes if actual =~ regexp
- #
- # == Examples
- #
- # email.should match(/^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i)
- def match(regexp)
- Matchers::Match.new(regexp)
- end
- end
-end
diff --git a/spec/lib/spec/matchers/operator_matcher.rb b/spec/lib/spec/matchers/operator_matcher.rb
deleted file mode 100755
index 2d47ea85a..000000000
--- a/spec/lib/spec/matchers/operator_matcher.rb
+++ /dev/null
@@ -1,72 +0,0 @@
-module Spec
- module Matchers
- class BaseOperatorMatcher
-
- def initialize(target)
- @target = target
- end
-
- def ==(expected)
- @expected = expected
- __delegate_method_missing_to_target("==", expected)
- end
-
- def ===(expected)
- @expected = expected
- __delegate_method_missing_to_target("===", expected)
- end
-
- def =~(expected)
- @expected = expected
- __delegate_method_missing_to_target("=~", expected)
- end
-
- def >(expected)
- @expected = expected
- __delegate_method_missing_to_target(">", expected)
- end
-
- def >=(expected)
- @expected = expected
- __delegate_method_missing_to_target(">=", expected)
- end
-
- def <(expected)
- @expected = expected
- __delegate_method_missing_to_target("<", expected)
- end
-
- def <=(expected)
- @expected = expected
- __delegate_method_missing_to_target("<=", expected)
- end
-
- def fail_with_message(message)
- Spec::Expectations.fail_with(message, @expected, @target)
- end
-
- end
-
- class PositiveOperatorMatcher < BaseOperatorMatcher #:nodoc:
-
- def __delegate_method_missing_to_target(operator, expected)
- ::Spec::Matchers.generated_description = "should #{operator} #{expected.inspect}"
- return if @target.send(operator, expected)
- return fail_with_message("expected: #{expected.inspect},\n got: #{@target.inspect} (using #{operator})") if ['==','===', '=~'].include?(operator)
- return fail_with_message("expected: #{operator} #{expected.inspect},\n got: #{operator.gsub(/./, ' ')} #{@target.inspect}")
- end
-
- end
-
- class NegativeOperatorMatcher < BaseOperatorMatcher #:nodoc:
-
- def __delegate_method_missing_to_target(operator, expected)
- ::Spec::Matchers.generated_description = "should not #{operator} #{expected.inspect}"
- return unless @target.send(operator, expected)
- return fail_with_message("expected not: #{operator} #{expected.inspect},\n got: #{operator.gsub(/./, ' ')} #{@target.inspect}")
- end
-
- end
-
- end
-end
diff --git a/spec/lib/spec/matchers/raise_error.rb b/spec/lib/spec/matchers/raise_error.rb
deleted file mode 100644
index b45dcf65c..000000000
--- a/spec/lib/spec/matchers/raise_error.rb
+++ /dev/null
@@ -1,105 +0,0 @@
-module Spec
- module Matchers
-
- class RaiseError #:nodoc:
- def initialize(error_or_message=Exception, message=nil)
- if String === error_or_message
- @expected_error = Exception
- @expected_message = error_or_message
- else
- @expected_error = error_or_message
- @expected_message = message
- end
- end
-
- def matches?(proc)
- @raised_expected_error = false
- @raised_other = false
- begin
- proc.call
- rescue @expected_error => @actual_error
- if @expected_message.nil?
- @raised_expected_error = true
- else
- case @expected_message
- when Regexp
- if @expected_message =~ @actual_error.message
- @raised_expected_error = true
- else
- @raised_other = true
- end
- else
- if @expected_message == @actual_error.message
- @raised_expected_error = true
- else
- @raised_other = true
- end
- end
- end
- rescue => @actual_error
- @raised_other = true
- ensure
- return @raised_expected_error
- end
- end
-
- def failure_message
- return "expected #{expected_error}#{actual_error}" if @raised_other || !@raised_expected_error
- end
-
- def negative_failure_message
- "expected no #{expected_error}#{actual_error}"
- end
-
- def description
- "raise #{expected_error}"
- end
-
- private
- def expected_error
- case @expected_message
- when nil
- @expected_error
- when Regexp
- "#{@expected_error} with message matching #{@expected_message.inspect}"
- else
- "#{@expected_error} with #{@expected_message.inspect}"
- end
- end
-
- def actual_error
- @actual_error.nil? ? " but nothing was raised" : ", got #{@actual_error.inspect}"
- end
- end
-
- # :call-seq:
- # should raise_error()
- # should raise_error(NamedError)
- # should raise_error(NamedError, String)
- # should raise_error(NamedError, Regexp)
- # should_not raise_error()
- # should_not raise_error(NamedError)
- # should_not raise_error(NamedError, String)
- # should_not raise_error(NamedError, Regexp)
- #
- # With no args, matches if any error is raised.
- # With a named error, matches only if that specific error is raised.
- # With a named error and messsage specified as a String, matches only if both match.
- # With a named error and messsage specified as a Regexp, matches only if both match.
- #
- # == Examples
- #
- # lambda { do_something_risky }.should raise_error
- # lambda { do_something_risky }.should raise_error(PoorRiskDecisionError)
- # lambda { do_something_risky }.should raise_error(PoorRiskDecisionError, "that was too risky")
- # lambda { do_something_risky }.should raise_error(PoorRiskDecisionError, /oo ri/)
- #
- # lambda { do_something_risky }.should_not raise_error
- # lambda { do_something_risky }.should_not raise_error(PoorRiskDecisionError)
- # lambda { do_something_risky }.should_not raise_error(PoorRiskDecisionError, "that was too risky")
- # lambda { do_something_risky }.should_not raise_error(PoorRiskDecisionError, /oo ri/)
- def raise_error(error=Exception, message=nil)
- Matchers::RaiseError.new(error, message)
- end
- end
-end
diff --git a/spec/lib/spec/matchers/respond_to.rb b/spec/lib/spec/matchers/respond_to.rb
deleted file mode 100644
index 3d23422aa..000000000
--- a/spec/lib/spec/matchers/respond_to.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-module Spec
- module Matchers
-
- class RespondTo #:nodoc:
- def initialize(*names)
- @names = names
- @names_not_responded_to = []
- end
-
- def matches?(target)
- @names.each do |name|
- unless target.respond_to?(name)
- @names_not_responded_to << name
- end
- end
- return @names_not_responded_to.empty?
- end
-
- def failure_message
- "expected target to respond to #{@names_not_responded_to.collect {|name| name.inspect }.join(', ')}"
- end
-
- def negative_failure_message
- "expected target not to respond to #{@names.collect {|name| name.inspect }.join(', ')}"
- end
-
- def description
- "respond to ##{@names.to_s}"
- end
- end
-
- # :call-seq:
- # should respond_to(*names)
- # should_not respond_to(*names)
- #
- # Matches if the target object responds to all of the names
- # provided. Names can be Strings or Symbols.
- #
- # == Examples
- #
- def respond_to(*names)
- Matchers::RespondTo.new(*names)
- end
- end
-end
diff --git a/spec/lib/spec/matchers/satisfy.rb b/spec/lib/spec/matchers/satisfy.rb
deleted file mode 100644
index 6c0ca95bc..000000000
--- a/spec/lib/spec/matchers/satisfy.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-module Spec
- module Matchers
-
- class Satisfy #:nodoc:
- def initialize(&block)
- @block = block
- end
-
- def matches?(actual, &block)
- @block = block if block
- @actual = actual
- @block.call(actual)
- end
-
- def failure_message
- "expected #{@actual} to satisfy block"
- end
-
- def negative_failure_message
- "expected #{@actual} not to satisfy block"
- end
- end
-
- # :call-seq:
- # should satisfy {}
- # should_not satisfy {}
- #
- # Passes if the submitted block returns true. Yields target to the
- # block.
- #
- # Generally speaking, this should be thought of as a last resort when
- # you can't find any other way to specify the behaviour you wish to
- # specify.
- #
- # If you do find yourself in such a situation, you could always write
- # a custom matcher, which would likely make your specs more expressive.
- #
- # == Examples
- #
- # 5.should satisfy { |n|
- # n > 3
- # }
- def satisfy(&block)
- Matchers::Satisfy.new(&block)
- end
- end
-end
diff --git a/spec/lib/spec/matchers/throw_symbol.rb b/spec/lib/spec/matchers/throw_symbol.rb
deleted file mode 100644
index 6d047bc39..000000000
--- a/spec/lib/spec/matchers/throw_symbol.rb
+++ /dev/null
@@ -1,72 +0,0 @@
-module Spec
- module Matchers
-
- class ThrowSymbol #:nodoc:
- def initialize(expected=nil)
- @expected = expected
- end
-
- def matches?(proc)
- begin
- proc.call
- rescue NameError => e
- @actual = e.name.to_sym
- ensure
- if @expected.nil?
- return @actual.nil? ? false : true
- else
- return @actual == @expected
- end
- end
- end
-
- def failure_message
- if @actual
- "expected #{expected}, got #{@actual.inspect}"
- else
- "expected #{expected} but nothing was thrown"
- end
- end
-
- def negative_failure_message
- if @expected
- "expected #{expected} not to be thrown"
- else
- "expected no Symbol, got :#{@actual}"
- end
- end
-
- def description
- "throw #{expected}"
- end
-
- private
-
- def expected
- @expected.nil? ? "a Symbol" : @expected.inspect
- end
-
- end
-
- # :call-seq:
- # should throw_symbol()
- # should throw_symbol(:sym)
- # should_not throw_symbol()
- # should_not throw_symbol(:sym)
- #
- # Given a Symbol argument, matches if a proc throws the specified Symbol.
- #
- # Given no argument, matches if a proc throws any Symbol.
- #
- # == Examples
- #
- # lambda { do_something_risky }.should throw_symbol
- # lambda { do_something_risky }.should throw_symbol(:that_was_risky)
- #
- # lambda { do_something_risky }.should_not throw_symbol
- # lambda { do_something_risky }.should_not throw_symbol(:that_was_risky)
- def throw_symbol(sym=nil)
- Matchers::ThrowSymbol.new(sym)
- end
- end
-end
diff --git a/spec/lib/spec/mocks.rb b/spec/lib/spec/mocks.rb
deleted file mode 100644
index 66cbafb3c..000000000
--- a/spec/lib/spec/mocks.rb
+++ /dev/null
@@ -1,208 +0,0 @@
-require 'spec/mocks/methods'
-require 'spec/mocks/argument_constraint_matchers'
-require 'spec/mocks/spec_methods'
-require 'spec/mocks/proxy'
-require 'spec/mocks/mock'
-require 'spec/mocks/argument_expectation'
-require 'spec/mocks/message_expectation'
-require 'spec/mocks/order_group'
-require 'spec/mocks/errors'
-require 'spec/mocks/error_generator'
-require 'spec/mocks/extensions/object'
-require 'spec/mocks/space'
-
-
-module Spec
- # == Mocks and Stubs
- #
- # RSpec will create Mock Objects and Stubs for you at runtime, or attach stub/mock behaviour
- # to any of your real objects (Partial Mock/Stub). Because the underlying implementation
- # for mocks and stubs is the same, you can intermingle mock and stub
- # behaviour in either dynamically generated mocks or your pre-existing classes.
- # There is a semantic difference in how they are created, however,
- # which can help clarify the role it is playing within a given spec.
- #
- # == Mock Objects
- #
- # Mocks are objects that allow you to set and verify expectations that they will
- # receive specific messages during run time. They are very useful for specifying how the subject of
- # the spec interacts with its collaborators. This approach is widely known as "interaction
- # testing".
- #
- # Mocks are also very powerful as a design tool. As you are
- # driving the implementation of a given class, Mocks provide an anonymous
- # collaborator that can change in behaviour as quickly as you can write an expectation in your
- # spec. This flexibility allows you to design the interface of a collaborator that often
- # does not yet exist. As the shape of the class being specified becomes more clear, so do the
- # requirements for its collaborators - often leading to the discovery of new types that are
- # needed in your system.
- #
- # Read Endo-Testing[http://www.mockobjects.com/files/endotesting.pdf] for a much
- # more in depth description of this process.
- #
- # == Stubs
- #
- # Stubs are objects that allow you to set "stub" responses to
- # messages. As Martin Fowler points out on his site,
- # mocks_arent_stubs[http://www.martinfowler.com/articles/mocksArentStubs.html].
- # Paraphrasing Fowler's paraphrasing
- # of Gerard Meszaros: Stubs provide canned responses to messages they might receive in a test, while
- # mocks allow you to specify and, subsquently, verify that certain messages should be received during
- # the execution of a test.
- #
- # == Partial Mocks/Stubs
- #
- # RSpec also supports partial mocking/stubbing, allowing you to add stub/mock behaviour
- # to instances of your existing classes. This is generally
- # something to be avoided, because changes to the class can have ripple effects on
- # seemingly unrelated specs. When specs fail due to these ripple effects, the fact
- # that some methods are being mocked can make it difficult to understand why a
- # failure is occurring.
- #
- # That said, partials do allow you to expect and
- # verify interactions with class methods such as +#find+ and +#create+
- # on Ruby on Rails model classes.
- #
- # == Further Reading
- #
- # There are many different viewpoints about the meaning of mocks and stubs. If you are interested
- # in learning more, here is some recommended reading:
- #
- # * Mock Objects: http://www.mockobjects.com/
- # * Endo-Testing: http://www.mockobjects.com/files/endotesting.pdf
- # * Mock Roles, Not Objects: http://www.mockobjects.com/files/mockrolesnotobjects.pdf
- # * Test Double Patterns: http://xunitpatterns.com/Test%20Double%20Patterns.html
- # * Mocks aren't stubs: http://www.martinfowler.com/articles/mocksArentStubs.html
- #
- # == Creating a Mock
- #
- # You can create a mock in any specification (or setup) using:
- #
- # mock(name, options={})
- #
- # The optional +options+ argument is a +Hash+. Currently the only supported
- # option is +:null_object+. Setting this to true instructs the mock to ignore
- # any messages it hasn’t been told to expect – and quietly return itself. For example:
- #
- # mock("person", :null_object => true)
- #
- # == Creating a Stub
- #
- # You can create a stub in any specification (or setup) using:
- #
- # stub(name, stub_methods_and_values_hash)
- #
- # For example, if you wanted to create an object that always returns
- # "More?!?!?!" to "please_sir_may_i_have_some_more" you would do this:
- #
- # stub("Mr Sykes", :please_sir_may_i_have_some_more => "More?!?!?!")
- #
- # == Creating a Partial Mock
- #
- # You don't really "create" a partial mock, you simply add method stubs and/or
- # mock expectations to existing classes and objects:
- #
- # Factory.should_receive(:find).with(id).and_return(value)
- # obj.stub!(:to_i).and_return(3)
- # etc ...
- #
- # == Expecting Messages
- #
- # my_mock.should_receive(:sym)
- # my_mock.should_not_receive(:sym)
- #
- # == Expecting Arguments
- #
- # my_mock.should_receive(:sym).with(*args)
- # my_mock.should_not_receive(:sym).with(*args)
- #
- # == Argument Constraints using Expression Matchers
- #
- # Arguments that are passed to #with are compared with actual arguments received
- # using == by default. In cases in which you want to specify things about the arguments
- # rather than the arguments themselves, you can use any of the Expression Matchers.
- # They don't all make syntactic sense (they were primarily designed for use with
- # Spec::Expectations), but you are free to create your own custom Spec::Matchers.
- #
- # Spec::Mocks does provide one additional Matcher method named #ducktype.
- #
- # In addition, Spec::Mocks adds some keyword Symbols that you can use to
- # specify certain kinds of arguments:
- #
- # my_mock.should_receive(:sym).with(no_args())
- # my_mock.should_receive(:sym).with(any_args())
- # my_mock.should_receive(:sym).with(1, an_instance_of(Numeric), "b") #2nd argument can any type of Numeric
- # my_mock.should_receive(:sym).with(1, boolean(), "b") #2nd argument can true or false
- # my_mock.should_receive(:sym).with(1, /abc/, "b") #2nd argument can be any String matching the submitted Regexp
- # my_mock.should_receive(:sym).with(1, anything(), "b") #2nd argument can be anything at all
- # my_mock.should_receive(:sym).with(1, ducktype(:abs, :div), "b")
- # #2nd argument can be object that responds to #abs and #div
- #
- # == Receive Counts
- #
- # my_mock.should_receive(:sym).once
- # my_mock.should_receive(:sym).twice
- # my_mock.should_receive(:sym).exactly(n).times
- # my_mock.should_receive(:sym).at_least(:once)
- # my_mock.should_receive(:sym).at_least(:twice)
- # my_mock.should_receive(:sym).at_least(n).times
- # my_mock.should_receive(:sym).at_most(:once)
- # my_mock.should_receive(:sym).at_most(:twice)
- # my_mock.should_receive(:sym).at_most(n).times
- # my_mock.should_receive(:sym).any_number_of_times
- #
- # == Ordering
- #
- # my_mock.should_receive(:sym).ordered
- # my_mock.should_receive(:other_sym).ordered
- # #This will fail if the messages are received out of order
- #
- # == Setting Reponses
- #
- # Whether you are setting a mock expectation or a simple stub, you can tell the
- # object precisely how to respond:
- #
- # my_mock.should_receive(:sym).and_return(value)
- # my_mock.should_receive(:sym).exactly(3).times.and_return(value1, value2, value3)
- # # returns value1 the first time, value2 the second, etc
- # my_mock.should_receive(:sym).and_return { ... } #returns value returned by the block
- # my_mock.should_receive(:sym).and_raise(error)
- # #error can be an instantiated object or a class
- # #if it is a class, it must be instantiable with no args
- # my_mock.should_receive(:sym).and_throw(:sym)
- # my_mock.should_receive(:sym).and_yield([array,of,values,to,yield])
- #
- # Any of these responses can be applied to a stub as well, but stubs do
- # not support any qualifiers about the message received (i.e. you can't specify arguments
- # or receive counts):
- #
- # my_mock.stub!(:sym).and_return(value)
- # my_mock.stub!(:sym).and_return(value1, value2, value3)
- # my_mock.stub!(:sym).and_raise(error)
- # my_mock.stub!(:sym).and_throw(:sym)
- # my_mock.stub!(:sym).and_yield([array,of,values,to,yield])
- #
- # == Arbitrary Handling
- #
- # Once in a while you'll find that the available expectations don't solve the
- # particular problem you are trying to solve. Imagine that you expect the message
- # to come with an Array argument that has a specific length, but you don't care
- # what is in it. You could do this:
- #
- # my_mock.should_receive(:sym) do |arg|
- # arg.should be_an_istance_of(Array)
- # arg.length.should == 7
- # end
- #
- # Note that this would fail if the number of arguments received was different from
- # the number of block arguments (in this case 1).
- #
- # == Combining Expectation Details
- #
- # Combining the message name with specific arguments, receive counts and responses
- # you can get quite a bit of detail in your expectations:
- #
- # my_mock.should_receive(:<<).with("illegal value").once.and_raise(ArgumentError)
- module Mocks
- end
-end
diff --git a/spec/lib/spec/mocks/argument_constraint_matchers.rb b/spec/lib/spec/mocks/argument_constraint_matchers.rb
deleted file mode 100644
index 0e4777082..000000000
--- a/spec/lib/spec/mocks/argument_constraint_matchers.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-module Spec
- module Mocks
- module ArgumentConstraintMatchers
-
- # Shortcut for creating an instance of Spec::Mocks::DuckTypeArgConstraint
- def duck_type(*args)
- DuckTypeArgConstraint.new(*args)
- end
-
- def any_args
- AnyArgsConstraint.new
- end
-
- def anything
- AnyArgConstraint.new(nil)
- end
-
- def boolean
- BooleanArgConstraint.new(nil)
- end
-
- def no_args
- NoArgsConstraint.new
- end
- end
- end
-end
diff --git a/spec/lib/spec/mocks/argument_expectation.rb b/spec/lib/spec/mocks/argument_expectation.rb
deleted file mode 100644
index 5da069b87..000000000
--- a/spec/lib/spec/mocks/argument_expectation.rb
+++ /dev/null
@@ -1,183 +0,0 @@
-module Spec
- module Mocks
-
- class MatcherConstraint
- def initialize(matcher)
- @matcher = matcher
- end
-
- def matches?(value)
- @matcher.matches?(value)
- end
- end
-
- class LiteralArgConstraint
- def initialize(literal)
- @literal_value = literal
- end
-
- def matches?(value)
- @literal_value == value
- end
- end
-
- class RegexpArgConstraint
- def initialize(regexp)
- @regexp = regexp
- end
-
- def matches?(value)
- return value =~ @regexp unless value.is_a?(Regexp)
- value == @regexp
- end
- end
-
- class AnyArgConstraint
- def initialize(ignore)
- end
-
- def ==(other)
- true
- end
-
- # TODO - need this?
- def matches?(value)
- true
- end
- end
-
- class AnyArgsConstraint
- def description
- "any args"
- end
- end
-
- class NoArgsConstraint
- def description
- "no args"
- end
-
- def ==(args)
- args == []
- end
- end
-
- class NumericArgConstraint
- def initialize(ignore)
- end
-
- def matches?(value)
- value.is_a?(Numeric)
- end
- end
-
- class BooleanArgConstraint
- def initialize(ignore)
- end
-
- def ==(value)
- matches?(value)
- end
-
- def matches?(value)
- return true if value.is_a?(TrueClass)
- return true if value.is_a?(FalseClass)
- false
- end
- end
-
- class StringArgConstraint
- def initialize(ignore)
- end
-
- def matches?(value)
- value.is_a?(String)
- end
- end
-
- class DuckTypeArgConstraint
- def initialize(*methods_to_respond_to)
- @methods_to_respond_to = methods_to_respond_to
- end
-
- def matches?(value)
- @methods_to_respond_to.all? { |sym| value.respond_to?(sym) }
- end
-
- def description
- "duck_type"
- end
- end
-
- class ArgumentExpectation
- attr_reader :args
- @@constraint_classes = Hash.new { |hash, key| LiteralArgConstraint}
- @@constraint_classes[:anything] = AnyArgConstraint
- @@constraint_classes[:numeric] = NumericArgConstraint
- @@constraint_classes[:boolean] = BooleanArgConstraint
- @@constraint_classes[:string] = StringArgConstraint
-
- def initialize(args)
- @args = args
- if [:any_args] == args
- @expected_params = nil
- warn_deprecated(:any_args.inspect, "any_args()")
- elsif args.length == 1 && args[0].is_a?(AnyArgsConstraint) then @expected_params = nil
- elsif [:no_args] == args
- @expected_params = []
- warn_deprecated(:no_args.inspect, "no_args()")
- elsif args.length == 1 && args[0].is_a?(NoArgsConstraint) then @expected_params = []
- else @expected_params = process_arg_constraints(args)
- end
- end
-
- def process_arg_constraints(constraints)
- constraints.collect do |constraint|
- convert_constraint(constraint)
- end
- end
-
- def warn_deprecated(deprecated_method, instead)
- STDERR.puts "The #{deprecated_method} constraint is deprecated. Use #{instead} instead."
- end
-
- def convert_constraint(constraint)
- if [:anything, :numeric, :boolean, :string].include?(constraint)
- case constraint
- when :anything
- instead = "anything()"
- when :boolean
- instead = "boolean()"
- when :numeric
- instead = "an_instance_of(Numeric)"
- when :string
- instead = "an_instance_of(String)"
- end
- warn_deprecated(constraint.inspect, instead)
- return @@constraint_classes[constraint].new(constraint)
- end
- return MatcherConstraint.new(constraint) if is_matcher?(constraint)
- return RegexpArgConstraint.new(constraint) if constraint.is_a?(Regexp)
- return LiteralArgConstraint.new(constraint)
- end
-
- def is_matcher?(obj)
- return obj.respond_to?(:matches?) && obj.respond_to?(:description)
- end
-
- def check_args(args)
- return true if @expected_params.nil?
- return true if @expected_params == args
- return constraints_match?(args)
- end
-
- def constraints_match?(args)
- return false if args.length != @expected_params.length
- @expected_params.each_index { |i| return false unless @expected_params[i].matches?(args[i]) }
- return true
- end
-
- end
-
- end
-end
diff --git a/spec/lib/spec/mocks/error_generator.rb b/spec/lib/spec/mocks/error_generator.rb
deleted file mode 100644
index 01d8f720d..000000000
--- a/spec/lib/spec/mocks/error_generator.rb
+++ /dev/null
@@ -1,84 +0,0 @@
-module Spec
- module Mocks
- class ErrorGenerator
- attr_writer :opts
-
- def initialize(target, name)
- @target = target
- @name = name
- end
-
- def opts
- @opts ||= {}
- end
-
- def raise_unexpected_message_error(sym, *args)
- __raise "#{intro} received unexpected message :#{sym}#{arg_message(*args)}"
- end
-
- def raise_unexpected_message_args_error(expectation, *args)
- expected_args = format_args(*expectation.expected_args)
- actual_args = args.empty? ? "(no args)" : format_args(*args)
- __raise "#{intro} expected #{expectation.sym.inspect} with #{expected_args} but received it with #{actual_args}"
- end
-
- def raise_expectation_error(sym, expected_received_count, actual_received_count, *args)
- __raise "#{intro} expected :#{sym}#{arg_message(*args)} #{count_message(expected_received_count)}, but received it #{count_message(actual_received_count)}"
- end
-
- def raise_out_of_order_error(sym)
- __raise "#{intro} received :#{sym} out of order"
- end
-
- def raise_block_failed_error(sym, detail)
- __raise "#{intro} received :#{sym} but passed block failed with: #{detail}"
- end
-
- def raise_missing_block_error(args_to_yield)
- __raise "#{intro} asked to yield |#{arg_list(*args_to_yield)}| but no block was passed"
- end
-
- def raise_wrong_arity_error(args_to_yield, arity)
- __raise "#{intro} yielded |#{arg_list(*args_to_yield)}| to block with arity of #{arity}"
- end
-
- private
- def intro
- @name ? "Mock '#{@name}'" : @target.inspect
- end
-
- def __raise(message)
- message = opts[:message] unless opts[:message].nil?
- Kernel::raise(Spec::Mocks::MockExpectationError, message)
- end
-
- def arg_message(*args)
- " with " + format_args(*args)
- end
-
- def format_args(*args)
- return "(no args)" if args.empty? || args == [:no_args]
- return "(any args)" if args == [:any_args]
- "(" + arg_list(*args) + ")"
- end
-
- def arg_list(*args)
- args.collect do |arg|
- arg.respond_to?(:description) ? arg.description : arg.inspect
- end.join(", ")
- end
-
- def count_message(count)
- return "at least #{pretty_print(count.abs)}" if count < 0
- return pretty_print(count)
- end
-
- def pretty_print(count)
- return "once" if count == 1
- return "twice" if count == 2
- return "#{count} times"
- end
-
- end
- end
-end
diff --git a/spec/lib/spec/mocks/errors.rb b/spec/lib/spec/mocks/errors.rb
deleted file mode 100644
index 68fdfe006..000000000
--- a/spec/lib/spec/mocks/errors.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-module Spec
- module Mocks
- class MockExpectationError < StandardError
- end
-
- class AmbiguousReturnError < StandardError
- end
- end
-end
-
diff --git a/spec/lib/spec/mocks/extensions/object.rb b/spec/lib/spec/mocks/extensions/object.rb
deleted file mode 100644
index 4b7531066..000000000
--- a/spec/lib/spec/mocks/extensions/object.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-class Object
- include Spec::Mocks::Methods
-end
diff --git a/spec/lib/spec/mocks/message_expectation.rb b/spec/lib/spec/mocks/message_expectation.rb
deleted file mode 100644
index 74ade3c58..000000000
--- a/spec/lib/spec/mocks/message_expectation.rb
+++ /dev/null
@@ -1,242 +0,0 @@
-module Spec
- module Mocks
-
- class BaseExpectation
- attr_reader :sym
-
- def initialize(error_generator, expectation_ordering, expected_from, sym, method_block, expected_received_count=1, opts={})
- @error_generator = error_generator
- @error_generator.opts = opts
- @expected_from = expected_from
- @sym = sym
- @method_block = method_block
- @return_block = lambda {}
- @received_count = 0
- @expected_received_count = expected_received_count
- @args_expectation = ArgumentExpectation.new([AnyArgsConstraint.new])
- @consecutive = false
- @exception_to_raise = nil
- @symbol_to_throw = nil
- @order_group = expectation_ordering
- @at_least = nil
- @at_most = nil
- @args_to_yield = nil
- end
-
- def expected_args
- @args_expectation.args
- end
-
- def and_return(*values, &return_block)
- Kernel::raise AmbiguousReturnError unless @method_block.nil?
- if values.size == 0
- value = nil
- elsif values.size == 1
- value = values[0]
- else
- value = values
- @consecutive = true
- @expected_received_count = values.size if @expected_received_count != :any &&
- @expected_received_count < values.size
- end
- @return_block = block_given? ? return_block : lambda { value }
- end
-
- # :call-seq:
- # and_raise()
- # and_raise(Exception) #any exception class
- # and_raise(exception) #any exception object
- #
- # == Warning
- #
- # When you pass an exception class, the MessageExpectation will
- # raise an instance of it, creating it with +new+. If the exception
- # class initializer requires any parameters, you must pass in an
- # instance and not the class.
- def and_raise(exception=Exception)
- @exception_to_raise = exception
- end
-
- def and_throw(symbol)
- @symbol_to_throw = symbol
- end
-
- def and_yield(*args)
- @args_to_yield = args
- end
-
- def matches(sym, args)
- @sym == sym and @args_expectation.check_args(args)
- end
-
- def invoke(args, block)
- @order_group.handle_order_constraint self
-
- begin
- if @exception_to_raise.class == Class
- @exception_instance_to_raise = @exception_to_raise.new
- else
- @exception_instance_to_raise = @exception_to_raise
- end
- Kernel::raise @exception_to_raise unless @exception_to_raise.nil?
- Kernel::throw @symbol_to_throw unless @symbol_to_throw.nil?
-
- if !@method_block.nil?
- return invoke_method_block(args)
- elsif !@args_to_yield.nil?
- return invoke_with_yield(block)
- elsif @consecutive
- return invoke_consecutive_return_block(args, block)
- else
- return invoke_return_block(args, block)
- end
- ensure
- @received_count += 1
- end
- end
-
- protected
-
- def invoke_method_block(args)
- begin
- @method_block.call(*args)
- rescue => detail
- @error_generator.raise_block_failed_error @sym, detail.message
- end
- end
-
- def invoke_with_yield(block)
- if block.nil?
- @error_generator.raise_missing_block_error @args_to_yield
- end
- if block.arity > -1 && @args_to_yield.length != block.arity
- @error_generator.raise_wrong_arity_error @args_to_yield, block.arity
- end
- block.call(*@args_to_yield)
- end
-
- def invoke_consecutive_return_block(args, block)
- args << block unless block.nil?
- value = @return_block.call(*args)
-
- index = [@received_count, value.size-1].min
- value[index]
- end
-
- def invoke_return_block(args, block)
- args << block unless block.nil?
- value = @return_block.call(*args)
-
- value
- end
- end
-
- class MessageExpectation < BaseExpectation
-
- def matches_name_but_not_args(sym, args)
- @sym == sym and not @args_expectation.check_args(args)
- end
-
- def verify_messages_received
- return if @expected_received_count == :any
- return if (@at_least) && (@received_count >= @expected_received_count)
- return if (@at_most) && (@received_count <= @expected_received_count)
- return if @expected_received_count == @received_count
-
- begin
- @error_generator.raise_expectation_error(@sym, @expected_received_count, @received_count, *@args_expectation.args)
- rescue => error
- error.backtrace.insert(0, @expected_from)
- Kernel::raise error
- end
- end
-
- def with(*args, &block)
- @method_block = block if block
- @args_expectation = ArgumentExpectation.new(args)
- self
- end
-
- def exactly(n)
- set_expected_received_count :exactly, n
- self
- end
-
- def at_least(n)
- set_expected_received_count :at_least, n
- self
- end
-
- def at_most(n)
- set_expected_received_count :at_most, n
- self
- end
-
- def times(&block)
- @method_block = block if block
- self
- end
-
- def any_number_of_times(&block)
- @method_block = block if block
- @expected_received_count = :any
- self
- end
-
- def never
- @expected_received_count = 0
- self
- end
-
- def once(&block)
- @method_block = block if block
- @expected_received_count = 1
- self
- end
-
- def twice(&block)
- @method_block = block if block
- @expected_received_count = 2
- self
- end
-
- def ordered(&block)
- @method_block = block if block
- @order_group.register(self)
- @ordered = true
- self
- end
-
- def negative_expectation_for?(sym)
- return false
- end
-
- protected
- def set_expected_received_count(relativity, n)
- @at_least = (relativity == :at_least)
- @at_most = (relativity == :at_most)
- @expected_received_count = 1 if n == :once
- @expected_received_count = 2 if n == :twice
- @expected_received_count = n if n.kind_of? Numeric
- end
-
- end
-
- class NegativeMessageExpectation < MessageExpectation
- def initialize(message, expectation_ordering, expected_from, sym, method_block)
- super(message, expectation_ordering, expected_from, sym, method_block, 0)
- end
-
- def negative_expectation_for?(sym)
- return @sym == sym
- end
- end
-
- class MethodStub < BaseExpectation
- def initialize(message, expectation_ordering, expected_from, sym, method_block)
- super(message, expectation_ordering, expected_from, sym, method_block, 0)
- @expected_received_count = :any
- end
- end
- end
-end
diff --git a/spec/lib/spec/mocks/methods.rb b/spec/lib/spec/mocks/methods.rb
deleted file mode 100644
index 3d898cf31..000000000
--- a/spec/lib/spec/mocks/methods.rb
+++ /dev/null
@@ -1,39 +0,0 @@
-module Spec
- module Mocks
- module Methods
- def should_receive(sym, opts={}, &block)
- __mock_proxy.add_message_expectation(opts[:expected_from] || caller(1)[0], sym.to_sym, opts, &block)
- end
-
- def should_not_receive(sym, &block)
- __mock_proxy.add_negative_message_expectation(caller(1)[0], sym.to_sym, &block)
- end
-
- def stub!(sym)
- __mock_proxy.add_stub(caller(1)[0], sym.to_sym)
- end
-
- def received_message?(sym, *args, &block) #:nodoc:
- __mock_proxy.received_message?(sym.to_sym, *args, &block)
- end
-
- def rspec_verify #:nodoc:
- __mock_proxy.verify
- end
-
- def rspec_reset #:nodoc:
- __mock_proxy.reset
- end
-
- private
-
- def __mock_proxy
- if Mock === self
- @mock_proxy ||= Proxy.new(self, @name, @options)
- else
- @mock_proxy ||= Proxy.new(self, self.class.name)
- end
- end
- end
- end
-end
diff --git a/spec/lib/spec/mocks/mock.rb b/spec/lib/spec/mocks/mock.rb
deleted file mode 100644
index aa380e0af..000000000
--- a/spec/lib/spec/mocks/mock.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-module Spec
- module Mocks
- class Mock
- include Methods
-
- # Creates a new mock with a +name+ (that will be used in error messages only)
- # == Options:
- # * <tt>:null_object</tt> - if true, the mock object acts as a forgiving null object allowing any message to be sent to it.
- def initialize(name, options={})
- @name = name
- @options = options
- end
-
- def method_missing(sym, *args, &block)
- __mock_proxy.instance_eval {@messages_received << [sym, args, block]}
- begin
- return self if __mock_proxy.null_object?
- super(sym, *args, &block)
- rescue NoMethodError
- __mock_proxy.raise_unexpected_message_error sym, *args
- end
- end
-
- def inspect
- "#<#{self.class}:#{sprintf '0x%x', self.object_id} @name=#{@name.inspect}>"
- end
- end
- end
-end
diff --git a/spec/lib/spec/mocks/order_group.rb b/spec/lib/spec/mocks/order_group.rb
deleted file mode 100644
index 9983207eb..000000000
--- a/spec/lib/spec/mocks/order_group.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-module Spec
- module Mocks
- class OrderGroup
- def initialize error_generator
- @error_generator = error_generator
- @ordering = Array.new
- end
-
- def register(expectation)
- @ordering << expectation
- end
-
- def ready_for?(expectation)
- return @ordering.first == expectation
- end
-
- def consume
- @ordering.shift
- end
-
- def handle_order_constraint expectation
- return unless @ordering.include? expectation
- return consume if ready_for?(expectation)
- @error_generator.raise_out_of_order_error expectation.sym
- end
-
- end
- end
-end
diff --git a/spec/lib/spec/mocks/proxy.rb b/spec/lib/spec/mocks/proxy.rb
deleted file mode 100644
index 6c79d1068..000000000
--- a/spec/lib/spec/mocks/proxy.rb
+++ /dev/null
@@ -1,167 +0,0 @@
-module Spec
- module Mocks
- class Proxy
- DEFAULT_OPTIONS = {
- :null_object => false,
- }
-
- def initialize(target, name, options={})
- @target = target
- @name = name
- @error_generator = ErrorGenerator.new target, name
- @expectation_ordering = OrderGroup.new @error_generator
- @expectations = []
- @messages_received = []
- @stubs = []
- @proxied_methods = []
- @options = options ? DEFAULT_OPTIONS.dup.merge(options) : DEFAULT_OPTIONS
- end
-
- def null_object?
- @options[:null_object]
- end
-
- def add_message_expectation(expected_from, sym, opts={}, &block)
- __add sym, block
- @expectations << MessageExpectation.new(@error_generator, @expectation_ordering, expected_from, sym, block_given? ? block : nil, 1, opts)
- @expectations.last
- end
-
- def add_negative_message_expectation(expected_from, sym, &block)
- __add sym, block
- @expectations << NegativeMessageExpectation.new(@error_generator, @expectation_ordering, expected_from, sym, block_given? ? block : nil)
- @expectations.last
- end
-
- def add_stub(expected_from, sym)
- __add sym, nil
- @stubs.unshift MethodStub.new(@error_generator, @expectation_ordering, expected_from, sym, nil)
- @stubs.first
- end
-
- def verify #:nodoc:
- begin
- verify_expectations
- ensure
- reset
- end
- end
-
- def reset
- clear_expectations
- clear_stubs
- reset_proxied_methods
- clear_proxied_methods
- end
-
- def received_message?(sym, *args, &block)
- return true if @messages_received.find {|array| array == [sym, args, block]}
- return false
- end
-
- def has_negative_expectation?(sym)
- @expectations.detect {|expectation| expectation.negative_expectation_for?(sym)}
- end
-
- def message_received(sym, *args, &block)
- if expectation = find_matching_expectation(sym, *args)
- expectation.invoke(args, block)
- elsif stub = find_matching_method_stub(sym)
- stub.invoke([], block)
- elsif expectation = find_almost_matching_expectation(sym, *args)
- raise_unexpected_message_args_error(expectation, *args) unless has_negative_expectation?(sym) unless null_object?
- else
- @target.send :method_missing, sym, *args, &block
- end
- end
-
- def raise_unexpected_message_args_error(expectation, *args)
- @error_generator.raise_unexpected_message_args_error expectation, *args
- end
-
- def raise_unexpected_message_error(sym, *args)
- @error_generator.raise_unexpected_message_error sym, *args
- end
-
- private
-
- def __add(sym, block)
- $rspec_mocks.add(@target) unless $rspec_mocks.nil?
- define_expected_method(sym)
- end
-
- def define_expected_method(sym)
- if target_responds_to?(sym) && !@proxied_methods.include?(sym)
- metaclass.__send__(:alias_method, munge(sym), sym) if metaclass.instance_methods.include?(sym.to_s)
- @proxied_methods << sym
- end
-
- metaclass_eval(<<-EOF, __FILE__, __LINE__)
- def #{sym}(*args, &block)
- __mock_proxy.message_received :#{sym}, *args, &block
- end
- EOF
- end
-
- def target_responds_to?(sym)
- return @target.send(munge(:respond_to?),sym) if @already_proxied_respond_to
- return @already_proxied_respond_to = true if sym == :respond_to?
- return @target.respond_to?(sym)
- end
-
- def munge(sym)
- "proxied_by_rspec__#{sym.to_s}".to_sym
- end
-
- def clear_expectations
- @expectations.clear
- end
-
- def clear_stubs
- @stubs.clear
- end
-
- def clear_proxied_methods
- @proxied_methods.clear
- end
-
- def metaclass_eval(str, filename, lineno)
- metaclass.class_eval(str, filename, lineno)
- end
-
- def metaclass
- (class << @target; self; end)
- end
-
- def verify_expectations
- @expectations.each do |expectation|
- expectation.verify_messages_received
- end
- end
-
- def reset_proxied_methods
- @proxied_methods.each do |sym|
- if metaclass.instance_methods.include?(munge(sym).to_s)
- metaclass.__send__(:alias_method, sym, munge(sym))
- metaclass.__send__(:undef_method, munge(sym))
- else
- metaclass.__send__(:undef_method, sym)
- end
- end
- end
-
- def find_matching_expectation(sym, *args)
- @expectations.find {|expectation| expectation.matches(sym, args)}
- end
-
- def find_almost_matching_expectation(sym, *args)
- @expectations.find {|expectation| expectation.matches_name_but_not_args(sym, args)}
- end
-
- def find_matching_method_stub(sym)
- @stubs.find {|stub| stub.matches(sym, [])}
- end
-
- end
- end
-end
diff --git a/spec/lib/spec/mocks/space.rb b/spec/lib/spec/mocks/space.rb
deleted file mode 100644
index e04bc5ccb..000000000
--- a/spec/lib/spec/mocks/space.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-module Spec
- module Mocks
- class Space
- def add(obj)
- mocks << obj unless mocks.include?(obj)
- end
-
- def verify_all
- mocks.each do |mock|
- mock.rspec_verify
- end
- end
-
- def reset_all
- mocks.each do |mock|
- mock.rspec_reset
- end
- mocks.clear
- end
-
- private
-
- def mocks
- @mocks ||= []
- end
- end
- end
-end
diff --git a/spec/lib/spec/mocks/spec_methods.rb b/spec/lib/spec/mocks/spec_methods.rb
deleted file mode 100644
index fd67fd210..000000000
--- a/spec/lib/spec/mocks/spec_methods.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-module Spec
- module Mocks
- module SpecMethods
- include Spec::Mocks::ArgumentConstraintMatchers
-
- # Shortcut for creating an instance of Spec::Mocks::Mock.
- def mock(name, options={})
- Spec::Mocks::Mock.new(name, options)
- end
-
- # Shortcut for creating an instance of Spec::Mocks::Mock with
- # predefined method stubs.
- #
- # == Examples
- #
- # stub_thing = stub("thing", :a => "A")
- # stub_thing.a == "A" => true
- #
- # stub_person = stub("thing", :name => "Joe", :email => "joe@domain.com")
- # stub_person.name => "Joe"
- # stub_person.email => "joe@domain.com"
- def stub(name, stubs={})
- object_stub = mock(name)
- stubs.each { |key, value| object_stub.stub!(key).and_return(value) }
- object_stub
- end
-
- end
- end
-end
diff --git a/spec/lib/spec/rake/spectask.rb b/spec/lib/spec/rake/spectask.rb
deleted file mode 100644
index f8c6809a9..000000000
--- a/spec/lib/spec/rake/spectask.rb
+++ /dev/null
@@ -1,217 +0,0 @@
-#!/usr/bin/env ruby
-
-# Define a task library for running RSpec contexts.
-
-require 'rake'
-require 'rake/tasklib'
-
-module Spec
- module Rake
-
- # A Rake task that runs a set of RSpec contexts.
- #
- # Example:
- #
- # Spec::Rake::SpecTask.new do |t|
- # t.warning = true
- # t.rcov = true
- # end
- #
- # This will create a task that can be run with:
- #
- # rake spec
- #
- # If rake is invoked with a "SPEC=filename" command line option,
- # then the list of spec files will be overridden to include only the
- # filename specified on the command line. This provides an easy way
- # to run just one spec.
- #
- # If rake is invoked with a "SPEC_OPTS=options" command line option,
- # then the given options will override the value of the +spec_opts+
- # attribute.
- #
- # If rake is invoked with a "RCOV_OPTS=options" command line option,
- # then the given options will override the value of the +rcov_opts+
- # attribute.
- #
- # Examples:
- #
- # rake spec # run specs normally
- # rake spec SPEC=just_one_file.rb # run just one spec file.
- # rake spec SPEC_OPTS="--diff" # enable diffing
- # rake spec RCOV_OPTS="--aggregate myfile.txt" # see rcov --help for details
- #
- # Each attribute of this task may be a proc. This allows for lazy evaluation,
- # which is sometimes handy if you want to defer the evaluation of an attribute value
- # until the task is run (as opposed to when it is defined).
- class SpecTask < ::Rake::TaskLib
- class << self
- def attr_accessor(*names)
- super(*names)
- names.each do |name|
- module_eval "def #{name}() evaluate(@#{name}) end" # Allows use of procs
- end
- end
- end
-
- # Name of spec task. (default is :spec)
- attr_accessor :name
-
- # Array of directories to be added to $LOAD_PATH before running the
- # specs. Defaults to ['<the absolute path to RSpec's lib directory>']
- attr_accessor :libs
-
- # If true, requests that the specs be run with the warning flag set.
- # E.g. warning=true implies "ruby -w" used to run the specs. Defaults to false.
- attr_accessor :warning
-
- # Glob pattern to match spec files. (default is 'spec/**/*_spec.rb')
- # Setting the SPEC environment variable overrides this.
- attr_accessor :pattern
-
- # Array of commandline options to pass to RSpec. Defaults to [].
- # Setting the SPEC_OPTS environment variable overrides this.
- attr_accessor :spec_opts
-
- # Whether or not to use RCov (default is false)
- # See http://eigenclass.org/hiki.rb?rcov
- attr_accessor :rcov
-
- # Array of commandline options to pass to RCov. Defaults to ['--exclude', 'lib\/spec,bin\/spec'].
- # Ignored if rcov=false
- # Setting the RCOV_OPTS environment variable overrides this.
- attr_accessor :rcov_opts
-
- # Directory where the RCov report is written. Defaults to "coverage"
- # Ignored if rcov=false
- attr_accessor :rcov_dir
-
- # Array of commandline options to pass to ruby. Defaults to [].
- attr_accessor :ruby_opts
-
- # Whether or not to fail Rake when an error occurs (typically when specs fail).
- # Defaults to true.
- attr_accessor :fail_on_error
-
- # A message to print to stderr when there are failures.
- attr_accessor :failure_message
-
- # Where RSpec's output is written. Defaults to STDOUT.
- # DEPRECATED. Use --format FORMAT:WHERE in spec_opts.
- attr_accessor :out
-
- # Explicitly define the list of spec files to be included in a
- # spec. +spec_files+ is expected to be an array of file names (a
- # FileList is acceptable). If both +pattern+ and +spec_files+ are
- # used, then the list of spec files is the union of the two.
- # Setting the SPEC environment variable overrides this.
- attr_accessor :spec_files
-
- # Defines a new task, using the name +name+.
- def initialize(name=:spec)
- @name = name
- @libs = [File.expand_path(File.dirname(__FILE__) + '/../../../lib')]
- @pattern = nil
- @spec_files = nil
- @spec_opts = []
- @warning = false
- @ruby_opts = []
- @fail_on_error = true
- @rcov = false
- @rcov_opts = ['--exclude', 'lib\/spec,bin\/spec,config\/boot.rb']
- @rcov_dir = "coverage"
-
- yield self if block_given?
- @pattern = 'spec/**/*_spec.rb' if pattern.nil? && spec_files.nil?
- define
- end
-
- def define # :nodoc:
- spec_script = File.expand_path(File.dirname(__FILE__) + '/../../../bin/spec')
-
- lib_path = libs.join(File::PATH_SEPARATOR)
- actual_name = Hash === name ? name.keys.first : name
- unless ::Rake.application.last_comment
- desc "Run specs" + (rcov ? " using RCov" : "")
- end
- task name do
- RakeFileUtils.verbose(verbose) do
- unless spec_file_list.empty?
- # ruby [ruby_opts] -Ilib -S rcov [rcov_opts] bin/spec -- examples [spec_opts]
- # or
- # ruby [ruby_opts] -Ilib bin/spec examples [spec_opts]
- cmd = "ruby "
-
- rb_opts = ruby_opts.clone
- rb_opts << "-I\"#{lib_path}\""
- rb_opts << "-S rcov" if rcov
- rb_opts << "-w" if warning
- cmd << rb_opts.join(" ")
- cmd << " "
- cmd << rcov_option_list
- cmd << %[ -o "#{rcov_dir}" ] if rcov
- cmd << %Q|"#{spec_script}"|
- cmd << " "
- cmd << "-- " if rcov
- cmd << spec_file_list.collect { |fn| %["#{fn}"] }.join(' ')
- cmd << " "
- cmd << spec_option_list
- if out
- cmd << " "
- cmd << %Q| > "#{out}"|
- STDERR.puts "The Spec::Rake::SpecTask#out attribute is DEPRECATED and will be removed in a future version. Use --format FORMAT:WHERE instead."
- end
- unless system(cmd)
- STDERR.puts failure_message if failure_message
- raise("Command #{cmd} failed") if fail_on_error
- end
- end
- end
- end
-
- if rcov
- desc "Remove rcov products for #{actual_name}"
- task paste("clobber_", actual_name) do
- rm_r rcov_dir rescue nil
- end
-
- clobber_task = paste("clobber_", actual_name)
- task :clobber => [clobber_task]
-
- task actual_name => clobber_task
- end
- self
- end
-
- def rcov_option_list # :nodoc:
- return "" unless rcov
- ENV['RCOV_OPTS'] || rcov_opts.join(" ") || ""
- end
-
- def spec_option_list # :nodoc:
- STDERR.puts "RSPECOPTS is DEPRECATED and will be removed in a future version. Use SPEC_OPTS instead." if ENV['RSPECOPTS']
- ENV['SPEC_OPTS'] || ENV['RSPECOPTS'] || spec_opts.join(" ") || ""
- end
-
- def evaluate(o) # :nodoc:
- case o
- when Proc then o.call
- else o
- end
- end
-
- def spec_file_list # :nodoc:
- if ENV['SPEC']
- FileList[ ENV['SPEC'] ]
- else
- result = []
- result += spec_files.to_a if spec_files
- result += FileList[ pattern ].to_a if pattern
- FileList[result]
- end
- end
-
- end
- end
-end
-
diff --git a/spec/lib/spec/rake/verify_rcov.rb b/spec/lib/spec/rake/verify_rcov.rb
deleted file mode 100644
index 9715744e9..000000000
--- a/spec/lib/spec/rake/verify_rcov.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-module RCov
- # A task that can verify that the RCov coverage doesn't
- # drop below a certain threshold. It should be run after
- # running Spec::Rake::SpecTask.
- class VerifyTask < Rake::TaskLib
- # Name of the task. Defaults to :verify_rcov
- attr_accessor :name
-
- # Path to the index.html file generated by RCov, which
- # is the file containing the total coverage.
- # Defaults to 'coverage/index.html'
- attr_accessor :index_html
-
- # Whether or not to output details. Defaults to true.
- attr_accessor :verbose
-
- # The threshold value (in percent) for coverage. If the
- # actual coverage is not equal to this value, the task will raise an
- # exception.
- attr_accessor :threshold
-
- # Require the threshold value be met exactly. This is the default.
- attr_accessor :require_exact_threshold
-
- def initialize(name=:verify_rcov)
- @name = name
- @index_html = 'coverage/index.html'
- @verbose = true
- @require_exact_threshold = true
- yield self if block_given?
- raise "Threshold must be set" if @threshold.nil?
- define
- end
-
- def define
- desc "Verify that rcov coverage is at least #{threshold}%"
- task @name do
- total_coverage = nil
-
- File.open(index_html).each_line do |line|
- if line =~ /<tt.*>(\d+\.\d+)%<\/tt>&nbsp;<\/td>/
- total_coverage = eval($1)
- break
- end
- end
- puts "Coverage: #{total_coverage}% (threshold: #{threshold}%)" if verbose
- raise "Coverage must be at least #{threshold}% but was #{total_coverage}%" if total_coverage < threshold
- raise "Coverage has increased above the threshold of #{threshold}% to #{total_coverage}%. You should update your threshold value." if (total_coverage > threshold) and require_exact_threshold
- end
- end
- end
-end
diff --git a/spec/lib/spec/runner.rb b/spec/lib/spec/runner.rb
deleted file mode 100644
index 9d801adc3..000000000
--- a/spec/lib/spec/runner.rb
+++ /dev/null
@@ -1,165 +0,0 @@
-require 'spec/runner/formatter'
-require 'spec/runner/behaviour_runner'
-require 'spec/runner/options'
-require 'spec/runner/option_parser'
-require 'spec/runner/command_line'
-require 'spec/runner/drb_command_line'
-require 'spec/runner/backtrace_tweaker'
-require 'spec/runner/reporter'
-require 'spec/runner/extensions/object'
-require 'spec/runner/extensions/kernel'
-require 'spec/runner/spec_parser'
-
-module Spec
- # == Behaviours and Examples
- #
- # Rather than expressing examples in classes, RSpec uses a custom domain specific language to
- # describe Behaviours and Examples of those behaviours.
- #
- # A Behaviour is the equivalent of a fixture in xUnit-speak. It is a metaphor for the context
- # in which you will run your executable example - a set of known objects in a known starting state.
- # We begin be describing
- #
- # describe Account do
- #
- # before do
- # @account = Account.new
- # end
- #
- # it "should have a balance of $0" do
- # @account.balance.should == Money.new(0, :dollars)
- # end
- #
- # end
- #
- # We use the before block to set up the Behaviour (given), and then the #it method to
- # hold the example code that expresses the event (when) and the expected outcome (then).
- #
- # == Helper Methods
- #
- # A primary goal of RSpec is to keep the examples clear. We therefore prefer
- # less indirection than you might see in xUnit examples and in well factored, DRY production code. We feel
- # that duplication is OK if removing it makes it harder to understand an example without
- # having to look elsewhere to understand its context.
- #
- # That said, RSpec does support some level of encapsulating common code in helper
- # methods that can exist within a context or within an included module.
- #
- # == Setup and Teardown
- #
- # You can use before and after within a Behaviour. Both methods take an optional
- # scope argument so you can run the block before :each example or before :all examples
- #
- # describe "..." do
- # before :all do
- # ...
- # end
- #
- # before :each do
- # ...
- # end
- #
- # it "should do something" do
- # ...
- # end
- #
- # it "should do something else" do
- # ...
- # end
- #
- # after :each do
- # ...
- # end
- #
- # after :all do
- # ...
- # end
- #
- # end
- #
- # The <tt>before :each</tt> block will run before each of the examples, once for each example. Likewise,
- # the <tt>after :each</tt> block will run after each of the examples.
- #
- # It is also possible to specify a <tt>before :all</tt> and <tt>after :all</tt>
- # block that will run only once for each behaviour, respectively before the first <code>before :each</code>
- # and after the last <code>after :each</code>. The use of these is generally discouraged, because it
- # introduces dependencies between the examples. Still, it might prove useful for very expensive operations
- # if you know what you are doing.
- #
- # == Local helper methods
- #
- # You can include local helper methods by simply expressing them within a context:
- #
- # describe "..." do
- #
- # it "..." do
- # helper_method
- # end
- #
- # def helper_method
- # ...
- # end
- #
- # end
- #
- # == Included helper methods
- #
- # You can include helper methods in multiple contexts by expressing them within
- # a module, and then including that module in your context:
- #
- # module AccountExampleHelperMethods
- # def helper_method
- # ...
- # end
- # end
- #
- # describe "A new account" do
- # include AccountExampleHelperMethods
- # before do
- # @account = Account.new
- # end
- #
- # it "should have a balance of $0" do
- # helper_method
- # @account.balance.should eql(Money.new(0, :dollars))
- # end
- # end
- #
- # == Shared behaviour
- #
- # You can define a shared behaviour, that may be used on other behaviours
- #
- # describe "All Editions", :shared => true do
- # it "all editions behaviour" ...
- # end
- #
- # describe SmallEdition do
- # it_should_behave_like "All Editions"
- #
- # it "should do small edition stuff" do
- # ...
- # end
- # end
- module Runner
- class << self
- def configuration # :nodoc:
- @configuration ||= Spec::DSL::Configuration.new
- end
-
- # Use this to configure various configurable aspects of
- # RSpec:
- #
- # Spec::Runner.configure do |configuration|
- # # Configure RSpec here
- # end
- #
- # The yielded <tt>configuration</tt> object is a
- # Spec::DSL::Configuration instance. See its RDoc
- # for details about what you can do with it.
- #
- def configure
- yield configuration if @configuration.nil?
- end
- end
- end
-end
diff --git a/spec/lib/spec/runner/backtrace_tweaker.rb b/spec/lib/spec/runner/backtrace_tweaker.rb
deleted file mode 100644
index aacc2c8b8..000000000
--- a/spec/lib/spec/runner/backtrace_tweaker.rb
+++ /dev/null
@@ -1,57 +0,0 @@
-module Spec
- module Runner
- class BacktraceTweaker
- def clean_up_double_slashes(line)
- line.gsub!('//','/')
- end
- end
-
- class NoisyBacktraceTweaker < BacktraceTweaker
- def tweak_backtrace(error, spec_name)
- return if error.backtrace.nil?
- error.backtrace.each do |line|
- clean_up_double_slashes(line)
- end
- end
- end
-
- # Tweaks raised Exceptions to mask noisy (unneeded) parts of the backtrace
- class QuietBacktraceTweaker < BacktraceTweaker
- unless defined?(IGNORE_PATTERNS)
- root_dir = File.expand_path(File.join(__FILE__, '..', '..', '..', '..'))
- spec_files = Dir["#{root_dir}/lib/spec/*"].map do |path|
- subpath = path[root_dir.length..-1]
- /#{subpath}/
- end
- IGNORE_PATTERNS = spec_files + [
- /\/lib\/ruby\//,
- /bin\/spec:/,
- /bin\/rcov:/,
- /lib\/rspec_on_rails/,
- /vendor\/rails/,
- # TextMate's Ruby and RSpec plugins
- /Ruby\.tmbundle\/Support\/tmruby.rb:/,
- /RSpec\.tmbundle\/Support\/lib/,
- /temp_textmate\./,
- /mock_frameworks\/rspec/,
- /spec_server/
- ]
- end
-
- def tweak_backtrace(error, spec_name)
- return if error.backtrace.nil?
- error.backtrace.collect! do |line|
- clean_up_double_slashes(line)
- IGNORE_PATTERNS.each do |ignore|
- if line =~ ignore
- line = nil
- break
- end
- end
- line
- end
- error.backtrace.compact!
- end
- end
- end
-end
diff --git a/spec/lib/spec/runner/behaviour_runner.rb b/spec/lib/spec/runner/behaviour_runner.rb
deleted file mode 100644
index 1ac891f3c..000000000
--- a/spec/lib/spec/runner/behaviour_runner.rb
+++ /dev/null
@@ -1,123 +0,0 @@
-module Spec
- module Runner
- class BehaviourRunner
-
- def initialize(options, arg=nil)
- @behaviours = []
- @options = options
- end
-
- def add_behaviour(behaviour)
- if !specified_examples.nil? && !specified_examples.empty?
- behaviour.retain_examples_matching!(specified_examples)
- end
- @behaviours << behaviour if behaviour.number_of_examples != 0 && !behaviour.shared?
- end
-
- # Runs all behaviours and returns the number of failures.
- def run(paths, exit_when_done)
- prepare!(paths)
- begin
- run_behaviours
- rescue Interrupt
- ensure
- report_end
- end
- failure_count = report_dump
-
- heckle if(failure_count == 0 && !@options.heckle_runner.nil?)
-
- if(exit_when_done)
- exit_code = (failure_count == 0) ? 0 : 1
- exit(exit_code)
- end
- failure_count
- end
-
- def report_end
- @options.reporter.end
- end
-
- def report_dump
- @options.reporter.dump
- end
-
- def prepare!(paths)
- unless paths.nil? # It's nil when running single specs with ruby
- paths = find_paths(paths)
- sorted_paths = sort_paths(paths)
- load_specs(sorted_paths) # This will populate @behaviours via callbacks to add_behaviour
- end
- @options.reporter.start(number_of_examples)
- @behaviours.reverse! if @options.reverse
- set_sequence_numbers
- end
-
- def run_behaviours
- @behaviours.each do |behaviour|
- behaviour.run(@options.reporter, @options.dry_run, @options.reverse, @options.timeout)
- end
- end
-
- def number_of_examples
- @behaviours.inject(0) {|sum, behaviour| sum + behaviour.number_of_examples}
- end
-
- FILE_SORTERS = {
- 'mtime' => lambda {|file_a, file_b| File.mtime(file_b) <=> File.mtime(file_a)}
- }
-
- def sorter(paths)
- FILE_SORTERS[@options.loadby]
- end
-
- def sort_paths(paths)
- sorter = sorter(paths)
- paths = paths.sort(&sorter) unless sorter.nil?
- paths
- end
-
- private
-
- # Sets the #number on each Example
- def set_sequence_numbers
- number = 0
- @behaviours.each do |behaviour|
- number = behaviour.set_sequence_numbers(number, @options.reverse)
- end
- end
-
- def find_paths(paths)
- result = []
- paths.each do |path|
- if File.directory?(path)
- result += Dir["#{path}/**/*.rb"]
- elsif File.file?(path)
- result << path
- else
- raise "File or directory not found: #{path}"
- end
- end
- result
- end
-
- def load_specs(paths)
- paths.each do |path|
- load path
- end
- end
-
- def specified_examples
- @options.examples
- end
-
- def heckle
- heckle_runner = @options.heckle_runner
- @options.heckle_runner = nil
- behaviour_runner = self.class.new(@options)
- behaviour_runner.instance_variable_set(:@behaviours, @behaviours)
- heckle_runner.heckle_with(behaviour_runner)
- end
- end
- end
-end
diff --git a/spec/lib/spec/runner/command_line.rb b/spec/lib/spec/runner/command_line.rb
deleted file mode 100644
index 0d70337e1..000000000
--- a/spec/lib/spec/runner/command_line.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-require 'spec/runner/option_parser'
-
-module Spec
- module Runner
- # Facade to run specs without having to fork a new ruby process (using `spec ...`)
- class CommandLine
- # Runs specs. +argv+ is the commandline args as per the spec commandline API, +err+
- # and +out+ are the streams output will be written to. +exit+ tells whether or
- # not a system exit should be called after the specs are run and
- # +warn_if_no_files+ tells whether or not a warning (the help message)
- # should be printed to +err+ in case no files are specified.
- def self.run(argv, err, out, exit=true, warn_if_no_files=true)
- old_behaviour_runner = defined?($behaviour_runner) ? $behaviour_runner : nil
- $behaviour_runner = OptionParser.new.create_behaviour_runner(argv, err, out, warn_if_no_files)
- return if $behaviour_runner.nil? # This is the case if we use --drb
-
- $behaviour_runner.run(argv, exit)
- $behaviour_runner = old_behaviour_runner
- end
- end
- end
-end
diff --git a/spec/lib/spec/runner/drb_command_line.rb b/spec/lib/spec/runner/drb_command_line.rb
deleted file mode 100644
index 7e745fb71..000000000
--- a/spec/lib/spec/runner/drb_command_line.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-require "drb/drb"
-
-module Spec
- module Runner
- # Facade to run specs by connecting to a DRB server
- class DrbCommandLine
- # Runs specs on a DRB server. Note that this API is similar to that of
- # CommandLine - making it possible for clients to use both interchangeably.
- def self.run(argv, stderr, stdout, exit=true, warn_if_no_files=true)
- begin
- DRb.start_service
- spec_server = DRbObject.new_with_uri("druby://localhost:8989")
- spec_server.run(argv, stderr, stdout)
- rescue DRb::DRbConnError
- stderr.puts "No server is running"
- exit 1 if exit
- end
- end
- end
- end
-end
diff --git a/spec/lib/spec/runner/extensions/kernel.rb b/spec/lib/spec/runner/extensions/kernel.rb
deleted file mode 100644
index 75f2c335e..000000000
--- a/spec/lib/spec/runner/extensions/kernel.rb
+++ /dev/null
@@ -1,50 +0,0 @@
-module Kernel
- # Creates and registers an instance of a Spec::DSL::Behaviour (or a subclass).
- # The instantiated behaviour class depends on the directory of the file
- # calling this method. For example, Spec::Rails will use different
- # classes for specs living in <tt>spec/models</tt>, <tt>spec/helpers</tt>,
- # <tt>spec/views</tt> and <tt>spec/controllers</tt>.
- #
- # It is also possible to override autodiscovery of the behaviour class
- # with an options Hash as the last argument:
- #
- # describe "name", :behaviour_type => :something_special do ...
- #
- # The reason for using different behaviour classes is to have
- # different matcher methods available from within the <tt>describe</tt>
- # block.
- #
- # See Spec::DSL::BehaviourFactory#add_behaviour_class for details about
- # how to register special Spec::DSL::Behaviour implementations.
- #
- def describe(*args, &block)
- raise ArgumentError if args.empty?
- args << {} unless Hash === args.last
- args.last[:spec_path] = caller(0)[1]
- register_behaviour(Spec::DSL::BehaviourFactory.create(*args, &block))
- end
- alias :context :describe
-
- def respond_to(*names)
- Spec::Matchers::RespondTo.new(*names)
- end
-
-private
-
- def register_behaviour(behaviour)
- if behaviour.shared?
- Spec::DSL::Behaviour.add_shared_behaviour(behaviour)
- else
- behaviour_runner.add_behaviour(behaviour)
- end
- end
-
- def behaviour_runner
- # TODO: Figure out a better way to get this considered "covered" and keep this statement on multiple lines
- unless $behaviour_runner; \
- $behaviour_runner = ::Spec::Runner::OptionParser.new.create_behaviour_runner(ARGV.dup, STDERR, STDOUT, false); \
- at_exit { $behaviour_runner.run(nil, false) }; \
- end
- $behaviour_runner
- end
-end
diff --git a/spec/lib/spec/runner/extensions/object.rb b/spec/lib/spec/runner/extensions/object.rb
deleted file mode 100644
index 49745352f..000000000
--- a/spec/lib/spec/runner/extensions/object.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-# The following copyright applies to Object#copy_instance_variables_from,
-# which we borrowed from active_support.
-#
-# Copyright (c) 2004 David Heinemeier Hansson
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-class Object
- # From active_support
- def copy_instance_variables_from(object, exclude = []) # :nodoc:
- exclude += object.protected_instance_variables if object.respond_to? :protected_instance_variables
-
- instance_variables = object.instance_variables - exclude.map { |name| name.to_s }
- instance_variables.each { |name| instance_variable_set(name, object.instance_variable_get(name)) }
- end
-end
diff --git a/spec/lib/spec/runner/formatter.rb b/spec/lib/spec/runner/formatter.rb
deleted file mode 100644
index 17512d958..000000000
--- a/spec/lib/spec/runner/formatter.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-require 'spec/runner/formatter/base_formatter'
-require 'spec/runner/formatter/base_text_formatter'
-require 'spec/runner/formatter/progress_bar_formatter'
-require 'spec/runner/formatter/rdoc_formatter'
-require 'spec/runner/formatter/specdoc_formatter'
-require 'spec/runner/formatter/html_formatter'
-require 'spec/runner/formatter/failing_examples_formatter'
-require 'spec/runner/formatter/failing_behaviours_formatter'
-require 'spec/runner/formatter/snippet_extractor'
diff --git a/spec/lib/spec/runner/formatter/base_formatter.rb b/spec/lib/spec/runner/formatter/base_formatter.rb
deleted file mode 100644
index 7cc43ef0e..000000000
--- a/spec/lib/spec/runner/formatter/base_formatter.rb
+++ /dev/null
@@ -1,76 +0,0 @@
-module Spec
- module Runner
- module Formatter
- # Baseclass for formatters that implements all required methods as no-ops.
- class BaseFormatter
- def initialize(where)
- @where = where
- end
-
- # This method is invoked before any examples are run, right after
- # they have all been collected. This can be useful for special
- # formatters that need to provide progress on feedback (graphical ones)
- #
- # This method will only be invoked once, and the next one to be invoked
- # is #add_behaviour
- def start(example_count)
- end
-
- # This method is invoked at the beginning of the execution of each behaviour.
- # +name+ is the name of the behaviour and +first+ is true if it is the
- # first behaviour - otherwise it's false.
- #
- # The next method to be invoked after this is #example_failed or #example_finished
- def add_behaviour(name)
- end
-
- # This method is invoked when an +example+ starts.
- def example_started(example)
- end
-
- # This method is invoked when an +example+ passes.
- def example_passed(example)
- end
-
- # This method is invoked when an +example+ fails, i.e. an exception occurred
- # inside it (such as a failed should or other exception). +counter+ is the
- # sequence number of the failure (starting at 1) and +failure+ is the associated
- # Failure object.
- def example_failed(example, counter, failure)
- end
-
- # This method is invoked when an example is not yet implemented (i.e. has not
- # been provided a block), or when an ExamplePendingError is raised.
- # +name+ is the name of the example.
- # +message+ is the message from the ExamplePendingError, if it exists, or the
- # default value of "Not Yet Implemented"
- def example_pending(behaviour_name, example_name, message)
- end
-
- # This method is invoked after all of the examples have executed. The next method
- # to be invoked after this one is #dump_failure (once for each failed example),
- def start_dump
- end
-
- # Dumps detailed information about an example failure.
- # This method is invoked for each failed example after all examples have run. +counter+ is the sequence number
- # of the associated example. +failure+ is a Failure object, which contains detailed
- # information about the failure.
- def dump_failure(counter, failure)
- end
-
- # This method is invoked after the dumping of examples and failures.
- def dump_summary(duration, example_count, failure_count, pending_count)
- end
-
- # This gets invoked after the summary if option is set to do so.
- def dump_pending
- end
-
- # This method is invoked at the very end. Allows the formatter to clean up, like closing open streams.
- def close
- end
- end
- end
- end
-end
diff --git a/spec/lib/spec/runner/formatter/base_text_formatter.rb b/spec/lib/spec/runner/formatter/base_text_formatter.rb
deleted file mode 100644
index c3cf01b76..000000000
--- a/spec/lib/spec/runner/formatter/base_text_formatter.rb
+++ /dev/null
@@ -1,130 +0,0 @@
-module Spec
- module Runner
- module Formatter
- # Baseclass for text-based formatters. Can in fact be used for
- # non-text based ones too - just ignore the +output+ constructor
- # argument.
- class BaseTextFormatter < BaseFormatter
- attr_writer :dry_run
-
- # Creates a new instance that will write to +where+. If +where+ is a
- # String, output will be written to the File with that name, otherwise
- # +where+ is exected to be an IO (or an object that responds to #puts and #write).
- def initialize(where)
- super(where)
- if where.is_a?(String)
- @output = File.open(where, 'w')
- elsif where == STDOUT
- @output = Kernel
- def @output.flush
- STDOUT.flush
- end
- else
- @output = where
- end
- @colour = false
- @dry_run = false
- @snippet_extractor = SnippetExtractor.new
- @pending_examples = []
- end
-
- def example_pending(behaviour_name, example_name, message)
- @pending_examples << ["#{behaviour_name} #{example_name}", message]
- end
-
- def colour=(colour)
- @colour = colour
- begin ; require 'Win32/Console/ANSI' if @colour && PLATFORM =~ /win32/ ; rescue LoadError ; raise "You must gem install win32console to use colour on Windows" ; end
- end
-
- def dump_failure(counter, failure)
- @output.puts
- @output.puts "#{counter.to_s})"
- @output.puts colourise("#{failure.header}\n#{failure.exception.message}", failure)
- @output.puts format_backtrace(failure.exception.backtrace)
- @output.flush
- end
-
- def colourise(s, failure)
- if(failure.expectation_not_met?)
- red(s)
- elsif(failure.pending_fixed?)
- blue(s)
- else
- magenta(s)
- end
- end
-
- def dump_summary(duration, example_count, failure_count, pending_count)
- return if @dry_run
- @output.puts
- @output.puts "Finished in #{duration} seconds"
- @output.puts
-
- summary = "#{example_count} example#{'s' unless example_count == 1}, #{failure_count} failure#{'s' unless failure_count == 1}"
- summary << ", #{pending_count} pending" if pending_count > 0
-
- if failure_count == 0
- if pending_count > 0
- @output.puts yellow(summary)
- else
- @output.puts green(summary)
- end
- else
- @output.puts red(summary)
- end
- @output.flush
- dump_pending
- end
-
- def dump_pending
- unless @pending_examples.empty?
- @output.puts
- @output.puts "Pending:"
- @pending_examples.each do |pending_example|
- @output.puts "#{pending_example[0]} (#{pending_example[1]})"
- end
- end
- @output.flush
- end
-
- def close
- if IO === @output
- @output.close
- end
- end
-
- def format_backtrace(backtrace)
- return "" if backtrace.nil?
- backtrace.map { |line| backtrace_line(line) }.join("\n")
- end
-
- protected
-
- def backtrace_line(line)
- line.sub(/\A([^:]+:\d+)$/, '\\1:')
- end
-
- def colour(text, colour_code)
- return text unless @colour && output_to_tty?
- "#{colour_code}#{text}\e[0m"
- end
-
- def output_to_tty?
- begin
- @output == Kernel || @output.tty?
- rescue NoMethodError
- false
- end
- end
-
- def green(text); colour(text, "\e[32m"); end
- def red(text); colour(text, "\e[31m"); end
- def magenta(text); colour(text, "\e[35m"); end
- def yellow(text); colour(text, "\e[33m"); end
- def blue(text); colour(text, "\e[34m"); end
-
- end
- end
- end
-end
diff --git a/spec/lib/spec/runner/formatter/failing_behaviours_formatter.rb b/spec/lib/spec/runner/formatter/failing_behaviours_formatter.rb
deleted file mode 100644
index 2b3940fd3..000000000
--- a/spec/lib/spec/runner/formatter/failing_behaviours_formatter.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-module Spec
- module Runner
- module Formatter
- class FailingBehavioursFormatter < BaseTextFormatter
- def add_behaviour(behaviour_name)
- if behaviour_name =~ /(.*) \(druby.*\)$/
- @behaviour_name = $1
- else
- @behaviour_name = behaviour_name
- end
- end
-
- def example_failed(example, counter, failure)
- unless @behaviour_name.nil?
- @output.puts @behaviour_name
- @behaviour_name = nil
- @output.flush
- end
- end
-
- def dump_failure(counter, failure)
- end
-
- def dump_summary(duration, example_count, failure_count, pending_count)
- end
- end
- end
- end
-end
diff --git a/spec/lib/spec/runner/formatter/failing_examples_formatter.rb b/spec/lib/spec/runner/formatter/failing_examples_formatter.rb
deleted file mode 100644
index 9728deaf0..000000000
--- a/spec/lib/spec/runner/formatter/failing_examples_formatter.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-module Spec
- module Runner
- module Formatter
- class FailingExamplesFormatter < BaseTextFormatter
- def add_behaviour(behaviour_name)
- @behaviour_name = behaviour_name
- end
-
- def example_failed(example, counter, failure)
- @output.puts "#{@behaviour_name} #{example.description}"
- @output.flush
- end
-
- def dump_failure(counter, failure)
- end
-
- def dump_summary(duration, example_count, failure_count, pending_count)
- end
- end
- end
- end
-end
diff --git a/spec/lib/spec/runner/formatter/html_formatter.rb b/spec/lib/spec/runner/formatter/html_formatter.rb
deleted file mode 100644
index d9c422e55..000000000
--- a/spec/lib/spec/runner/formatter/html_formatter.rb
+++ /dev/null
@@ -1,323 +0,0 @@
-require 'erb'
-
-module Spec
- module Runner
- module Formatter
- class HtmlFormatter < BaseTextFormatter
- include ERB::Util # for the #h method
-
- def initialize(output)
- super
- @current_behaviour_number = 0
- @current_example_number = 0
- end
-
- # The number of the currently running behaviour
- def current_behaviour_number
- @current_behaviour_number
- end
-
- # The number of the currently running example (a global counter)
- def current_example_number
- @current_example_number
- end
-
- def start(example_count)
- @example_count = example_count
-
- @output.puts html_header
- @output.puts report_header
- @output.flush
- end
-
- def add_behaviour(name)
- @behaviour_red = false
- @behaviour_red = false
- @current_behaviour_number += 1
- unless current_behaviour_number == 1
- @output.puts " </dl>"
- @output.puts "</div>"
- end
- @output.puts "<div class=\"behaviour\">"
- @output.puts " <dl>"
- @output.puts " <dt id=\"behaviour_#{current_behaviour_number}\">#{h(name)}</dt>"
- @output.flush
- end
-
- def start_dump
- @output.puts " </dl>"
- @output.puts "</div>"
- @output.flush
- end
-
- def example_started(example)
- @current_example_number = example.number
- end
-
- def example_passed(example)
- move_progress
- @output.puts " <dd class=\"spec passed\"><span class=\"passed_spec_name\">#{h(example.description)}</span></dd>"
- @output.flush
- end
-
- def example_failed(example, counter, failure)
- extra = extra_failure_content(failure)
- failure_style = failure.pending_fixed? ? 'pending_fixed' : 'failed'
- @output.puts " <script type=\"text/javascript\">makeRed('rspec-header');</script>" unless @header_red
- @header_red = true
- @output.puts " <script type=\"text/javascript\">makeRed('behaviour_#{current_behaviour_number}');</script>" unless @behaviour_red
- @behaviour_red = true
- move_progress
- @output.puts " <dd class=\"spec #{failure_style}\">"
- @output.puts " <span class=\"failed_spec_name\">#{h(example.description)}</span>"
- @output.puts " <div class=\"failure\" id=\"failure_#{counter}\">"
- @output.puts " <div class=\"message\"><pre>#{h(failure.exception.message)}</pre></div>" unless failure.exception.nil?
- @output.puts " <div class=\"backtrace\"><pre>#{format_backtrace(failure.exception.backtrace)}</pre></div>" unless failure.exception.nil?
- @output.puts extra unless extra == ""
- @output.puts " </div>"
- @output.puts " </dd>"
- @output.flush
- end
-
- def example_pending(behaviour_name, example_name, message)
- @output.puts " <script type=\"text/javascript\">makeYellow('rspec-header');</script>" unless @header_red
- @output.puts " <script type=\"text/javascript\">makeYellow('behaviour_#{current_behaviour_number}');</script>" unless @behaviour_red
- move_progress
- @output.puts " <dd class=\"spec not_implemented\"><span class=\"not_implemented_spec_name\">#{h(example_name)}</span></dd>"
- @output.flush
- end
-
- # Override this method if you wish to output extra HTML for a failed spec. For example, you
- # could output links to images or other files produced during the specs.
- #
- def extra_failure_content(failure)
- " <pre class=\"ruby\"><code>#{@snippet_extractor.snippet(failure.exception)}</code></pre>"
- end
-
- def move_progress
- percent_done = @example_count == 0 ? 100.0 : ((current_example_number + 1).to_f / @example_count.to_f * 1000).to_i / 10.0
- @output.puts " <script type=\"text/javascript\">moveProgressBar('#{percent_done}');</script>"
- @output.flush
- end
-
- def dump_failure(counter, failure)
- end
-
- def dump_summary(duration, example_count, failure_count, pending_count)
- if @dry_run
- totals = "This was a dry-run"
- else
- totals = "#{example_count} example#{'s' unless example_count == 1}, #{failure_count} failure#{'s' unless failure_count == 1}"
- totals << ", #{pending_count} pending" if pending_count > 0
- end
- @output.puts "<script type=\"text/javascript\">document.getElementById('duration').innerHTML = \"Finished in <strong>#{duration} seconds</strong>\";</script>"
- @output.puts "<script type=\"text/javascript\">document.getElementById('totals').innerHTML = \"#{totals}\";</script>"
- @output.puts "</div>"
- @output.puts "</div>"
- @output.puts "</body>"
- @output.puts "</html>"
- @output.flush
- end
-
- def html_header
- <<-EOF
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!DOCTYPE html
- PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
- <title>RSpec results</title>
- <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
- <meta http-equiv="Expires" content="-1" />
- <meta http-equiv="Pragma" content="no-cache" />
- <style type="text/css">
- body {
- margin: 0;
- padding: 0;
- background: #fff;
- font-size: 80%;
- }
- </style>
-</head>
-<body>
-EOF
- end
-
- def report_header
- <<-EOF
-<div class="rspec-report">
- <script type="text/javascript">
- // <![CDATA[
-#{global_scripts}
- // ]]>
- </script>
- <style type="text/css">
-#{global_styles}
- </style>
-
-<div id="rspec-header">
- <h1>RSpec Results</h1>
-
- <div id="summary">
- <p id="totals">&nbsp;</p>
- <p id="duration">&nbsp;</p>
- </div>
-</div>
-
-<div class="results">
-EOF
- end
-
- def global_scripts
- <<-EOF
-function moveProgressBar(percentDone) {
- document.getElementById("rspec-header").style.width = percentDone +"%";
-}
-function makeRed(element_id) {
- document.getElementById(element_id).style.background = '#C40D0D';
- document.getElementById(element_id).style.color = '#FFFFFF';
-}
-
-function makeYellow(element_id) {
- if (element_id == "rspec-header" && document.getElementById(element_id).style.background != '#C40D0D')
- {
- document.getElementById(element_id).style.background = '#FAF834';
- document.getElementById(element_id).style.color = '#000000';
- }
- else
- {
- document.getElementById(element_id).style.background = '#FAF834';
- document.getElementById(element_id).style.color = '#000000';
- }
-}
-EOF
- end
-
- def global_styles
- <<-EOF
-#rspec-header {
- background: #65C400; color: #fff;
-}
-
-.rspec-report h1 {
- margin: 0px 10px 0px 10px;
- padding: 10px;
- font-family: "Lucida Grande", Helvetica, sans-serif;
- font-size: 1.8em;
-}
-
-#summary {
- margin: 0; padding: 5px 10px;
- font-family: "Lucida Grande", Helvetica, sans-serif;
- text-align: right;
- position: absolute;
- top: 0px;
- right: 0px;
-}
-
-#summary p {
- margin: 0 0 0 2px;
-}
-
-#summary #totals {
- font-size: 1.2em;
-}
-
-.behaviour {
- margin: 0 10px 5px;
- background: #fff;
-}
-
-dl {
- margin: 0; padding: 0 0 5px;
- font: normal 11px "Lucida Grande", Helvetica, sans-serif;
-}
-
-dt {
- padding: 3px;
- background: #65C400;
- color: #fff;
- font-weight: bold;
-}
-
-dd {
- margin: 5px 0 5px 5px;
- padding: 3px 3px 3px 18px;
-}
-
-dd.spec.passed {
- border-left: 5px solid #65C400;
- border-bottom: 1px solid #65C400;
- background: #DBFFB4; color: #3D7700;
-}
-
-dd.spec.failed {
- border-left: 5px solid #C20000;
- border-bottom: 1px solid #C20000;
- color: #C20000; background: #FFFBD3;
-}
-
-dd.spec.not_implemented {
- border-left: 5px solid #FAF834;
- border-bottom: 1px solid #FAF834;
- background: #FCFB98; color: #131313;
-}
-
-dd.spec.pending_fixed {
- border-left: 5px solid #0000C2;
- border-bottom: 1px solid #0000C2;
- color: #0000C2; background: #D3FBFF;
-}
-
-.backtrace {
- color: #000;
- font-size: 12px;
-}
-
-a {
- color: #BE5C00;
-}
-
-/* Ruby code, style similar to vibrant ink */
-.ruby {
- font-size: 12px;
- font-family: monospace;
- color: white;
- background-color: black;
- padding: 0.1em 0 0.2em 0;
-}
-
-.ruby .keyword { color: #FF6600; }
-.ruby .constant { color: #339999; }
-.ruby .attribute { color: white; }
-.ruby .global { color: white; }
-.ruby .module { color: white; }
-.ruby .class { color: white; }
-.ruby .string { color: #66FF00; }
-.ruby .ident { color: white; }
-.ruby .method { color: #FFCC00; }
-.ruby .number { color: white; }
-.ruby .char { color: white; }
-.ruby .comment { color: #9933CC; }
-.ruby .symbol { color: white; }
-.ruby .regex { color: #44B4CC; }
-.ruby .punct { color: white; }
-.ruby .escape { color: white; }
-.ruby .interp { color: white; }
-.ruby .expr { color: white; }
-
-.ruby .offending { background-color: gray; }
-.ruby .linenum {
- width: 75px;
- padding: 0.1em 1em 0.2em 0;
- color: #000000;
- background-color: #FFFBD3;
-}
-EOF
- end
- end
- end
- end
-end
diff --git a/spec/lib/spec/runner/formatter/progress_bar_formatter.rb b/spec/lib/spec/runner/formatter/progress_bar_formatter.rb
deleted file mode 100644
index 624f06e7c..000000000
--- a/spec/lib/spec/runner/formatter/progress_bar_formatter.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-module Spec
- module Runner
- module Formatter
- class ProgressBarFormatter < BaseTextFormatter
- def add_behaviour(name)
- end
-
- def example_failed(example, counter, failure)
- @output.print colourise('F', failure)
- @output.flush
- end
-
- def example_passed(example)
- @output.print green('.')
- @output.flush
- end
-
- def example_pending(behaviour_name, example_name, message)
- super
- @output.print yellow('P')
- @output.flush
- end
-
- def start_dump
- @output.puts
- @output.flush
- end
- end
- end
- end
-end
diff --git a/spec/lib/spec/runner/formatter/rdoc_formatter.rb b/spec/lib/spec/runner/formatter/rdoc_formatter.rb
deleted file mode 100644
index 0fd22ba6c..000000000
--- a/spec/lib/spec/runner/formatter/rdoc_formatter.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-module Spec
- module Runner
- module Formatter
- class RdocFormatter < BaseTextFormatter
- def add_behaviour(name)
- @output.puts "# #{name}"
- end
-
- def example_passed(example)
- @output.puts "# * #{example.description}"
- @output.flush
- end
-
- def example_failed(example, counter, failure)
- @output.puts "# * #{example.description} [#{counter} - FAILED]"
- end
-
- def example_pending(behaviour_name, example_name, message)
- @output.puts "# * #{behaviour_name} #{example_name} [PENDING: #{message}]"
- end
- end
- end
- end
-end
diff --git a/spec/lib/spec/runner/formatter/snippet_extractor.rb b/spec/lib/spec/runner/formatter/snippet_extractor.rb
deleted file mode 100644
index 41119fe46..000000000
--- a/spec/lib/spec/runner/formatter/snippet_extractor.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-module Spec
- module Runner
- module Formatter
- # This class extracts code snippets by looking at the backtrace of the passed error
- class SnippetExtractor #:nodoc:
- class NullConverter; def convert(code, pre); code; end; end #:nodoc:
- begin; require 'rubygems'; require 'syntax/convertors/html'; @@converter = Syntax::Convertors::HTML.for_syntax "ruby"; rescue LoadError => e; @@converter = NullConverter.new; end
-
- def snippet(error)
- raw_code, line = snippet_for(error.backtrace[0])
- highlighted = @@converter.convert(raw_code, false)
- highlighted << "\n<span class=\"comment\"># gem install syntax to get syntax highlighting</span>" if @@converter.is_a?(NullConverter)
- post_process(highlighted, line)
- end
-
- def snippet_for(error_line)
- if error_line =~ /(.*):(\d+)/
- file = $1
- line = $2.to_i
- [lines_around(file, line), line]
- else
- ["# Couldn't get snippet for #{error_line}", 1]
- end
- end
-
- def lines_around(file, line)
- if File.file?(file)
- lines = File.open(file).read.split("\n")
- min = [0, line-3].max
- max = [line+1, lines.length-1].min
- selected_lines = []
- selected_lines.join("\n")
- lines[min..max].join("\n")
- else
- "# Couldn't get snippet for #{file}"
- end
- end
-
- def post_process(highlighted, offending_line)
- new_lines = []
- highlighted.split("\n").each_with_index do |line, i|
- new_line = "<span class=\"linenum\">#{offending_line+i-2}</span>#{line}"
- new_line = "<span class=\"offending\">#{new_line}</span>" if i == 2
- new_lines << new_line
- end
- new_lines.join("\n")
- end
-
- end
- end
- end
-end
diff --git a/spec/lib/spec/runner/formatter/specdoc_formatter.rb b/spec/lib/spec/runner/formatter/specdoc_formatter.rb
deleted file mode 100644
index ad794b238..000000000
--- a/spec/lib/spec/runner/formatter/specdoc_formatter.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-module Spec
- module Runner
- module Formatter
- class SpecdocFormatter < BaseTextFormatter
- def add_behaviour(name)
- @output.puts
- @output.puts name
- @output.flush
- end
-
- def example_failed(example, counter, failure)
- @output.puts failure.expectation_not_met? ? red("- #{example.description} (FAILED - #{counter})") : magenta("- #{example.description} (ERROR - #{counter})")
- @output.flush
- end
-
- def example_passed(example)
- @output.puts green("- #{example.description}")
- @output.flush
- end
-
- def example_pending(behaviour_name, example_name, message)
- super
- @output.puts yellow("- #{example_name} (PENDING: #{message})")
- @output.flush
- end
- end
- end
- end
-end
diff --git a/spec/lib/spec/runner/heckle_runner.rb b/spec/lib/spec/runner/heckle_runner.rb
deleted file mode 100644
index b6de4ef73..000000000
--- a/spec/lib/spec/runner/heckle_runner.rb
+++ /dev/null
@@ -1,72 +0,0 @@
-begin
- require 'rubygems'
- require 'heckle'
-rescue LoadError ; raise "You must gem install heckle to use --heckle" ; end
-
-module Spec
- module Runner
- # Creates a new Heckler configured to heckle all methods in the classes
- # whose name matches +filter+
- class HeckleRunner
- def initialize(filter, heckle_class=Heckler)
- @filter = filter
- @heckle_class = heckle_class
- end
-
- # Runs all the contexts held by +behaviour_runner+ once for each of the
- # methods in the matched classes.
- def heckle_with(behaviour_runner)
- if @filter =~ /(.*)[#\.](.*)/
- heckle_method($1, $2)
- else
- heckle_class_or_module(@filter)
- end
- end
-
- def heckle_method(class_name, method_name)
- verify_constant(class_name)
- heckle = @heckle_class.new(class_name, method_name, behaviour_runner)
- heckle.validate
- end
-
- def heckle_class_or_module(class_or_module_name)
- verify_constant(class_or_module_name)
- pattern = /^#{class_or_module_name}/
- classes = []
- ObjectSpace.each_object(Class) do |klass|
- classes << klass if klass.name =~ pattern
- end
-
- classes.each do |klass|
- klass.instance_methods(false).each do |method_name|
- heckle = @heckle_class.new(klass.name, method_name, behaviour_runner)
- heckle.validate
- end
- end
- end
-
- def verify_constant(name)
- begin
- # This is defined in Heckle
- name.to_class
- rescue
- raise "Heckling failed - \"#{name}\" is not a known class or module"
- end
- end
- end
-
- #Supports Heckle 1.2 and prior (earlier versions used Heckle::Base)
- class Heckler < (Heckle.const_defined?(:Base) ? Heckle::Base : Heckle)
- def initialize(klass_name, method_name, behaviour_runner)
- super(klass_name, method_name)
- @behaviour_runner = behaviour_runner
- end
-
- def tests_pass?
- paths = [] # We can pass an empty array of paths - our specs are already loaded.
- failure_count = @behaviour_runner.run(paths, false)
- failure_count == 0
- end
- end
- end
-end
diff --git a/spec/lib/spec/runner/heckle_runner_unsupported.rb b/spec/lib/spec/runner/heckle_runner_unsupported.rb
deleted file mode 100644
index 02aa37953..000000000
--- a/spec/lib/spec/runner/heckle_runner_unsupported.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-module Spec
- module Runner
- # Dummy implementation for Windows that just fails (Heckle is not supported on Windows)
- class HeckleRunner
- def initialize(filter)
- raise "Heckle not supported on Windows"
- end
- end
- end
-end
diff --git a/spec/lib/spec/runner/option_parser.rb b/spec/lib/spec/runner/option_parser.rb
deleted file mode 100644
index 1facb85a8..000000000
--- a/spec/lib/spec/runner/option_parser.rb
+++ /dev/null
@@ -1,227 +0,0 @@
-require 'optparse'
-require 'stringio'
-
-module Spec
- module Runner
- class OptionParser
- BUILT_IN_FORMATTERS = {
- 'specdoc' => Formatter::SpecdocFormatter,
- 's' => Formatter::SpecdocFormatter,
- 'html' => Formatter::HtmlFormatter,
- 'h' => Formatter::HtmlFormatter,
- 'rdoc' => Formatter::RdocFormatter,
- 'r' => Formatter::RdocFormatter,
- 'progress' => Formatter::ProgressBarFormatter,
- 'p' => Formatter::ProgressBarFormatter,
- 'failing_examples' => Formatter::FailingExamplesFormatter,
- 'e' => Formatter::FailingExamplesFormatter,
- 'failing_behaviours' => Formatter::FailingBehavioursFormatter,
- 'b' => Formatter::FailingBehavioursFormatter
- }
-
- COMMAND_LINE = {
- :diff => ["-D", "--diff [FORMAT]", "Show diff of objects that are expected to be equal when they are not",
- "Builtin formats: unified|u|context|c",
- "You can also specify a custom differ class",
- "(in which case you should also specify --require)"],
- :colour => ["-c", "--colour", "--color", "Show coloured (red/green) output"],
- :example => ["-e", "--example [NAME|FILE_NAME]", "Execute example(s) with matching name(s). If the argument is",
- "the path to an existing file (typically generated by a previous",
- "run using --format failing_examples:file.txt), then the examples",
- "on each line of thatfile will be executed. If the file is empty,",
- "all examples will be run (as if --example was not specified).",
- " ",
- "If the argument is not an existing file, then it is treated as",
- "an example name directly, causing RSpec to run just the example",
- "matching that name"],
- :specification => ["-s", "--specification [NAME]", "DEPRECATED - use -e instead", "(This will be removed when autotest works with -e)"],
- :line => ["-l", "--line LINE_NUMBER", Integer, "Execute behaviout or specification at given line.",
- "(does not work for dynamically generated specs)"],
- :format => ["-f", "--format FORMAT[:WHERE]", "Specifies what format to use for output. Specify WHERE to tell",
- "the formatter where to write the output. All built-in formats",
- "expect WHERE to be a file name, and will write to STDOUT if it's",
- "not specified. The --format option may be specified several times",
- "if you want several outputs",
- " ",
- "Builtin formats: ",
- "progress|p : Text progress",
- "specdoc|s : Behaviour doc as text",
- "rdoc|r : Behaviour doc as RDoc",
- "html|h : A nice HTML report",
- "failing_examples|e : Write all failing examples - input for --example",
- "failing_behaviours|b : Write all failing behaviours - input for --example",
- " ",
- "FORMAT can also be the name of a custom formatter class",
- "(in which case you should also specify --require to load it)"],
- :require => ["-r", "--require FILE", "Require FILE before running specs",
- "Useful for loading custom formatters or other extensions.",
- "If this option is used it must come before the others"],
- :backtrace => ["-b", "--backtrace", "Output full backtrace"],
- :loadby => ["-L", "--loadby STRATEGY", "Specify the strategy by which spec files should be loaded.",
- "STRATEGY can currently only be 'mtime' (File modification time)",
- "By default, spec files are loaded in alphabetical order if --loadby",
- "is not specified."],
- :reverse => ["-R", "--reverse", "Run examples in reverse order"],
- :timeout => ["-t", "--timeout FLOAT", "Interrupt and fail each example that doesn't complete in the",
- "specified time"],
- :heckle => ["-H", "--heckle CODE", "If all examples pass, this will mutate the classes and methods",
- "identified by CODE little by little and run all the examples again",
- "for each mutation. The intent is that for each mutation, at least",
- "one example *should* fail, and RSpec will tell you if this is not the",
- "case. CODE should be either Some::Module, Some::Class or",
- "Some::Fabulous#method}"],
- :dry_run => ["-d", "--dry-run", "Invokes formatters without executing the examples."],
- :options_file => ["-O", "--options PATH", "Read options from a file"],
- :generate_options => ["-G", "--generate-options PATH", "Generate an options file for --options"],
- :runner => ["-U", "--runner RUNNER", "Use a custom BehaviourRunner."],
- :drb => ["-X", "--drb", "Run examples via DRb. (For example against script/spec_server)"],
- :version => ["-v", "--version", "Show version"],
- :help => ["-h", "--help", "You're looking at it"]
- }
-
- def initialize
- @spec_parser = SpecParser.new
- @file_factory = File
- end
-
- def create_behaviour_runner(args, err, out, warn_if_no_files)
- options = parse(args, err, out, warn_if_no_files)
- # Some exit points in parse (--generate-options, --drb) don't return the options,
- # but hand over control. In that case we don't want to continue.
- return nil unless options.is_a?(Options)
- options.configure
- options.behaviour_runner
- end
-
- def parse(args, err, out, warn_if_no_files)
- options_file = nil
- args_copy = args.dup
- options = Options.new(err, out)
-
- opts = ::OptionParser.new do |opts|
- opts.banner = "Usage: spec (FILE|DIRECTORY|GLOB)+ [options]"
- opts.separator ""
-
- def opts.rspec_on(name, &block)
- on(*COMMAND_LINE[name], &block)
- end
-
- opts.rspec_on(:diff) {|diff| options.parse_diff(diff)}
-
- opts.rspec_on(:colour) {options.colour = true}
-
- opts.rspec_on(:example) {|example| options.parse_example(example)}
-
- opts.rspec_on(:specification) {|example| options.parse_example(example)}
-
- opts.rspec_on(:line) {|line_number| options.line_number = line_number.to_i}
-
- opts.rspec_on(:format) {|format| options.parse_format(format)}
-
- opts.rspec_on(:require) {|req| options.parse_require(req)}
-
- opts.rspec_on(:backtrace) {options.backtrace_tweaker = NoisyBacktraceTweaker.new}
-
- opts.rspec_on(:loadby) {|loadby| options.loadby = loadby}
-
- opts.rspec_on(:reverse) {options.reverse = true}
-
- opts.rspec_on(:timeout) {|timeout| options.timeout = timeout.to_f}
-
- opts.rspec_on(:heckle) {|heckle| options.parse_heckle(heckle)}
-
- opts.rspec_on(:dry_run) {options.dry_run = true}
-
- opts.rspec_on(:options_file) do |options_file|
- return parse_options_file(options_file, out, err, args_copy, warn_if_no_files)
- end
-
- opts.rspec_on(:generate_options) do |options_file|
- options.parse_generate_options(options_file, args_copy, out)
- end
-
- opts.rspec_on(:runner) do |runner|
- options.runner_arg = runner
- end
-
- opts.rspec_on(:drb) do
- return parse_drb(args_copy, out, err, warn_if_no_files)
- end
-
- opts.rspec_on(:version) {parse_version(out)}
-
- opts.on_tail(*COMMAND_LINE[:help]) {parse_help(opts, out)}
- end
- opts.parse!(args)
-
- if args.empty? && warn_if_no_files
- err.puts "No files specified."
- err.puts opts
- exit(6) if err == $stderr
- end
-
- if options.line_number
- set_spec_from_line_number(options, args, err)
- end
-
- if options.formatters.empty?
- options.formatters << Formatter::ProgressBarFormatter.new(out)
- end
-
- options
- end
-
- def parse_options_file(options_file, out_stream, error_stream, args_copy, warn_if_no_files)
- # Remove the --options option and the argument before writing to file
- index = args_copy.index("-O") || args_copy.index("--options")
- args_copy.delete_at(index)
- args_copy.delete_at(index)
-
- new_args = args_copy + IO.readlines(options_file).map {|l| l.chomp.split " "}.flatten
- return CommandLine.run(new_args, error_stream, out_stream, true, warn_if_no_files)
- end
-
- def parse_drb(args_copy, out_stream, error_stream, warn_if_no_files)
- # Remove the --drb option
- index = args_copy.index("-X") || args_copy.index("--drb")
- args_copy.delete_at(index)
-
- return DrbCommandLine.run(args_copy, error_stream, out_stream, true, warn_if_no_files)
- end
-
- def parse_version(out_stream)
- out_stream.puts ::Spec::VERSION::DESCRIPTION
- exit if out_stream == $stdout
- end
-
- def parse_help(opts, out_stream)
- out_stream.puts opts
- exit if out_stream == $stdout
- end
-
- def set_spec_from_line_number(options, args, err)
- if options.examples.empty?
- if args.length == 1
- if @file_factory.file?(args[0])
- source = @file_factory.open(args[0])
- example = @spec_parser.spec_name_for(source, options.line_number)
- options.parse_example(example)
- elsif @file_factory.directory?(args[0])
- err.puts "You must specify one file, not a directory when using the --line option"
- exit(1) if err == $stderr
- else
- err.puts "#{args[0]} does not exist"
- exit(2) if err == $stderr
- end
- else
- err.puts "Only one file can be specified when using the --line option: #{args.inspect}"
- exit(3) if err == $stderr
- end
- else
- err.puts "You cannot use both --line and --example"
- exit(4) if err == $stderr
- end
- end
- end
- end
-end
diff --git a/spec/lib/spec/runner/options.rb b/spec/lib/spec/runner/options.rb
deleted file mode 100644
index a940133eb..000000000
--- a/spec/lib/spec/runner/options.rb
+++ /dev/null
@@ -1,175 +0,0 @@
-module Spec
- module Runner
- class Options
- BUILT_IN_FORMATTERS = {
- 'specdoc' => Formatter::SpecdocFormatter,
- 's' => Formatter::SpecdocFormatter,
- 'html' => Formatter::HtmlFormatter,
- 'h' => Formatter::HtmlFormatter,
- 'rdoc' => Formatter::RdocFormatter,
- 'r' => Formatter::RdocFormatter,
- 'progress' => Formatter::ProgressBarFormatter,
- 'p' => Formatter::ProgressBarFormatter,
- 'failing_examples' => Formatter::FailingExamplesFormatter,
- 'e' => Formatter::FailingExamplesFormatter,
- 'failing_behaviours' => Formatter::FailingBehavioursFormatter,
- 'b' => Formatter::FailingBehavioursFormatter
- }
-
- attr_accessor(
- :backtrace_tweaker,
- :colour,
- :context_lines,
- :diff_format,
- :differ_class,
- :dry_run,
- :examples,
- :failure_file,
- :formatters,
- :generate,
- :heckle_runner,
- :line_number,
- :loadby,
- :reporter,
- :reverse,
- :timeout,
- :verbose,
- :runner_arg,
- :behaviour_runner
- )
-
- def initialize(err, out)
- @err, @out = err, out
- @backtrace_tweaker = QuietBacktraceTweaker.new
- @examples = []
- @formatters = []
- @colour = false
- @dry_run = false
- end
-
- def configure
- configure_formatters
- create_reporter
- configure_differ
- create_behaviour_runner
- end
-
- def create_behaviour_runner
- return nil if @generate
- @behaviour_runner = if @runner_arg
- klass_name, arg = split_at_colon(@runner_arg)
- runner_type = load_class(klass_name, 'behaviour runner', '--runner')
- runner_type.new(self, arg)
- else
- BehaviourRunner.new(self)
- end
- end
-
- def configure_formatters
- @formatters.each do |formatter|
- formatter.colour = @colour if formatter.respond_to?(:colour=)
- formatter.dry_run = @dry_run if formatter.respond_to?(:dry_run=)
- end
- end
-
- def create_reporter
- @reporter = Reporter.new(@formatters, @backtrace_tweaker)
- end
-
- def configure_differ
- if @differ_class
- Spec::Expectations.differ = @differ_class.new(@diff_format, @context_lines, @colour)
- end
- end
-
- def parse_diff(format)
- @context_lines = 3
- case format
- when :context, 'context', 'c'
- @diff_format = :context
- when :unified, 'unified', 'u', '', nil
- @diff_format = :unified
- end
-
- if [:context,:unified].include? @diff_format
- require 'spec/expectations/differs/default'
- @differ_class = Spec::Expectations::Differs::Default
- else
- @diff_format = :custom
- @differ_class = load_class(format, 'differ', '--diff')
- end
- end
-
- def parse_example(example)
- if(File.file?(example))
- @examples = File.open(example).read.split("\n")
- else
- @examples = [example]
- end
- end
-
- def parse_format(format_arg)
- format, where = split_at_colon(format_arg)
- # This funky regexp checks whether we have a FILE_NAME or not
- if where.nil?
- raise "When using several --format options only one of them can be without a file" if @out_used
- where = @out
- @out_used = true
- end
-
- formatter_type = BUILT_IN_FORMATTERS[format] || load_class(format, 'formatter', '--format')
- @formatters << formatter_type.new(where)
- end
-
- def parse_require(req)
- req.split(",").each{|file| require file}
- end
-
- def parse_heckle(heckle)
- heckle_require = [/mswin/, /java/].detect{|p| p =~ RUBY_PLATFORM} ? 'spec/runner/heckle_runner_unsupported' : 'spec/runner/heckle_runner'
- require heckle_require
- @heckle_runner = HeckleRunner.new(heckle)
- end
-
- def parse_generate_options(options_file, args_copy, out_stream)
- # Remove the --generate-options option and the argument before writing to file
- index = args_copy.index("-G") || args_copy.index("--generate-options")
- args_copy.delete_at(index)
- args_copy.delete_at(index)
- File.open(options_file, 'w') do |io|
- io.puts args_copy.join("\n")
- end
- out_stream.puts "\nOptions written to #{options_file}. You can now use these options with:"
- out_stream.puts "spec --options #{options_file}"
- @generate = true
- end
-
- def split_at_colon(s)
- if s =~ /([a-zA-Z_]+(?:::[a-zA-Z_]+)*):?(.*)/
- arg = $2 == "" ? nil : $2
- [$1, arg]
- else
- raise "Couldn't parse #{s.inspect}"
- end
- end
-
- def load_class(name, kind, option)
- if name =~ /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/
- arg = $2 == "" ? nil : $2
- [$1, arg]
- else
- m = "#{name.inspect} is not a valid class name"
- @err.puts m
- raise m
- end
- begin
- eval(name, binding, __FILE__, __LINE__)
- rescue NameError => e
- @err.puts "Couldn't find #{kind} class #{name}"
- @err.puts "Make sure the --require option is specified *before* #{option}"
- if $_spec_spec ; raise e ; else exit(1) ; end
- end
- end
- end
- end
-end
diff --git a/spec/lib/spec/runner/reporter.rb b/spec/lib/spec/runner/reporter.rb
deleted file mode 100644
index b1dc2a27a..000000000
--- a/spec/lib/spec/runner/reporter.rb
+++ /dev/null
@@ -1,125 +0,0 @@
-module Spec
- module Runner
- class Reporter
-
- def initialize(formatters, backtrace_tweaker)
- @formatters = formatters
- @backtrace_tweaker = backtrace_tweaker
- clear!
- end
-
- def add_behaviour(name)
- @formatters.each{|f| f.add_behaviour(name)}
- @behaviour_names << name
- end
-
- def example_started(name)
- @formatters.each{|f| f.example_started(name)}
- end
-
- def example_finished(name, error=nil, failure_location=nil, not_implemented = false)
- @example_names << name
-
- if not_implemented
- example_pending(@behaviour_names.last, name)
- elsif error.nil?
- example_passed(name)
- elsif Spec::DSL::ExamplePendingError === error
- example_pending(@behaviour_names.last, name, error.message)
- else
- example_failed(name, error, failure_location)
- end
- end
-
- def start(number_of_examples)
- clear!
- @start_time = Time.new
- @formatters.each{|f| f.start(number_of_examples)}
- end
-
- def end
- @end_time = Time.new
- end
-
- # Dumps the summary and returns the total number of failures
- def dump
- @formatters.each{|f| f.start_dump}
- dump_failures
- @formatters.each do |f|
- f.dump_summary(duration, @example_names.length, @failures.length, @pending_count)
- f.close
- end
- @failures.length
- end
-
- private
-
- def clear!
- @behaviour_names = []
- @failures = []
- @pending_count = 0
- @example_names = []
- @start_time = nil
- @end_time = nil
- end
-
- def dump_failures
- return if @failures.empty?
- @failures.inject(1) do |index, failure|
- @formatters.each{|f| f.dump_failure(index, failure)}
- index + 1
- end
- end
-
- def duration
- return @end_time - @start_time unless (@end_time.nil? or @start_time.nil?)
- return "0.0"
- end
-
- def example_passed(name)
- @formatters.each{|f| f.example_passed(name)}
- end
-
- def example_failed(name, error, failure_location)
- @backtrace_tweaker.tweak_backtrace(error, failure_location)
- example_name = "#{@behaviour_names.last} #{name}"
- failure = Failure.new(example_name, error)
- @failures << failure
- @formatters.each{|f| f.example_failed(name, @failures.length, failure)}
- end
-
- def example_pending(behaviour_name, example_name, message="Not Yet Implemented")
- @pending_count += 1
- @formatters.each{|f| f.example_pending(behaviour_name, example_name, message)}
- end
-
- class Failure
- attr_reader :exception
-
- def initialize(example_name, exception)
- @example_name = example_name
- @exception = exception
- end
-
- def header
- if expectation_not_met?
- "'#{@example_name}' FAILED"
- elsif pending_fixed?
- "'#{@example_name}' FIXED"
- else
- "#{@exception.class.name} in '#{@example_name}'"
- end
- end
-
- def pending_fixed?
- @exception.is_a?(Spec::DSL::PendingFixedError)
- end
-
- def expectation_not_met?
- @exception.is_a?(Spec::Expectations::ExpectationNotMetError)
- end
-
- end
- end
- end
-end
diff --git a/spec/lib/spec/runner/spec_parser.rb b/spec/lib/spec/runner/spec_parser.rb
deleted file mode 100644
index bc9170065..000000000
--- a/spec/lib/spec/runner/spec_parser.rb
+++ /dev/null
@@ -1,50 +0,0 @@
-module Spec
- module Runner
- # Parses a spec file and finds the nearest example for a given line number.
- class SpecParser
- def spec_name_for(io, line_number)
- source = io.read
- behaviour, behaviour_line = behaviour_at_line(source, line_number)
- example, example_line = example_at_line(source, line_number)
- if behaviour && example && (behaviour_line < example_line)
- "#{behaviour} #{example}"
- elsif behaviour
- behaviour
- else
- nil
- end
- end
-
- protected
-
- def behaviour_at_line(source, line_number)
- find_above(source, line_number, /^\s*(context|describe)\s+(.*)\s+do/)
- end
-
- def example_at_line(source, line_number)
- find_above(source, line_number, /^\s*(specify|it)\s+(.*)\s+do/)
- end
-
- # Returns the context/describe or specify/it name and the line number
- def find_above(source, line_number, pattern)
- lines_above_reversed(source, line_number).each_with_index do |line, n|
- return [parse_description($2), line_number-n] if line =~ pattern
- end
- nil
- end
-
- def lines_above_reversed(source, line_number)
- lines = source.split("\n")
- lines[0...line_number].reverse
- end
-
- def parse_description(str)
- return str[1..-2] if str =~ /^['"].*['"]$/
- if matches = /^(.*)\s*,\s*['"](.*)['"]$/.match(str)
- return ::Spec::DSL::Description.generate_description(matches[1], matches[2])
- end
- return str
- end
- end
- end
-end
diff --git a/spec/lib/spec/test_case_adapter.rb b/spec/lib/spec/test_case_adapter.rb
deleted file mode 100755
index 992e098fd..000000000
--- a/spec/lib/spec/test_case_adapter.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-require 'spec/expectations'
-require 'spec/matchers'
-
-module Test
- module Unit
- class TestCase
- include Spec::Matchers
- end
- end
-end
diff --git a/spec/lib/spec/translator.rb b/spec/lib/spec/translator.rb
deleted file mode 100644
index c1e07eda4..000000000
--- a/spec/lib/spec/translator.rb
+++ /dev/null
@@ -1,114 +0,0 @@
-require 'fileutils'
-
-module Spec
- class Translator
- def translate(from, to)
- from = File.expand_path(from)
- to = File.expand_path(to)
- if File.directory?(from)
- translate_dir(from, to)
- elsif(from =~ /\.rb$/)
- translate_file(from, to)
- end
- end
-
- def translate_dir(from, to)
- FileUtils.mkdir_p(to) unless File.directory?(to)
- Dir["#{from}/*"].each do |sub_from|
- path = sub_from[from.length+1..-1]
- sub_to = File.join(to, path)
- translate(sub_from, sub_to)
- end
- end
-
- def translate_file(from, to)
- translation = ""
- File.open(from) do |io|
- io.each_line do |line|
- translation << translate_line(line)
- end
- end
- File.open(to, "w") do |io|
- io.write(translation)
- end
- end
-
- def translate_line(line)
- # Translate deprecated mock constraints
- line.gsub!(/:any_args/, 'any_args')
- line.gsub!(/:anything/, 'anything')
- line.gsub!(/:boolean/, 'boolean')
- line.gsub!(/:no_args/, 'no_args')
- line.gsub!(/:numeric/, 'an_instance_of(Numeric)')
- line.gsub!(/:string/, 'an_instance_of(String)')
-
- return line if line =~ /(should_not|should)_receive/
-
- line.gsub!(/(^\s*)context([\s*|\(]['|"|A-Z])/, '\1describe\2')
- line.gsub!(/(^\s*)specify([\s*|\(]['|"|A-Z])/, '\1it\2')
- line.gsub!(/(^\s*)context_setup(\s*[do|\{])/, '\1before(:all)\2')
- line.gsub!(/(^\s*)context_teardown(\s*[do|\{])/, '\1after(:all)\2')
- line.gsub!(/(^\s*)setup(\s*[do|\{])/, '\1before(:each)\2')
- line.gsub!(/(^\s*)teardown(\s*[do|\{])/, '\1after(:each)\2')
-
- if line =~ /(.*\.)(should_not|should)(?:_be)(?!_)(.*)/m
- pre = $1
- should = $2
- post = $3
- be_or_equal = post =~ /(<|>)/ ? "be" : "equal"
-
- return "#{pre}#{should} #{be_or_equal}#{post}"
- end
-
- if line =~ /(.*\.)(should_not|should)_(?!not)\s*(.*)/m
- pre = $1
- should = $2
- post = $3
-
- post.gsub!(/^raise/, 'raise_error')
- post.gsub!(/^throw/, 'throw_symbol')
-
- unless standard_matcher?(post)
- post = "be_#{post}"
- end
-
- # Add parenthesis
- post.gsub!(/^(\w+)\s+([\w|\.|\,|\(.*\)|\'|\"|\:|@| ]+)(\})/, '\1(\2)\3') # inside a block
- post.gsub!(/^(redirect_to)\s+(.*)/, '\1(\2)') # redirect_to, which often has http:
- post.gsub!(/^(\w+)\s+([\w|\.|\,|\(.*\)|\{.*\}|\'|\"|\:|@| ]+)/, '\1(\2)')
- post.gsub!(/(\s+\))/, ')')
- post.gsub!(/\)\}/, ') }')
- post.gsub!(/^(\w+)\s+(\/.*\/)/, '\1(\2)') #regexps
- line = "#{pre}#{should} #{post}"
- end
-
- line
- end
-
- def standard_matcher?(matcher)
- patterns = [
- /^be/,
- /^be_close/,
- /^eql/,
- /^equal/,
- /^has/,
- /^have/,
- /^change/,
- /^include/,
- /^match/,
- /^raise_error/,
- /^respond_to/,
- /^redirect_to/,
- /^satisfy/,
- /^throw_symbol/,
- # Extra ones that we use in spec_helper
- /^pass/,
- /^fail/,
- /^fail_with/,
- ]
- matched = patterns.detect{ |p| matcher =~ p }
- !matched.nil?
- end
-
- end
-end
diff --git a/spec/lib/spec/version.rb b/spec/lib/spec/version.rb
deleted file mode 100644
index 5b1db9b37..000000000
--- a/spec/lib/spec/version.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-module Spec
- module VERSION
- unless defined? MAJOR
- MAJOR = 1
- MINOR = 0
- TINY = 8
- RELEASE_CANDIDATE = nil
-
- # RANDOM_TOKEN: 0.510454315029681
- REV = "$LastChangedRevision: 2338 $".match(/LastChangedRevision: (\d+)/)[1]
-
- STRING = [MAJOR, MINOR, TINY].join('.')
- TAG = "REL_#{[MAJOR, MINOR, TINY, RELEASE_CANDIDATE].compact.join('_')}".upcase.gsub(/\.|-/, '_')
- FULL_VERSION = "#{[MAJOR, MINOR, TINY, RELEASE_CANDIDATE].compact.join('.')} (r#{REV})"
-
- NAME = "RSpec"
- URL = "http://rspec.rubyforge.org/"
-
- DESCRIPTION = "#{NAME}-#{FULL_VERSION} - BDD for Ruby\n#{URL}"
- end
- end
-end
-
diff --git a/spec/monkey_patches/add_confine_and_runnable_to_rspec_dsl.rb b/spec/monkey_patches/add_confine_and_runnable_to_rspec_dsl.rb
new file mode 100644
index 000000000..e2f3d4728
--- /dev/null
+++ b/spec/monkey_patches/add_confine_and_runnable_to_rspec_dsl.rb
@@ -0,0 +1,43 @@
+dir = File.expand_path(File.dirname(__FILE__))
+[ "#{dir}/../../lib", "#{dir}/../../test/lib"].each do |dir|
+ fulldir = File.expand_path(dir)
+ $LOAD_PATH.unshift(fulldir) unless $LOAD_PATH.include?(fulldir)
+end
+
+require 'spec'
+require 'puppettest'
+require 'puppettest/runnable_test'
+
+module Spec
+ module Runner
+ class ExampleGroupRunner
+ def run
+ prepare
+ success = true
+ example_groups.each do |example_group|
+ next unless example_group.runnable?
+ success = success & example_group.run
+ end
+ return success
+ ensure
+ finish
+ end
+ end
+ end
+end
+
+module Spec
+ module Example
+ class ExampleGroup
+ extend PuppetTest::RunnableTest
+ end
+ end
+end
+
+module Test
+ module Unit
+ class TestCase
+ extend PuppetTest::RunnableTest
+ end
+ end
+end
diff --git a/spec/plugins/mock_frameworks/flexmock.rb b/spec/plugins/mock_frameworks/flexmock.rb
deleted file mode 100644
index 6875a5222..000000000
--- a/spec/plugins/mock_frameworks/flexmock.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/env ruby
-#
-# Created by Jim Weirich on 2007-04-10.
-# Copyright (c) 2007. All rights reserved.
-
-require 'flexmock/rspec'
-
-module Spec
- module Plugins
- module MockFramework
- include FlexMock::MockContainer
- def setup_mocks_for_rspec
- # No setup required
- end
- def verify_mocks_for_rspec
- flexmock_verify
- end
- def teardown_mocks_for_rspec
- flexmock_close
- end
- end
- end
-end
diff --git a/spec/plugins/mock_frameworks/mocha.rb b/spec/plugins/mock_frameworks/mocha.rb
deleted file mode 100644
index 69d11636c..000000000
--- a/spec/plugins/mock_frameworks/mocha.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-require 'mocha/standalone'
-require 'mocha/object'
-
-module Spec
- module Plugins
- module MockFramework
- include Mocha::Standalone
- def setup_mocks_for_rspec
- mocha_setup
- end
- def verify_mocks_for_rspec
- mocha_verify
- end
- def teardown_mocks_for_rspec
- mocha_teardown
- end
- end
- end
-end
diff --git a/spec/plugins/mock_frameworks/rr.rb b/spec/plugins/mock_frameworks/rr.rb
deleted file mode 100644
index c019c18a1..000000000
--- a/spec/plugins/mock_frameworks/rr.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-require 'rr'
-
-patterns = ::Spec::Runner::QuietBacktraceTweaker::IGNORE_PATTERNS
-patterns.push(RR::Errors::BACKTRACE_IDENTIFIER)
-
-module Spec
- module Plugins
- module MockFramework
- include RR::Extensions::InstanceMethods
- def setup_mocks_for_rspec
- RR::Space.instance.reset
- end
- def verify_mocks_for_rspec
- RR::Space.instance.verify_doubles
- end
- def teardown_mocks_for_rspec
- RR::Space.instance.reset
- end
- end
- end
-end
diff --git a/spec/plugins/mock_frameworks/rspec.rb b/spec/plugins/mock_frameworks/rspec.rb
deleted file mode 100644
index e606c3089..000000000
--- a/spec/plugins/mock_frameworks/rspec.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "lib", "spec", "mocks"))
-
-module Spec
- module Plugins
- module MockFramework
- include Spec::Mocks::SpecMethods
- def setup_mocks_for_rspec
- $rspec_mocks ||= Spec::Mocks::Space.new
- end
- def verify_mocks_for_rspec
- $rspec_mocks.verify_all
- end
- def teardown_mocks_for_rspec
- $rspec_mocks.reset_all
- end
- end
- end
-end
diff --git a/spec/lib/shared_behaviours/file_server_terminus.rb b/spec/shared_behaviours/file_server_terminus.rb
index de08f29fc..de08f29fc 100644
--- a/spec/lib/shared_behaviours/file_server_terminus.rb
+++ b/spec/shared_behaviours/file_server_terminus.rb
diff --git a/spec/lib/shared_behaviours/file_serving.rb b/spec/shared_behaviours/file_serving.rb
index b5ab6b0fd..b5ab6b0fd 100644
--- a/spec/lib/shared_behaviours/file_serving.rb
+++ b/spec/shared_behaviours/file_serving.rb
diff --git a/spec/spec.opts b/spec/spec.opts
index 2cac5f260..2f9bf0d0a 100644
--- a/spec/spec.opts
+++ b/spec/spec.opts
@@ -1,5 +1,3 @@
--colour
---format
-s
--loadby
-mtime \ No newline at end of file
+mtime
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index bfac9095f..db14b47cb 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -1,22 +1,36 @@
dir = File.expand_path(File.dirname(__FILE__))
-$LOAD_PATH.unshift("#{dir}/lib")
+
+$LOAD_PATH.unshift("#{dir}/")
$LOAD_PATH.unshift("#{dir}/../lib")
$LOAD_PATH.unshift("#{dir}/../test/lib") # Add the old test dir, so that we can still find our local mocha and spec
+# include any gems in vendor/gems
+Dir["#{dir}/../vendor/gems/**"].each do |path|
+ libpath = File.join(path, "lib")
+ if File.directory?(libpath)
+ $LOAD_PATH.unshift(libpath)
+ else
+ $LOAD_PATH.unshift(path)
+ end
+end
+
require 'puppettest'
require 'puppettest/runnable_test'
require 'mocha'
require 'spec'
+# load any monkey-patches
+Dir["#{dir}/monkey_patches/*.rb"].map { |file| require file }
+
Spec::Runner.configure do |config|
config.mock_with :mocha
- config.prepend_before :each do
- setup() if respond_to? :setup
- end
- config.prepend_after :each do
- teardown() if respond_to? :teardown
- end
+# config.prepend_before :all do
+# setup_mocks_for_rspec
+# setup() if respond_to? :setup
+# end
+#
+# config.prepend_after :all do
+# teardown() if respond_to? :teardown
+# end
end
-
-require "#{dir}/lib/monkey_patches/add_confine_and_runnable_to_rspec_dsl"
diff --git a/spec/unit/file_serving/configuration.rb b/spec/unit/file_serving/configuration.rb
index df46b9b6a..eecaefe5f 100755
--- a/spec/unit/file_serving/configuration.rb
+++ b/spec/unit/file_serving/configuration.rb
@@ -4,17 +4,6 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/file_serving/configuration'
-module FSConfigurationTesting
- def setup
- @path = "/path/to/configuration/file.conf"
- Puppet.settings.stubs(:value).with(:fileserverconfig).returns(@path)
- end
-
- def teardown
- Puppet::FileServing::Configuration.clear_cache
- end
-end
-
describe Puppet::FileServing::Configuration do
it "should make :new a private method" do
proc { Puppet::FileServing::Configuration.new }.should raise_error
@@ -35,193 +24,201 @@ describe Puppet::FileServing::Configuration do
end
end
-describe Puppet::FileServing::Configuration, " when initializing" do
- include FSConfigurationTesting
-
- it "should work without a configuration file" do
- FileTest.stubs(:exists?).with(@path).returns(false)
- proc { Puppet::FileServing::Configuration.create }.should_not raise_error
- end
-
- it "should parse the configuration file if present" do
- FileTest.stubs(:exists?).with(@path).returns(true)
- @parser = mock 'parser'
- @parser.expects(:parse).returns({})
- Puppet::FileServing::Configuration::Parser.stubs(:new).returns(@parser)
- Puppet::FileServing::Configuration.create
- end
-
- it "should determine the path to the configuration file from the Puppet settings" do
- Puppet::FileServing::Configuration.create
- end
-end
-
-describe Puppet::FileServing::Configuration, " when parsing the configuration file" do
- include FSConfigurationTesting
-
- before do
- FileTest.stubs(:exists?).with(@path).returns(true)
- @parser = mock 'parser'
- Puppet::FileServing::Configuration::Parser.stubs(:new).returns(@parser)
- end
-
- it "should set the mount list to the results of parsing" do
- @parser.expects(:parse).returns("one" => mock("mount"))
- config = Puppet::FileServing::Configuration.create
- config.mounted?("one").should be_true
- end
-
- it "should not raise exceptions" do
- @parser.expects(:parse).raises(ArgumentError)
- proc { Puppet::FileServing::Configuration.create }.should_not raise_error
- end
-
- it "should replace the existing mount list with the results of reparsing" do
- @parser.expects(:parse).returns("one" => mock("mount"))
- config = Puppet::FileServing::Configuration.create
- config.mounted?("one").should be_true
- # Now parse again
- @parser.expects(:parse).returns("two" => mock('other'))
- config.send(:readconfig, false)
- config.mounted?("one").should be_false
- config.mounted?("two").should be_true
- end
-
- it "should not replace the mount list until the file is entirely parsed successfully" do
- @parser.expects(:parse).returns("one" => mock("mount"))
- @parser.expects(:parse).raises(ArgumentError)
- config = Puppet::FileServing::Configuration.create
- # Now parse again, so the exception gets thrown
- config.send(:readconfig, false)
- config.mounted?("one").should be_true
- end
-end
-
-describe Puppet::FileServing::Configuration, " when finding files" do
- include FSConfigurationTesting
-
- before do
- @parser = mock 'parser'
- @parser.stubs(:changed?).returns true
- FileTest.stubs(:exists?).with(@path).returns(true)
- Puppet::FileServing::Configuration::Parser.stubs(:new).returns(@parser)
-
- @mount1 = stub 'mount', :name => "one"
- @mounts = {"one" => @mount1}
-
- Facter.stubs(:value).with("hostname").returns("whatever")
-
- @config = Puppet::FileServing::Configuration.create
- end
-
- it "should fail if the uri does not match a leading slash followed by a valid mount name" do
- @parser.expects(:parse).returns(@mounts)
- proc { @config.file_path("something") }.should raise_error(ArgumentError)
- end
-
- it "should use the first term after the first slash for the mount name" do
- @parser.expects(:parse).returns(@mounts)
- FileTest.stubs(:exists?).returns(true)
- @mount1.expects(:file)
- @config.file_path("/one")
- end
-
- it "should use the remainder of the URI after the mount name as the file name" do
- @parser.expects(:parse).returns(@mounts)
- @mount1.expects(:file).with("something/else", {})
- FileTest.stubs(:exists?).returns(true)
- @config.file_path("/one/something/else")
- end
-
- it "should treat a bare name as a mount and no relative file" do
- @parser.expects(:parse).returns(@mounts)
- @mount1.expects(:file).with(nil, {})
- FileTest.stubs(:exists?).returns(true)
- @config.file_path("/one")
- end
-
- it "should treat a name with a trailing slash equivalently to a name with no trailing slash" do
- @parser.expects(:parse).returns(@mounts)
- @mount1.expects(:file).with(nil, {})
- FileTest.stubs(:exists?).returns(true)
- @config.file_path("/one/")
- end
-
- it "should return nil if the mount cannot be found" do
- @parser.expects(:changed?).returns(true)
- @parser.expects(:parse).returns({})
- @config.file_path("/one/something").should be_nil
- end
-
- it "should return nil if the mount does not contain the file" do
- @parser.expects(:parse).returns(@mounts)
- @mount1.expects(:file).with("something/else", {}).returns(nil)
- @config.file_path("/one/something/else").should be_nil
- end
-
- it "should return the fully qualified path if the mount exists" do
- @parser.expects(:parse).returns(@mounts)
- @mount1.expects(:file).with("something/else", {}).returns("/full/path")
- @config.file_path("/one/something/else").should == "/full/path"
- end
-
- it "should reparse the configuration file when it has changed" do
- @mount1.stubs(:file).returns("whatever")
- @parser.expects(:changed?).returns(true)
- @parser.expects(:parse).returns(@mounts)
- FileTest.stubs(:exists?).returns(true)
- @config.file_path("/one/something")
-
- @parser.expects(:changed?).returns(true)
- @parser.expects(:parse).returns({})
- @config.file_path("/one/something").should be_nil
- end
-end
-
-describe Puppet::FileServing::Configuration, " when checking authorization" do
- include FSConfigurationTesting
-
- before do
- @parser = mock 'parser'
- @parser.stubs(:changed?).returns true
- FileTest.stubs(:exists?).with(@path).returns(true)
- Puppet::FileServing::Configuration::Parser.stubs(:new).returns(@parser)
-
- @mount1 = stub 'mount', :name => "one"
- @mounts = {"one" => @mount1}
- @parser.stubs(:parse).returns(@mounts)
-
- Facter.stubs(:value).with("hostname").returns("whatever")
-
- @config = Puppet::FileServing::Configuration.create
- end
-
- it "should return false if the mount cannot be found" do
- @config.authorized?("/nope/my/file").should be_false
- end
-
- it "should use the mount to determine authorization" do
- @mount1.expects(:allowed?)
- @config.authorized?("/one/my/file")
- end
-
- it "should pass the client's name to the mount if provided" do
- @mount1.expects(:allowed?).with("myhost", nil)
- @config.authorized?("/one/my/file", :node => "myhost")
- end
+describe Puppet::FileServing::Configuration do
- it "should pass the client's IP to the mount if provided" do
- @mount1.expects(:allowed?).with("myhost", "myip")
- @config.authorized?("/one/my/file", :node => "myhost", :ipaddress => "myip")
+ before :each do
+ @path = "/path/to/configuration/file.conf"
+ Puppet.settings.stubs(:value).with(:fileserverconfig).returns(@path)
end
- it "should return true if the mount allows the client" do
- @mount1.expects(:allowed?).returns(true)
- @config.authorized?("/one/my/file").should be_true
+ after :each do
+ Puppet::FileServing::Configuration.clear_cache
end
- it "should return false if the mount denies the client" do
- @mount1.expects(:allowed?).returns(false)
- @config.authorized?("/one/my/file").should be_false
- end
-end
+ describe Puppet::FileServing::Configuration, " when initializing" do
+
+ it "should work without a configuration file" do
+ FileTest.stubs(:exists?).with(@path).returns(false)
+ proc { Puppet::FileServing::Configuration.create }.should_not raise_error
+ end
+
+ it "should parse the configuration file if present" do
+ FileTest.stubs(:exists?).with(@path).returns(true)
+ @parser = mock 'parser'
+ @parser.expects(:parse).returns({})
+ Puppet::FileServing::Configuration::Parser.stubs(:new).returns(@parser)
+ Puppet::FileServing::Configuration.create
+ end
+
+ it "should determine the path to the configuration file from the Puppet settings" do
+ Puppet::FileServing::Configuration.create
+ end
+ end
+
+ describe Puppet::FileServing::Configuration, " when parsing the configuration file" do
+
+ before do
+ FileTest.stubs(:exists?).with(@path).returns(true)
+ @parser = mock 'parser'
+ Puppet::FileServing::Configuration::Parser.stubs(:new).returns(@parser)
+ end
+
+ it "should set the mount list to the results of parsing" do
+ @parser.expects(:parse).returns("one" => mock("mount"))
+ config = Puppet::FileServing::Configuration.create
+ config.mounted?("one").should be_true
+ end
+
+ it "should not raise exceptions" do
+ @parser.expects(:parse).raises(ArgumentError)
+ proc { Puppet::FileServing::Configuration.create }.should_not raise_error
+ end
+
+ it "should replace the existing mount list with the results of reparsing" do
+ @parser.expects(:parse).returns("one" => mock("mount"))
+ config = Puppet::FileServing::Configuration.create
+ config.mounted?("one").should be_true
+ # Now parse again
+ @parser.expects(:parse).returns("two" => mock('other'))
+ config.send(:readconfig, false)
+ config.mounted?("one").should be_false
+ config.mounted?("two").should be_true
+ end
+
+ it "should not replace the mount list until the file is entirely parsed successfully" do
+ @parser.expects(:parse).returns("one" => mock("mount"))
+ @parser.expects(:parse).raises(ArgumentError)
+ config = Puppet::FileServing::Configuration.create
+ # Now parse again, so the exception gets thrown
+ config.send(:readconfig, false)
+ config.mounted?("one").should be_true
+ end
+ end
+
+ describe Puppet::FileServing::Configuration, " when finding files" do
+
+ before do
+ @parser = mock 'parser'
+ @parser.stubs(:changed?).returns true
+ FileTest.stubs(:exists?).with(@path).returns(true)
+ Puppet::FileServing::Configuration::Parser.stubs(:new).returns(@parser)
+
+ @mount1 = stub 'mount', :name => "one"
+ @mounts = {"one" => @mount1}
+
+ Facter.stubs(:value).with("hostname").returns("whatever")
+
+ @config = Puppet::FileServing::Configuration.create
+ end
+
+ it "should fail if the uri does not match a leading slash followed by a valid mount name" do
+ @parser.expects(:parse).returns(@mounts)
+ proc { @config.file_path("something") }.should raise_error(ArgumentError)
+ end
+
+ it "should use the first term after the first slash for the mount name" do
+ @parser.expects(:parse).returns(@mounts)
+ FileTest.stubs(:exists?).returns(true)
+ @mount1.expects(:file)
+ @config.file_path("/one")
+ end
+
+ it "should use the remainder of the URI after the mount name as the file name" do
+ @parser.expects(:parse).returns(@mounts)
+ @mount1.expects(:file).with("something/else", {})
+ FileTest.stubs(:exists?).returns(true)
+ @config.file_path("/one/something/else")
+ end
+
+ it "should treat a bare name as a mount and no relative file" do
+ @parser.expects(:parse).returns(@mounts)
+ @mount1.expects(:file).with(nil, {})
+ FileTest.stubs(:exists?).returns(true)
+ @config.file_path("/one")
+ end
+
+ it "should treat a name with a trailing slash equivalently to a name with no trailing slash" do
+ @parser.expects(:parse).returns(@mounts)
+ @mount1.expects(:file).with(nil, {})
+ FileTest.stubs(:exists?).returns(true)
+ @config.file_path("/one/")
+ end
+
+ it "should return nil if the mount cannot be found" do
+ @parser.expects(:changed?).returns(true)
+ @parser.expects(:parse).returns({})
+ @config.file_path("/one/something").should be_nil
+ end
+
+ it "should return nil if the mount does not contain the file" do
+ @parser.expects(:parse).returns(@mounts)
+ @mount1.expects(:file).with("something/else", {}).returns(nil)
+ @config.file_path("/one/something/else").should be_nil
+ end
+
+ it "should return the fully qualified path if the mount exists" do
+ @parser.expects(:parse).returns(@mounts)
+ @mount1.expects(:file).with("something/else", {}).returns("/full/path")
+ @config.file_path("/one/something/else").should == "/full/path"
+ end
+
+ it "should reparse the configuration file when it has changed" do
+ @mount1.stubs(:file).returns("whatever")
+ @parser.expects(:changed?).returns(true)
+ @parser.expects(:parse).returns(@mounts)
+ FileTest.stubs(:exists?).returns(true)
+ @config.file_path("/one/something")
+
+ @parser.expects(:changed?).returns(true)
+ @parser.expects(:parse).returns({})
+ @config.file_path("/one/something").should be_nil
+ end
+ end
+
+ describe Puppet::FileServing::Configuration, " when checking authorization" do
+
+ before do
+ @parser = mock 'parser'
+ @parser.stubs(:changed?).returns true
+ FileTest.stubs(:exists?).with(@path).returns(true)
+ Puppet::FileServing::Configuration::Parser.stubs(:new).returns(@parser)
+
+ @mount1 = stub 'mount', :name => "one"
+ @mounts = {"one" => @mount1}
+ @parser.stubs(:parse).returns(@mounts)
+
+ Facter.stubs(:value).with("hostname").returns("whatever")
+
+ @config = Puppet::FileServing::Configuration.create
+ end
+
+ it "should return false if the mount cannot be found" do
+ @config.authorized?("/nope/my/file").should be_false
+ end
+
+ it "should use the mount to determine authorization" do
+ @mount1.expects(:allowed?)
+ @config.authorized?("/one/my/file")
+ end
+
+ it "should pass the client's name to the mount if provided" do
+ @mount1.expects(:allowed?).with("myhost", nil)
+ @config.authorized?("/one/my/file", :node => "myhost")
+ end
+
+ it "should pass the client's IP to the mount if provided" do
+ @mount1.expects(:allowed?).with("myhost", "myip")
+ @config.authorized?("/one/my/file", :node => "myhost", :ipaddress => "myip")
+ end
+
+ it "should return true if the mount allows the client" do
+ @mount1.expects(:allowed?).returns(true)
+ @config.authorized?("/one/my/file").should be_true
+ end
+
+ it "should return false if the mount denies the client" do
+ @mount1.expects(:allowed?).returns(false)
+ @config.authorized?("/one/my/file").should be_false
+ end
+ end
+end \ No newline at end of file
diff --git a/spec/unit/file_serving/configuration/parser.rb b/spec/unit/file_serving/configuration/parser.rb
index aa296cf43..df2f629d5 100755
--- a/spec/unit/file_serving/configuration/parser.rb
+++ b/spec/unit/file_serving/configuration/parser.rb
@@ -10,8 +10,17 @@ describe Puppet::FileServing::Configuration::Parser do
end
end
+
module FSConfigurationParserTesting
- def setup
+ def mock_file_content(content)
+ # We want an array, but we actually want our carriage returns on all of it.
+ lines = content.split("\n").collect { |l| l + "\n" }
+ @filehandle.stubs(:each).multiple_yields(*lines)
+ end
+end
+
+describe Puppet::FileServing::Configuration::Parser do
+ before :each do
@path = "/my/config.conf"
FileTest.stubs(:exists?).with(@path).returns(true)
FileTest.stubs(:readable?).with(@path).returns(true)
@@ -20,113 +29,107 @@ module FSConfigurationParserTesting
@parser = Puppet::FileServing::Configuration::Parser.new(@path)
end
- def mock_file_content(content)
- # We want an array, but we actually want our carriage returns on all of it.
- lines = content.split("\n").collect { |l| l + "\n" }
- @filehandle.stubs(:each).multiple_yields(*lines)
- end
-end
-
-describe Puppet::FileServing::Configuration::Parser, " when parsing" do
- include FSConfigurationParserTesting
+ describe Puppet::FileServing::Configuration::Parser, " when parsing" do
+ include FSConfigurationParserTesting
- before do
- @parser.stubs(:add_modules_mount)
- end
+ before do
+ @parser.stubs(:add_modules_mount)
+ end
- it "should allow comments" do
- @filehandle.expects(:each).yields("# this is a comment\n")
- proc { @parser.parse }.should_not raise_error
- end
+ it "should allow comments" do
+ @filehandle.expects(:each).yields("# this is a comment\n")
+ proc { @parser.parse }.should_not raise_error
+ end
- it "should allow blank lines" do
- @filehandle.expects(:each).yields("\n")
- proc { @parser.parse }.should_not raise_error
- end
+ it "should allow blank lines" do
+ @filehandle.expects(:each).yields("\n")
+ proc { @parser.parse }.should_not raise_error
+ end
- it "should create a new mount for each section in the configuration" do
- mount1 = mock 'one'
- mount2 = mock 'two'
- Puppet::FileServing::Mount.expects(:new).with("one").returns(mount1)
- Puppet::FileServing::Mount.expects(:new).with("two").returns(mount2)
- mock_file_content "[one]\n[two]\n"
- @parser.parse
- end
+ it "should create a new mount for each section in the configuration" do
+ mount1 = mock 'one'
+ mount2 = mock 'two'
+ Puppet::FileServing::Mount.expects(:new).with("one").returns(mount1)
+ Puppet::FileServing::Mount.expects(:new).with("two").returns(mount2)
+ mock_file_content "[one]\n[two]\n"
+ @parser.parse
+ end
- # This test is almost the exact same as the previous one.
- it "should return a hash of the created mounts" do
- mount1 = mock 'one'
- mount2 = mock 'two'
- Puppet::FileServing::Mount.expects(:new).with("one").returns(mount1)
- Puppet::FileServing::Mount.expects(:new).with("two").returns(mount2)
- mock_file_content "[one]\n[two]\n"
+ # This test is almost the exact same as the previous one.
+ it "should return a hash of the created mounts" do
+ mount1 = mock 'one'
+ mount2 = mock 'two'
+ Puppet::FileServing::Mount.expects(:new).with("one").returns(mount1)
+ Puppet::FileServing::Mount.expects(:new).with("two").returns(mount2)
+ mock_file_content "[one]\n[two]\n"
- @parser.parse.should == {"one" => mount1, "two" => mount2}
- end
+ @parser.parse.should == {"one" => mount1, "two" => mount2}
+ end
- it "should only allow mount names that are alphanumeric plus dashes" do
- mock_file_content "[a*b]\n"
- proc { @parser.parse }.should raise_error(ArgumentError)
- end
+ it "should only allow mount names that are alphanumeric plus dashes" do
+ mock_file_content "[a*b]\n"
+ proc { @parser.parse }.should raise_error(ArgumentError)
+ end
- it "should fail if the value for path/allow/deny starts with an equals sign" do
- mock_file_content "[one]\npath = /testing"
- proc { @parser.parse }.should raise_error(ArgumentError)
+ it "should fail if the value for path/allow/deny starts with an equals sign" do
+ mock_file_content "[one]\npath = /testing"
+ proc { @parser.parse }.should raise_error(ArgumentError)
+ end
end
-end
-describe Puppet::FileServing::Configuration::Parser, " when parsing mount attributes" do
- include FSConfigurationParserTesting
+ describe Puppet::FileServing::Configuration::Parser, " when parsing mount attributes" do
+ include FSConfigurationParserTesting
- before do
- @mount = stub 'mount', :name => "one"
- Puppet::FileServing::Mount.expects(:new).with("one").returns(@mount)
- @parser.stubs(:add_modules_mount)
- end
+ before do
+ @mount = stub 'mount', :name => "one"
+ Puppet::FileServing::Mount.expects(:new).with("one").returns(@mount)
+ @parser.stubs(:add_modules_mount)
+ end
- it "should set the mount path to the path attribute from that section" do
- mock_file_content "[one]\npath /some/path\n"
+ it "should set the mount path to the path attribute from that section" do
+ mock_file_content "[one]\npath /some/path\n"
- @mount.expects(:path=).with("/some/path")
- @parser.parse
- end
+ @mount.expects(:path=).with("/some/path")
+ @parser.parse
+ end
- it "should tell the mount to allow any allow values from the section" do
- mock_file_content "[one]\nallow something\n"
+ it "should tell the mount to allow any allow values from the section" do
+ mock_file_content "[one]\nallow something\n"
- @mount.expects(:info)
- @mount.expects(:allow).with("something")
- @parser.parse
- end
+ @mount.expects(:info)
+ @mount.expects(:allow).with("something")
+ @parser.parse
+ end
- it "should tell the mount to deny any deny values from the section" do
- mock_file_content "[one]\ndeny something\n"
+ it "should tell the mount to deny any deny values from the section" do
+ mock_file_content "[one]\ndeny something\n"
- @mount.expects(:info)
- @mount.expects(:deny).with("something")
- @parser.parse
- end
+ @mount.expects(:info)
+ @mount.expects(:deny).with("something")
+ @parser.parse
+ end
- it "should fail on any attributes other than path, allow, and deny" do
- mock_file_content "[one]\ndo something\n"
+ it "should fail on any attributes other than path, allow, and deny" do
+ mock_file_content "[one]\ndo something\n"
- proc { @parser.parse }.should raise_error(ArgumentError)
+ proc { @parser.parse }.should raise_error(ArgumentError)
+ end
end
-end
-describe Puppet::FileServing::Configuration::Parser, " when parsing the modules mount" do
- include FSConfigurationParserTesting
+ describe Puppet::FileServing::Configuration::Parser, " when parsing the modules mount" do
+ include FSConfigurationParserTesting
- before do
- @mount = stub 'mount', :name => "modules"
- Puppet::FileServing::Mount.expects(:new).with("modules").returns(@mount)
- end
+ before do
+ @mount = stub 'mount', :name => "modules"
+ Puppet::FileServing::Mount.expects(:new).with("modules").returns(@mount)
+ end
- it "should warn if a path is set" do
- mock_file_content "[modules]\npath /some/path\n"
+ it "should warn if a path is set" do
+ mock_file_content "[modules]\npath /some/path\n"
- @modules.expects(:path=).never
- Puppet.expects(:warning)
- @parser.parse
+ @modules.expects(:path=).never
+ Puppet.expects(:warning)
+ @parser.parse
+ end
end
-end
+end \ No newline at end of file
diff --git a/spec/unit/file_serving/file_base.rb b/spec/unit/file_serving/file_base.rb
index 4c7724f7c..ded6ae4a8 100755
--- a/spec/unit/file_serving/file_base.rb
+++ b/spec/unit/file_serving/file_base.rb
@@ -4,7 +4,7 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/file_serving/file_base'
-describe Puppet::FileServing::FileBase, " when initializing" do
+describe Puppet::FileServing::FileBase do
it "should accept a key in the form of a URI" do
Puppet::FileServing::FileBase.new("puppet://host/module/dir/file").key.should == "puppet://host/module/dir/file"
end
@@ -13,7 +13,11 @@ describe Puppet::FileServing::FileBase, " when initializing" do
Puppet::FileServing::FileBase.new("puppet://host/module/dir/file", :links => :manage).links.should == :manage
end
- it "should fail if :links is set to anything other than :manage or :follow" do
+ it "should consider :ignore links equivalent to :manage links" do
+ Puppet::FileServing::FileBase.new("puppet://host/module/dir/file", :links => :ignore).links.should == :manage
+ end
+
+ it "should fail if :links is set to anything other than :manage, :follow, or :ignore" do
proc { Puppet::FileServing::FileBase.new("puppet://host/module/dir/file", :links => :else) }.should raise_error(ArgumentError)
end
@@ -30,72 +34,91 @@ describe Puppet::FileServing::FileBase, " when initializing" do
FileTest.stubs(:exists?).returns(true)
Puppet::FileServing::FileBase.new("puppet://host/module/dir/file", :relative_path => "my/file").relative_path.should == "my/file"
end
-end
-describe Puppet::FileServing::FileBase, " when setting the base path" do
- before do
- @file = Puppet::FileServing::FileBase.new("puppet://host/module/dir/file")
+ it "should have a means of determining if the file exists" do
+ Puppet::FileServing::FileBase.new("blah").should respond_to(:exist?)
end
- it "should require that the base path be fully qualified" do
- FileTest.stubs(:exists?).returns(true)
- proc { @file.path = "unqualified/file" }.should raise_error(ArgumentError)
+ it "should correctly indicate if the file is present" do
+ File.expects(:lstat).with("/my/file").returns(mock("stat"))
+ Puppet::FileServing::FileBase.new("blah", :path => "/my/file").exist?.should be_true
end
-end
-describe Puppet::FileServing::FileBase, " when setting the relative path" do
- it "should require that the relative path be unqualified" do
- @file = Puppet::FileServing::FileBase.new("puppet://host/module/dir/file")
- FileTest.stubs(:exists?).returns(true)
- proc { @file.relative_path = "/qualified/file" }.should raise_error(ArgumentError)
+ it "should correctly indicate if the file is asbsent" do
+ File.expects(:lstat).with("/my/file").raises RuntimeError
+ Puppet::FileServing::FileBase.new("blah", :path => "/my/file").exist?.should be_false
end
-end
-describe Puppet::FileServing::FileBase, " when determining the full file path" do
- before do
- @file = Puppet::FileServing::FileBase.new("mykey", :path => "/this/file")
- end
+ describe "when setting the base path" do
+ before do
+ @file = Puppet::FileServing::FileBase.new("puppet://host/module/dir/file")
+ end
- it "should return the path if there is no relative path" do
- @file.full_path.should == "/this/file"
+ it "should require that the base path be fully qualified" do
+ FileTest.stubs(:exists?).returns(true)
+ proc { @file.path = "unqualified/file" }.should raise_error(ArgumentError)
+ end
end
- it "should return the path joined with the relative path if there is a relative path" do
- @file.relative_path = "not/qualified"
- @file.full_path.should == "/this/file/not/qualified"
+ describe "when setting the relative path" do
+ it "should require that the relative path be unqualified" do
+ @file = Puppet::FileServing::FileBase.new("puppet://host/module/dir/file")
+ FileTest.stubs(:exists?).returns(true)
+ proc { @file.relative_path = "/qualified/file" }.should raise_error(ArgumentError)
+ end
end
- it "should should fail if there is no path set" do
- @file = Puppet::FileServing::FileBase.new("not/qualified")
- proc { @file.full_path }.should raise_error(ArgumentError)
- end
-end
+ describe "when determining the full file path" do
+ before do
+ @file = Puppet::FileServing::FileBase.new("mykey", :path => "/this/file")
+ end
-describe Puppet::FileServing::FileBase, " when stat'ing files" do
- before do
- @file = Puppet::FileServing::FileBase.new("mykey", :path => "/this/file")
- end
+ it "should return the path if there is no relative path" do
+ @file.full_path.should == "/this/file"
+ end
- it "should stat the file's full path" do
- @file.stubs(:full_path).returns("/this/file")
- File.expects(:lstat).with("/this/file").returns stub("stat", :ftype => "file")
- @file.stat
- end
+ it "should return the path if the relative_path is set to ''" do
+ @file.relative_path = ""
+ @file.full_path.should == "/this/file"
+ end
- it "should fail if the file does not exist" do
- @file.stubs(:full_path).returns("/this/file")
- File.expects(:lstat).with("/this/file").raises(Errno::ENOENT)
- proc { @file.stat }.should raise_error(Errno::ENOENT)
- end
+ it "should return the path joined with the relative path if there is a relative path and it is not set to '/' or ''" do
+ @file.relative_path = "not/qualified"
+ @file.full_path.should == "/this/file/not/qualified"
+ end
- it "should use :lstat if :links is set to :manage" do
- File.expects(:lstat).with("/this/file").returns stub("stat", :ftype => "file")
- @file.stat
+ it "should should fail if there is no path set" do
+ @file = Puppet::FileServing::FileBase.new("not/qualified")
+ proc { @file.full_path }.should raise_error(ArgumentError)
+ end
end
- it "should use :stat if :links is set to :follow" do
- File.expects(:stat).with("/this/file").returns stub("stat", :ftype => "file")
- @file.links = :follow
- @file.stat
+ describe "when stat'ing files" do
+ before do
+ @file = Puppet::FileServing::FileBase.new("mykey", :path => "/this/file")
+ end
+
+ it "should stat the file's full path" do
+ @file.stubs(:full_path).returns("/this/file")
+ File.expects(:lstat).with("/this/file").returns stub("stat", :ftype => "file")
+ @file.stat
+ end
+
+ it "should fail if the file does not exist" do
+ @file.stubs(:full_path).returns("/this/file")
+ File.expects(:lstat).with("/this/file").raises(Errno::ENOENT)
+ proc { @file.stat }.should raise_error(Errno::ENOENT)
+ end
+
+ it "should use :lstat if :links is set to :manage" do
+ File.expects(:lstat).with("/this/file").returns stub("stat", :ftype => "file")
+ @file.stat
+ end
+
+ it "should use :stat if :links is set to :follow" do
+ File.expects(:stat).with("/this/file").returns stub("stat", :ftype => "file")
+ @file.links = :follow
+ @file.stat
+ end
end
end
diff --git a/spec/unit/file_serving/metadata.rb b/spec/unit/file_serving/metadata.rb
index f7ab0c8d6..9743370c1 100755
--- a/spec/unit/file_serving/metadata.rb
+++ b/spec/unit/file_serving/metadata.rb
@@ -26,8 +26,8 @@ describe Puppet::FileServing::Metadata, " when finding the file to use for setti
@metadata.path = @full
- # Use a symlink because it's easier to test -- no checksumming
- @stat = stub "stat", :uid => 10, :gid => 20, :mode => 0755, :ftype => "symlink"
+ # Use a link because it's easier to test -- no checksumming
+ @stat = stub "stat", :uid => 10, :gid => 20, :mode => 0755, :ftype => "link"
end
it "should accept a base path path to which the file should be relative" do
@@ -55,16 +55,19 @@ end
describe Puppet::FileServing::Metadata, " when collecting attributes" do
before do
@path = "/my/file"
- @stat = stub 'stat', :uid => 10, :gid => 20, :mode => 0755, :ftype => "file"
+ # Use a real file mode, so we can validate the masking is done.
+ @stat = stub 'stat', :uid => 10, :gid => 20, :mode => 33261, :ftype => "file"
File.stubs(:lstat).returns(@stat)
- @filehandle = mock 'filehandle'
- @filehandle.expects(:each_line).yields("some content\n")
- File.stubs(:open).with(@path, 'r').yields(@filehandle)
@checksum = Digest::MD5.hexdigest("some content\n")
@metadata = Puppet::FileServing::Metadata.new("file", :path => "/my/file")
+ @metadata.stubs(:md5_file).returns(@checksum)
@metadata.collect_attributes
end
+ it "should be able to produce xmlrpc-style attribute information" do
+ @metadata.should respond_to(:attributes_with_tabs)
+ end
+
# LAK:FIXME This should actually change at some point
it "should set the owner by id" do
@metadata.owner.should be_instance_of(Fixnum)
@@ -83,28 +86,63 @@ describe Puppet::FileServing::Metadata, " when collecting attributes" do
@metadata.group.should == 20
end
- it "should set the mode to a string version of the mode in octal" do
- @metadata.mode.should == "755"
- end
-
- it "should set the mode to the file's current mode" do
- @metadata.mode.should == "755"
+ it "should set the mode to the file's masked mode" do
+ @metadata.mode.should == 0755
end
it "should set the checksum to the file's current checksum" do
@metadata.checksum.should == "{md5}" + @checksum
end
- it "should default to a checksum of type MD5" do
- @metadata.checksum.should == "{md5}" + @checksum
+ describe "when managing files" do
+ it "should default to a checksum of type MD5" do
+ @metadata.checksum.should == "{md5}" + @checksum
+ end
+
+ it "should produce tab-separated mode, type, owner, group, and checksum for xmlrpc" do
+ @metadata.attributes_with_tabs.should == "#{0755.to_s}\tfile\t10\t20\t{md5}#{@checksum}"
+ end
+ end
+
+ describe "when managing directories" do
+ before do
+ @stat.stubs(:ftype).returns("directory")
+ @time = Time.now
+ @metadata.expects(:ctime_file).returns(@time)
+ @metadata.collect_attributes
+ end
+
+ it "should only use checksums of type 'ctime' for directories" do
+ @metadata.checksum.should == "{ctime}" + @time.to_s
+ end
+
+ it "should produce tab-separated mode, type, owner, group, and checksum for xmlrpc" do
+ @metadata.attributes_with_tabs.should == "#{0755.to_s}\tdirectory\t10\t20\t{ctime}#{@time.to_s}"
+ end
+ end
+
+ describe "when managing links" do
+ before do
+ @stat.stubs(:ftype).returns("link")
+ File.expects(:readlink).with("/my/file").returns("/path/to/link")
+ @metadata.collect_attributes
+ end
+
+ it "should read links instead of returning their checksums" do
+ @metadata.destination.should == "/path/to/link"
+ end
+
+ it "should produce tab-separated mode, type, owner, group, and destination for xmlrpc" do
+ @metadata.attributes_with_tabs.should == "#{0755.to_s}\tlink\t10\t20\t/path/to/link"
+ end
end
end
-describe Puppet::FileServing::Metadata, " when pointing to a symlink" do
- it "should store the destination of the symlink in :destination if links are :manage" do
+describe Puppet::FileServing::Metadata, " when pointing to a link" do
+ it "should store the destination of the link in :destination if links are :manage" do
file = Puppet::FileServing::Metadata.new("mykey", :links => :manage, :path => "/base/path/my/file")
- File.expects(:lstat).with("/base/path/my/file").returns stub("stat", :uid => 1, :gid => 2, :ftype => "symlink", :mode => 0755)
+ File.expects(:lstat).with("/base/path/my/file").returns stub("stat", :uid => 1, :gid => 2, :ftype => "link", :mode => 0755)
File.expects(:readlink).with("/base/path/my/file").returns "/some/other/path"
file.collect_attributes
@@ -114,7 +152,7 @@ describe Puppet::FileServing::Metadata, " when pointing to a symlink" do
it "should not collect the checksum" do
file = Puppet::FileServing::Metadata.new("my/file", :links => :manage, :path => "/base/path/my/file")
- File.expects(:lstat).with("/base/path/my/file").returns stub("stat", :uid => 1, :gid => 2, :ftype => "symlink", :mode => 0755)
+ File.expects(:lstat).with("/base/path/my/file").returns stub("stat", :uid => 1, :gid => 2, :ftype => "link", :mode => 0755)
File.expects(:readlink).with("/base/path/my/file").returns "/some/other/path"
file.collect_attributes
diff --git a/spec/unit/indirector/catalog/compiler.rb b/spec/unit/indirector/catalog/compiler.rb
index 77638a410..a4a0acd58 100755
--- a/spec/unit/indirector/catalog/compiler.rb
+++ b/spec/unit/indirector/catalog/compiler.rb
@@ -171,7 +171,7 @@ describe Puppet::Node::Catalog::Compiler, " when determining a client's availabl
end
it "should use the client's Facts version as the available catalog version if it is the most recent" do
- Puppet::Node::Facts.expects(:version).with(@name).returns(5)
+ Puppet::Node::Facts.stubs(:version).with(@name).returns(5)
Puppet::Node.expects(:version).with(@name).returns(3)
@catalog.interpreter.stubs(:catalog_version).returns(4)
@@ -179,7 +179,7 @@ describe Puppet::Node::Catalog::Compiler, " when determining a client's availabl
end
it "should use the client's Node version as the available catalog version if it is the most recent" do
- Puppet::Node::Facts.expects(:version).with(@name).returns(3)
+ Puppet::Node::Facts.stubs(:version).with(@name).returns(3)
Puppet::Node.expects(:version).with(@name).returns(5)
@catalog.interpreter.stubs(:catalog_version).returns(4)
@@ -187,7 +187,7 @@ describe Puppet::Node::Catalog::Compiler, " when determining a client's availabl
end
it "should use the last parse date as the available catalog version if it is the most recent" do
- Puppet::Node::Facts.expects(:version).with(@name).returns(3)
+ Puppet::Node::Facts.stubs(:version).with(@name).returns(3)
Puppet::Node.expects(:version).with(@name).returns(4)
@catalog.interpreter.stubs(:catalog_version).returns(5)
diff --git a/spec/unit/indirector/checksum/file.rb b/spec/unit/indirector/checksum/file.rb
index 82319fa40..4f8ee98b2 100755
--- a/spec/unit/indirector/checksum/file.rb
+++ b/spec/unit/indirector/checksum/file.rb
@@ -7,22 +7,6 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/checksum/file'
-module FileChecksumTesting
- def setup
- Puppet.settings.stubs(:use)
- @store = Puppet::Checksum::File.new
-
- @value = "70924d6fa4b2d745185fa4660703a5c0"
- @sum = stub 'sum', :name => @value
-
- @dir = "/what/ever"
-
- Puppet.stubs(:[]).with(:bucketdir).returns(@dir)
-
- @path = @store.path(@value)
- end
-end
-
describe Puppet::Checksum::File do
it "should be a subclass of the File terminus class" do
Puppet::Checksum::File.superclass.should equal(Puppet::Indirector::File)
@@ -40,103 +24,117 @@ describe Puppet::Checksum::File, " when initializing" do
end
end
-describe Puppet::Checksum::File, " when determining file paths" do
- include FileChecksumTesting
- # I was previously passing the object in.
- it "should use the value passed in to path() as the checksum" do
- @value.expects(:name).never
- @store.path(@value)
- end
+describe Puppet::Checksum::File do
+ before :each do
+ Puppet.settings.stubs(:use)
+ @store = Puppet::Checksum::File.new
- it "should use the value of the :bucketdir setting as the root directory" do
- @path.should =~ %r{^#{@dir}}
- end
+ @value = "70924d6fa4b2d745185fa4660703a5c0"
+ @sum = stub 'sum', :name => @value
- it "should choose a path 8 directories deep with each directory name being the respective character in the checksum" do
- dirs = @value[0..7].split("").join(File::SEPARATOR)
- @path.should be_include(dirs)
- end
+ @dir = "/what/ever"
- it "should use the full checksum as the final directory name" do
- File.basename(File.dirname(@path)).should == @value
- end
+ Puppet.stubs(:[]).with(:bucketdir).returns(@dir)
- it "should use 'contents' as the actual file name" do
- File.basename(@path).should == "contents"
+ @path = @store.path(@value)
end
- it "should use the bucketdir, the 8 sum character directories, the full checksum, and 'contents' as the full file name" do
- @path.should == [@dir, @value[0..7].split(""), @value, "contents"].flatten.join(File::SEPARATOR)
- end
-end
-describe Puppet::Checksum::File, " when retrieving files" do
- include FileChecksumTesting
+ describe Puppet::Checksum::File, " when determining file paths" do
- # The smallest test that will use the calculated path
- it "should look for the calculated path" do
- File.expects(:exist?).with(@path).returns(false)
- @store.find(@value)
- end
+ # I was previously passing the object in.
+ it "should use the value passed in to path() as the checksum" do
+ @value.expects(:name).never
+ @store.path(@value)
+ end
- it "should return an instance of Puppet::Checksum created with the content if the file exists" do
- content = "my content"
- sum = stub 'file'
- Puppet::Checksum.expects(:new).with(content).returns(sum)
+ it "should use the value of the :bucketdir setting as the root directory" do
+ @path.should =~ %r{^#{@dir}}
+ end
- File.expects(:exist?).with(@path).returns(true)
- File.expects(:read).with(@path).returns(content)
+ it "should choose a path 8 directories deep with each directory name being the respective character in the checksum" do
+ dirs = @value[0..7].split("").join(File::SEPARATOR)
+ @path.should be_include(dirs)
+ end
- @store.find(@value).should equal(sum)
- end
+ it "should use the full checksum as the final directory name" do
+ File.basename(File.dirname(@path)).should == @value
+ end
- it "should return nil if no file is found" do
- File.expects(:exist?).with(@path).returns(false)
- @store.find(@value).should be_nil
- end
+ it "should use 'contents' as the actual file name" do
+ File.basename(@path).should == "contents"
+ end
- it "should fail intelligently if a found file cannot be read" do
- File.expects(:exist?).with(@path).returns(true)
- File.expects(:read).with(@path).raises(RuntimeError)
- proc { @store.find(@value) }.should raise_error(Puppet::Error)
+ it "should use the bucketdir, the 8 sum character directories, the full checksum, and 'contents' as the full file name" do
+ @path.should == [@dir, @value[0..7].split(""), @value, "contents"].flatten.join(File::SEPARATOR)
+ end
end
-end
-describe Puppet::Checksum::File, " when saving files" do
- include FileChecksumTesting
+ describe Puppet::Checksum::File, " when retrieving files" do
+
+ # The smallest test that will use the calculated path
+ it "should look for the calculated path" do
+ File.expects(:exist?).with(@path).returns(false)
+ @store.find(@value)
+ end
+
+ it "should return an instance of Puppet::Checksum created with the content if the file exists" do
+ content = "my content"
+ sum = stub 'file'
+ Puppet::Checksum.expects(:new).with(content).returns(sum)
+
+ File.expects(:exist?).with(@path).returns(true)
+ File.expects(:read).with(@path).returns(content)
- # LAK:FIXME I don't know how to include in the spec the fact that we're
- # using the superclass's save() method and thus are acquiring all of
- # it's behaviours.
- it "should save the content to the calculated path" do
- File.stubs(:directory?).with(File.dirname(@path)).returns(true)
- File.expects(:open).with(@path, "w")
+ @store.find(@value).should equal(sum)
+ end
- file = stub 'file', :name => @value
- @store.save(file)
+ it "should return nil if no file is found" do
+ File.expects(:exist?).with(@path).returns(false)
+ @store.find(@value).should be_nil
+ end
+
+ it "should fail intelligently if a found file cannot be read" do
+ File.expects(:exist?).with(@path).returns(true)
+ File.expects(:read).with(@path).raises(RuntimeError)
+ proc { @store.find(@value) }.should raise_error(Puppet::Error)
+ end
end
- it "should make any directories necessary for storage" do
- FileUtils.expects(:mkdir_p).with do |arg|
- File.umask == 0007 and arg == File.dirname(@path)
+ describe Puppet::Checksum::File, " when saving files" do
+
+ # LAK:FIXME I don't know how to include in the spec the fact that we're
+ # using the superclass's save() method and thus are acquiring all of
+ # it's behaviours.
+ it "should save the content to the calculated path" do
+ File.stubs(:directory?).with(File.dirname(@path)).returns(true)
+ File.expects(:open).with(@path, "w")
+
+ file = stub 'file', :name => @value
+ @store.save(file)
end
- File.expects(:directory?).with(File.dirname(@path)).returns(true)
- File.expects(:open).with(@path, "w")
- file = stub 'file', :name => @value
- @store.save(file)
+ it "should make any directories necessary for storage" do
+ FileUtils.expects(:mkdir_p).with do |arg|
+ File.umask == 0007 and arg == File.dirname(@path)
+ end
+ File.expects(:directory?).with(File.dirname(@path)).returns(true)
+ File.expects(:open).with(@path, "w")
+
+ file = stub 'file', :name => @value
+ @store.save(file)
+ end
end
-end
-describe Puppet::Checksum::File, " when deleting files" do
- include FileChecksumTesting
+ describe Puppet::Checksum::File, " when deleting files" do
- it "should remove the file at the calculated path" do
- File.expects(:exist?).with(@path).returns(true)
- File.expects(:unlink).with(@path)
+ it "should remove the file at the calculated path" do
+ File.expects(:exist?).with(@path).returns(true)
+ File.expects(:unlink).with(@path)
- file = stub 'file', :name => @value
- @store.destroy(file)
+ file = stub 'file', :name => @value
+ @store.destroy(file)
+ end
end
-end
+end \ No newline at end of file
diff --git a/spec/unit/indirector/direct_file_server.rb b/spec/unit/indirector/direct_file_server.rb
index 2a8ec1a49..9f3652536 100755
--- a/spec/unit/indirector/direct_file_server.rb
+++ b/spec/unit/indirector/direct_file_server.rb
@@ -7,8 +7,8 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/indirector/direct_file_server'
-module DirectFileServerTerminusTesting
- def setup
+describe Puppet::Indirector::DirectFileServer do
+ before :each do
Puppet::Indirector::Terminus.stubs(:register_terminus_class)
@model = mock 'model'
@indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model
@@ -24,72 +24,69 @@ module DirectFileServerTerminusTesting
@uri = "file:///my/local"
end
-end
-describe Puppet::Indirector::DirectFileServer, "when finding a single file" do
- include DirectFileServerTerminusTesting
+ describe Puppet::Indirector::DirectFileServer, "when finding a single file" do
- it "should return nil if the file does not exist" do
- FileTest.expects(:exists?).with("/my/local").returns false
- @server.find(@uri).should be_nil
- end
+ it "should return nil if the file does not exist" do
+ FileTest.expects(:exists?).with("/my/local").returns false
+ @server.find(@uri).should be_nil
+ end
- it "should return a Content instance created with the full path to the file if the file exists" do
- FileTest.expects(:exists?).with("/my/local").returns true
- @model.expects(:new).returns(:mycontent)
- @server.find(@uri).should == :mycontent
+ it "should return a Content instance created with the full path to the file if the file exists" do
+ FileTest.expects(:exists?).with("/my/local").returns true
+ @model.expects(:new).returns(:mycontent)
+ @server.find(@uri).should == :mycontent
+ end
end
-end
-describe Puppet::Indirector::DirectFileServer, "when creating the instance for a single found file" do
- include DirectFileServerTerminusTesting
+ describe Puppet::Indirector::DirectFileServer, "when creating the instance for a single found file" do
- before do
- @data = mock 'content'
- @data.stubs(:collect_attributes)
- FileTest.expects(:exists?).with("/my/local").returns true
- end
+ before do
+ @data = mock 'content'
+ @data.stubs(:collect_attributes)
+ FileTest.expects(:exists?).with("/my/local").returns true
+ end
- it "should create the Content instance with the original key as the key" do
- @model.expects(:new).with { |key, options| key == @uri }.returns(@data)
- @server.find(@uri)
- end
+ it "should create the Content instance with the original key as the key" do
+ @model.expects(:new).with { |key, options| key == @uri }.returns(@data)
+ @server.find(@uri)
+ end
- it "should pass the full path to the instance" do
- @model.expects(:new).with { |key, options| options[:path] == "/my/local" }.returns(@data)
- @server.find(@uri)
- end
+ it "should pass the full path to the instance" do
+ @model.expects(:new).with { |key, options| options[:path] == "/my/local" }.returns(@data)
+ @server.find(@uri)
+ end
- it "should pass the :links setting on to the created Content instance if the file exists and there is a value for :links" do
- @model.expects(:new).returns(@data)
- @data.expects(:links=).with(:manage)
- @server.find(@uri, :links => :manage)
+ it "should pass the :links setting on to the created Content instance if the file exists and there is a value for :links" do
+ @model.expects(:new).returns(@data)
+ @data.expects(:links=).with(:manage)
+ @server.find(@uri, :links => :manage)
+ end
end
-end
-describe Puppet::Indirector::DirectFileServer, "when searching for multiple files" do
- include DirectFileServerTerminusTesting
+ describe Puppet::Indirector::DirectFileServer, "when searching for multiple files" do
- it "should return nil if the file does not exist" do
- FileTest.expects(:exists?).with("/my/local").returns false
- @server.find(@uri).should be_nil
- end
+ it "should return nil if the file does not exist" do
+ FileTest.expects(:exists?).with("/my/local").returns false
+ @server.find(@uri).should be_nil
+ end
- it "should pass the original key to :path2instances" do
- FileTest.expects(:exists?).with("/my/local").returns true
- @server.expects(:path2instances).with { |uri, path, options| uri == @uri }
- @server.search(@uri)
- end
+ it "should pass the original key to :path2instances" do
+ FileTest.expects(:exists?).with("/my/local").returns true
+ @server.expects(:path2instances).with { |uri, path, options| uri == @uri }
+ @server.search(@uri)
+ end
- it "should use :path2instances from the terminus_helper to return instances if the file exists" do
- FileTest.expects(:exists?).with("/my/local").returns true
- @server.expects(:path2instances)
- @server.search(@uri)
- end
+ it "should use :path2instances from the terminus_helper to return instances if the file exists" do
+ FileTest.expects(:exists?).with("/my/local").returns true
+ @server.expects(:path2instances)
+ @server.search(@uri)
+ end
- it "should pass any options on to :path2instances" do
- FileTest.expects(:exists?).with("/my/local").returns true
- @server.expects(:path2instances).with { |uri, path, options| options == {:testing => :one, :other => :two}}
- @server.search(@uri, :testing => :one, :other => :two)
+ it "should pass any options on to :path2instances" do
+ FileTest.expects(:exists?).with("/my/local").returns true
+ @server.expects(:path2instances).with { |uri, path, options| options == {:testing => :one, :other => :two}}
+ @server.search(@uri, :testing => :one, :other => :two)
+ end
end
-end
+end \ No newline at end of file
diff --git a/spec/unit/indirector/facts/facter.rb b/spec/unit/indirector/facts/facter.rb
index 1fad4c859..0974a60ec 100755
--- a/spec/unit/indirector/facts/facter.rb
+++ b/spec/unit/indirector/facts/facter.rb
@@ -31,49 +31,46 @@ describe Puppet::Node::Facts::Facter do
end
end
-module TestingCodeFacts
- def setup
+describe Puppet::Node::Facts::Facter do
+ before :each do
@facter = Puppet::Node::Facts::Facter.new
Facter.stubs(:to_hash).returns({})
@name = "me"
@facts = @facter.find(@name)
end
-end
-describe Puppet::Node::Facts::Facter, " when finding facts" do
- include TestingCodeFacts
+ describe Puppet::Node::Facts::Facter, " when finding facts" do
- it "should return a Facts instance" do
- @facts.should be_instance_of(Puppet::Node::Facts)
- end
+ it "should return a Facts instance" do
+ @facts.should be_instance_of(Puppet::Node::Facts)
+ end
- it "should return a Facts instance with the provided key as the name" do
- @facts.name.should == @name
- end
+ it "should return a Facts instance with the provided key as the name" do
+ @facts.name.should == @name
+ end
- it "should return the Facter facts as the values in the Facts instance" do
- Facter.expects(:to_hash).returns("one" => "two")
- facts = @facter.find(@name)
- facts.values["one"].should == "two"
+ it "should return the Facter facts as the values in the Facts instance" do
+ Facter.expects(:to_hash).returns("one" => "two")
+ facts = @facter.find(@name)
+ facts.values["one"].should == "two"
+ end
end
-end
-describe Puppet::Node::Facts::Facter, " when saving facts" do
- include TestingCodeFacts
+ describe Puppet::Node::Facts::Facter, " when saving facts" do
- it "should fail" do
- proc { @facter.save(@facts) }.should raise_error(Puppet::DevError)
+ it "should fail" do
+ proc { @facter.save(@facts) }.should raise_error(Puppet::DevError)
+ end
end
-end
-describe Puppet::Node::Facts::Facter, " when destroying facts" do
- include TestingCodeFacts
+ describe Puppet::Node::Facts::Facter, " when destroying facts" do
- it "should fail" do
- proc { @facter.destroy(@facts) }.should raise_error(Puppet::DevError)
+ it "should fail" do
+ proc { @facter.destroy(@facts) }.should raise_error(Puppet::DevError)
+ end
end
-end
-describe Puppet::Node::Facts::Facter, " when loading facts from the factpath" do
- it "should load every fact in each factpath directory"
-end
+ describe Puppet::Node::Facts::Facter, " when loading facts from the factpath" do
+ it "should load every fact in each factpath directory"
+ end
+end \ No newline at end of file
diff --git a/spec/unit/indirector/file.rb b/spec/unit/indirector/file.rb
index 216c9bfe1..37740f0d0 100755
--- a/spec/unit/indirector/file.rb
+++ b/spec/unit/indirector/file.rb
@@ -3,8 +3,9 @@
require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/indirector/file'
-module FileTerminusTesting
- def setup
+
+describe Puppet::Indirector::File do
+ before :each do
Puppet::Indirector::Terminus.stubs(:register_terminus_class)
@model = mock 'model'
@indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model
@@ -21,140 +22,137 @@ module FileTerminusTesting
@path = "/my/file"
@dir = "/my"
end
-end
+
+ describe Puppet::Indirector::File, " when finding files" do
-describe Puppet::Indirector::File, " when finding files" do
- include FileTerminusTesting
+ it "should provide a method to return file contents at a specified path" do
+ @searcher.should respond_to(:find)
+ end
- it "should provide a method to return file contents at a specified path" do
- @searcher.should respond_to(:find)
- end
+ it "should return file contents as an instance of the model" do
+ content = "my content"
- it "should return file contents as an instance of the model" do
- content = "my content"
+ file = mock 'file'
+ @model.expects(:new).with(content).returns(file)
- file = mock 'file'
- @model.expects(:new).with(content).returns(file)
+ File.expects(:exist?).with(@path).returns(true)
+ File.expects(:read).with(@path).returns(content)
+ @searcher.find(@path)
+ end
- File.expects(:exist?).with(@path).returns(true)
- File.expects(:read).with(@path).returns(content)
- @searcher.find(@path)
- end
+ it "should create the model instance with the content as the only argument to initialization" do
+ content = "my content"
- it "should create the model instance with the content as the only argument to initialization" do
- content = "my content"
+ file = mock 'file'
+ @model.expects(:new).with(content).returns(file)
- file = mock 'file'
- @model.expects(:new).with(content).returns(file)
+ File.expects(:exist?).with(@path).returns(true)
+ File.expects(:read).with(@path).returns(content)
+ @searcher.find(@path).should equal(file)
+ end
- File.expects(:exist?).with(@path).returns(true)
- File.expects(:read).with(@path).returns(content)
- @searcher.find(@path).should equal(file)
- end
+ it "should return nil if no file is found" do
+ File.expects(:exist?).with(@path).returns(false)
+ @searcher.find(@path).should be_nil
+ end
- it "should return nil if no file is found" do
- File.expects(:exist?).with(@path).returns(false)
- @searcher.find(@path).should be_nil
- end
+ it "should fail intelligently if a found file cannot be read" do
+ File.expects(:exist?).with(@path).returns(true)
+ File.expects(:read).with(@path).raises(RuntimeError)
+ proc { @searcher.find(@path) }.should raise_error(Puppet::Error)
+ end
- it "should fail intelligently if a found file cannot be read" do
- File.expects(:exist?).with(@path).returns(true)
- File.expects(:read).with(@path).raises(RuntimeError)
- proc { @searcher.find(@path) }.should raise_error(Puppet::Error)
- end
+ it "should use the path() method to calculate the path if it exists" do
+ @searcher.meta_def(:path) do |name|
+ name.upcase
+ end
- it "should use the path() method to calculate the path if it exists" do
- @searcher.meta_def(:path) do |name|
- name.upcase
+ File.expects(:exist?).with(@path.upcase).returns(false)
+ @searcher.find(@path)
end
-
- File.expects(:exist?).with(@path.upcase).returns(false)
- @searcher.find(@path)
end
-end
-describe Puppet::Indirector::File, " when saving files" do
- include FileTerminusTesting
+ describe Puppet::Indirector::File, " when saving files" do
- it "should provide a method to save file contents at a specified path" do
- filehandle = mock 'file'
- content = "my content"
- File.expects(:directory?).with(@dir).returns(true)
- File.expects(:open).with(@path, "w").yields(filehandle)
- filehandle.expects(:print).with(content)
+ it "should provide a method to save file contents at a specified path" do
+ filehandle = mock 'file'
+ content = "my content"
+ File.expects(:directory?).with(@dir).returns(true)
+ File.expects(:open).with(@path, "w").yields(filehandle)
+ filehandle.expects(:print).with(content)
- file = stub 'file', :content => content, :path => @path, :name => @path
+ file = stub 'file', :content => content, :path => @path, :name => @path
- @searcher.save(file)
- end
+ @searcher.save(file)
+ end
- it "should fail intelligently if the file's parent directory does not exist" do
- File.expects(:directory?).with(@dir).returns(false)
+ it "should fail intelligently if the file's parent directory does not exist" do
+ File.expects(:directory?).with(@dir).returns(false)
- file = stub 'file', :path => @path, :name => @path
+ file = stub 'file', :path => @path, :name => @path
- proc { @searcher.save(file) }.should raise_error(Puppet::Error)
- end
-
- it "should fail intelligently if a file cannot be written" do
- filehandle = mock 'file'
- content = "my content"
- File.expects(:directory?).with(@dir).returns(true)
- File.expects(:open).with(@path, "w").yields(filehandle)
- filehandle.expects(:print).with(content).raises(ArgumentError)
+ proc { @searcher.save(file) }.should raise_error(Puppet::Error)
+ end
- file = stub 'file', :content => content, :path => @path, :name => @path
+ it "should fail intelligently if a file cannot be written" do
+ filehandle = mock 'file'
+ content = "my content"
+ File.expects(:directory?).with(@dir).returns(true)
+ File.expects(:open).with(@path, "w").yields(filehandle)
+ filehandle.expects(:print).with(content).raises(ArgumentError)
- proc { @searcher.save(file) }.should raise_error(Puppet::Error)
- end
+ file = stub 'file', :content => content, :path => @path, :name => @path
- it "should use the path() method to calculate the path if it exists" do
- @searcher.meta_def(:path) do |name|
- name.upcase
+ proc { @searcher.save(file) }.should raise_error(Puppet::Error)
end
- file = stub 'file', :name => "/yay"
+ it "should use the path() method to calculate the path if it exists" do
+ @searcher.meta_def(:path) do |name|
+ name.upcase
+ end
+
+ file = stub 'file', :name => "/yay"
- File.expects(:open).with("/YAY", "w")
- @searcher.save(file)
+ File.expects(:open).with("/YAY", "w")
+ @searcher.save(file)
+ end
end
-end
-describe Puppet::Indirector::File, " when removing files" do
- include FileTerminusTesting
+ describe Puppet::Indirector::File, " when removing files" do
- it "should provide a method to remove files at a specified path" do
- file = stub 'file', :path => @path, :name => @path
- File.expects(:exist?).with(@path).returns(true)
- File.expects(:unlink).with(@path)
-
- @searcher.destroy(file)
- end
+ it "should provide a method to remove files at a specified path" do
+ file = stub 'file', :path => @path, :name => @path
+ File.expects(:exist?).with(@path).returns(true)
+ File.expects(:unlink).with(@path)
- it "should throw an exception if the file is not found" do
- file = stub 'file', :path => @path, :name => @path
- File.expects(:exist?).with(@path).returns(false)
+ @searcher.destroy(file)
+ end
- proc { @searcher.destroy(file) }.should raise_error(Puppet::Error)
- end
+ it "should throw an exception if the file is not found" do
+ file = stub 'file', :path => @path, :name => @path
+ File.expects(:exist?).with(@path).returns(false)
- it "should fail intelligently if the file cannot be removed" do
- file = stub 'file', :path => @path, :name => @path
- File.expects(:exist?).with(@path).returns(true)
- File.expects(:unlink).with(@path).raises(ArgumentError)
+ proc { @searcher.destroy(file) }.should raise_error(Puppet::Error)
+ end
- proc { @searcher.destroy(file) }.should raise_error(Puppet::Error)
- end
+ it "should fail intelligently if the file cannot be removed" do
+ file = stub 'file', :path => @path, :name => @path
+ File.expects(:exist?).with(@path).returns(true)
+ File.expects(:unlink).with(@path).raises(ArgumentError)
- it "should use the path() method to calculate the path if it exists" do
- @searcher.meta_def(:path) do |name|
- name.upcase
+ proc { @searcher.destroy(file) }.should raise_error(Puppet::Error)
end
- file = stub 'file', :name => "/yay"
- File.expects(:exist?).with("/YAY").returns(true)
- File.expects(:unlink).with("/YAY")
+ it "should use the path() method to calculate the path if it exists" do
+ @searcher.meta_def(:path) do |name|
+ name.upcase
+ end
+
+ file = stub 'file', :name => "/yay"
+ File.expects(:exist?).with("/YAY").returns(true)
+ File.expects(:unlink).with("/YAY")
- @searcher.destroy(file)
+ @searcher.destroy(file)
+ end
end
-end
+end \ No newline at end of file
diff --git a/spec/unit/indirector/file_server.rb b/spec/unit/indirector/file_server.rb
index fda60f1ec..974b95e0e 100755
--- a/spec/unit/indirector/file_server.rb
+++ b/spec/unit/indirector/file_server.rb
@@ -8,8 +8,9 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/indirector/file_server'
require 'puppet/file_serving/configuration'
-module FileServerTerminusTesting
- def setup
+describe Puppet::Indirector::FileServer do
+
+ before :each do
Puppet::Indirector::Terminus.stubs(:register_terminus_class)
@model = mock 'model'
@indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model
@@ -27,147 +28,141 @@ module FileServerTerminusTesting
@configuration = mock 'configuration'
Puppet::FileServing::Configuration.stubs(:create).returns(@configuration)
end
-end
-describe Puppet::Indirector::FileServer, " when finding files" do
- include FileServerTerminusTesting
+ describe Puppet::Indirector::FileServer, " when finding files" do
- it "should use the path portion of the URI as the file name" do
- @configuration.expects(:file_path).with("/my/local/file", :node => nil)
- @file_server.find(@uri)
- end
+ it "should use the path portion of the URI as the file name" do
+ @configuration.expects(:file_path).with("/my/local/file", :node => nil)
+ @file_server.find(@uri)
+ end
- it "should use the FileServing configuration to convert the file name to a fully qualified path" do
- @configuration.expects(:file_path).with("/my/local/file", :node => nil)
- @file_server.find(@uri)
- end
+ it "should use the FileServing configuration to convert the file name to a fully qualified path" do
+ @configuration.expects(:file_path).with("/my/local/file", :node => nil)
+ @file_server.find(@uri)
+ end
- it "should pass the node name to the FileServing configuration if one is provided" do
- @configuration.expects(:file_path).with("/my/local/file", :node => "testing")
- @file_server.find(@uri, :node => "testing")
- end
+ it "should pass the node name to the FileServing configuration if one is provided" do
+ @configuration.expects(:file_path).with("/my/local/file", :node => "testing")
+ @file_server.find(@uri, :node => "testing")
+ end
- it "should return nil if no fully qualified path is found" do
- @configuration.expects(:file_path).with("/my/local/file", :node => nil).returns(nil)
- @file_server.find(@uri).should be_nil
- end
+ it "should return nil if no fully qualified path is found" do
+ @configuration.expects(:file_path).with("/my/local/file", :node => nil).returns(nil)
+ @file_server.find(@uri).should be_nil
+ end
- it "should return an instance of the model created with the full path if a file is found" do
- @configuration.expects(:file_path).with("/my/local/file", :node => nil).returns("/some/file")
- @model.expects(:new).returns(:myinstance)
- @file_server.find(@uri).should == :myinstance
+ it "should return an instance of the model created with the full path if a file is found" do
+ @configuration.expects(:file_path).with("/my/local/file", :node => nil).returns("/some/file")
+ @model.expects(:new).returns(:myinstance)
+ @file_server.find(@uri).should == :myinstance
+ end
end
-end
+ describe Puppet::Indirector::FileServer, " when returning instances" do
+ before :each do
+ @configuration.expects(:file_path).with("/my/local/file", :node => nil).returns("/some/file")
+ @instance = mock 'instance'
+ end
-describe Puppet::Indirector::FileServer, " when returning instances" do
- include FileServerTerminusTesting
-
- before do
- @configuration.expects(:file_path).with("/my/local/file", :node => nil).returns("/some/file")
- @instance = mock 'instance'
- end
-
- it "should create the instance with the key used to find the instance" do
- @model.expects(:new).with { |key, *options| key == @uri }
- @file_server.find(@uri)
- end
+ it "should create the instance with the key used to find the instance" do
+ @model.expects(:new).with { |key, *options| key == @uri }
+ @file_server.find(@uri)
+ end
- it "should create the instance with the path at which the instance was found" do
- @model.expects(:new).with { |key, options| options[:path] == "/some/file" }
- @file_server.find(@uri)
- end
+ it "should create the instance with the path at which the instance was found" do
+ @model.expects(:new).with { |key, options| options[:path] == "/some/file" }
+ @file_server.find(@uri)
+ end
- it "should set the provided :links setting on to the instance if one is provided" do
- @model.expects(:new).returns(@instance)
- @instance.expects(:links=).with(:mytest)
- @file_server.find(@uri, :links => :mytest)
- end
+ it "should set the provided :links setting on to the instance if one is provided" do
+ @model.expects(:new).returns(@instance)
+ @instance.expects(:links=).with(:mytest)
+ @file_server.find(@uri, :links => :mytest)
+ end
- it "should not set a :links value if no :links parameter is provided" do
- @model.expects(:new).returns(@instance)
- @file_server.find(@uri)
+ it "should not set a :links value if no :links parameter is provided" do
+ @model.expects(:new).returns(@instance)
+ @file_server.find(@uri)
+ end
end
-end
-describe Puppet::Indirector::FileServer, " when checking authorization" do
- include FileServerTerminusTesting
+ describe Puppet::Indirector::FileServer, " when checking authorization" do
- it "should have an authorization hook" do
- @file_server.should respond_to(:authorized?)
- end
+ it "should have an authorization hook" do
+ @file_server.should respond_to(:authorized?)
+ end
- it "should deny the :destroy method" do
- @file_server.authorized?(:destroy, "whatever").should be_false
- end
+ it "should deny the :destroy method" do
+ @file_server.authorized?(:destroy, "whatever").should be_false
+ end
- it "should deny the :save method" do
- @file_server.authorized?(:save, "whatever").should be_false
- end
+ it "should deny the :save method" do
+ @file_server.authorized?(:save, "whatever").should be_false
+ end
- it "should use the file server configuration to determine authorization" do
- @configuration.expects(:authorized?)
- @file_server.authorized?(:find, "puppetmounts://host/my/file")
- end
+ it "should use the file server configuration to determine authorization" do
+ @configuration.expects(:authorized?)
+ @file_server.authorized?(:find, "puppetmounts://host/my/file")
+ end
- it "should pass the file path from the URI to the file server configuration" do
- @configuration.expects(:authorized?).with { |uri, *args| uri == "/my/file" }
- @file_server.authorized?(:find, "puppetmounts://host/my/file")
- end
+ it "should pass the file path from the URI to the file server configuration" do
+ @configuration.expects(:authorized?).with { |uri, *args| uri == "/my/file" }
+ @file_server.authorized?(:find, "puppetmounts://host/my/file")
+ end
- it "should pass the node name to the file server configuration" do
- @configuration.expects(:authorized?).with { |key, options| options[:node] == "mynode" }
- @file_server.authorized?(:find, "puppetmounts://host/my/file", :node => "mynode")
- end
+ it "should pass the node name to the file server configuration" do
+ @configuration.expects(:authorized?).with { |key, options| options[:node] == "mynode" }
+ @file_server.authorized?(:find, "puppetmounts://host/my/file", :node => "mynode")
+ end
- it "should pass the IP address to the file server configuration" do
- @configuration.expects(:authorized?).with { |key, options| options[:ipaddress] == "myip" }
- @file_server.authorized?(:find, "puppetmounts://host/my/file", :ipaddress => "myip")
- end
+ it "should pass the IP address to the file server configuration" do
+ @configuration.expects(:authorized?).with { |key, options| options[:ipaddress] == "myip" }
+ @file_server.authorized?(:find, "puppetmounts://host/my/file", :ipaddress => "myip")
+ end
- it "should return false if the file server configuration denies authorization" do
- @configuration.expects(:authorized?).returns(false)
- @file_server.authorized?(:find, "puppetmounts://host/my/file").should be_false
- end
+ it "should return false if the file server configuration denies authorization" do
+ @configuration.expects(:authorized?).returns(false)
+ @file_server.authorized?(:find, "puppetmounts://host/my/file").should be_false
+ end
- it "should return true if the file server configuration approves authorization" do
- @configuration.expects(:authorized?).returns(true)
- @file_server.authorized?(:find, "puppetmounts://host/my/file").should be_true
+ it "should return true if the file server configuration approves authorization" do
+ @configuration.expects(:authorized?).returns(true)
+ @file_server.authorized?(:find, "puppetmounts://host/my/file").should be_true
+ end
end
-end
-describe Puppet::Indirector::FileServer, " when searching for files" do
- include FileServerTerminusTesting
+ describe Puppet::Indirector::FileServer, " when searching for files" do
- it "should use the path portion of the URI as the file name" do
- @configuration.expects(:file_path).with("/my/local/file", :node => nil)
- @file_server.search(@uri)
- end
+ it "should use the path portion of the URI as the file name" do
+ @configuration.expects(:file_path).with("/my/local/file", :node => nil)
+ @file_server.search(@uri)
+ end
- it "should use the FileServing configuration to convert the file name to a fully qualified path" do
- @configuration.expects(:file_path).with("/my/local/file", :node => nil)
- @file_server.search(@uri)
- end
+ it "should use the FileServing configuration to convert the file name to a fully qualified path" do
+ @configuration.expects(:file_path).with("/my/local/file", :node => nil)
+ @file_server.search(@uri)
+ end
- it "should pass the node name to the FileServing configuration if one is provided" do
- @configuration.expects(:file_path).with("/my/local/file", :node => "testing")
- @file_server.search(@uri, :node => "testing")
- end
+ it "should pass the node name to the FileServing configuration if one is provided" do
+ @configuration.expects(:file_path).with("/my/local/file", :node => "testing")
+ @file_server.search(@uri, :node => "testing")
+ end
- it "should return nil if no fully qualified path is found" do
- @configuration.expects(:file_path).with("/my/local/file", :node => nil).returns(nil)
- @file_server.search(@uri).should be_nil
- end
+ it "should return nil if no fully qualified path is found" do
+ @configuration.expects(:file_path).with("/my/local/file", :node => nil).returns(nil)
+ @file_server.search(@uri).should be_nil
+ end
- it "should use :path2instances from the terminus_helper to return instances if a module is found and the file exists" do
- @configuration.expects(:file_path).with("/my/local/file", :node => nil).returns("/my/file")
- @file_server.expects(:path2instances).with(@uri, "/my/file", {})
- @file_server.search(@uri)
- end
+ it "should use :path2instances from the terminus_helper to return instances if a module is found and the file exists" do
+ @configuration.expects(:file_path).with("/my/local/file", :node => nil).returns("/my/file")
+ @file_server.expects(:path2instances).with(@uri, "/my/file", {})
+ @file_server.search(@uri)
+ end
- it "should pass any options on to :path2instances" do
- @configuration.expects(:file_path).with("/my/local/file", :node => nil).returns("/my/file")
- @file_server.expects(:path2instances).with(@uri, "/my/file", :testing => :one, :other => :two)
- @file_server.search(@uri, :testing => :one, :other => :two)
+ it "should pass any options on to :path2instances" do
+ @configuration.expects(:file_path).with("/my/local/file", :node => nil).returns("/my/file")
+ @file_server.expects(:path2instances).with(@uri, "/my/file", :testing => :one, :other => :two)
+ @file_server.search(@uri, :testing => :one, :other => :two)
+ end
end
-end
+end \ No newline at end of file
diff --git a/spec/unit/indirector/indirection.rb b/spec/unit/indirector/indirection.rb
index 36192b8e5..fe456b61e 100755
--- a/spec/unit/indirector/indirection.rb
+++ b/spec/unit/indirector/indirection.rb
@@ -4,21 +4,7 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/indirector'
-module IndirectionTesting
- def setup
- @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
- @terminus = stub 'terminus', :has_most_recent? => false
- @indirection.stubs(:terminus).returns(@terminus)
- @indirection.stubs(:terminus_class).returns(:whatever)
- @instance = stub 'instance', :version => nil, :version= => nil, :name => "whatever"
- @name = :mything
- end
-
- def teardown
- @indirection.delete
- Puppet::Indirector::Indirection.clear_cache
- end
-end
+
describe Puppet::Indirector::Indirection, " when initializing" do
# (LAK) I've no idea how to test this, really.
@@ -55,103 +41,183 @@ describe Puppet::Indirector::Indirection, " when initializing" do
end
end
-describe Puppet::Indirector::Indirection, " when looking for a model instance" do
- include IndirectionTesting
+describe Puppet::Indirector::Indirection do
+ before :each do
+ @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
+ @terminus = stub 'terminus', :has_most_recent? => false
+ @indirection.stubs(:terminus).returns(@terminus)
+ @indirection.stubs(:terminus_class).returns(:whatever)
+ @instance = stub 'instance', :version => nil, :version= => nil, :name => "whatever"
+ @name = :mything
+ end
+
+ describe Puppet::Indirector::Indirection, " when looking for a model instance" do
+
+ it "should let the appropriate terminus perform the lookup" do
+ @terminus.expects(:find).with(@name).returns(@instance)
+ @indirection.find(@name).should == @instance
+ end
+
+ it "should not attempt to set a timestamp if the terminus cannot find the instance" do
+ @terminus.expects(:find).with(@name).returns(nil)
+ proc { @indirection.find(@name) }.should_not raise_error
+ end
- it "should let the appropriate terminus perform the lookup" do
- @terminus.expects(:find).with(@name).returns(@instance)
- @indirection.find(@name).should == @instance
+ it "should pass the instance to the :post_find hook if there is one" do
+ class << @terminus
+ def post_find
+ end
+ end
+ @terminus.expects(:post_find).with(@instance)
+ @terminus.expects(:find).with(@name).returns(@instance)
+ @indirection.find(@name)
+ end
end
+
+ describe Puppet::Indirector::Indirection, " when removing a model instance" do
- it "should not attempt to set a timestamp if the terminus cannot find the instance" do
- @terminus.expects(:find).with(@name).returns(nil)
- proc { @indirection.find(@name) }.should_not raise_error
+ it "should let the appropriate terminus remove the instance" do
+ @terminus.expects(:destroy).with(@name).returns(@instance)
+ @indirection.destroy(@name).should == @instance
+ end
end
- it "should pass the instance to the :post_find hook if there is one" do
- class << @terminus
- def post_find
+ describe Puppet::Indirector::Indirection, " when searching for multiple model instances" do
+
+ it "should let the appropriate terminus find the matching instances" do
+ @terminus.expects(:search).with(@name).returns(@instance)
+ @indirection.search(@name).should == @instance
+ end
+
+ it "should pass the instances to the :post_search hook if there is one" do
+ class << @terminus
+ def post_search
+ end
end
+ @terminus.expects(:post_search).with(@instance)
+ @terminus.expects(:search).with(@name).returns(@instance)
+ @indirection.search(@name)
end
- @terminus.expects(:post_find).with(@instance)
- @terminus.expects(:find).with(@name).returns(@instance)
- @indirection.find(@name)
end
-end
-describe Puppet::Indirector::Indirection, " when removing a model instance" do
- include IndirectionTesting
+ describe Puppet::Indirector::Indirection, " when storing a model instance" do
- it "should let the appropriate terminus remove the instance" do
- @terminus.expects(:destroy).with(@name).returns(@instance)
- @indirection.destroy(@name).should == @instance
+ it "should let the appropriate terminus store the instance" do
+ @terminus.expects(:save).with(@instance).returns(@instance)
+ @indirection.save(@instance).should == @instance
+ end
end
-end
+
+ describe Puppet::Indirector::Indirection, " when handling instance versions" do
-describe Puppet::Indirector::Indirection, " when searching for multiple model instances" do
- include IndirectionTesting
-
- it "should let the appropriate terminus find the matching instances" do
- @terminus.expects(:search).with(@name).returns(@instance)
- @indirection.search(@name).should == @instance
- end
+ it "should let the appropriate terminus perform the lookup" do
+ @terminus.expects(:version).with(@name).returns(5)
+ @indirection.version(@name).should == 5
+ end
+
+ it "should add versions to found instances that do not already have them" do
+ @terminus.expects(:find).with(@name).returns(@instance)
+ time = mock 'time'
+ time.expects(:utc).returns(:mystamp)
+ Time.expects(:now).returns(time)
+ @instance.expects(:version=).with(:mystamp)
+ @indirection.find(@name)
+ end
+
+ it "should add versions to saved instances that do not already have them" do
+ time = mock 'time'
+ time.expects(:utc).returns(:mystamp)
+ Time.expects(:now).returns(time)
+ @instance.expects(:version=).with(:mystamp)
+ @terminus.stubs(:save)
+ @indirection.save(@instance)
+ end
- it "should pass the instances to the :post_search hook if there is one" do
- class << @terminus
- def post_search
+ # We've already tested this, basically, but...
+ it "should use the current time in UTC for versions" do
+ @instance.expects(:version=).with do |time|
+ time.utc?
end
+ @terminus.stubs(:save)
+ @indirection.save(@instance)
end
- @terminus.expects(:post_search).with(@instance)
- @terminus.expects(:search).with(@name).returns(@instance)
- @indirection.search(@name)
end
-end
-describe Puppet::Indirector::Indirection, " when storing a model instance" do
- include IndirectionTesting
-
- it "should let the appropriate terminus store the instance" do
- @terminus.expects(:save).with(@instance).returns(@instance)
- @indirection.save(@instance).should == @instance
- end
-end
-describe Puppet::Indirector::Indirection, " when handling instance versions" do
- include IndirectionTesting
-
- it "should let the appropriate terminus perform the lookup" do
- @terminus.expects(:version).with(@name).returns(5)
- @indirection.version(@name).should == 5
- end
+ describe Puppet::Indirector::Indirection, " when an authorization hook is present" do
- it "should add versions to found instances that do not already have them" do
- @terminus.expects(:find).with(@name).returns(@instance)
- time = mock 'time'
- time.expects(:utc).returns(:mystamp)
- Time.expects(:now).returns(time)
- @instance.expects(:version=).with(:mystamp)
- @indirection.find(@name)
- end
+ before do
+ # So the :respond_to? turns out right.
+ class << @terminus
+ def authorized?
+ end
+ end
+ end
- it "should add versions to saved instances that do not already have them" do
- time = mock 'time'
- time.expects(:utc).returns(:mystamp)
- Time.expects(:now).returns(time)
- @instance.expects(:version=).with(:mystamp)
- @terminus.stubs(:save)
- @indirection.save(@instance)
- end
+ it "should not check authorization if a node name is not provided" do
+ @terminus.expects(:authorized?).never
+ @terminus.stubs(:find)
+ @indirection.find("/my/key")
+ end
+
+ it "should fail while finding instances if authorization returns false" do
+ @terminus.expects(:authorized?).with(:find, "/my/key", :node => "mynode").returns(false)
+ @terminus.stubs(:find)
+ proc { @indirection.find("/my/key", :node => "mynode") }.should raise_error(ArgumentError)
+ end
+
+ it "should continue finding instances if authorization returns true" do
+ @terminus.expects(:authorized?).with(:find, "/my/key", :node => "mynode").returns(true)
+ @terminus.stubs(:find)
+ @indirection.find("/my/key", :node => "mynode")
+ end
+
+ it "should fail while saving instances if authorization returns false" do
+ @terminus.expects(:authorized?).with(:save, :myinstance, :node => "mynode").returns(false)
+ @terminus.stubs(:save)
+ proc { @indirection.save(:myinstance, :node => "mynode") }.should raise_error(ArgumentError)
+ end
+
+ it "should continue saving instances if authorization returns true" do
+ instance = stub 'instance', :version => 1.0, :name => "eh"
+ @terminus.expects(:authorized?).with(:save, instance, :node => "mynode").returns(true)
+ @terminus.stubs(:save)
+ @indirection.save(instance, :node => "mynode")
+ end
+
+ it "should fail while destroying instances if authorization returns false" do
+ @terminus.expects(:authorized?).with(:destroy, "/my/key", :node => "mynode").returns(false)
+ @terminus.stubs(:destroy)
+ proc { @indirection.destroy("/my/key", :node => "mynode") }.should raise_error(ArgumentError)
+ end
+
+ it "should continue destroying instances if authorization returns true" do
+ instance = stub 'instance', :version => 1.0, :name => "eh"
+ @terminus.expects(:authorized?).with(:destroy, instance, :node => "mynode").returns(true)
+ @terminus.stubs(:destroy)
+ @indirection.destroy(instance, :node => "mynode")
+ end
+
+ it "should fail while searching for instances if authorization returns false" do
+ @terminus.expects(:authorized?).with(:search, "/my/key", :node => "mynode").returns(false)
+ @terminus.stubs(:search)
+ proc { @indirection.search("/my/key", :node => "mynode") }.should raise_error(ArgumentError)
+ end
- # We've already tested this, basically, but...
- it "should use the current time in UTC for versions" do
- @instance.expects(:version=).with do |time|
- time.utc?
+ it "should continue searching for instances if authorization returns true" do
+ @terminus.expects(:authorized?).with(:search, "/my/key", :node => "mynode").returns(true)
+ @terminus.stubs(:search)
+ @indirection.search("/my/key", :node => "mynode")
end
- @terminus.stubs(:save)
- @indirection.save(@instance)
+ end
+
+ after :each do
+ @indirection.delete
+ Puppet::Indirector::Indirection.clear_cache
end
end
+
describe Puppet::Indirector::Indirection, " when managing indirection instances" do
it "should allow an indirection to be retrieved by name" do
@indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
@@ -397,8 +463,8 @@ describe Puppet::Indirector::Indirection, " when deciding whether to cache" do
end
end
-module IndirectionCacheTesting
- def setup
+describe Puppet::Indirector::Indirection do
+ before :each do
Puppet.settings.stubs(:value).with("test_terminus").returns("test_terminus")
@terminus_class = mock 'terminus_class'
@terminus = mock 'terminus'
@@ -411,175 +477,104 @@ module IndirectionCacheTesting
@indirection.terminus_class = :test_terminus
end
- def teardown
- @indirection.delete
- Puppet::Indirector::Indirection.clear_cache
- end
-end
-
-describe Puppet::Indirector::Indirection, " when managing the cache terminus" do
- include IndirectionCacheTesting
-
- it "should not create a cache terminus at initialization" do
- # This is weird, because all of the code is in the setup. If we got
- # new() called on the cache class, we'd get an exception here.
- end
-
- it "should reuse the cache terminus" do
- @cache_class.expects(:new).returns(@cache)
- Puppet.settings.stubs(:value).with("test_cache").returns("cache_terminus")
- @indirection.cache_class = :cache_terminus
- @indirection.cache.should equal(@cache)
- @indirection.cache.should equal(@cache)
- end
-
- it "should remove the cache terminus when all other terminus instances are cleared" do
- cache2 = mock 'cache2'
- @cache_class.stubs(:new).returns(@cache, cache2)
- @indirection.cache_class = :cache_terminus
- @indirection.cache.should equal(@cache)
- @indirection.clear_cache
- @indirection.cache.should equal(cache2)
- end
-end
-
-describe Puppet::Indirector::Indirection, " when saving and using a cache" do
- include IndirectionCacheTesting
-
- before do
- @indirection.cache_class = :cache_terminus
- @cache_class.expects(:new).returns(@cache)
- @name = "testing"
- @instance = stub 'instance', :version => 5, :name => @name
- end
-
- it "should not update the cache or terminus if the new object is not different" do
- @cache.expects(:has_most_recent?).with(@name, 5).returns(true)
- @indirection.save(@instance)
- end
+ describe Puppet::Indirector::Indirection, " when managing the cache terminus" do
- it "should update the original and the cache if the cached object is different" do
- @cache.expects(:has_most_recent?).with(@name, 5).returns(false)
- @terminus.expects(:save).with(@instance)
- @cache.expects(:save).with(@instance)
- @indirection.save(@instance)
- end
-end
+ it "should not create a cache terminus at initialization" do
+ # This is weird, because all of the code is in the setup. If we got
+ # new() called on the cache class, we'd get an exception here.
+ end
-describe Puppet::Indirector::Indirection, " when finding and using a cache" do
- include IndirectionCacheTesting
+ it "should reuse the cache terminus" do
+ @cache_class.expects(:new).returns(@cache)
+ Puppet.settings.stubs(:value).with("test_cache").returns("cache_terminus")
+ @indirection.cache_class = :cache_terminus
+ @indirection.cache.should equal(@cache)
+ @indirection.cache.should equal(@cache)
+ end
- before do
- @indirection.cache_class = :cache_terminus
- @cache_class.expects(:new).returns(@cache)
+ it "should remove the cache terminus when all other terminus instances are cleared" do
+ cache2 = mock 'cache2'
+ @cache_class.stubs(:new).returns(@cache, cache2)
+ @indirection.cache_class = :cache_terminus
+ @indirection.cache.should equal(@cache)
+ @indirection.clear_cache
+ @indirection.cache.should equal(cache2)
+ end
end
- it "should return the cached object if the cache is up to date" do
- cached = mock 'cached object'
+ describe Puppet::Indirector::Indirection, " when saving and using a cache" do
- name = "myobject"
-
- @terminus.expects(:version).with(name).returns(1)
- @cache.expects(:has_most_recent?).with(name, 1).returns(true)
+ before do
+ @indirection.cache_class = :cache_terminus
+ @cache_class.expects(:new).returns(@cache)
+ @name = "testing"
+ @instance = stub 'instance', :version => 5, :name => @name
+ end
- @cache.expects(:find).with(name).returns(cached)
+ it "should not update the cache or terminus if the new object is not different" do
+ @cache.expects(:has_most_recent?).with(@name, 5).returns(true)
+ @indirection.save(@instance)
+ end
- @indirection.find(name).should equal(cached)
+ it "should update the original and the cache if the cached object is different" do
+ @cache.expects(:has_most_recent?).with(@name, 5).returns(false)
+ @terminus.expects(:save).with(@instance)
+ @cache.expects(:save).with(@instance)
+ @indirection.save(@instance)
+ end
end
+
+ describe Puppet::Indirector::Indirection, " when finding and using a cache" do
- it "should return the original object if the cache is not up to date" do
- real = stub 'real object', :version => 1
-
- name = "myobject"
+ before do
+ @indirection.cache_class = :cache_terminus
+ @cache_class.expects(:new).returns(@cache)
+ end
- @cache.stubs(:save)
- @cache.expects(:has_most_recent?).with(name, 1).returns(false)
- @terminus.expects(:version).with(name).returns(1)
+ it "should return the cached object if the cache is up to date" do
+ cached = mock 'cached object'
- @terminus.expects(:find).with(name).returns(real)
+ name = "myobject"
- @indirection.find(name).should equal(real)
- end
+ @terminus.expects(:version).with(name).returns(1)
+ @cache.expects(:has_most_recent?).with(name, 1).returns(true)
- it "should cache any newly returned objects" do
- real = stub 'real object', :version => 1
+ @cache.expects(:find).with(name).returns(cached)
- name = "myobject"
+ @indirection.find(name).should equal(cached)
+ end
- @terminus.expects(:version).with(name).returns(1)
- @cache.expects(:has_most_recent?).with(name, 1).returns(false)
+ it "should return the original object if the cache is not up to date" do
+ real = stub 'real object', :version => 1
- @terminus.expects(:find).with(name).returns(real)
- @cache.expects(:save).with(real)
+ name = "myobject"
- @indirection.find(name).should equal(real)
- end
-end
+ @cache.stubs(:save)
+ @cache.expects(:has_most_recent?).with(name, 1).returns(false)
+ @terminus.expects(:version).with(name).returns(1)
-describe Puppet::Indirector::Indirection, " when an authorization hook is present" do
- include IndirectionTesting
+ @terminus.expects(:find).with(name).returns(real)
- before do
- # So the :respond_to? turns out right.
- class << @terminus
- def authorized?
- end
+ @indirection.find(name).should equal(real)
end
- end
- it "should not check authorization if a node name is not provided" do
- @terminus.expects(:authorized?).never
- @terminus.stubs(:find)
- @indirection.find("/my/key")
- end
-
- it "should fail while finding instances if authorization returns false" do
- @terminus.expects(:authorized?).with(:find, "/my/key", :node => "mynode").returns(false)
- @terminus.stubs(:find)
- proc { @indirection.find("/my/key", :node => "mynode") }.should raise_error(ArgumentError)
- end
-
- it "should continue finding instances if authorization returns true" do
- @terminus.expects(:authorized?).with(:find, "/my/key", :node => "mynode").returns(true)
- @terminus.stubs(:find)
- @indirection.find("/my/key", :node => "mynode")
- end
+ it "should cache any newly returned objects" do
+ real = stub 'real object', :version => 1
- it "should fail while saving instances if authorization returns false" do
- @terminus.expects(:authorized?).with(:save, :myinstance, :node => "mynode").returns(false)
- @terminus.stubs(:save)
- proc { @indirection.save(:myinstance, :node => "mynode") }.should raise_error(ArgumentError)
- end
+ name = "myobject"
- it "should continue saving instances if authorization returns true" do
- instance = stub 'instance', :version => 1.0, :name => "eh"
- @terminus.expects(:authorized?).with(:save, instance, :node => "mynode").returns(true)
- @terminus.stubs(:save)
- @indirection.save(instance, :node => "mynode")
- end
+ @terminus.expects(:version).with(name).returns(1)
+ @cache.expects(:has_most_recent?).with(name, 1).returns(false)
- it "should fail while destroying instances if authorization returns false" do
- @terminus.expects(:authorized?).with(:destroy, "/my/key", :node => "mynode").returns(false)
- @terminus.stubs(:destroy)
- proc { @indirection.destroy("/my/key", :node => "mynode") }.should raise_error(ArgumentError)
- end
+ @terminus.expects(:find).with(name).returns(real)
+ @cache.expects(:save).with(real)
- it "should continue destroying instances if authorization returns true" do
- instance = stub 'instance', :version => 1.0, :name => "eh"
- @terminus.expects(:authorized?).with(:destroy, instance, :node => "mynode").returns(true)
- @terminus.stubs(:destroy)
- @indirection.destroy(instance, :node => "mynode")
- end
-
- it "should fail while searching for instances if authorization returns false" do
- @terminus.expects(:authorized?).with(:search, "/my/key", :node => "mynode").returns(false)
- @terminus.stubs(:search)
- proc { @indirection.search("/my/key", :node => "mynode") }.should raise_error(ArgumentError)
+ @indirection.find(name).should equal(real)
+ end
end
-
- it "should continue searching for instances if authorization returns true" do
- @terminus.expects(:authorized?).with(:search, "/my/key", :node => "mynode").returns(true)
- @terminus.stubs(:search)
- @indirection.search("/my/key", :node => "mynode")
+
+ after :each do
+ @indirection.delete
+ Puppet::Indirector::Indirection.clear_cache
end
end
diff --git a/spec/unit/indirector/module_files.rb b/spec/unit/indirector/module_files.rb
index 9011530dd..0f6dbb6df 100755
--- a/spec/unit/indirector/module_files.rb
+++ b/spec/unit/indirector/module_files.rb
@@ -7,239 +7,237 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/indirector/module_files'
-module ModuleFilesTerminusTesting
- def setup
- Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
- Puppet::Indirector::Terminus.stubs(:register_terminus_class)
- @model = mock 'model'
- @indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model
- Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection)
- @module_files_class = Class.new(Puppet::Indirector::ModuleFiles) do
- def self.to_s
- "Testing::Mytype"
- end
- end
+describe Puppet::Indirector::ModuleFiles do
- @module_files = @module_files_class.new
+ before :each do
+ Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
+ Puppet::Indirector::Terminus.stubs(:register_terminus_class)
+ @model = mock 'model'
+ @indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model
+ Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection)
- @uri = "puppetmounts://host/modules/my/local/file"
- @module = Puppet::Module.new("mymod", "/module/path")
- end
-end
+ @module_files_class = Class.new(Puppet::Indirector::ModuleFiles) do
+ def self.to_s
+ "Testing::Mytype"
+ end
+ end
-describe Puppet::Indirector::ModuleFiles, " when finding files" do
- include ModuleFilesTerminusTesting
+ @module_files = @module_files_class.new
- it "should strip off the leading '/modules' mount name" do
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
- @module_files.find(@uri)
- end
+ @uri = "puppetmounts://host/modules/my/local/file"
+ @module = Puppet::Module.new("mymod", "/module/path")
+ end
- it "should not strip off leading terms that start with '/modules' but are longer words" do
- Puppet::Module.expects(:find).with('modulestart', "myenv").returns nil
- @module_files.find("puppetmounts://host/modulestart/my/local/file")
- end
+ describe Puppet::Indirector::ModuleFiles, " when finding files" do
- it "should search for a module whose name is the first term in the remaining file path" do
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
- @module_files.find(@uri)
- end
+ it "should strip off the leading '/modules' mount name" do
+ Puppet::Module.expects(:find).with('my', "myenv").returns @module
+ @module_files.find(@uri)
+ end
- it "should search for a file relative to the module's files directory" do
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
- FileTest.expects(:exists?).with("/module/path/files/local/file")
- @module_files.find(@uri)
- end
+ it "should not strip off leading terms that start with '/modules' but are longer words" do
+ Puppet::Module.expects(:find).with('modulestart', "myenv").returns nil
+ @module_files.find("puppetmounts://host/modulestart/my/local/file")
+ end
- it "should return nil if the module does not exist" do
- Puppet::Module.expects(:find).with('my', "myenv").returns nil
- @module_files.find(@uri).should be_nil
- end
+ it "should search for a module whose name is the first term in the remaining file path" do
+ Puppet::Module.expects(:find).with('my', "myenv").returns @module
+ @module_files.find(@uri)
+ end
- it "should return nil if the module exists but the file does not" do
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
- FileTest.expects(:exists?).with("/module/path/files/local/file").returns(false)
- @module_files.find(@uri).should be_nil
- end
+ it "should search for a file relative to the module's files directory" do
+ Puppet::Module.expects(:find).with('my', "myenv").returns @module
+ FileTest.expects(:exists?).with("/module/path/files/local/file")
+ @module_files.find(@uri)
+ end
- it "should return an instance of the model if a module is found and the file exists" do
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
- FileTest.expects(:exists?).with("/module/path/files/local/file").returns(true)
- @model.expects(:new).returns(:myinstance)
- @module_files.find(@uri).should == :myinstance
- end
+ it "should return nil if the module does not exist" do
+ Puppet::Module.expects(:find).with('my', "myenv").returns nil
+ @module_files.find(@uri).should be_nil
+ end
- it "should use the node's environment to look up the module if the node name is provided" do
- node = stub "node", :environment => "testing"
- Puppet::Node.expects(:find).with("mynode").returns(node)
- Puppet::Module.expects(:find).with('my', "testing")
- @module_files.find(@uri, :node => "mynode")
- end
+ it "should return nil if the module exists but the file does not" do
+ Puppet::Module.expects(:find).with('my', "myenv").returns @module
+ FileTest.expects(:exists?).with("/module/path/files/local/file").returns(false)
+ @module_files.find(@uri).should be_nil
+ end
- it "should use the default environment setting to look up the module if the node name is not provided" do
- env = stub "environment", :name => "testing"
- Puppet::Node::Environment.stubs(:new).returns(env)
- Puppet::Module.expects(:find).with('my', "testing")
- @module_files.find(@uri)
- end
-end
+ it "should return an instance of the model if a module is found and the file exists" do
+ Puppet::Module.expects(:find).with('my', "myenv").returns @module
+ FileTest.expects(:exists?).with("/module/path/files/local/file").returns(true)
+ @model.expects(:new).returns(:myinstance)
+ @module_files.find(@uri).should == :myinstance
+ end
-describe Puppet::Indirector::ModuleFiles, " when returning instances" do
- include ModuleFilesTerminusTesting
+ it "should use the node's environment to look up the module if the node name is provided" do
+ node = stub "node", :environment => "testing"
+ Puppet::Node.expects(:find).with("mynode").returns(node)
+ Puppet::Module.expects(:find).with('my', "testing")
+ @module_files.find(@uri, :node => "mynode")
+ end
- before do
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
- FileTest.expects(:exists?).with("/module/path/files/local/file").returns(true)
- @instance = mock 'instance'
+ it "should use the default environment setting to look up the module if the node name is not provided" do
+ env = stub "environment", :name => "testing"
+ Puppet::Node::Environment.stubs(:new).returns(env)
+ Puppet::Module.expects(:find).with('my', "testing")
+ @module_files.find(@uri)
+ end
end
- it "should create the instance with the key used to find the instance" do
- @model.expects(:new).with { |key, *options| key == @uri }
- @module_files.find(@uri)
- end
+ describe Puppet::Indirector::ModuleFiles, " when returning instances" do
- it "should create the instance with the path at which the instance was found" do
- @model.expects(:new).with { |key, options| options[:path] == "/module/path/files/local/file" }
- @module_files.find(@uri)
- end
+ before do
+ Puppet::Module.expects(:find).with('my', "myenv").returns @module
+ FileTest.expects(:exists?).with("/module/path/files/local/file").returns(true)
+ @instance = mock 'instance'
+ end
- it "should set the provided :links setting on to the instance if one is provided" do
- @model.expects(:new).returns(@instance)
- @instance.expects(:links=).with(:mytest)
- @module_files.find(@uri, :links => :mytest)
- end
+ it "should create the instance with the key used to find the instance" do
+ @model.expects(:new).with { |key, *options| key == @uri }
+ @module_files.find(@uri)
+ end
- it "should not set a :links value if no :links parameter is provided" do
- @model.expects(:new).returns(@instance)
- @module_files.find(@uri)
- end
-end
+ it "should create the instance with the path at which the instance was found" do
+ @model.expects(:new).with { |key, options| options[:path] == "/module/path/files/local/file" }
+ @module_files.find(@uri)
+ end
-describe Puppet::Indirector::ModuleFiles, " when authorizing" do
- include ModuleFilesTerminusTesting
+ it "should set the provided :links setting on to the instance if one is provided" do
+ @model.expects(:new).returns(@instance)
+ @instance.expects(:links=).with(:mytest)
+ @module_files.find(@uri, :links => :mytest)
+ end
- before do
- @configuration = mock 'configuration'
- Puppet::FileServing::Configuration.stubs(:create).returns(@configuration)
+ it "should not set a :links value if no :links parameter is provided" do
+ @model.expects(:new).returns(@instance)
+ @module_files.find(@uri)
+ end
end
- it "should have an authorization hook" do
- @module_files.should respond_to(:authorized?)
- end
+ describe Puppet::Indirector::ModuleFiles, " when authorizing" do
- it "should deny the :destroy method" do
- @module_files.authorized?(:destroy, "whatever").should be_false
- end
+ before do
+ @configuration = mock 'configuration'
+ Puppet::FileServing::Configuration.stubs(:create).returns(@configuration)
+ end
- it "should deny the :save method" do
- @module_files.authorized?(:save, "whatever").should be_false
- end
+ it "should have an authorization hook" do
+ @module_files.should respond_to(:authorized?)
+ end
- it "should use the file server configuration to determine authorization" do
- @configuration.expects(:authorized?)
- @module_files.authorized?(:find, "puppetmounts://host/my/file")
- end
+ it "should deny the :destroy method" do
+ @module_files.authorized?(:destroy, "whatever").should be_false
+ end
- it "should use the path directly from the URI if it already includes /modules" do
- @configuration.expects(:authorized?).with { |uri, *args| uri == "/modules/my/file" }
- @module_files.authorized?(:find, "puppetmounts://host/modules/my/file")
- end
+ it "should deny the :save method" do
+ @module_files.authorized?(:save, "whatever").should be_false
+ end
- it "should add /modules to the file path if it's not included in the URI" do
- @configuration.expects(:authorized?).with { |uri, *args| uri == "/modules/my/file" }
- @module_files.authorized?(:find, "puppetmounts://host/my/file")
- end
+ it "should use the file server configuration to determine authorization" do
+ @configuration.expects(:authorized?)
+ @module_files.authorized?(:find, "puppetmounts://host/my/file")
+ end
- it "should pass the node name to the file server configuration" do
- @configuration.expects(:authorized?).with { |key, options| options[:node] == "mynode" }
- @module_files.authorized?(:find, "puppetmounts://host/my/file", :node => "mynode")
- end
+ it "should use the path directly from the URI if it already includes /modules" do
+ @configuration.expects(:authorized?).with { |uri, *args| uri == "/modules/my/file" }
+ @module_files.authorized?(:find, "puppetmounts://host/modules/my/file")
+ end
- it "should pass the IP address to the file server configuration" do
- @configuration.expects(:authorized?).with { |key, options| options[:ipaddress] == "myip" }
- @module_files.authorized?(:find, "puppetmounts://host/my/file", :ipaddress => "myip")
- end
+ it "should add /modules to the file path if it's not included in the URI" do
+ @configuration.expects(:authorized?).with { |uri, *args| uri == "/modules/my/file" }
+ @module_files.authorized?(:find, "puppetmounts://host/my/file")
+ end
- it "should return false if the file server configuration denies authorization" do
- @configuration.expects(:authorized?).returns(false)
- @module_files.authorized?(:find, "puppetmounts://host/my/file").should be_false
- end
+ it "should pass the node name to the file server configuration" do
+ @configuration.expects(:authorized?).with { |key, options| options[:node] == "mynode" }
+ @module_files.authorized?(:find, "puppetmounts://host/my/file", :node => "mynode")
+ end
- it "should return true if the file server configuration approves authorization" do
- @configuration.expects(:authorized?).returns(true)
- @module_files.authorized?(:find, "puppetmounts://host/my/file").should be_true
- end
-end
+ it "should pass the IP address to the file server configuration" do
+ @configuration.expects(:authorized?).with { |key, options| options[:ipaddress] == "myip" }
+ @module_files.authorized?(:find, "puppetmounts://host/my/file", :ipaddress => "myip")
+ end
-describe Puppet::Indirector::ModuleFiles, " when searching for files" do
- include ModuleFilesTerminusTesting
+ it "should return false if the file server configuration denies authorization" do
+ @configuration.expects(:authorized?).returns(false)
+ @module_files.authorized?(:find, "puppetmounts://host/my/file").should be_false
+ end
- it "should strip off the leading '/modules' mount name" do
- Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
- @module_files.search(@uri)
+ it "should return true if the file server configuration approves authorization" do
+ @configuration.expects(:authorized?).returns(true)
+ @module_files.authorized?(:find, "puppetmounts://host/my/file").should be_true
+ end
end
- it "should not strip off leading terms that start with '/modules' but are longer words" do
- Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
- Puppet::Module.expects(:find).with('modulestart', "myenv").returns nil
- @module_files.search("puppetmounts://host/modulestart/my/local/file")
- end
+ describe Puppet::Indirector::ModuleFiles, " when searching for files" do
- it "should search for a module whose name is the first term in the remaining file path" do
- Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
- @module_files.search(@uri)
- end
+ it "should strip off the leading '/modules' mount name" do
+ Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
+ Puppet::Module.expects(:find).with('my', "myenv").returns @module
+ @module_files.search(@uri)
+ end
- it "should search for a file relative to the module's files directory" do
- Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
- FileTest.expects(:exists?).with("/module/path/files/local/file")
- @module_files.search(@uri)
- end
+ it "should not strip off leading terms that start with '/modules' but are longer words" do
+ Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
+ Puppet::Module.expects(:find).with('modulestart', "myenv").returns nil
+ @module_files.search("puppetmounts://host/modulestart/my/local/file")
+ end
- it "should return nil if the module does not exist" do
- Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
- Puppet::Module.expects(:find).with('my', "myenv").returns nil
- @module_files.search(@uri).should be_nil
- end
+ it "should search for a module whose name is the first term in the remaining file path" do
+ Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
+ Puppet::Module.expects(:find).with('my', "myenv").returns @module
+ @module_files.search(@uri)
+ end
- it "should return nil if the module exists but the file does not" do
- Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
- FileTest.expects(:exists?).with("/module/path/files/local/file").returns(false)
- @module_files.search(@uri).should be_nil
- end
+ it "should search for a file relative to the module's files directory" do
+ Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
+ Puppet::Module.expects(:find).with('my', "myenv").returns @module
+ FileTest.expects(:exists?).with("/module/path/files/local/file")
+ @module_files.search(@uri)
+ end
- it "should use the node's environment to look up the module if the node name is provided" do
- node = stub "node", :environment => "testing"
- Puppet::Node.expects(:find).with("mynode").returns(node)
- Puppet::Module.expects(:find).with('my', "testing")
- @module_files.search(@uri, :node => "mynode")
- end
+ it "should return nil if the module does not exist" do
+ Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
+ Puppet::Module.expects(:find).with('my', "myenv").returns nil
+ @module_files.search(@uri).should be_nil
+ end
- it "should use the default environment setting to look up the module if the node name is not provided and the environment is not set to ''" do
- env = stub 'env', :name => "testing"
- Puppet::Node::Environment.stubs(:new).returns(env)
- Puppet::Module.expects(:find).with('my', "testing")
- @module_files.search(@uri)
- end
+ it "should return nil if the module exists but the file does not" do
+ Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
+ Puppet::Module.expects(:find).with('my', "myenv").returns @module
+ FileTest.expects(:exists?).with("/module/path/files/local/file").returns(false)
+ @module_files.search(@uri).should be_nil
+ end
- it "should use :path2instances from the terminus_helper to return instances if a module is found and the file exists" do
- Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
- FileTest.expects(:exists?).with("/module/path/files/local/file").returns(true)
- @module_files.expects(:path2instances).with(@uri, "/module/path/files/local/file", {})
- @module_files.search(@uri)
- end
+ it "should use the node's environment to look up the module if the node name is provided" do
+ node = stub "node", :environment => "testing"
+ Puppet::Node.expects(:find).with("mynode").returns(node)
+ Puppet::Module.expects(:find).with('my', "testing")
+ @module_files.search(@uri, :node => "mynode")
+ end
- it "should pass any options on to :path2instances" do
- Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
- FileTest.expects(:exists?).with("/module/path/files/local/file").returns(true)
- @module_files.expects(:path2instances).with(@uri, "/module/path/files/local/file", :testing => :one, :other => :two)
- @module_files.search(@uri, :testing => :one, :other => :two)
+ it "should use the default environment setting to look up the module if the node name is not provided and the environment is not set to ''" do
+ env = stub 'env', :name => "testing"
+ Puppet::Node::Environment.stubs(:new).returns(env)
+ Puppet::Module.expects(:find).with('my', "testing")
+ @module_files.search(@uri)
+ end
+
+ it "should use :path2instances from the terminus_helper to return instances if a module is found and the file exists" do
+ Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
+ Puppet::Module.expects(:find).with('my', "myenv").returns @module
+ FileTest.expects(:exists?).with("/module/path/files/local/file").returns(true)
+ @module_files.expects(:path2instances).with(@uri, "/module/path/files/local/file", {})
+ @module_files.search(@uri)
+ end
+
+ it "should pass any options on to :path2instances" do
+ Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
+ Puppet::Module.expects(:find).with('my', "myenv").returns @module
+ FileTest.expects(:exists?).with("/module/path/files/local/file").returns(true)
+ @module_files.expects(:path2instances).with(@uri, "/module/path/files/local/file", :testing => :one, :other => :two)
+ @module_files.search(@uri, :testing => :one, :other => :two)
+ end
end
end
diff --git a/spec/unit/indirector/node/exec.rb b/spec/unit/indirector/node/exec.rb
index 744a32b0a..b67e0fe97 100755
--- a/spec/unit/indirector/node/exec.rb
+++ b/spec/unit/indirector/node/exec.rb
@@ -4,59 +4,70 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/node/exec'
-describe Puppet::Node::Exec, " when constructing the command to run" do
+describe Puppet::Node::Exec do
before do
@indirection = mock 'indirection'
Puppet.settings.stubs(:value).with(:external_nodes).returns("/echo")
@searcher = Puppet::Node::Exec.new
end
- it "should use the external_node script as the command" do
- Puppet.expects(:[]).with(:external_nodes).returns("/bin/echo")
- @searcher.command.should == %w{/bin/echo}
+ it "should use the version of the facts as its version" do
+ version = mock 'version'
+ Puppet::Node::Facts.expects(:version).with("me").returns version
+ @searcher.version("me").should equal(version)
end
- it "should throw an exception if no external node command is set" do
- Puppet.expects(:[]).with(:external_nodes).returns("none")
- proc { @searcher.find("foo") }.should raise_error(ArgumentError)
- end
-end
+ describe "when constructing the command to run" do
+ it "should use the external_node script as the command" do
+ Puppet.expects(:[]).with(:external_nodes).returns("/bin/echo")
+ @searcher.command.should == %w{/bin/echo}
+ end
-describe Puppet::Node::Exec, " when handling the results of the command" do
- before do
- @indirection = mock 'indirection'
- Puppet.settings.stubs(:value).with(:external_nodes).returns("/echo")
- @searcher = Puppet::Node::Exec.new
- @node = stub 'node', :fact_merge => nil
- @name = "yay"
- Puppet::Node.expects(:new).with(@name).returns(@node)
- @result = {}
- # Use a local variable so the reference is usable in the execute() definition.
- result = @result
- @searcher.meta_def(:execute) do |command|
- return YAML.dump(result)
+ it "should throw an exception if no external node command is set" do
+ Puppet.expects(:[]).with(:external_nodes).returns("none")
+ proc { @searcher.find("foo") }.should raise_error(ArgumentError)
end
end
- it "should translate the YAML into a Node instance" do
- # Use an empty hash
- @searcher.find(@name).should equal(@node)
- end
+ describe "when handling the results of the command" do
+ before do
+ @node = stub 'node', :fact_merge => nil
+ @name = "yay"
+ Puppet::Node.expects(:new).with(@name).returns(@node)
+ @result = {}
+ # Use a local variable so the reference is usable in the execute() definition.
+ result = @result
+ @searcher.meta_def(:execute) do |command|
+ return YAML.dump(result)
+ end
+ end
- it "should set the resulting parameters as the node parameters" do
- @result[:parameters] = {"a" => "b", "c" => "d"}
- @node.expects(:parameters=).with "a" => "b", "c" => "d"
- @searcher.find(@name)
- end
+ it "should translate the YAML into a Node instance" do
+ # Use an empty hash
+ @searcher.find(@name).should equal(@node)
+ end
- it "should set the resulting classes as the node classes" do
- @result[:classes] = %w{one two}
- @node.expects(:classes=).with %w{one two}
- @searcher.find(@name)
- end
+ it "should set the resulting parameters as the node parameters" do
+ @result[:parameters] = {"a" => "b", "c" => "d"}
+ @node.expects(:parameters=).with "a" => "b", "c" => "d"
+ @searcher.find(@name)
+ end
- it "should merge the node's facts with its parameters" do
- @node.expects(:fact_merge)
- @searcher.find(@name)
+ it "should set the resulting classes as the node classes" do
+ @result[:classes] = %w{one two}
+ @node.expects(:classes=).with %w{one two}
+ @searcher.find(@name)
+ end
+
+ it "should merge the node's facts with its parameters" do
+ @node.expects(:fact_merge)
+ @searcher.find(@name)
+ end
+
+ it "should set the node's environment if one is provided" do
+ @result[:environment] = "yay"
+ @node.expects(:environment=).with "yay"
+ @searcher.find(@name)
+ end
end
end
diff --git a/spec/unit/indirector/node/ldap.rb b/spec/unit/indirector/node/ldap.rb
index 8c6888357..34456703d 100755
--- a/spec/unit/indirector/node/ldap.rb
+++ b/spec/unit/indirector/node/ldap.rb
@@ -4,168 +4,202 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/node/ldap'
-module LdapNodeSearching
- def setup
+describe Puppet::Node::Ldap do
+ it "should use the version of the facts as its version" do
@searcher = Puppet::Node::Ldap.new
- @entries = {}
- entries = @entries
-
- @connection = mock 'connection'
- @entry = mock 'entry'
- @connection.stubs(:search).yields(@entry)
- @searcher.stubs(:connection).returns(@connection)
- @searcher.stubs(:class_attributes).returns([])
- @searcher.stubs(:parent_attribute).returns(nil)
- @searcher.stubs(:search_base).returns(:yay)
- @searcher.stubs(:search_filter).returns(:filter)
-
- @node = mock 'node'
- @node.stubs(:fact_merge)
- @name = "mynode"
- Puppet::Node.stubs(:new).with(@name).returns(@node)
+ version = mock 'version'
+ Puppet::Node::Facts.expects(:version).with("me").returns version
+ @searcher.version("me").should equal(version)
end
-end
-describe Puppet::Node::Ldap, " when searching for nodes" do
- include LdapNodeSearching
+ describe "when searching for nodes" do
+ before :each do
+ @searcher = Puppet::Node::Ldap.new
+ @entries = {}
+ entries = @entries
+
+ @connection = mock 'connection'
+ @entry = mock 'entry'
+ @connection.stubs(:search).yields(@entry)
+ @searcher.stubs(:connection).returns(@connection)
+ @searcher.stubs(:class_attributes).returns([])
+ @searcher.stubs(:parent_attribute).returns(nil)
+ @searcher.stubs(:search_base).returns(:yay)
+ @searcher.stubs(:search_filter).returns(:filter)
+
+ @node = mock 'node'
+ @node.stubs(:fact_merge)
+ @name = "mynode"
+ Puppet::Node.stubs(:new).with(@name).returns(@node)
+ end
- it "should return nil if no results are found in ldap" do
- @connection.stubs(:search)
- @searcher.find("mynode").should be_nil
- end
+ it "should return nil if no results are found in ldap" do
+ @connection.stubs(:search)
+ @searcher.find("mynode").should be_nil
+ end
- it "should return a node object if results are found in ldap" do
- @entry.stubs(:to_hash).returns({})
- @searcher.find("mynode").should equal(@node)
- end
+ it "should return a node object if results are found in ldap" do
+ @entry.stubs(:to_hash).returns({})
+ @searcher.find("mynode").should equal(@node)
+ end
- it "should deduplicate class values" do
- @entry.stubs(:to_hash).returns({})
- @searcher.stubs(:class_attributes).returns(%w{one two})
- @entry.stubs(:vals).with("one").returns(%w{a b})
- @entry.stubs(:vals).with("two").returns(%w{b c})
- @node.expects(:classes=).with(%w{a b c})
- @searcher.find("mynode")
- end
+ it "should deduplicate class values" do
+ @entry.stubs(:to_hash).returns({})
+ @searcher.stubs(:class_attributes).returns(%w{one two})
+ @entry.stubs(:vals).with("one").returns(%w{a b})
+ @entry.stubs(:vals).with("two").returns(%w{b c})
+ @node.expects(:classes=).with(%w{a b c})
+ @searcher.find("mynode")
+ end
- it "should add any values stored in the class_attributes attributes to the node classes" do
- @entry.stubs(:to_hash).returns({})
- @searcher.stubs(:class_attributes).returns(%w{one two})
- @entry.stubs(:vals).with("one").returns(%w{a b})
- @entry.stubs(:vals).with("two").returns(%w{c d})
- @node.expects(:classes=).with(%w{a b c d})
- @searcher.find("mynode")
- end
+ it "should add any values stored in the class_attributes attributes to the node classes" do
+ @entry.stubs(:to_hash).returns({})
+ @searcher.stubs(:class_attributes).returns(%w{one two})
+ @entry.stubs(:vals).with("one").returns(%w{a b})
+ @entry.stubs(:vals).with("two").returns(%w{c d})
+ @node.expects(:classes=).with(%w{a b c d})
+ @searcher.find("mynode")
+ end
- it "should add all entry attributes as node parameters" do
- @entry.stubs(:to_hash).returns("one" => ["two"], "three" => ["four"])
- @node.expects(:parameters=).with("one" => "two", "three" => "four")
- @searcher.find("mynode")
- end
+ it "should add all entry attributes as node parameters" do
+ @entry.stubs(:to_hash).returns("one" => ["two"], "three" => ["four"])
+ @node.expects(:parameters=).with("one" => "two", "three" => "four")
+ @searcher.find("mynode")
+ end
- it "should retain false parameter values" do
- @entry.stubs(:to_hash).returns("one" => [false])
- @node.expects(:parameters=).with("one" => false)
- @searcher.find("mynode")
- end
+ it "should set the node's environment to the environment of the results" do
+ @entry.stubs(:to_hash).returns("environment" => ["test"])
+ @node.stubs(:parameters=)
+ @node.expects(:environment=).with("test")
+ @searcher.find("mynode")
+ end
- it "should turn single-value parameter value arrays into single non-arrays" do
- @entry.stubs(:to_hash).returns("one" => ["a"])
- @node.expects(:parameters=).with("one" => "a")
- @searcher.find("mynode")
- end
+ it "should retain false parameter values" do
+ @entry.stubs(:to_hash).returns("one" => [false])
+ @node.expects(:parameters=).with("one" => false)
+ @searcher.find("mynode")
+ end
- it "should keep multi-valued parametes as arrays" do
- @entry.stubs(:to_hash).returns("one" => ["a", "b"])
- @node.expects(:parameters=).with("one" => ["a", "b"])
- @searcher.find("mynode")
- end
-end
+ it "should turn single-value parameter value arrays into single non-arrays" do
+ @entry.stubs(:to_hash).returns("one" => ["a"])
+ @node.expects(:parameters=).with("one" => "a")
+ @searcher.find("mynode")
+ end
-describe Puppet::Node::Ldap, " when a parent node is specified" do
- include LdapNodeSearching
+ it "should keep multi-valued parametes as arrays" do
+ @entry.stubs(:to_hash).returns("one" => ["a", "b"])
+ @node.expects(:parameters=).with("one" => ["a", "b"])
+ @searcher.find("mynode")
+ end
- before do
- @parent = mock 'parent'
- @parent_parent = mock 'parent_parent'
+ describe "and a parent node is specified" do
+ before do
+ @parent = mock 'parent'
+ @parent_parent = mock 'parent_parent'
- @searcher.meta_def(:search_filter) do |name|
- return name
- end
- @connection.stubs(:search).with { |*args| args[2] == @name }.yields(@entry)
- @connection.stubs(:search).with { |*args| args[2] == 'parent' }.yields(@parent)
- @connection.stubs(:search).with { |*args| args[2] == 'parent_parent' }.yields(@parent_parent)
+ @searcher.meta_def(:search_filter) do |name|
+ return name
+ end
+ @connection.stubs(:search).with { |*args| args[2] == @name }.yields(@entry)
+ @connection.stubs(:search).with { |*args| args[2] == 'parent' }.yields(@parent)
+ @connection.stubs(:search).with { |*args| args[2] == 'parent_parent' }.yields(@parent_parent)
- @searcher.stubs(:parent_attribute).returns(:parent)
- end
+ @searcher.stubs(:parent_attribute).returns(:parent)
+ end
- it "should fail if the parent cannot be found" do
- @connection.stubs(:search).with { |*args| args[2] == 'parent' }.returns("whatever")
+ it "should fail if the parent cannot be found" do
+ @connection.stubs(:search).with { |*args| args[2] == 'parent' }.returns("whatever")
- @entry.stubs(:to_hash).returns({})
- @entry.stubs(:vals).with(:parent).returns(%w{parent})
+ @entry.stubs(:to_hash).returns({})
+ @entry.stubs(:vals).with(:parent).returns(%w{parent})
- proc { @searcher.find("mynode") }.should raise_error(Puppet::Error)
- end
+ proc { @searcher.find("mynode") }.should raise_error(Puppet::Error)
+ end
- it "should add any parent classes to the node's classes" do
- @entry.stubs(:to_hash).returns({})
- @entry.stubs(:vals).with(:parent).returns(%w{parent})
- @entry.stubs(:vals).with("classes").returns(%w{a b})
+ it "should add any parent classes to the node's classes" do
+ @entry.stubs(:to_hash).returns({})
+ @entry.stubs(:vals).with(:parent).returns(%w{parent})
+ @entry.stubs(:vals).with("classes").returns(%w{a b})
- @parent.stubs(:to_hash).returns({})
- @parent.stubs(:vals).with("classes").returns(%w{c d})
- @parent.stubs(:vals).with(:parent).returns(nil)
+ @parent.stubs(:to_hash).returns({})
+ @parent.stubs(:vals).with("classes").returns(%w{c d})
+ @parent.stubs(:vals).with(:parent).returns(nil)
- @searcher.stubs(:class_attributes).returns(%w{classes})
- @node.expects(:classes=).with(%w{a b c d})
- @searcher.find("mynode")
- end
+ @searcher.stubs(:class_attributes).returns(%w{classes})
+ @node.expects(:classes=).with(%w{a b c d})
+ @searcher.find("mynode")
+ end
- it "should add any parent parameters to the node's parameters" do
- @entry.stubs(:to_hash).returns("one" => "two")
- @entry.stubs(:vals).with(:parent).returns(%w{parent})
+ it "should add any parent parameters to the node's parameters" do
+ @entry.stubs(:to_hash).returns("one" => "two")
+ @entry.stubs(:vals).with(:parent).returns(%w{parent})
- @parent.stubs(:to_hash).returns("three" => "four")
- @parent.stubs(:vals).with(:parent).returns(nil)
+ @parent.stubs(:to_hash).returns("three" => "four")
+ @parent.stubs(:vals).with(:parent).returns(nil)
- @node.expects(:parameters=).with("one" => "two", "three" => "four")
- @searcher.find("mynode")
- end
+ @node.expects(:parameters=).with("one" => "two", "three" => "four")
+ @searcher.find("mynode")
+ end
- it "should prefer node parameters over parent parameters" do
- @entry.stubs(:to_hash).returns("one" => "two")
- @entry.stubs(:vals).with(:parent).returns(%w{parent})
+ it "should prefer node parameters over parent parameters" do
+ @entry.stubs(:to_hash).returns("one" => "two")
+ @entry.stubs(:vals).with(:parent).returns(%w{parent})
- @parent.stubs(:to_hash).returns("one" => "three")
- @parent.stubs(:vals).with(:parent).returns(nil)
+ @parent.stubs(:to_hash).returns("one" => "three")
+ @parent.stubs(:vals).with(:parent).returns(nil)
- @node.expects(:parameters=).with("one" => "two")
- @searcher.find("mynode")
- end
+ @node.expects(:parameters=).with("one" => "two")
+ @searcher.find("mynode")
+ end
- it "should recursively look up parent information" do
- @entry.stubs(:to_hash).returns("one" => "two")
- @entry.stubs(:vals).with(:parent).returns(%w{parent})
+ it "should use the parent's environment if the node has none" do
+ @entry.stubs(:to_hash).returns({})
+ @entry.stubs(:vals).with(:parent).returns(%w{parent})
- @parent.stubs(:to_hash).returns("three" => "four")
- @parent.stubs(:vals).with(:parent).returns(['parent_parent'])
+ @parent.stubs(:to_hash).returns("environment" => ["parent"])
+ @parent.stubs(:vals).with(:parent).returns(nil)
- @parent_parent.stubs(:to_hash).returns("five" => "six")
- @parent_parent.stubs(:vals).with(:parent).returns(nil)
- @parent_parent.stubs(:vals).with(:parent).returns(nil)
+ @node.stubs(:parameters=)
+ @node.expects(:environment=).with("parent")
+ @searcher.find("mynode")
+ end
- @node.expects(:parameters=).with("one" => "two", "three" => "four", "five" => "six")
- @searcher.find("mynode")
- end
+ it "should prefer the node's environment to the parent's" do
+ @entry.stubs(:to_hash).returns("environment" => %w{child})
+ @entry.stubs(:vals).with(:parent).returns(%w{parent})
+
+ @parent.stubs(:to_hash).returns("environment" => ["parent"])
+ @parent.stubs(:vals).with(:parent).returns(nil)
+
+ @node.stubs(:parameters=)
+ @node.expects(:environment=).with("child")
+ @searcher.find("mynode")
+ end
+
+ it "should recursively look up parent information" do
+ @entry.stubs(:to_hash).returns("one" => "two")
+ @entry.stubs(:vals).with(:parent).returns(%w{parent})
- it "should not allow loops in parent declarations" do
- @entry.stubs(:to_hash).returns("one" => "two")
- @entry.stubs(:vals).with(:parent).returns(%w{parent})
+ @parent.stubs(:to_hash).returns("three" => "four")
+ @parent.stubs(:vals).with(:parent).returns(['parent_parent'])
- @parent.stubs(:to_hash).returns("three" => "four")
- @parent.stubs(:vals).with(:parent).returns([@name])
- proc { @searcher.find("mynode") }.should raise_error(ArgumentError)
+ @parent_parent.stubs(:to_hash).returns("five" => "six")
+ @parent_parent.stubs(:vals).with(:parent).returns(nil)
+ @parent_parent.stubs(:vals).with(:parent).returns(nil)
+
+ @node.expects(:parameters=).with("one" => "two", "three" => "four", "five" => "six")
+ @searcher.find("mynode")
+ end
+
+ it "should not allow loops in parent declarations" do
+ @entry.stubs(:to_hash).returns("one" => "two")
+ @entry.stubs(:vals).with(:parent).returns(%w{parent})
+
+ @parent.stubs(:to_hash).returns("three" => "four")
+ @parent.stubs(:vals).with(:parent).returns([@name])
+ proc { @searcher.find("mynode") }.should raise_error(ArgumentError)
+ end
+ end
end
end
diff --git a/spec/unit/indirector/node/plain.rb b/spec/unit/indirector/node/plain.rb
index 105d0ed63..943af52b4 100755
--- a/spec/unit/indirector/node/plain.rb
+++ b/spec/unit/indirector/node/plain.rb
@@ -15,4 +15,10 @@ describe Puppet::Node::Plain do
node.expects(:fact_merge)
@searcher.find("mynode")
end
+
+ it "should use the version of the facts as its version" do
+ version = mock 'version'
+ Puppet::Node::Facts.expects(:version).with("me").returns version
+ @searcher.version("me").should equal(version)
+ end
end
diff --git a/spec/unit/indirector/rest.rb b/spec/unit/indirector/rest.rb
index cf29577b9..3c4716dc8 100755
--- a/spec/unit/indirector/rest.rb
+++ b/spec/unit/indirector/rest.rb
@@ -13,7 +13,7 @@ describe Puppet::Indirector::REST do
@rest_class = Class.new(Puppet::Indirector::REST) do
def self.to_s
- "Testing"
+ "This::Is::A::Test::Class"
end
end
diff --git a/spec/unit/indirector/terminus.rb b/spec/unit/indirector/terminus.rb
index 99193dbc3..86813e4e5 100755
--- a/spec/unit/indirector/terminus.rb
+++ b/spec/unit/indirector/terminus.rb
@@ -5,8 +5,8 @@ require 'puppet/defaults'
require 'puppet/indirector'
require 'puppet/indirector/file'
-module TerminusInstanceTesting
- def setup
+describe Puppet::Indirector::Terminus do
+ before :each do
Puppet::Indirector::Terminus.stubs(:register_terminus_class)
@indirection = stub 'indirection', :name => :my_stuff, :register_terminus_type => nil
Puppet::Indirector::Indirection.stubs(:instance).with(:my_stuff).returns(@indirection)
@@ -22,51 +22,143 @@ module TerminusInstanceTesting
end
@terminus = @terminus_class.new
end
-end
-describe Puppet::Indirector::Terminus do
- include TerminusInstanceTesting
+ describe Puppet::Indirector::Terminus do
- it "should provide a method for setting terminus class documentation" do
- @terminus_class.should respond_to(:desc)
- end
+ it "should provide a method for setting terminus class documentation" do
+ @terminus_class.should respond_to(:desc)
+ end
- it "should support a class-level name attribute" do
- @terminus_class.should respond_to(:name)
- end
+ it "should support a class-level name attribute" do
+ @terminus_class.should respond_to(:name)
+ end
- it "should support a class-level indirection attribute" do
- @terminus_class.should respond_to(:indirection)
- end
+ it "should support a class-level indirection attribute" do
+ @terminus_class.should respond_to(:indirection)
+ end
- it "should support a class-level terminus-type attribute" do
- @terminus_class.should respond_to(:terminus_type)
- end
+ it "should support a class-level terminus-type attribute" do
+ @terminus_class.should respond_to(:terminus_type)
+ end
- it "should support a class-level model attribute" do
- @terminus_class.should respond_to(:model)
+ it "should support a class-level model attribute" do
+ @terminus_class.should respond_to(:model)
+ end
+
+ it "should accept indirection instances as its indirection" do
+ indirection = stub 'indirection', :is_a? => true, :register_terminus_type => nil
+ proc { @terminus_class.indirection = indirection }.should_not raise_error
+ @terminus_class.indirection.should equal(indirection)
+ end
+
+ it "should look up indirection instances when only a name has been provided" do
+ indirection = mock 'indirection'
+ Puppet::Indirector::Indirection.expects(:instance).with(:myind).returns(indirection)
+ @terminus_class.indirection = :myind
+ @terminus_class.indirection.should equal(indirection)
+ end
+
+ it "should fail when provided a name that does not resolve to an indirection" do
+ Puppet::Indirector::Indirection.expects(:instance).with(:myind).returns(nil)
+ proc { @terminus_class.indirection = :myind }.should raise_error(ArgumentError)
+
+ # It shouldn't overwrite our existing one (or, more normally, it shouldn't set
+ # anything).
+ @terminus_class.indirection.should equal(@indirection)
+ end
end
- it "should accept indirection instances as its indirection" do
- indirection = stub 'indirection', :is_a? => true, :register_terminus_type => nil
- proc { @terminus_class.indirection = indirection }.should_not raise_error
- @terminus_class.indirection.should equal(indirection)
+ describe Puppet::Indirector::Terminus, " when creating terminus classes" do
+ it "should associate the subclass with an indirection based on the subclass constant" do
+ @terminus.indirection.should equal(@indirection)
+ end
+
+ it "should set the subclass's type to the abstract terminus name" do
+ @terminus.terminus_type.should == :abstract
+ end
+
+ it "should set the subclass's name to the indirection name" do
+ @terminus.name.should == :term_type
+ end
+
+ it "should set the subclass's model to the indirection model" do
+ @indirection.expects(:model).returns :yay
+ @terminus.model.should == :yay
+ end
end
- it "should look up indirection instances when only a name has been provided" do
- indirection = mock 'indirection'
- Puppet::Indirector::Indirection.expects(:instance).with(:myind).returns(indirection)
- @terminus_class.indirection = :myind
- @terminus_class.indirection.should equal(indirection)
+ describe Puppet::Indirector::Terminus, " when a terminus instance" do
+
+ it "should return the class's name as its name" do
+ @terminus.name.should == :term_type
+ end
+
+ it "should return the class's indirection as its indirection" do
+ @terminus.indirection.should equal(@indirection)
+ end
+
+ it "should set the instances's type to the abstract terminus type's name" do
+ @terminus.terminus_type.should == :abstract
+ end
+
+ it "should set the instances's model to the indirection's model" do
+ @indirection.expects(:model).returns :yay
+ @terminus.model.should == :yay
+ end
end
- it "should fail when provided a name that does not resolve to an indirection" do
- Puppet::Indirector::Indirection.expects(:instance).with(:myind).returns(nil)
- proc { @terminus_class.indirection = :myind }.should raise_error(ArgumentError)
+ describe Puppet::Indirector::Terminus, " when managing indirected instances" do
+
+ it "should support comparing an instance's version with the terminus's version using just the instance's key" do
+ @terminus.should respond_to(:has_most_recent?)
+ end
+
+ it "should fail if the :version method has not been overridden and no :find method is available" do
+ proc { @terminus.version('yay') }.should raise_error(Puppet::DevError)
+ end
+
+ it "should use a found instance's version by default" do
+ name = 'instance'
+ instance = stub name, :version => 2
+ @terminus.expects(:find).with(name).returns(instance)
+ @terminus.version(name).should == 2
+ end
- # It shouldn't overwrite our existing one (or, more normally, it shouldn't set
- # anything).
- @terminus_class.indirection.should equal(@indirection)
+ it "should return nil as the version if no instance can be found" do
+ name = 'instance'
+ @terminus.expects(:find).with(name).returns(nil)
+ @terminus.version(name).should be_nil
+ end
+
+ it "should consider an instance fresh if its version is more recent than the version provided" do
+ name = "yay"
+ @terminus.expects(:version).with(name).returns(5)
+ @terminus.has_most_recent?(name, 4).should be_true
+ end
+
+ it "should consider an instance fresh if its version is equal to the version provided" do
+ name = "yay"
+ @terminus.expects(:version).with(name).returns(5)
+ @terminus.has_most_recent?(name, 5).should be_true
+ end
+
+ it "should consider an instance not fresh if the provided version is more recent than its version" do
+ name = "yay"
+ @terminus.expects(:version).with(name).returns(4)
+ @terminus.has_most_recent?(name, 5).should be_false
+ end
+
+ # Times annoyingly can't be compared directly to numbers, and our
+ # default version is 0.
+ it "should convert versions to floats when checking for freshness" do
+ existing = mock 'existing version'
+ new = mock 'new version'
+ existing.expects(:to_f).returns(1.0)
+ new.expects(:to_f).returns(1.0)
+ name = "yay"
+ @terminus.expects(:version).with(name).returns(existing)
+ @terminus.has_most_recent?(name, new)
+ end
end
end
@@ -205,98 +297,3 @@ describe Puppet::Indirector::Terminus, " when creating terminus class types" do
end
end
-describe Puppet::Indirector::Terminus, " when creating terminus classes" do
- include TerminusInstanceTesting
- it "should associate the subclass with an indirection based on the subclass constant" do
- @terminus.indirection.should equal(@indirection)
- end
-
- it "should set the subclass's type to the abstract terminus name" do
- @terminus.terminus_type.should == :abstract
- end
-
- it "should set the subclass's name to the indirection name" do
- @terminus.name.should == :term_type
- end
-
- it "should set the subclass's model to the indirection model" do
- @indirection.expects(:model).returns :yay
- @terminus.model.should == :yay
- end
-end
-
-describe Puppet::Indirector::Terminus, " when a terminus instance" do
- include TerminusInstanceTesting
-
- it "should return the class's name as its name" do
- @terminus.name.should == :term_type
- end
-
- it "should return the class's indirection as its indirection" do
- @terminus.indirection.should equal(@indirection)
- end
-
- it "should set the instances's type to the abstract terminus type's name" do
- @terminus.terminus_type.should == :abstract
- end
-
- it "should set the instances's model to the indirection's model" do
- @indirection.expects(:model).returns :yay
- @terminus.model.should == :yay
- end
-end
-
-describe Puppet::Indirector::Terminus, " when managing indirected instances" do
- include TerminusInstanceTesting
-
- it "should support comparing an instance's version with the terminus's version using just the instance's key" do
- @terminus.should respond_to(:has_most_recent?)
- end
-
- it "should fail if the :version method has not been overridden and no :find method is available" do
- proc { @terminus.version('yay') }.should raise_error(Puppet::DevError)
- end
-
- it "should use a found instance's version by default" do
- name = 'instance'
- instance = stub name, :version => 2
- @terminus.expects(:find).with(name).returns(instance)
- @terminus.version(name).should == 2
- end
-
- it "should return nil as the version if no instance can be found" do
- name = 'instance'
- @terminus.expects(:find).with(name).returns(nil)
- @terminus.version(name).should be_nil
- end
-
- it "should consider an instance fresh if its version is more recent than the version provided" do
- name = "yay"
- @terminus.expects(:version).with(name).returns(5)
- @terminus.has_most_recent?(name, 4).should be_true
- end
-
- it "should consider an instance fresh if its version is equal to the version provided" do
- name = "yay"
- @terminus.expects(:version).with(name).returns(5)
- @terminus.has_most_recent?(name, 5).should be_true
- end
-
- it "should consider an instance not fresh if the provided version is more recent than its version" do
- name = "yay"
- @terminus.expects(:version).with(name).returns(4)
- @terminus.has_most_recent?(name, 5).should be_false
- end
-
- # Times annoyingly can't be compared directly to numbers, and our
- # default version is 0.
- it "should convert versions to floats when checking for freshness" do
- existing = mock 'existing version'
- new = mock 'new version'
- existing.expects(:to_f).returns(1.0)
- new.expects(:to_f).returns(1.0)
- name = "yay"
- @terminus.expects(:version).with(name).returns(existing)
- @terminus.has_most_recent?(name, new)
- end
-end
diff --git a/spec/unit/indirector/yaml.rb b/spec/unit/indirector/yaml.rb
index f217a31b5..339529ab0 100755
--- a/spec/unit/indirector/yaml.rb
+++ b/spec/unit/indirector/yaml.rb
@@ -4,8 +4,8 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/indirector/yaml'
-module YamlTesting
- def setup
+describe Puppet::Indirector::Yaml, " when choosing file location" do
+ before :each do
@indirection = stub 'indirection', :name => :my_yaml, :register_terminus_type => nil
Puppet::Indirector::Indirection.stubs(:instance).with(:my_yaml).returns(@indirection)
@store_class = Class.new(Puppet::Indirector::Yaml) do
@@ -20,85 +20,91 @@ module YamlTesting
@subject.name = :me
@dir = "/what/ever"
- Puppet.settings.stubs(:use)
Puppet.settings.stubs(:value).with(:yamldir).returns(@dir)
end
-end
-describe Puppet::Indirector::Yaml, " when choosing file location" do
- include YamlTesting
+ it "should use the mtime of the written file as the version" do
+ stat = mock 'stat'
+ FileTest.stubs(:exist?).returns true
+ File.expects(:stat).returns stat
+ time = Time.now
+ stat.expects(:mtime).returns time
- it "should store all files in a single file root set in the Puppet defaults" do
- @store.send(:path, :me).should =~ %r{^#{@dir}}
+ @store.version(:me).should equal(time)
end
- it "should use the terminus name for choosing the subdirectory" do
- @store.send(:path, :me).should =~ %r{^#{@dir}/my_yaml}
- end
+ describe Puppet::Indirector::Yaml, " when choosing file location" do
- it "should use the object's name to determine the file name" do
- @store.send(:path, :me).should =~ %r{me.yaml$}
- end
-end
+ it "should store all files in a single file root set in the Puppet defaults" do
+ @store.send(:path, :me).should =~ %r{^#{@dir}}
+ end
-describe Puppet::Indirector::Yaml, " when storing objects as YAML" do
- include YamlTesting
+ it "should use the terminus name for choosing the subdirectory" do
+ @store.send(:path, :me).should =~ %r{^#{@dir}/my_yaml}
+ end
- it "should only store objects that respond to :name" do
- proc { @store.save(Object.new) }.should raise_error(ArgumentError)
+ it "should use the object's name to determine the file name" do
+ @store.send(:path, :me).should =~ %r{me.yaml$}
+ end
end
- it "should convert Ruby objects to YAML and write them to disk" do
- yaml = @subject.to_yaml
- file = mock 'file'
- path = @store.send(:path, @subject.name)
- FileTest.expects(:exist?).with(File.dirname(path)).returns(true)
- File.expects(:open).with(path, "w", 0660).yields(file)
- file.expects(:print).with(yaml)
+ describe Puppet::Indirector::Yaml, " when storing objects as YAML" do
- @store.save(@subject)
- end
+ it "should only store objects that respond to :name" do
+ proc { @store.save(Object.new) }.should raise_error(ArgumentError)
+ end
- it "should create the indirection subdirectory if it does not exist" do
- yaml = @subject.to_yaml
- file = mock 'file'
- path = @store.send(:path, @subject.name)
- dir = File.dirname(path)
- FileTest.expects(:exist?).with(dir).returns(false)
- Dir.expects(:mkdir).with(dir)
- File.expects(:open).with(path, "w", 0660).yields(file)
- file.expects(:print).with(yaml)
-
- @store.save(@subject)
- end
-end
+ it "should convert Ruby objects to YAML and write them to disk" do
+ yaml = @subject.to_yaml
+ file = mock 'file'
+ path = @store.send(:path, @subject.name)
+ FileTest.expects(:exist?).with(File.dirname(path)).returns(true)
+ File.expects(:open).with(path, "w", 0660).yields(file)
+ file.expects(:print).with(yaml)
-describe Puppet::Indirector::Yaml, " when retrieving YAML" do
- include YamlTesting
+ @store.save(@subject)
+ end
- it "should require the name of the object to retrieve" do
- proc { @store.find(nil) }.should raise_error(ArgumentError)
+ it "should create the indirection subdirectory if it does not exist" do
+ yaml = @subject.to_yaml
+ file = mock 'file'
+ path = @store.send(:path, @subject.name)
+ dir = File.dirname(path)
+ FileTest.expects(:exist?).with(dir).returns(false)
+ Dir.expects(:mkdir).with(dir)
+ File.expects(:open).with(path, "w", 0660).yields(file)
+ file.expects(:print).with(yaml)
+
+ @store.save(@subject)
+ end
end
- it "should read YAML in from disk and convert it to Ruby objects" do
- path = @store.send(:path, @subject.name)
+ describe Puppet::Indirector::Yaml, " when retrieving YAML" do
+
+ it "should require the name of the object to retrieve" do
+ proc { @store.find(nil) }.should raise_error(ArgumentError)
+ end
- yaml = @subject.to_yaml
- FileTest.expects(:exist?).with(path).returns(true)
- File.expects(:read).with(path).returns(yaml)
+ it "should read YAML in from disk and convert it to Ruby objects" do
+ path = @store.send(:path, @subject.name)
- @store.find(@subject.name).instance_variable_get("@name").should == :me
- end
+ yaml = @subject.to_yaml
+ FileTest.expects(:exist?).with(path).returns(true)
+ File.expects(:read).with(path).returns(yaml)
- it "should fail coherently when the stored YAML is invalid" do
- path = @store.send(:path, @subject.name)
+ @store.find(@subject.name).instance_variable_get("@name").should == :me
+ end
- # Something that will fail in yaml
- yaml = "--- !ruby/object:Hash"
+ it "should fail coherently when the stored YAML is invalid" do
+ path = @store.send(:path, @subject.name)
- FileTest.expects(:exist?).with(path).returns(true)
- File.expects(:read).with(path).returns(yaml)
+ # Something that will fail in yaml
+ yaml = "--- !ruby/object:Hash"
- proc { @store.find(@subject.name) }.should raise_error(Puppet::Error)
+ FileTest.expects(:exist?).with(path).returns(true)
+ File.expects(:read).with(path).returns(yaml)
+
+ proc { @store.find(@subject.name) }.should raise_error(Puppet::Error)
+ end
end
end
diff --git a/spec/unit/network/client.rb b/spec/unit/network/client.rb
new file mode 100644
index 000000000..bc41efb4f
--- /dev/null
+++ b/spec/unit/network/client.rb
@@ -0,0 +1,43 @@
+#!/usr/bin/env ruby
+#
+# Created by Luke Kanies on 2008-3-24.
+# Copyright (c) 2008. All rights reserved.
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+require 'puppet/network/client'
+
+describe Puppet::Network::Client do
+ before do
+ Puppet::Network::HttpPool.stubs(:cert_setup)
+ end
+ describe "when keep-alive is enabled" do
+ before do
+ Puppet::Network::HttpPool.stubs(:keep_alive?).returns true
+ end
+ it "should start the http client up on creation" do
+ http = mock 'http'
+ http.stub_everything
+ http.expects(:start)
+ Net::HTTP.stubs(:new).returns http
+
+ # Pick a random subclass...
+ Puppet::Network::Client.master.new :Server => Puppet[:server]
+ end
+ end
+
+ describe "when keep-alive is disabled" do
+ before do
+ Puppet::Network::HttpPool.stubs(:keep_alive?).returns false
+ end
+ it "should not start the http client up on creation" do
+ http = mock 'http'
+ http.stub_everything
+ http.expects(:start).never
+ Net::HTTP.stubs(:new).returns http
+
+ # Pick a random subclass...
+ Puppet::Network::Client.master.new :Server => Puppet[:server]
+ end
+ end
+end
diff --git a/spec/unit/network/http_pool.rb b/spec/unit/network/http_pool.rb
index 49da7d8f3..1fbc17471 100755
--- a/spec/unit/network/http_pool.rb
+++ b/spec/unit/network/http_pool.rb
@@ -9,6 +9,13 @@ require 'puppet/network/http_pool'
describe Puppet::Network::HttpPool, " when adding certificate information to http instances" do
before do
@http = mock 'http'
+ [:cert_store=, :verify_mode=, :ca_file=, :cert=, :key=].each { |m| @http.stubs(m) }
+ @store = stub 'store'
+ [:add_file,:purpose=].each { |m| @store.stubs(m) }
+ end
+
+ it "should have keep-alive disabled" do
+ Puppet::Network::HttpPool::HTTP_KEEP_ALIVE.should be_false
end
it "should do nothing if no certificate is available" do
@@ -19,26 +26,19 @@ describe Puppet::Network::HttpPool, " when adding certificate information to htt
it "should add a certificate store" do
Puppet::Network::HttpPool.stubs(:read_cert).returns(true)
- store = stub "store"
- OpenSSL::X509::Store.expects(:new).returns(store)
- store.stubs(:add_file)
- store.stubs(:purpose=)
- [:verify_mode=, :ca_file=, :cert=, :key=].each { |method| @http.stubs(method) }
- @http.expects(:cert_store=).with(store)
+ Puppet::Network::HttpPool.stubs(:key).returns(:mykey)
+ OpenSSL::X509::Store.expects(:new).returns(@store)
+ @http.expects(:cert_store=).with(@store)
Puppet::Network::HttpPool.cert_setup(@http)
end
it "should add the local CA cert to the certificate store" do
Puppet::Network::HttpPool.stubs(:read_cert).returns(true)
- store = stub "store"
- OpenSSL::X509::Store.expects(:new).returns(store)
- store.stubs(:purpose=)
- @http.stubs(:cert_store=)
+ OpenSSL::X509::Store.expects(:new).returns(@store)
Puppet.settings.stubs(:value).with(:localcacert).returns("/some/file")
Puppet.settings.stubs(:value).with(:localcacert).returns("/some/file")
- store.expects(:add_file).with("/some/file")
- [:store=, :verify_mode=, :ca_file=, :cert=, :key=].each { |method| @http.stubs(method) }
+ @store.expects(:add_file).with("/some/file")
Puppet::Network::HttpPool.stubs(:key).returns(:whatever)
@@ -47,12 +47,10 @@ describe Puppet::Network::HttpPool, " when adding certificate information to htt
it "should set the purpose of the cert store to OpenSSL::X509::PURPOSE_SSL_CLIENT" do
Puppet::Network::HttpPool.stubs(:read_cert).returns(true)
- store = stub "store"
- OpenSSL::X509::Store.expects(:new).returns(store)
- store.stubs(:add_file)
- [:cert_store=, :verify_mode=, :ca_file=, :cert=, :key=].each { |method| @http.stubs(method) }
+ Puppet::Network::HttpPool.stubs(:key).returns(:mykey)
+ OpenSSL::X509::Store.expects(:new).returns(@store)
- store.expects(:purpose=).with(OpenSSL::X509::PURPOSE_SSL_CLIENT)
+ @store.expects(:purpose=).with(OpenSSL::X509::PURPOSE_SSL_CLIENT)
Puppet::Network::HttpPool.cert_setup(@http)
end
@@ -60,7 +58,8 @@ describe Puppet::Network::HttpPool, " when adding certificate information to htt
it "should add the client certificate" do
Puppet::Network::HttpPool.stubs(:read_cert).returns(true)
Puppet::Network::HttpPool.stubs(:cert).returns(:mycert)
- [:cert_store=, :verify_mode=, :ca_file=, :key=].each { |method| @http.stubs(method) }
+ Puppet::Network::HttpPool.stubs(:key).returns(:mykey)
+ OpenSSL::X509::Store.expects(:new).returns(@store)
@http.expects(:cert=).with(:mycert)
@@ -70,7 +69,7 @@ describe Puppet::Network::HttpPool, " when adding certificate information to htt
it "should add the client key" do
Puppet::Network::HttpPool.stubs(:read_cert).returns(true)
Puppet::Network::HttpPool.stubs(:key).returns(:mykey)
- [:cert_store=, :verify_mode=, :cert=, :ca_file=].each { |method| @http.stubs(method) }
+ OpenSSL::X509::Store.expects(:new).returns(@store)
@http.expects(:key=).with(:mykey)
@@ -79,7 +78,8 @@ describe Puppet::Network::HttpPool, " when adding certificate information to htt
it "should set the verify mode to OpenSSL::SSL::VERIFY_PEER" do
Puppet::Network::HttpPool.stubs(:read_cert).returns(true)
- [:key=, :cert=, :cert_store=, :ca_file=].each { |method| @http.stubs(method) }
+ Puppet::Network::HttpPool.stubs(:key).returns(:mykey)
+ OpenSSL::X509::Store.expects(:new).returns(@store)
@http.expects(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
@@ -89,12 +89,7 @@ describe Puppet::Network::HttpPool, " when adding certificate information to htt
it "should set the ca file" do
Puppet::Network::HttpPool.stubs(:read_cert).returns(true)
Puppet.settings.stubs(:value).with(:localcacert).returns("/some/file")
- [:key=, :cert=, :cert_store=, :verify_mode=].each { |method| @http.stubs(method) }
-
- store = stub "store"
- OpenSSL::X509::Store.expects(:new).returns(store)
- store.stubs(:purpose=)
- store.stubs(:add_file)
+ OpenSSL::X509::Store.expects(:new).returns(@store)
@http.expects(:ca_file=).with("/some/file")
@@ -111,117 +106,135 @@ describe Puppet::Network::HttpPool, " when adding certificate information to htt
after do
Puppet::Network::HttpPool.clear_http_instances
end
-end
-describe Puppet::Network::HttpPool, " when managing http instances" do
- def stub_settings(settings)
- settings.each do |param, value|
- Puppet.settings.stubs(:value).with(param).returns(value)
+ describe "when managing http instances" do
+ def stub_settings(settings)
+ settings.each do |param, value|
+ Puppet.settings.stubs(:value).with(param).returns(value)
+ end
end
- end
-
- before do
- # All of hte cert stuff is tested elsewhere
- Puppet::Network::HttpPool.stubs(:cert_setup)
- end
- it "should return an http instance created with the passed host and port" do
- http = stub 'http', :use_ssl= => nil, :read_timeout= => nil, :open_timeout= => nil, :enable_post_connection_check= => nil, :started? => false
- Net::HTTP.expects(:new).with("me", 54321, nil, nil).returns(http)
- Puppet::Network::HttpPool.http_instance("me", 54321).should equal(http)
- end
-
- it "should enable ssl on the http instance" do
- Puppet::Network::HttpPool.http_instance("me", 54321).instance_variable_get("@use_ssl").should be_true
- end
-
- it "should set the read timeout" do
- Puppet::Network::HttpPool.http_instance("me", 54321).read_timeout.should == 120
- end
+ before do
+ # All of hte cert stuff is tested elsewhere
+ Puppet::Network::HttpPool.stubs(:cert_setup)
+ end
- it "should set the open timeout" do
- Puppet::Network::HttpPool.http_instance("me", 54321).open_timeout.should == 120
- end
+ it "should return an http instance created with the passed host and port" do
+ http = stub 'http', :use_ssl= => nil, :read_timeout= => nil, :open_timeout= => nil, :enable_post_connection_check= => nil, :started? => false
+ Net::HTTP.expects(:new).with("me", 54321, nil, nil).returns(http)
+ Puppet::Network::HttpPool.http_instance("me", 54321).should equal(http)
+ end
- it "should default to http_enable_post_connection_check being enabled" do
- Puppet.settings[:http_enable_post_connection_check].should be_true
- end
+ it "should enable ssl on the http instance" do
+ Puppet::Network::HttpPool.http_instance("me", 54321).instance_variable_get("@use_ssl").should be_true
+ end
- # JJM: I'm not sure if this is correct, as this really follows the
- # configuration option.
- it "should set enable_post_connection_check true " do
- Puppet::Network::HttpPool.http_instance("me", 54321).instance_variable_get("@enable_post_connection_check").should be_true
- end
+ it "should set the read timeout" do
+ Puppet::Network::HttpPool.http_instance("me", 54321).read_timeout.should == 120
+ end
- it "should create the http instance with the proxy host and port set if the http_proxy is not set to 'none'" do
- stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true
- Puppet::Network::HttpPool.http_instance("me", 54321).open_timeout.should == 120
- end
+ it "should set the open timeout" do
+ Puppet::Network::HttpPool.http_instance("me", 54321).open_timeout.should == 120
+ end
- it "should cache http instances" do
- stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true
- old = Puppet::Network::HttpPool.http_instance("me", 54321)
- Puppet::Network::HttpPool.http_instance("me", 54321).should equal(old)
- end
+ it "should default to http_enable_post_connection_check being enabled" do
+ Puppet.settings[:http_enable_post_connection_check].should be_true
+ end
- it "should have a mechanism for getting a new http instance instead of the cached instance" do
- stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true
- old = Puppet::Network::HttpPool.http_instance("me", 54321)
- Puppet::Network::HttpPool.http_instance("me", 54321, true).should_not equal(old)
- end
+ # JJM: I'm not sure if this is correct, as this really follows the
+ # configuration option.
+ it "should set enable_post_connection_check true " do
+ Puppet::Network::HttpPool.http_instance("me", 54321).instance_variable_get("@enable_post_connection_check").should be_true
+ end
- it "should close existing, open connections when requesting a new connection" do
- stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true
- old = Puppet::Network::HttpPool.http_instance("me", 54321)
- old.expects(:started?).returns(true)
- old.expects(:finish)
- Puppet::Network::HttpPool.http_instance("me", 54321, true)
- end
+ it "should create the http instance with the proxy host and port set if the http_proxy is not set to 'none'" do
+ stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true
+ Puppet::Network::HttpPool.http_instance("me", 54321).open_timeout.should == 120
+ end
- it "should have a mechanism for clearing the http cache" do
- stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true
- old = Puppet::Network::HttpPool.http_instance("me", 54321)
- Puppet::Network::HttpPool.http_instance("me", 54321).should equal(old)
- old = Puppet::Network::HttpPool.http_instance("me", 54321)
- Puppet::Network::HttpPool.clear_http_instances
- Puppet::Network::HttpPool.http_instance("me", 54321).should_not equal(old)
- end
+ describe "when http keep-alive is enabled" do
+ before do
+ Puppet::Network::HttpPool.stubs(:keep_alive?).returns true
+ end
+
+ it "should cache http instances" do
+ stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true
+ old = Puppet::Network::HttpPool.http_instance("me", 54321)
+ Puppet::Network::HttpPool.http_instance("me", 54321).should equal(old)
+ end
+
+ it "should have a mechanism for getting a new http instance instead of the cached instance" do
+ stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true
+ old = Puppet::Network::HttpPool.http_instance("me", 54321)
+ Puppet::Network::HttpPool.http_instance("me", 54321, true).should_not equal(old)
+ end
+
+ it "should close existing, open connections when requesting a new connection" do
+ stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true
+ old = Puppet::Network::HttpPool.http_instance("me", 54321)
+ old.expects(:started?).returns(true)
+ old.expects(:finish)
+ Puppet::Network::HttpPool.http_instance("me", 54321, true)
+ end
+
+ it "should have a mechanism for clearing the http cache" do
+ stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true
+ old = Puppet::Network::HttpPool.http_instance("me", 54321)
+ Puppet::Network::HttpPool.http_instance("me", 54321).should equal(old)
+ old = Puppet::Network::HttpPool.http_instance("me", 54321)
+ Puppet::Network::HttpPool.clear_http_instances
+ Puppet::Network::HttpPool.http_instance("me", 54321).should_not equal(old)
+ end
+
+ it "should close open http connections when clearing the cache" do
+ stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true
+ one = Puppet::Network::HttpPool.http_instance("me", 54321)
+ one.expects(:started?).returns(true)
+ one.expects(:finish).returns(true)
+ Puppet::Network::HttpPool.clear_http_instances
+ end
+
+ it "should not close unopened http connections when clearing the cache" do
+ stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true
+ one = Puppet::Network::HttpPool.http_instance("me", 54321)
+ one.expects(:started?).returns(false)
+ one.expects(:finish).never
+ Puppet::Network::HttpPool.clear_http_instances
+ end
+ end
- it "should close open http connections when clearing the cache" do
- stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true
- one = Puppet::Network::HttpPool.http_instance("me", 54321)
- one.expects(:started?).returns(true)
- one.expects(:finish).returns(true)
- Puppet::Network::HttpPool.clear_http_instances
- end
+ describe "when http keep-alive is disabled" do
+ before do
+ Puppet::Network::HttpPool.stubs(:keep_alive?).returns false
+ end
- it "should not close unopened http connections when clearing the cache" do
- stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true
- one = Puppet::Network::HttpPool.http_instance("me", 54321)
- one.expects(:started?).returns(false)
- one.expects(:finish).never
- Puppet::Network::HttpPool.clear_http_instances
- end
+ it "should not cache http instances" do
+ stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true
+ old = Puppet::Network::HttpPool.http_instance("me", 54321)
+ Puppet::Network::HttpPool.http_instance("me", 54321).should_not equal(old)
+ end
+ end
- # We mostly have to do this for testing, since in real life people
- # won't change certs within a single process.
- it "should remove its loaded certificate when clearing the cache" do
- Puppet::Network::HttpPool.instance_variable_set("@cert", :yay)
- Puppet::Network::HttpPool.clear_http_instances
- # Can't use the accessor, because it will read the cert in
- Puppet::Network::HttpPool.instance_variable_get("@cert").should be_nil
- end
+ # We mostly have to do this for testing, since in real life people
+ # won't change certs within a single process.
+ it "should remove its loaded certificate when clearing the cache" do
+ Puppet::Network::HttpPool.instance_variable_set("@cert", :yay)
+ Puppet::Network::HttpPool.clear_http_instances
+ # Can't use the accessor, because it will read the cert in
+ Puppet::Network::HttpPool.instance_variable_get("@cert").should be_nil
+ end
- # We mostly have to do this for testing, since in real life people
- # won't change certs within a single process.
- it "should remove its loaded key when clearing the cache" do
- Puppet::Network::HttpPool.instance_variable_set("@key", :yay)
- Puppet::Network::HttpPool.clear_http_instances
- # Can't use the accessor, because it will read the cert in
- Puppet::Network::HttpPool.instance_variable_get("@key").should be_nil
- end
+ # We mostly have to do this for testing, since in real life people
+ # won't change certs within a single process.
+ it "should remove its loaded key when clearing the cache" do
+ Puppet::Network::HttpPool.instance_variable_set("@key", :yay)
+ Puppet::Network::HttpPool.clear_http_instances
+ # Can't use the accessor, because it will read the cert in
+ Puppet::Network::HttpPool.instance_variable_get("@key").should be_nil
+ end
- after do
- Puppet::Network::HttpPool.clear_http_instances
+ after do
+ Puppet::Network::HttpPool.clear_http_instances
+ end
end
end
diff --git a/spec/unit/network/server.rb b/spec/unit/network/server.rb
index 3e29807ad..846b5471d 100644
--- a/spec/unit/network/server.rb
+++ b/spec/unit/network/server.rb
@@ -212,7 +212,7 @@ describe Puppet::Network::Server, "when listening is on" do
@server.listen
end
- it "should indicate that listening is turned off" do
+ it "should indicate that it is listening" do
@server.should be_listening
end
@@ -235,14 +235,14 @@ describe Puppet::Network::Server, "when listening is being turned on" do
@mock_http_server.stubs(:listen)
end
- it "should fetch an instance of an HTTP server when listening is turned on" do
+ it "should fetch an instance of an HTTP server" do
mock_http_server_class = mock('http server class')
mock_http_server_class.expects(:new).returns(@mock_http_server)
@server.expects(:http_server_class).returns(mock_http_server_class)
@server.listen
end
- it "should cause the HTTP server to listen when listening is turned on" do
+ it "should cause the HTTP server to listen" do
@mock_http_server.expects(:listen)
@server.expects(:http_server).returns(@mock_http_server)
@server.listen
@@ -261,7 +261,7 @@ describe Puppet::Network::Server, "when listening is being turned off" do
@server.listen
end
- it "should cause the HTTP server to stop listening when listening is turned off" do
+ it "should cause the HTTP server to stop listening" do
@mock_http_server.expects(:unlisten)
@server.unlisten
end
diff --git a/spec/unit/node.rb b/spec/unit/node.rb
index 0ce702936..bb99378d9 100755
--- a/spec/unit/node.rb
+++ b/spec/unit/node.rb
@@ -113,6 +113,22 @@ describe Puppet::Node, " when merging facts" do
@node.merge "two" => "three"
@node.parameters["two"].should == "three"
end
+
+ it "should add the environment to the list of parameters" do
+ Puppet.settings.stubs(:value).with(:environments).returns("one,two")
+ Puppet.settings.stubs(:value).with(:environment).returns("one")
+ @node = Puppet::Node.new("testnode", :environment => "one")
+ @node.merge "two" => "three"
+ @node.parameters["environment"].should == "one"
+ end
+
+ it "should not set the environment if it is already set in the parameters" do
+ Puppet.settings.stubs(:value).with(:environments).returns("one,two")
+ Puppet.settings.stubs(:value).with(:environment).returns("one")
+ @node = Puppet::Node.new("testnode", :environment => "one")
+ @node.merge "environment" => "two"
+ @node.parameters["environment"].should == "two"
+ end
end
describe Puppet::Node, " when indirecting" do
@@ -127,6 +143,10 @@ describe Puppet::Node, " when indirecting" do
Puppet::Node.indirection.terminus_class.should == :plain
end
+ it "should not have a cache class defined" do
+ Puppet::Node.indirection.cache_class.should be_nil
+ end
+
after do
Puppet::Indirector::Indirection.clear_cache
end
diff --git a/spec/unit/node/catalog.rb b/spec/unit/node/catalog.rb
index 4f9613d00..434242103 100755
--- a/spec/unit/node/catalog.rb
+++ b/spec/unit/node/catalog.rb
@@ -57,11 +57,11 @@ describe Puppet::Node::Catalog, " when extracting transobjects" do
def mkscope
@parser = Puppet::Parser::Parser.new :Code => ""
@node = Puppet::Node.new("mynode")
- @compile = Puppet::Parser::Compile.new(@node, @parser)
+ @compiler = Puppet::Parser::Compiler.new(@node, @parser)
# XXX This is ridiculous.
- @compile.send(:evaluate_main)
- @scope = @compile.topscope
+ @compiler.send(:evaluate_main)
+ @scope = @compiler.topscope
end
def mkresource(type, name)
@@ -75,7 +75,7 @@ describe Puppet::Node::Catalog, " when extracting transobjects" do
@source = mock 'source'
main = mkresource("class", :main)
- config.add_vertex!(main)
+ config.add_vertex(main)
bucket = mock 'bucket'
bucket.expects(:classes=).with(config.classes)
@@ -95,7 +95,7 @@ describe Puppet::Node::Catalog, " when extracting transobjects" do
defined = mkresource("class", :main)
builtin = mkresource("file", "/yay")
- config.add_edge!(defined, builtin)
+ config.add_edge(defined, builtin)
bucket = []
bucket.expects(:classes=).with(config.classes)
@@ -121,21 +121,21 @@ describe Puppet::Node::Catalog, " when extracting transobjects" do
top.expects(:to_trans).returns(topbucket)
topres = mkresource "file", "/top"
topres.expects(:to_trans).returns(:topres)
- config.add_edge! top, topres
+ config.add_edge top, topres
middle = mkresource "class", "middle"
middle.expects(:to_trans).returns([])
- config.add_edge! top, middle
+ config.add_edge top, middle
midres = mkresource "file", "/mid"
midres.expects(:to_trans).returns(:midres)
- config.add_edge! middle, midres
+ config.add_edge middle, midres
bottom = mkresource "class", "bottom"
bottom.expects(:to_trans).returns([])
- config.add_edge! middle, bottom
+ config.add_edge middle, bottom
botres = mkresource "file", "/bot"
botres.expects(:to_trans).returns(:botres)
- config.add_edge! bottom, botres
+ config.add_edge bottom, botres
toparray = config.extract_to_transportable
@@ -196,13 +196,13 @@ describe Puppet::Node::Catalog, " when converting to a transobject catalog" do
@resources = [@top, @topobject, @middle, @middleobject, @bottom, @bottomobject]
- @original.add_edge!(@top, @topobject)
- @original.add_edge!(@top, @virtual)
- @original.add_edge!(@virtual, @virtualobject)
- @original.add_edge!(@top, @middle)
- @original.add_edge!(@middle, @middleobject)
- @original.add_edge!(@middle, @bottom)
- @original.add_edge!(@bottom, @bottomobject)
+ @original.add_edge(@top, @topobject)
+ @original.add_edge(@top, @virtual)
+ @original.add_edge(@virtual, @virtualobject)
+ @original.add_edge(@top, @middle)
+ @original.add_edge(@middle, @middleobject)
+ @original.add_edge(@middle, @bottom)
+ @original.add_edge(@bottom, @bottomobject)
@catalog = @original.to_transportable
end
@@ -261,11 +261,11 @@ describe Puppet::Node::Catalog, " when converting to a RAL catalog" do
@original.add_resource(*@resources)
- @original.add_edge!(@top, @topobject)
- @original.add_edge!(@top, @middle)
- @original.add_edge!(@middle, @middleobject)
- @original.add_edge!(@middle, @bottom)
- @original.add_edge!(@bottom, @bottomobject)
+ @original.add_edge(@top, @topobject)
+ @original.add_edge(@top, @middle)
+ @original.add_edge(@middle, @middleobject)
+ @original.add_edge(@middle, @bottom)
+ @original.add_edge(@bottom, @bottomobject)
@catalog = @original.to_ral
end
@@ -300,10 +300,12 @@ describe Puppet::Node::Catalog, " when converting to a RAL catalog" do
config.add_resource(changer)
config.add_resource(@top)
- config.add_edge!(@top, changer)
+ config.add_edge(@top, changer)
resource = stub 'resource', :name => "changer2", :title => "changer2", :ref => "Test[changer2]", :catalog= => nil, :remove => nil
+ #changer is going to get duplicated as part of a fix for aliases 1094
+ changer.expects(:dup).returns(changer)
changer.expects(:to_type).returns(resource)
newconfig = nil
@@ -363,6 +365,12 @@ describe Puppet::Node::Catalog, " when functioning as a resource container" do
it "should not allow two resources with the same resource reference" do
@catalog.add_resource(@one)
+
+ # These are used to build the failure
+ @dupe.stubs(:file)
+ @dupe.stubs(:line)
+ @one.stubs(:file)
+ @one.stubs(:line)
proc { @catalog.add_resource(@dupe) }.should raise_error(ArgumentError)
end
@@ -469,9 +477,15 @@ describe Puppet::Node::Catalog, " when functioning as a resource container" do
proc { @catalog.alias @two, "one" }.should raise_error(ArgumentError)
end
- it "should fail to add an alias if the aliased name already exists as an alias" do
- @catalog.alias(@one, "yayness")
- proc { @catalog.alias @two, "yayness" }.should raise_error(ArgumentError)
+ it "should not fail when a resource has duplicate aliases created" do
+ @catalog.add_resource @one
+ proc { @catalog.alias @one, "one" }.should_not raise_error
+ end
+
+ it "should be able to look resources up by their aliases" do
+ @catalog.add_resource @one
+ @catalog.alias @one, "two"
+ @catalog.resource(:me, "two").should equal(@one)
end
it "should remove resource aliases when the target resource is removed" do
@@ -482,15 +496,32 @@ describe Puppet::Node::Catalog, " when functioning as a resource container" do
@catalog.resource("me", "other").should be_nil
end
- it "should return aliased resources when asked for the resource by the alias" do
- @catalog.add_resource @one
- @catalog.alias(@one, "other")
- @catalog.resource("Me[other]").should equal(@one)
+ it "should add an alias for the namevar when the title and name differ on isomorphic resource types" do
+ resource = Puppet::Type.type(:file).create :path => "/something", :title => "other", :content => "blah"
+ resource.expects(:isomorphic?).returns(true)
+ @catalog.add_resource(resource)
+ @catalog.resource(:file, "other").should equal(resource)
+ @catalog.resource(:file, "/something").ref.should == resource.ref
+ end
+
+ it "should not add an alias for the namevar when the title and name differ on non-isomorphic resource types" do
+ resource = Puppet::Type.type(:file).create :path => "/something", :title => "other", :content => "blah"
+ resource.expects(:isomorphic?).returns(false)
+ @catalog.add_resource(resource)
+ @catalog.resource(:file, resource.title).should equal(resource)
+ # We can't use .should here, because the resources respond to that method.
+ if @catalog.resource(:file, resource.name)
+ raise "Aliased non-isomorphic resource"
+ end
+ end
+
+ after do
+ Puppet::Type.allclear
end
end
-module ApplyingCatalogs
- def setup
+describe Puppet::Node::Catalog do
+ before :each do
@catalog = Puppet::Node::Catalog.new("host")
@catalog.retrieval_duration = Time.now
@@ -500,130 +531,124 @@ module ApplyingCatalogs
@transaction.stubs(:cleanup)
@transaction.stubs(:addtimes)
end
-end
-describe Puppet::Node::Catalog, " when applying" do
- include ApplyingCatalogs
+ describe Puppet::Node::Catalog, " when applying" do
- it "should create and evaluate a transaction" do
- @transaction.expects(:evaluate)
- @catalog.apply
- end
+ it "should create and evaluate a transaction" do
+ @transaction.expects(:evaluate)
+ @catalog.apply
+ end
- it "should provide the catalog time to the transaction" do
- @transaction.expects(:addtimes).with do |arg|
- arg[:config_retrieval].should be_instance_of(Time)
- true
+ it "should provide the catalog time to the transaction" do
+ @transaction.expects(:addtimes).with do |arg|
+ arg[:config_retrieval].should be_instance_of(Time)
+ true
+ end
+ @catalog.apply
end
- @catalog.apply
- end
- it "should clean up the transaction" do
- @transaction.expects :cleanup
- @catalog.apply
- end
+ it "should clean up the transaction" do
+ @transaction.expects :cleanup
+ @catalog.apply
+ end
- it "should return the transaction" do
- @catalog.apply.should equal(@transaction)
- end
+ it "should return the transaction" do
+ @catalog.apply.should equal(@transaction)
+ end
- it "should yield the transaction if a block is provided" do
- @catalog.apply do |trans|
- trans.should equal(@transaction)
+ it "should yield the transaction if a block is provided" do
+ @catalog.apply do |trans|
+ trans.should equal(@transaction)
+ end
end
- end
- it "should default to not being a host catalog" do
- @catalog.host_config.should be_nil
- end
+ it "should default to not being a host catalog" do
+ @catalog.host_config.should be_nil
+ end
- it "should pass supplied tags on to the transaction" do
- @transaction.expects(:tags=).with(%w{one two})
- @catalog.apply(:tags => %w{one two})
- end
+ it "should pass supplied tags on to the transaction" do
+ @transaction.expects(:tags=).with(%w{one two})
+ @catalog.apply(:tags => %w{one two})
+ end
- it "should set ignoreschedules on the transaction if specified in apply()" do
- @transaction.expects(:ignoreschedules=).with(true)
- @catalog.apply(:ignoreschedules => true)
+ it "should set ignoreschedules on the transaction if specified in apply()" do
+ @transaction.expects(:ignoreschedules=).with(true)
+ @catalog.apply(:ignoreschedules => true)
+ end
end
-end
-describe Puppet::Node::Catalog, " when applying host catalogs" do
- include ApplyingCatalogs
+ describe Puppet::Node::Catalog, " when applying host catalogs" do
- # super() doesn't work in the setup method for some reason
- before do
- @catalog.host_config = true
- end
+ # super() doesn't work in the setup method for some reason
+ before do
+ @catalog.host_config = true
+ end
- it "should send a report if reporting is enabled" do
- Puppet[:report] = true
- @transaction.expects :send_report
- @transaction.stubs :any_failed? => false
- @catalog.apply
- end
+ it "should send a report if reporting is enabled" do
+ Puppet[:report] = true
+ @transaction.expects :send_report
+ @transaction.stubs :any_failed? => false
+ @catalog.apply
+ end
- it "should send a report if report summaries are enabled" do
- Puppet[:summarize] = true
- @transaction.expects :send_report
- @transaction.stubs :any_failed? => false
- @catalog.apply
- end
+ it "should send a report if report summaries are enabled" do
+ Puppet[:summarize] = true
+ @transaction.expects :send_report
+ @transaction.stubs :any_failed? => false
+ @catalog.apply
+ end
- it "should initialize the state database before applying a catalog" do
- Puppet::Util::Storage.expects(:load)
+ it "should initialize the state database before applying a catalog" do
+ Puppet::Util::Storage.expects(:load)
- # Short-circuit the apply, so we know we're loading before the transaction
- Puppet::Transaction.expects(:new).raises ArgumentError
- proc { @catalog.apply }.should raise_error(ArgumentError)
- end
+ # Short-circuit the apply, so we know we're loading before the transaction
+ Puppet::Transaction.expects(:new).raises ArgumentError
+ proc { @catalog.apply }.should raise_error(ArgumentError)
+ end
- it "should sync the state database after applying" do
- Puppet::Util::Storage.expects(:store)
- @transaction.stubs :any_failed? => false
- @catalog.apply
- end
+ it "should sync the state database after applying" do
+ Puppet::Util::Storage.expects(:store)
+ @transaction.stubs :any_failed? => false
+ @catalog.apply
+ end
- after { Puppet.settings.clear }
-end
+ after { Puppet.settings.clear }
+ end
-describe Puppet::Node::Catalog, " when applying non-host catalogs" do
- include ApplyingCatalogs
+ describe Puppet::Node::Catalog, " when applying non-host catalogs" do
- before do
- @catalog.host_config = false
- end
+ before do
+ @catalog.host_config = false
+ end
- it "should never send reports" do
- Puppet[:report] = true
- Puppet[:summarize] = true
- @transaction.expects(:send_report).never
- @catalog.apply
- end
+ it "should never send reports" do
+ Puppet[:report] = true
+ Puppet[:summarize] = true
+ @transaction.expects(:send_report).never
+ @catalog.apply
+ end
- it "should never modify the state database" do
- Puppet::Util::Storage.expects(:load).never
- Puppet::Util::Storage.expects(:store).never
- @catalog.apply
- end
+ it "should never modify the state database" do
+ Puppet::Util::Storage.expects(:load).never
+ Puppet::Util::Storage.expects(:store).never
+ @catalog.apply
+ end
- after { Puppet.settings.clear }
+ after { Puppet.settings.clear }
+ end
end
describe Puppet::Node::Catalog, " when creating a relationship graph" do
before do
+ Puppet::Type.type(:component)
@catalog = Puppet::Node::Catalog.new("host")
@compone = Puppet::Type::Component.create :name => "one"
@comptwo = Puppet::Type::Component.create :name => "two", :require => ["class", "one"]
@file = Puppet::Type.type(:file)
@one = @file.create :path => "/one"
@two = @file.create :path => "/two"
- @sub = @file.create :path => "/two/three"
-
- @sub.stubs(:autorequire).returns([Puppet::Relationship.new(@two, @sub)])
-
- @catalog.add_edge! @compone, @one
- @catalog.add_edge! @comptwo, @two
+ @catalog.add_edge @compone, @one
+ @catalog.add_edge @comptwo, @two
@three = @file.create :path => "/three"
@four = @file.create :path => "/four", :require => ["file", "/three"]
@@ -796,7 +821,7 @@ end
describe Puppet::Node::Catalog, " when converting to yaml" do
before do
@catalog = Puppet::Node::Catalog.new("me")
- @catalog.add_edge!("one", "two")
+ @catalog.add_edge("one", "two")
end
it "should be able to be dumped to yaml" do
@@ -807,7 +832,7 @@ end
describe Puppet::Node::Catalog, " when converting from yaml" do
before do
@catalog = Puppet::Node::Catalog.new("me")
- @catalog.add_edge!("one", "two")
+ @catalog.add_edge("one", "two")
text = YAML.dump(@catalog)
@newcatalog = YAML.load(text)
diff --git a/spec/unit/other/pgraph.rb b/spec/unit/other/pgraph.rb
index 252a807ec..10ab934a6 100755
--- a/spec/unit/other/pgraph.rb
+++ b/spec/unit/other/pgraph.rb
@@ -5,6 +5,7 @@
require File.dirname(__FILE__) + '/../../spec_helper'
+require 'puppet/pgraph'
require 'puppet/util/graph'
class Container
@@ -35,8 +36,8 @@ describe Puppet::PGraph do
end
it "should correctly clear vertices and edges when asked" do
- @graph.add_edge!("a", "b")
- @graph.add_vertex! "c"
+ @graph.add_edge("a", "b")
+ @graph.add_vertex "c"
@graph.clear
@graph.vertices.should be_empty
@graph.edges.should be_empty
@@ -52,7 +53,7 @@ describe Puppet::PGraph, " when matching edges" do
@edges = {}
@edges["a/b"] = Puppet::Relationship.new("a", "b", {:event => :yay, :callback => :refresh})
@edges["a/c"] = Puppet::Relationship.new("a", "c", {:event => :yay, :callback => :refresh})
- @graph.add_edge!(@edges["a/b"])
+ @graph.add_edge(@edges["a/b"])
end
it "should match edges whose source matches the source of the event" do
@@ -64,7 +65,7 @@ describe Puppet::PGraph, " when matching edges" do
end
it "should match multiple edges" do
- @graph.add_edge!(@edges["a/c"])
+ @graph.add_edge(@edges["a/c"])
edges = @graph.matching_edges([@event])
edges.should be_include(@edges["a/b"])
edges.should be_include(@edges["a/c"])
@@ -75,9 +76,9 @@ describe Puppet::PGraph, " when determining dependencies" do
before do
@graph = Puppet::PGraph.new
- @graph.add_edge!("a", "b")
- @graph.add_edge!("a", "c")
- @graph.add_edge!("b", "d")
+ @graph.add_edge("a", "b")
+ @graph.add_edge("a", "c")
+ @graph.add_edge("b", "d")
end
it "should find all dependents when they are on multiple levels" do
@@ -118,19 +119,19 @@ describe Puppet::PGraph, " when splicing the relationship graph" do
# We have to add the container to the main graph, else it won't
# be spliced in the dependency graph.
- @contgraph.add_vertex!(@empty)
+ @contgraph.add_vertex(@empty)
end
def dependency_graph
@depgraph = Puppet::PGraph.new
@contgraph.vertices.each do |v|
- @depgraph.add_vertex!(v)
+ @depgraph.add_vertex(v)
end
# We have to specify a relationship to our empty container, else it
# never makes it into the dep graph in the first place.
{@one => @two, "f" => "c", "h" => @middle, "c" => @empty}.each do |source, target|
- @depgraph.add_edge!(source, target, :callback => :refresh)
+ @depgraph.add_edge(source, target, :callback => :refresh)
end
end
@@ -176,13 +177,13 @@ describe Puppet::PGraph, " when splicing the relationship graph" do
end
it "should not add labels to edges that have none" do
- @depgraph.add_edge!(@two, @three)
+ @depgraph.add_edge(@two, @three)
splice
@depgraph.edge_label("c", "i").should == {}
end
it "should copy labels over edges that have none" do
- @depgraph.add_edge!("c", @three, {:callback => :refresh})
+ @depgraph.add_edge("c", @three, {:callback => :refresh})
splice
# And make sure the label got copied.
@depgraph.edge_label("c", "i").should == {:callback => :refresh}
@@ -190,18 +191,18 @@ describe Puppet::PGraph, " when splicing the relationship graph" do
it "should not replace a label with a nil label" do
# Lastly, add some new label-less edges and make sure the label stays.
- @depgraph.add_edge!(@middle, @three)
- @depgraph.add_edge!("c", @three, {:callback => :refresh})
+ @depgraph.add_edge(@middle, @three)
+ @depgraph.add_edge("c", @three, {:callback => :refresh})
splice
@depgraph.edge_label("c", "i").should == {:callback => :refresh}
end
it "should copy labels to all created edges" do
- @depgraph.add_edge!(@middle, @three)
- @depgraph.add_edge!("c", @three, {:callback => :refresh})
+ @depgraph.add_edge(@middle, @three)
+ @depgraph.add_edge("c", @three, {:callback => :refresh})
splice
@three.each do |child|
- edge = @depgraph.edge_class.new("c", child)
+ edge = Puppet::Relationship.new("c", child)
@depgraph.should be_edge(edge.source, edge.target)
@depgraph.edge_label(edge.source, edge.target).should == {:callback => :refresh}
end
diff --git a/spec/unit/other/transaction.rb b/spec/unit/other/transaction.rb
index d88f03005..0db470d26 100755
--- a/spec/unit/other/transaction.rb
+++ b/spec/unit/other/transaction.rb
@@ -2,6 +2,8 @@
require File.dirname(__FILE__) + '/../../spec_helper'
+require 'puppet/transaction'
+
describe Puppet::Transaction, " when determining tags" do
before do
@config = Puppet::Node::Catalog.new
@@ -23,4 +25,9 @@ describe Puppet::Transaction, " when determining tags" do
@transaction.tags = %w{one two}
@transaction.tags.should == %w{one two}
end
+
+ it "should always convert assigned tags to an array" do
+ @transaction.tags = "one::two"
+ @transaction.tags.should == %w{one::two}
+ end
end
diff --git a/spec/unit/other/transbucket.rb b/spec/unit/other/transbucket.rb
index 89f48ad41..4494f2abb 100755
--- a/spec/unit/other/transbucket.rb
+++ b/spec/unit/other/transbucket.rb
@@ -87,35 +87,49 @@ describe Puppet::TransBucket, " when generating a catalog" do
@top.push(@topobj)
@top.push(@middle)
- @config = @top.to_catalog
-
@users = %w{top middle bottom}
@fakes = %w{Fake[bottom] Fake[middle] Fake[top]}
end
+ after do
+ Puppet::Type.allclear
+ end
+
it "should convert all transportable objects to RAL resources" do
+ @catalog = @top.to_catalog
@users.each do |name|
- @config.vertices.find { |r| r.class.name == :user and r.title == name }.should be_instance_of(Puppet::Type.type(:user))
+ @catalog.vertices.find { |r| r.class.name == :user and r.title == name }.should be_instance_of(Puppet::Type.type(:user))
end
end
+ it "should fail if any transportable resources fail to convert to RAL resources" do
+ @bottomobj.expects(:to_type).raises ArgumentError
+ lambda { @bottom.to_catalog }.should raise_error(ArgumentError)
+ end
+
it "should convert all transportable buckets to RAL components" do
+ @catalog = @top.to_catalog
@fakes.each do |name|
- @config.vertices.find { |r| r.class.name == :component and r.title == name }.should be_instance_of(Puppet::Type.type(:component))
+ @catalog.vertices.find { |r| r.class.name == :component and r.title == name }.should be_instance_of(Puppet::Type.type(:component))
end
end
it "should add all resources to the graph's resource table" do
- @config.resource("fake[top]").should equal(@top)
+ @catalog = @top.to_catalog
+ @catalog.resource("fake[top]").should equal(@top)
end
it "should finalize all resources" do
- @config.vertices.each do |vertex| vertex.should be_finalized end
+ @catalog = @top.to_catalog
+ @catalog.vertices.each do |vertex| vertex.should be_finalized end
end
it "should only call to_type on each resource once" do
- @topobj.expects(:to_type)
- @bottomobj.expects(:to_type)
+ # We just raise exceptions here because we're not interested in
+ # what happens with the result, only that the method only
+ # gets called once.
+ resource = @topobj.to_type
+ @topobj.expects(:to_type).once.returns resource
@top.to_catalog
end
diff --git a/spec/unit/parser/ast/definition.rb b/spec/unit/parser/ast/definition.rb
index a27fb4721..a58e4d00e 100755
--- a/spec/unit/parser/ast/definition.rb
+++ b/spec/unit/parser/ast/definition.rb
@@ -12,8 +12,8 @@ describe Puppet::Parser::AST::Definition, "when evaluating" do
@source = @parser.newclass ""
@definition = @parser.newdefine "mydefine"
@node = Puppet::Node.new("yaynode")
- @compile = Puppet::Parser::Compile.new(@node, @parser)
- @scope = @compile.topscope
+ @compiler = Puppet::Parser::Compiler.new(@node, @parser)
+ @scope = @compiler.topscope
@resource = Puppet::Parser::Resource.new(:type => "mydefine", :title => "myresource", :scope => @scope, :source => @source)
end
@@ -21,12 +21,12 @@ describe Puppet::Parser::AST::Definition, "when evaluating" do
it "should create a new scope" do
scope = nil
code = mock 'code'
- code.expects(:safeevaluate).with do |options|
- options[:scope].object_id.should_not == @scope.object_id
+ code.expects(:safeevaluate).with do |scope|
+ scope.object_id.should_not == @scope.object_id
true
end
@definition.stubs(:code).returns(code)
- @definition.evaluate(:scope => @scope, :resource => @resource)
+ @definition.evaluate_code(@resource)
end
# it "should copy its namespace to the scope"
@@ -44,4 +44,152 @@ describe Puppet::Parser::AST::Definition, "when evaluating" do
# it "should not copy the resource's title as the name if 'name' is one of the resource parameters"
#
# it "should evaluate the associated code with the new scope"
+
+ def old_test_initialize
+ parser = mkparser
+
+ # Create a new definition
+ klass = parser.newdefine "yayness",
+ :arguments => [["owner", stringobj("nobody")], %w{mode}],
+ :code => AST::ASTArray.new(
+ :children => [resourcedef("file", "/tmp/$name",
+ "owner" => varref("owner"), "mode" => varref("mode"))]
+ )
+
+ # Test validattr? a couple different ways
+ [:owner, "owner", :schedule, "schedule"].each do |var|
+ assert(klass.validattr?(var), "%s was not considered valid" % var.inspect)
+ end
+
+ [:random, "random"].each do |var|
+ assert(! klass.validattr?(var), "%s was considered valid" % var.inspect)
+ end
+
+ end
+
+ def oldtest_evaluate
+ parser = mkparser
+ config = mkcompiler
+ config.send(:evaluate_main)
+ scope = config.topscope
+ klass = parser.newdefine "yayness",
+ :arguments => [["owner", stringobj("nobody")], %w{mode}],
+ :code => AST::ASTArray.new(
+ :children => [resourcedef("file", "/tmp/$name",
+ "owner" => varref("owner"), "mode" => varref("mode"))]
+ )
+
+ resource = Puppet::Parser::Resource.new(
+ :title => "first",
+ :type => "yayness",
+ :exported => false,
+ :virtual => false,
+ :scope => scope,
+ :source => scope.source
+ )
+ resource.send(:set_parameter, "name", "first")
+ resource.send(:set_parameter, "mode", "755")
+
+ resource.stubs(:title)
+ assert_nothing_raised do
+ klass.evaluate_code(resource)
+ end
+
+ firstobj = config.findresource("File[/tmp/first]")
+ assert(firstobj, "Did not create /tmp/first obj")
+
+ assert_equal("File", firstobj.type)
+ assert_equal("/tmp/first", firstobj.title)
+ assert_equal("nobody", firstobj[:owner])
+ assert_equal("755", firstobj[:mode])
+
+ # Make sure we can't evaluate it with the same args
+ assert_raise(Puppet::ParseError) do
+ klass.evaluate_code(resource)
+ end
+
+ # Now create another with different args
+ resource2 = Puppet::Parser::Resource.new(
+ :title => "second",
+ :type => "yayness",
+ :exported => false,
+ :virtual => false,
+ :scope => scope,
+ :source => scope.source
+ )
+ resource2.send(:set_parameter, "name", "second")
+ resource2.send(:set_parameter, "mode", "755")
+ resource2.send(:set_parameter, "owner", "daemon")
+
+ assert_nothing_raised do
+ klass.evaluate_code(resource2)
+ end
+
+ secondobj = config.findresource("File[/tmp/second]")
+ assert(secondobj, "Did not create /tmp/second obj")
+
+ assert_equal("File", secondobj.type)
+ assert_equal("/tmp/second", secondobj.title)
+ assert_equal("daemon", secondobj[:owner])
+ assert_equal("755", secondobj[:mode])
+ end
+
+ # #539 - definitions should support both names and titles
+ def oldtest_names_and_titles
+ parser = mkparser
+ scope = mkscope :parser => parser
+
+ [
+ {:name => "one", :title => "two"},
+ {:title => "mytitle"}
+ ].each_with_index do |hash, i|
+ # Create a definition that uses both name and title. Put this
+ # inside the loop so the subscope expectations work.
+ klass = parser.newdefine "yayness%s" % i
+
+ resource = Puppet::Parser::Resource.new(
+ :title => hash[:title],
+ :type => "yayness%s" % i,
+ :exported => false,
+ :virtual => false,
+ :scope => scope,
+ :source => scope.source
+ )
+
+ subscope = klass.subscope(scope, resource)
+
+ klass.expects(:subscope).returns(subscope)
+
+ if hash[:name]
+ resource.stubs(:to_hash).returns({:name => hash[:name]})
+ end
+
+ assert_nothing_raised("Could not evaluate definition with %s" % hash.inspect) do
+ klass.evaluate_code(resource)
+ end
+
+ name = hash[:name] || hash[:title]
+ title = hash[:title]
+
+ assert_equal(name, subscope.lookupvar("name"),
+ "Name did not get set correctly")
+ assert_equal(title, subscope.lookupvar("title"),
+ "title did not get set correctly")
+
+ [:name, :title].each do |param|
+ val = resource.send(param)
+ assert(subscope.tags.include?(val),
+ "Scope was not tagged with %s '%s'" % [param, val])
+ end
+ end
+ end
+
+ # Testing the root cause of #615. We should be using the fqname for the type, instead
+ # of just the short name.
+ def oldtest_fully_qualified_types
+ parser = mkparser
+ klass = parser.newclass("one::two")
+
+ assert_equal("one::two", klass.classname, "Class did not get fully qualified class name")
+ end
end
diff --git a/spec/unit/parser/ast/hostclass.rb b/spec/unit/parser/ast/hostclass.rb
new file mode 100755
index 000000000..0abc174d9
--- /dev/null
+++ b/spec/unit/parser/ast/hostclass.rb
@@ -0,0 +1,135 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+describe Puppet::Parser::AST::HostClass do
+ before :each do
+ @node = Puppet::Node.new "testnode"
+ @parser = Puppet::Parser::Parser.new :environment => "development"
+ @scope_resource = stub 'scope_resource', :builtin? => true
+ @compiler = Puppet::Parser::Compiler.new(@node, @parser)
+
+ @scope = @compiler.topscope
+ end
+
+ describe Puppet::Parser::AST::HostClass, "when evaluating" do
+
+ before do
+ @top = @parser.newclass "top"
+ @middle = @parser.newclass "middle", :parent => "top"
+ end
+
+ it "should create a resource that references itself" do
+ @top.evaluate(@scope)
+
+ @compiler.catalog.resource(:class, "top").should be_instance_of(Puppet::Parser::Resource)
+ end
+
+ it "should evaluate the parent class if one exists" do
+ @middle.evaluate(@scope)
+
+ @compiler.catalog.resource(:class, "top").should be_instance_of(Puppet::Parser::Resource)
+ end
+
+ it "should fail to evaluate if a parent class is defined but cannot be found" do
+ othertop = @parser.newclass "something", :parent => "yay"
+ lambda { othertop.evaluate(@scope) }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should not create a new resource if one already exists" do
+ @compiler.catalog.expects(:resource).with(:class, "top").returns("something")
+ @compiler.catalog.expects(:add_resource).never
+ @top.evaluate(@scope)
+ end
+
+ it "should return the existing resource when not creating a new one" do
+ @compiler.catalog.expects(:resource).with(:class, "top").returns("something")
+ @compiler.catalog.expects(:add_resource).never
+ @top.evaluate(@scope).should == "something"
+ end
+
+ it "should not create a new parent resource if one already exists and it has a parent class" do
+ @top.evaluate(@scope)
+
+ top_resource = @compiler.catalog.resource(:class, "top")
+
+ @middle.evaluate(@scope)
+
+ @compiler.catalog.resource(:class, "top").should equal(top_resource)
+ end
+
+ # #795 - tag before evaluation.
+ it "should tag the catalog with the resource tags when it is evaluated" do
+ @middle.evaluate(@scope)
+
+ @compiler.catalog.should be_tagged("middle")
+ end
+
+ it "should tag the catalog with the parent class tags when it is evaluated" do
+ @middle.evaluate(@scope)
+
+ @compiler.catalog.should be_tagged("top")
+ end
+ end
+
+ describe Puppet::Parser::AST::HostClass, "when evaluating code" do
+
+ before do
+ @top_resource = stub "top_resource"
+ @top = @parser.newclass "top", :code => @top_resource
+
+ @middle_resource = stub "middle_resource"
+ @middle = @parser.newclass "top::middle", :parent => "top", :code => @middle_resource
+ end
+
+ it "should set its namespace to its fully qualified name" do
+ @middle.namespace.should == "top::middle"
+ end
+
+ it "should evaluate the code referred to by the class" do
+ @top_resource.expects(:safeevaluate)
+
+ resource = @top.evaluate(@scope)
+
+ @top.evaluate_code(resource)
+ end
+
+ it "should evaluate the parent class's code if it has a parent" do
+ @top_resource.expects(:safeevaluate)
+ @middle_resource.expects(:safeevaluate)
+
+ resource = @middle.evaluate(@scope)
+
+ @middle.evaluate_code(resource)
+ end
+
+ it "should not evaluate the parent class's code if the parent has already been evaluated" do
+ @top_resource.stubs(:safeevaluate)
+ resource = @top.evaluate(@scope)
+ @top.evaluate_code(resource)
+
+ @top_resource.expects(:safeevaluate).never
+ @middle_resource.stubs(:safeevaluate)
+ resource = @middle.evaluate(@scope)
+ @middle.evaluate_code(resource)
+ end
+
+ it "should use the parent class's scope as its parent scope" do
+ @top_resource.stubs(:safeevaluate)
+ @middle_resource.stubs(:safeevaluate)
+ resource = @middle.evaluate(@scope)
+ @middle.evaluate_code(resource)
+
+ @compiler.class_scope(@middle).parent.should equal(@compiler.class_scope(@top))
+ end
+
+ it "should add the parent class's namespace to its namespace search path" do
+ @top_resource.stubs(:safeevaluate)
+ @middle_resource.stubs(:safeevaluate)
+ resource = @middle.evaluate(@scope)
+ @middle.evaluate_code(resource)
+
+ @compiler.class_scope(@middle).namespaces.should be_include(@top.namespace)
+ end
+ end
+end
diff --git a/spec/unit/parser/ast/node.rb b/spec/unit/parser/ast/node.rb
new file mode 100755
index 000000000..757934415
--- /dev/null
+++ b/spec/unit/parser/ast/node.rb
@@ -0,0 +1,125 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+describe Puppet::Parser::AST::Node do
+ before :each do
+ @node = Puppet::Node.new "testnode"
+ @parser = Puppet::Parser::Parser.new :environment => "development"
+ @scope_resource = stub 'scope_resource', :builtin? => true
+ @compiler = Puppet::Parser::Compiler.new(@node, @parser)
+
+ @scope = @compiler.topscope
+ end
+
+ describe Puppet::Parser::AST::Node, "when evaluating" do
+
+ before do
+ @top = @parser.newnode("top").shift
+ @middle = @parser.newnode("middle", :parent => "top").shift
+ end
+
+ it "should create a resource that references itself" do
+ @top.evaluate(@scope)
+
+ @compiler.catalog.resource(:node, "top").should be_an_instance_of(Puppet::Parser::Resource)
+ end
+
+ it "should evaluate the parent class if one exists" do
+ @middle.evaluate(@scope)
+
+ @compiler.catalog.resource(:node, "top").should be_an_instance_of(Puppet::Parser::Resource)
+ end
+
+ it "should fail to evaluate if a parent class is defined but cannot be found" do
+ othertop = @parser.newnode("something", :parent => "yay").shift
+ lambda { othertop.evaluate(@scope) }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should not create a new resource if one already exists" do
+ @compiler.catalog.expects(:resource).with(:node, "top").returns("something")
+ @compiler.catalog.expects(:add_resource).never
+ @top.evaluate(@scope)
+ end
+
+ it "should not create a new parent resource if one already exists and it has a parent class" do
+ @top.evaluate(@scope)
+
+ top_resource = @compiler.catalog.resource(:node, "top")
+
+ @middle.evaluate(@scope)
+
+ @compiler.catalog.resource(:node, "top").should equal(top_resource)
+ end
+
+ # #795 - tag before evaluation.
+ it "should tag the catalog with the resource tags when it is evaluated" do
+ @middle.evaluate(@scope)
+
+ @compiler.catalog.should be_tagged("middle")
+ end
+
+ it "should tag the catalog with the parent class tags when it is evaluated" do
+ @middle.evaluate(@scope)
+
+ @compiler.catalog.should be_tagged("top")
+ end
+ end
+
+ describe Puppet::Parser::AST::Node, "when evaluating code" do
+
+ before do
+ @top_resource = stub "top_resource"
+ @top = @parser.newnode("top", :code => @top_resource).shift
+
+ @middle_resource = stub "middle_resource"
+ @middle = @parser.newnode("middle", :parent => "top", :code => @middle_resource).shift
+ end
+
+ it "should evaluate the code referred to by the class" do
+ @top_resource.expects(:safeevaluate)
+
+ resource = @top.evaluate(@scope)
+
+ @top.evaluate_code(resource)
+ end
+
+ it "should evaluate the parent class's code if it has a parent" do
+ @top_resource.expects(:safeevaluate)
+ @middle_resource.expects(:safeevaluate)
+
+ resource = @middle.evaluate(@scope)
+
+ @middle.evaluate_code(resource)
+ end
+
+ it "should not evaluate the parent class's code if the parent has already been evaluated" do
+ @top_resource.stubs(:safeevaluate)
+ resource = @top.evaluate(@scope)
+ @top.evaluate_code(resource)
+
+ @top_resource.expects(:safeevaluate).never
+ @middle_resource.stubs(:safeevaluate)
+ resource = @middle.evaluate(@scope)
+ @middle.evaluate_code(resource)
+ end
+
+ it "should use the parent class's scope as its parent scope" do
+ @top_resource.stubs(:safeevaluate)
+ @middle_resource.stubs(:safeevaluate)
+ resource = @middle.evaluate(@scope)
+ @middle.evaluate_code(resource)
+
+ @compiler.class_scope(@middle).parent.should equal(@compiler.class_scope(@top))
+ end
+
+ it "should add the parent class's namespace to its namespace search path" do
+ @top_resource.stubs(:safeevaluate)
+ @middle_resource.stubs(:safeevaluate)
+ resource = @middle.evaluate(@scope)
+ @middle.evaluate_code(resource)
+
+ @compiler.class_scope(@middle).namespaces.should be_include(@top.namespace)
+ end
+ end
+end \ No newline at end of file
diff --git a/spec/unit/parser/collector.rb b/spec/unit/parser/collector.rb
index 9b5eab1f4..e1ceb23ed 100755
--- a/spec/unit/parser/collector.rb
+++ b/spec/unit/parser/collector.rb
@@ -79,8 +79,8 @@ describe Puppet::Parser::Collector, "when collecting specific virtual resources"
@collector.resources = ["File[virtual1]"]
one = mock 'one'
one.stubs(:virtual=)
- @compile.expects(:delete_collection).with(@collector)
- @scope.expects(:compile).returns(@compile)
+ @compiler.expects(:delete_collection).with(@collector)
+ @scope.expects(:compiler).returns(@compiler)
@scope.stubs(:findresource).with("File[virtual1]").returns(one)
@collector.evaluate
end
@@ -89,7 +89,7 @@ describe Puppet::Parser::Collector, "when collecting specific virtual resources"
@collector.resources = ["File[virtual1]"]
one = mock 'one'
one.stubs(:virtual=)
- @compile.expects(:delete_collection).never
+ @compiler.expects(:delete_collection).never
@scope.stubs(:findresource).with("File[virtual1]").returns(nil)
@collector.evaluate
end
@@ -98,8 +98,8 @@ end
describe Puppet::Parser::Collector, "when collecting virtual resources" do
before do
@scope = mock 'scope'
- @compile = mock 'compile'
- @scope.stubs(:compile).returns(@compile)
+ @compiler = mock 'compile'
+ @scope.stubs(:compiler).returns(@compiler)
@resource_type = "Mytype"
@vquery = proc { |res| true }
@@ -113,7 +113,7 @@ describe Puppet::Parser::Collector, "when collecting virtual resources" do
one.stubs(:virtual=)
two.stubs(:virtual=)
- @compile.expects(:resources).returns([one, two])
+ @compiler.expects(:resources).returns([one, two])
@collector.evaluate.should == [one, two]
end
@@ -123,7 +123,7 @@ describe Puppet::Parser::Collector, "when collecting virtual resources" do
one.expects(:virtual=).with(false)
- @compile.expects(:resources).returns([one])
+ @compiler.expects(:resources).returns([one])
@collector.evaluate
end
@@ -135,7 +135,7 @@ describe Puppet::Parser::Collector, "when collecting virtual resources" do
one.stubs(:virtual=)
two.stubs(:virtual=)
- @compile.expects(:resources).returns([one, two])
+ @compiler.expects(:resources).returns([one, two])
@collector.evaluate.should == [one, two]
end
@@ -147,7 +147,7 @@ describe Puppet::Parser::Collector, "when collecting virtual resources" do
one.expects(:virtual=).with(false)
two.expects(:virtual=).with(false)
- @compile.expects(:resources).returns([one, two])
+ @compiler.expects(:resources).returns([one, two])
@collector = Puppet::Parser::Collector.new(@scope, @resource_type, nil, nil, :virtual)
@@ -161,7 +161,7 @@ describe Puppet::Parser::Collector, "when collecting virtual resources" do
one.expects(:virtual=).with(false)
two.expects(:virtual=).never
- @compile.expects(:resources).returns([one, two])
+ @compiler.expects(:resources).returns([one, two])
@collector.evaluate.should == [one]
end
@@ -173,7 +173,7 @@ describe Puppet::Parser::Collector, "when collecting virtual resources" do
one.expects(:virtual=).never
two.expects(:virtual=).never
- @compile.expects(:resources).returns([one, two])
+ @compiler.expects(:resources).returns([one, two])
@collector.evaluate.should be_false
end
@@ -187,7 +187,7 @@ describe Puppet::Parser::Collector, "when collecting virtual resources" do
one.expects(:virtual=).with(false)
two.expects(:virtual=).never
- @compile.expects(:resources).returns([one, two])
+ @compiler.expects(:resources).returns([one, two])
@collector.evaluate.should == [one]
end
@@ -198,8 +198,8 @@ describe Puppet::Parser::Collector, "when collecting exported resources" do
before do
@scope = stub 'scope', :host => "myhost", :debug => nil
- @compile = mock 'compile'
- @scope.stubs(:compile).returns(@compile)
+ @compiler = mock 'compile'
+ @scope.stubs(:compiler).returns(@compiler)
@resource_type = "Mytype"
@equery = "test = true"
@vquery = proc { |r| true }
@@ -218,7 +218,7 @@ describe Puppet::Parser::Collector, "when collecting exported resources" do
end
it "should use initialize the Rails support if ActiveRecord is not connected" do
- @compile.stubs(:resources).returns([])
+ @compiler.stubs(:resources).returns([])
ActiveRecord::Base.expects(:connected?).returns(false)
Puppet::Rails.expects(:init)
Puppet::Rails::Host.stubs(:find_by_name).returns(nil)
@@ -238,7 +238,7 @@ describe Puppet::Parser::Collector, "when collecting exported resources" do
two.stubs(:exported=)
two.stubs(:virtual=)
- @compile.expects(:resources).returns([one, two])
+ @compiler.expects(:resources).returns([one, two])
@collector.evaluate.should == [one, two]
end
@@ -251,7 +251,7 @@ describe Puppet::Parser::Collector, "when collecting exported resources" do
one.stubs(:exported=)
one.expects(:virtual=).with(false)
- @compile.expects(:resources).returns([one])
+ @compiler.expects(:resources).returns([one])
@collector.evaluate.should == [one]
end
@@ -268,10 +268,10 @@ describe Puppet::Parser::Collector, "when collecting exported resources" do
resource.stubs(:exported=)
resource.stubs(:virtual=)
- @compile.stubs(:resources).returns([])
+ @compiler.stubs(:resources).returns([])
@scope.stubs(:findresource).returns(nil)
- @compile.stubs(:store_resource)
+ @compiler.stubs(:add_resource)
@collector.evaluate.should == [resource]
end
@@ -288,10 +288,10 @@ describe Puppet::Parser::Collector, "when collecting exported resources" do
resource.stubs(:exported=)
resource.stubs(:virtual=)
- @compile.stubs(:resources).returns([])
+ @compiler.stubs(:resources).returns([])
@scope.stubs(:findresource).returns(nil)
- @compile.expects(:store_resource).with(@scope, resource)
+ @compiler.expects(:add_resource).with(@scope, resource)
@collector.evaluate.should == [resource]
end
@@ -309,10 +309,10 @@ describe Puppet::Parser::Collector, "when collecting exported resources" do
resource.expects(:exported=).with(false)
resource.stubs(:virtual=)
- @compile.stubs(:resources).returns([])
+ @compiler.stubs(:resources).returns([])
@scope.stubs(:findresource).returns(nil)
- @compile.stubs(:store_resource)
+ @compiler.stubs(:add_resource)
@collector.evaluate
end
@@ -328,10 +328,10 @@ describe Puppet::Parser::Collector, "when collecting exported resources" do
resource = mock 'resource'
- @compile.stubs(:resources).returns([])
+ @compiler.stubs(:resources).returns([])
@scope.stubs(:findresource).returns(inmemory)
- @compile.stubs(:store_resource)
+ @compiler.stubs(:add_resource)
proc { @collector.evaluate }.should raise_error(Puppet::ParseError)
end
@@ -347,10 +347,10 @@ describe Puppet::Parser::Collector, "when collecting exported resources" do
resource = mock 'resource'
- @compile.stubs(:resources).returns([])
+ @compiler.stubs(:resources).returns([])
@scope.stubs(:findresource).returns(inmemory)
- @compile.stubs(:store_resource)
+ @compiler.stubs(:add_resource)
proc { @collector.evaluate }.should_not raise_error(Puppet::ParseError)
end
@@ -361,14 +361,14 @@ describe Puppet::Parser::Collector, "when building its ActiveRecord query for co
before do
@scope = stub 'scope', :host => "myhost", :debug => nil
- @compile = mock 'compile'
- @scope.stubs(:compile).returns(@compile)
+ @compiler = mock 'compile'
+ @scope.stubs(:compiler).returns(@compiler)
@resource_type = "Mytype"
@equery = nil
@vquery = proc { |r| true }
@collector = Puppet::Parser::Collector.new(@scope, @resource_type, @equery, @vquery, :exported)
- @compile.stubs(:resources).returns([])
+ @compiler.stubs(:resources).returns([])
ActiveRecord::Base.stubs(:connected?).returns(false)
diff --git a/spec/unit/parser/compile.rb b/spec/unit/parser/compile.rb
deleted file mode 100755
index 092bece0c..000000000
--- a/spec/unit/parser/compile.rb
+++ /dev/null
@@ -1,281 +0,0 @@
-#!/usr/bin/env ruby
-
-require File.dirname(__FILE__) + '/../../spec_helper'
-
-describe Puppet::Parser::Compile, " when compiling" do
- before do
- @node = stub 'node', :name => 'mynode'
- @parser = stub 'parser', :version => "1.0"
- @compile = Puppet::Parser::Compile.new(@node, @parser)
- end
-
- def compile_methods
- [:set_node_parameters, :evaluate_main, :evaluate_ast_node, :evaluate_node_classes, :evaluate_generators, :fail_on_unevaluated,
- :finish, :store, :extract]
- end
-
- # Stub all of the main compile methods except the ones we're specifically interested in.
- def compile_stub(*except)
- (compile_methods - except).each { |m| @compile.stubs(m) }
- end
-
- it "should set node parameters as variables in the top scope" do
- params = {"a" => "b", "c" => "d"}
- @node.stubs(:parameters).returns(params)
- compile_stub(:set_node_parameters)
- @compile.compile
- @compile.topscope.lookupvar("a").should == "b"
- @compile.topscope.lookupvar("c").should == "d"
- end
-
- it "should evaluate any existing classes named in the node" do
- classes = %w{one two three four}
- main = stub 'main'
- one = stub 'one', :classname => "one"
- three = stub 'three', :classname => "three"
- @node.stubs(:name).returns("whatever")
- @node.stubs(:classes).returns(classes)
-
- @compile.expects(:evaluate_classes).with(classes, @compile.topscope)
- @compile.send :evaluate_node_classes
- end
-
- it "should enable ast_nodes if the parser has any nodes" do
- @parser.expects(:nodes).returns(:one => :yay)
- @compile.ast_nodes?.should be_true
- end
-
- it "should disable ast_nodes if the parser has no nodes" do
- @parser.expects(:nodes).returns({})
- @compile.ast_nodes?.should be_false
- end
-end
-
-describe Puppet::Parser::Compile, " when evaluating classes" do
- before do
- @node = stub 'node', :name => 'mynode'
- @parser = stub 'parser', :version => "1.0"
- @scope = stub 'scope', :source => mock("source")
- @compile = Puppet::Parser::Compile.new(@node, @parser)
- end
-
- it "should fail if there's no source listed for the scope" do
- scope = stub 'scope', :source => nil
- proc { @compile.evaluate_classes(%w{one two}, scope) }.should raise_error(Puppet::DevError)
- end
-
- it "should tag the catalog with the name of each not-found class" do
- @compile.catalog.expects(:tag).with("notfound")
- @scope.expects(:findclass).with("notfound").returns(nil)
- @compile.evaluate_classes(%w{notfound}, @scope)
- end
-end
-
-describe Puppet::Parser::Compile, " when evaluating collections" do
- before do
- @node = stub 'node', :name => 'mynode'
- @parser = stub 'parser', :version => "1.0"
- @scope = stub 'scope', :source => mock("source")
- @compile = Puppet::Parser::Compile.new(@node, @parser)
- end
-
- it "should evaluate each collection" do
- 2.times { |i|
- coll = mock 'coll%s' % i
- @compile.add_collection(coll)
-
- # This is the hard part -- we have to emulate the fact that
- # collections delete themselves if they are done evaluating.
- coll.expects(:evaluate).with do
- @compile.delete_collection(coll)
- end
- }
-
- @compile.class.publicize_methods(:evaluate_collections) { @compile.evaluate_collections }
- end
-end
-
-
-describe Puppet::Parser::Compile, " when evaluating found classes" do
- before do
- @node = stub 'node', :name => 'mynode'
- @parser = stub 'parser', :version => "1.0"
- @scope = stub 'scope', :source => mock("source")
- @compile = Puppet::Parser::Compile.new(@node, @parser)
-
- @class = stub 'class', :classname => "my::class"
- @scope.stubs(:findclass).with("myclass").returns(@class)
-
- @resource = stub 'resource', :ref => 'Class[myclass]'
- end
-
- it "should create a resource for each found class" do
- @compile.catalog.stubs(:tag)
-
- @compile.stubs :store_resource
-
- Puppet::Parser::Resource.expects(:new).with(:scope => @scope, :source => @scope.source, :title => "my::class", :type => "class").returns(@resource)
- @compile.evaluate_classes(%w{myclass}, @scope)
- end
-
- it "should store each created resource in the compile" do
- @compile.catalog.stubs(:tag)
-
- @compile.expects(:store_resource).with(@scope, @resource)
-
- Puppet::Parser::Resource.stubs(:new).returns(@resource)
- @compile.evaluate_classes(%w{myclass}, @scope)
- end
-
- it "should tag the catalog with the fully-qualified name of each found class" do
- @compile.catalog.expects(:tag).with("my::class")
-
- @compile.stubs(:store_resource)
-
- Puppet::Parser::Resource.stubs(:new).returns(@resource)
- @compile.evaluate_classes(%w{myclass}, @scope)
- end
-
- it "should not evaluate the resources created for found classes unless asked" do
- @compile.catalog.stubs(:tag)
-
- @compile.stubs(:store_resource)
- @resource.expects(:evaluate).never
-
- Puppet::Parser::Resource.stubs(:new).returns(@resource)
- @compile.evaluate_classes(%w{myclass}, @scope)
- end
-
- it "should immediately evaluate the resources created for found classes when asked" do
- @compile.catalog.stubs(:tag)
-
- @compile.stubs(:store_resource)
- @resource.expects(:evaluate)
-
- Puppet::Parser::Resource.stubs(:new).returns(@resource)
- @compile.evaluate_classes(%w{myclass}, @scope, false)
- end
-
- it "should skip classes that have already been evaluated" do
- @compile.catalog.stubs(:tag)
-
- @compile.expects(:class_scope).with(@class).returns("something")
-
- @compile.expects(:store_resource).never
-
- @resource.expects(:evaluate).never
-
- Puppet::Parser::Resource.expects(:new).never
- @compile.evaluate_classes(%w{myclass}, @scope, false)
- end
-
- it "should return the list of found classes" do
- @compile.catalog.stubs(:tag)
-
- @compile.stubs(:store_resource)
- @scope.stubs(:findclass).with("notfound").returns(nil)
-
- Puppet::Parser::Resource.stubs(:new).returns(@resource)
- @compile.evaluate_classes(%w{myclass notfound}, @scope).should == %w{myclass}
- end
-end
-
-describe Puppet::Parser::Compile, " when evaluating AST nodes with no AST nodes present" do
- before do
- @node = stub 'node', :name => "foo"
- @parser = stub 'parser', :version => "1.0", :nodes => {}
- @compile = Puppet::Parser::Compile.new(@node, @parser)
- end
-
- it "should do nothing" do
- @compile.expects(:ast_nodes?).returns(false)
- @compile.parser.expects(:nodes).never
- Puppet::Parser::Resource.expects(:new).never
-
- @compile.send(:evaluate_ast_node)
- end
-end
-
-describe Puppet::Parser::Compile, " when evaluating AST nodes with AST nodes present" do
- before do
- @node = stub 'node', :name => "foo"
- @parser = stub 'parser', :version => "1.0", :nodes => {}
- @compile = Puppet::Parser::Compile.new(@node, @parser)
-
- @nodes = mock 'node_hash'
- @compile.stubs(:ast_nodes?).returns(true)
- @compile.parser.stubs(:nodes).returns(@nodes)
-
- # Set some names for our test
- @node.stubs(:names).returns(%w{a b c})
- @nodes.stubs(:[]).with("a").returns(nil)
- @nodes.stubs(:[]).with("b").returns(nil)
- @nodes.stubs(:[]).with("c").returns(nil)
-
- # It should check this last, of course.
- @nodes.stubs(:[]).with("default").returns(nil)
- end
-
- it "should fail if the named node cannot be found" do
- proc { @compile.send(:evaluate_ast_node) }.should raise_error(Puppet::ParseError)
- end
-
- it "should create a resource for the first node class matching the node name" do
- node_class = stub 'node', :classname => "c"
- @nodes.stubs(:[]).with("c").returns(node_class)
-
- node_resource = stub 'node resource', :ref => "Node[c]", :evaluate => nil
- Puppet::Parser::Resource.expects(:new).with { |args| args[:title] == "c" and args[:type] == "node" }.returns(node_resource)
-
- @compile.send(:evaluate_ast_node)
- end
-
- it "should match the default node if no matching node can be found" do
- node_class = stub 'node', :classname => "default"
- @nodes.stubs(:[]).with("default").returns(node_class)
-
- node_resource = stub 'node resource', :ref => "Node[default]", :evaluate => nil
- Puppet::Parser::Resource.expects(:new).with { |args| args[:title] == "default" and args[:type] == "node" }.returns(node_resource)
-
- @compile.send(:evaluate_ast_node)
- end
-
- it "should tag the catalog with the found node name" do
- node_class = stub 'node', :classname => "c"
- @nodes.stubs(:[]).with("c").returns(node_class)
-
- node_resource = stub 'node resource', :ref => "Node[c]", :evaluate => nil
- Puppet::Parser::Resource.stubs(:new).returns(node_resource)
-
- @compile.catalog.expects(:tag).with("c")
- @compile.send(:evaluate_ast_node)
- end
-
- it "should evaluate the node resource immediately rather than using lazy evaluation" do
- node_class = stub 'node', :classname => "c"
- @nodes.stubs(:[]).with("c").returns(node_class)
-
- node_resource = stub 'node resource', :ref => "Node[c]"
- Puppet::Parser::Resource.stubs(:new).returns(node_resource)
-
- node_resource.expects(:evaluate)
-
- @compile.send(:evaluate_ast_node)
- end
-
- it "should set the node's scope as the top scope" do
- node_class = stub 'node', :classname => "c"
- @nodes.stubs(:[]).with("c").returns(node_class)
-
- node_resource = stub 'node resource', :ref => "Node[c]"
- Puppet::Parser::Resource.stubs(:new).returns(node_resource)
-
- # The #evaluate method normally does this.
- @compile.class_set(node_class.classname, :my_node_scope)
- node_resource.stubs(:evaluate)
-
- @compile.send(:evaluate_ast_node)
-
- @compile.topscope.should == :my_node_scope
- end
-end
diff --git a/spec/unit/parser/compiler.rb b/spec/unit/parser/compiler.rb
new file mode 100755
index 000000000..ab430da62
--- /dev/null
+++ b/spec/unit/parser/compiler.rb
@@ -0,0 +1,532 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+describe Puppet::Parser::Compiler do
+ before :each do
+ @node = Puppet::Node.new "testnode"
+ @parser = Puppet::Parser::Parser.new :environment => "development"
+
+ @scope_resource = stub 'scope_resource', :builtin? => true, :finish => nil, :ref => 'Class[main]'
+ @scope = stub 'scope', :resource => @scope_resource, :source => mock("source")
+ @compiler = Puppet::Parser::Compiler.new(@node, @parser)
+ end
+
+ describe Puppet::Parser::Compiler do
+
+ it "should be able to store references to class scopes" do
+ lambda { @compiler.class_set "myname", "myscope" }.should_not raise_error
+ end
+
+ it "should be able to retrieve class scopes by name" do
+ @compiler.class_set "myname", "myscope"
+ @compiler.class_scope("myname").should == "myscope"
+ end
+
+ it "should be able to retrieve class scopes by object" do
+ klass = mock 'ast_class'
+ klass.expects(:classname).returns("myname")
+ @compiler.class_set "myname", "myscope"
+ @compiler.class_scope(klass).should == "myscope"
+ end
+
+ it "should be able to return a class list containing all set classes" do
+ @compiler.class_set "", "empty"
+ @compiler.class_set "one", "yep"
+ @compiler.class_set "two", "nope"
+
+ @compiler.classlist.sort.should == %w{one two}.sort
+ end
+ end
+
+ describe Puppet::Parser::Compiler, " when initializing" do
+
+ it "should set its node attribute" do
+ @compiler.node.should equal(@node)
+ end
+
+ it "should set its parser attribute" do
+ @compiler.parser.should equal(@parser)
+ end
+
+ it "should detect when ast nodes are absent" do
+ @compiler.ast_nodes?.should be_false
+ end
+
+ it "should detect when ast nodes are present" do
+ @parser.nodes["testing"] = "yay"
+ @compiler.ast_nodes?.should be_true
+ end
+ end
+
+ describe Puppet::Parser::Compiler, "when managing scopes" do
+
+ it "should create a top scope" do
+ @compiler.topscope.should be_instance_of(Puppet::Parser::Scope)
+ end
+
+ it "should be able to create new scopes" do
+ @compiler.newscope(@compiler.topscope).should be_instance_of(Puppet::Parser::Scope)
+ end
+
+ it "should correctly set the level of newly created scopes" do
+ @compiler.newscope(@compiler.topscope, :level => 5).level.should == 5
+ end
+
+ it "should set the parent scope of the new scope to be the passed-in parent" do
+ scope = mock 'scope'
+ newscope = @compiler.newscope(scope)
+
+ @compiler.parent(newscope).should equal(scope)
+ end
+ end
+
+ describe Puppet::Parser::Compiler, " when compiling" do
+
+ def compile_methods
+ [:set_node_parameters, :evaluate_main, :evaluate_ast_node, :evaluate_node_classes, :evaluate_generators, :fail_on_unevaluated,
+ :finish, :store, :extract]
+ end
+
+ # Stub all of the main compile methods except the ones we're specifically interested in.
+ def compile_stub(*except)
+ (compile_methods - except).each { |m| @compiler.stubs(m) }
+ end
+
+ it "should set node parameters as variables in the top scope" do
+ params = {"a" => "b", "c" => "d"}
+ @node.stubs(:parameters).returns(params)
+ compile_stub(:set_node_parameters)
+ @compiler.compile
+ @compiler.topscope.lookupvar("a").should == "b"
+ @compiler.topscope.lookupvar("c").should == "d"
+ end
+
+ it "should evaluate any existing classes named in the node" do
+ classes = %w{one two three four}
+ main = stub 'main'
+ one = stub 'one', :classname => "one"
+ three = stub 'three', :classname => "three"
+ @node.stubs(:name).returns("whatever")
+ @node.stubs(:classes).returns(classes)
+
+ @compiler.expects(:evaluate_classes).with(classes, @compiler.topscope)
+ @compiler.class.publicize_methods(:evaluate_node_classes) { @compiler.evaluate_node_classes }
+ end
+
+ it "should enable ast_nodes if the parser has any nodes" do
+ @parser.expects(:nodes).returns(:one => :yay)
+ @compiler.ast_nodes?.should be_true
+ end
+
+ it "should disable ast_nodes if the parser has no nodes" do
+ @parser.expects(:nodes).returns({})
+ @compiler.ast_nodes?.should be_false
+ end
+
+ it "should evaluate the main class if it exists" do
+ compile_stub(:evaluate_main)
+ main_class = mock 'main_class'
+ main_class.expects(:evaluate_code).with { |r| r.is_a?(Puppet::Parser::Resource) }
+ @compiler.topscope.expects(:source=).with(main_class)
+ @parser.stubs(:findclass).with("", "").returns(main_class)
+
+ @compiler.compile
+ end
+
+ it "should evaluate any node classes" do
+ @node.stubs(:classes).returns(%w{one two three four})
+ @compiler.expects(:evaluate_classes).with(%w{one two three four}, @compiler.topscope)
+ @compiler.send(:evaluate_node_classes)
+ end
+
+ it "should evaluate all added collections" do
+ colls = []
+ # And when the collections fail to evaluate.
+ colls << mock("coll1-false")
+ colls << mock("coll2-false")
+ colls.each { |c| c.expects(:evaluate).returns(false) }
+
+ @compiler.add_collection(colls[0])
+ @compiler.add_collection(colls[1])
+
+ compile_stub(:evaluate_generators)
+ @compiler.compile
+ end
+
+ it "should ignore builtin resources" do
+ resource = stub 'builtin', :ref => "File[testing]", :builtin? => true
+
+ @compiler.add_resource(@scope, resource)
+ resource.expects(:evaluate).never
+
+ @compiler.compile
+ end
+
+ it "should evaluate unevaluated resources" do
+ resource = stub 'notevaluated', :ref => "File[testing]", :builtin? => false, :evaluated? => false, :virtual? => false
+ @compiler.add_resource(@scope, resource)
+
+ # We have to now mark the resource as evaluated
+ resource.expects(:evaluate).with { |*whatever| resource.stubs(:evaluated?).returns true }
+
+ @compiler.compile
+ end
+
+ it "should not evaluate already-evaluated resources" do
+ resource = stub 'already_evaluated', :ref => "File[testing]", :builtin? => false, :evaluated? => true, :virtual? => false
+ @compiler.add_resource(@scope, resource)
+ resource.expects(:evaluate).never
+
+ @compiler.compile
+ end
+
+ it "should evaluate unevaluated resources created by evaluating other resources" do
+ resource = stub 'notevaluated', :ref => "File[testing]", :builtin? => false, :evaluated? => false, :virtual? => false
+ @compiler.add_resource(@scope, resource)
+
+ resource2 = stub 'created', :ref => "File[other]", :builtin? => false, :evaluated? => false, :virtual? => false
+
+ # We have to now mark the resource as evaluated
+ resource.expects(:evaluate).with { |*whatever| resource.stubs(:evaluated?).returns(true); @compiler.add_resource(@scope, resource2) }
+ resource2.expects(:evaluate).with { |*whatever| resource2.stubs(:evaluated?).returns(true) }
+
+
+ @compiler.compile
+ end
+
+ it "should call finish() on all resources" do
+ # Add a resource that does respond to :finish
+ resource = Puppet::Parser::Resource.new :scope => @scope, :type => "file", :title => "finish"
+ resource.expects(:finish)
+
+ @compiler.add_resource(@scope, resource)
+
+ # And one that does not
+ dnf = stub "dnf", :ref => "File[dnf]"
+
+ @compiler.add_resource(@scope, dnf)
+
+ @compiler.send(:finish)
+ end
+
+ it "should add resources that do not conflict with existing resources" do
+ resource = stub "noconflict", :ref => "File[yay]"
+ @compiler.add_resource(@scope, resource)
+
+ @compiler.catalog.should be_vertex(resource)
+ end
+
+ it "should fail to add resources that conflict with existing resources" do
+ type = stub 'faketype', :isomorphic? => true, :name => "mytype"
+ Puppet::Type.stubs(:type).with("mytype").returns(type)
+
+ resource1 = stub "iso1conflict", :ref => "Mytype[yay]", :type => "mytype", :file => "eh", :line => 0
+ resource2 = stub "iso2conflict", :ref => "Mytype[yay]", :type => "mytype", :file => "eh", :line => 0
+
+ @compiler.add_resource(@scope, resource1)
+ lambda { @compiler.add_resource(@scope, resource2) }.should raise_error(ArgumentError)
+ end
+
+ it "should have a method for looking up resources" do
+ resource = stub 'resource', :ref => "Yay[foo]"
+ @compiler.add_resource(@scope, resource)
+ @compiler.findresource("Yay[foo]").should equal(resource)
+ end
+
+ it "should be able to look resources up by type and title" do
+ resource = stub 'resource', :ref => "Yay[foo]"
+ @compiler.add_resource(@scope, resource)
+ @compiler.findresource("Yay", "foo").should equal(resource)
+ end
+
+ it "should not evaluate virtual defined resources" do
+ resource = stub 'notevaluated', :ref => "File[testing]", :builtin? => false, :evaluated? => false, :virtual? => true
+ @compiler.add_resource(@scope, resource)
+
+ resource.expects(:evaluate).never
+
+ @compiler.compile
+ end
+ end
+
+ describe Puppet::Parser::Compiler, " when evaluating collections" do
+
+ it "should evaluate each collection" do
+ 2.times { |i|
+ coll = mock 'coll%s' % i
+ @compiler.add_collection(coll)
+
+ # This is the hard part -- we have to emulate the fact that
+ # collections delete themselves if they are done evaluating.
+ coll.expects(:evaluate).with do
+ @compiler.delete_collection(coll)
+ end
+ }
+
+ @compiler.class.publicize_methods(:evaluate_collections) { @compiler.evaluate_collections }
+ end
+
+ it "should not fail when there are unevaluated resource collections that do not refer to specific resources" do
+ coll = stub 'coll', :evaluate => false
+ coll.expects(:resources).returns(nil)
+
+ @compiler.add_collection(coll)
+
+ lambda { @compiler.compile }.should_not raise_error
+ end
+
+ it "should fail when there are unevaluated resource collections that refer to a specific resource" do
+ coll = stub 'coll', :evaluate => false
+ coll.expects(:resources).returns(:something)
+
+ @compiler.add_collection(coll)
+
+ lambda { @compiler.compile }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should fail when there are unevaluated resource collections that refer to multiple specific resources" do
+ coll = stub 'coll', :evaluate => false
+ coll.expects(:resources).returns([:one, :two])
+
+ @compiler.add_collection(coll)
+
+ lambda { @compiler.compile }.should raise_error(Puppet::ParseError)
+ end
+ end
+
+ describe Puppet::Parser::Compiler, "when told to evaluate missing classes" do
+
+ it "should fail if there's no source listed for the scope" do
+ scope = stub 'scope', :source => nil
+ proc { @compiler.evaluate_classes(%w{one two}, scope) }.should raise_error(Puppet::DevError)
+ end
+
+ it "should tag the catalog with the name of each not-found class" do
+ @compiler.catalog.expects(:tag).with("notfound")
+ @scope.expects(:findclass).with("notfound").returns(nil)
+ @compiler.evaluate_classes(%w{notfound}, @scope)
+ end
+ end
+
+ describe Puppet::Parser::Compiler, " when evaluating found classes" do
+
+ before do
+ @class = stub 'class', :classname => "my::class"
+ @scope.stubs(:findclass).with("myclass").returns(@class)
+
+ @resource = stub 'resource', :ref => "Class[myclass]"
+ end
+
+ it "should evaluate each class" do
+ @compiler.catalog.stubs(:tag)
+
+ @class.expects(:evaluate).with(@scope)
+
+ @compiler.evaluate_classes(%w{myclass}, @scope)
+ end
+
+ it "should not evaluate the resources created for found classes unless asked" do
+ @compiler.catalog.stubs(:tag)
+
+ @resource.expects(:evaluate).never
+
+ @class.expects(:evaluate).returns(@resource)
+
+ @compiler.evaluate_classes(%w{myclass}, @scope)
+ end
+
+ it "should immediately evaluate the resources created for found classes when asked" do
+ @compiler.catalog.stubs(:tag)
+
+ @resource.expects(:evaluate)
+ @class.expects(:evaluate).returns(@resource)
+
+ @compiler.evaluate_classes(%w{myclass}, @scope, false)
+ end
+
+ it "should skip classes that have already been evaluated" do
+ @compiler.catalog.stubs(:tag)
+
+ @compiler.expects(:class_scope).with(@class).returns("something")
+
+ @compiler.expects(:add_resource).never
+
+ @resource.expects(:evaluate).never
+
+ Puppet::Parser::Resource.expects(:new).never
+ @compiler.evaluate_classes(%w{myclass}, @scope, false)
+ end
+
+ it "should return the list of found classes" do
+ @compiler.catalog.stubs(:tag)
+
+ @compiler.stubs(:add_resource)
+ @scope.stubs(:findclass).with("notfound").returns(nil)
+
+ Puppet::Parser::Resource.stubs(:new).returns(@resource)
+ @class.stubs :evaluate
+ @compiler.evaluate_classes(%w{myclass notfound}, @scope).should == %w{myclass}
+ end
+ end
+
+ describe Puppet::Parser::Compiler, " when evaluating AST nodes with no AST nodes present" do
+
+ it "should do nothing" do
+ @compiler.expects(:ast_nodes?).returns(false)
+ @compiler.parser.expects(:nodes).never
+ Puppet::Parser::Resource.expects(:new).never
+
+ @compiler.send(:evaluate_ast_node)
+ end
+ end
+
+ describe Puppet::Parser::Compiler, " when evaluating AST nodes with AST nodes present" do
+
+ before do
+ @nodes = mock 'node_hash'
+ @compiler.stubs(:ast_nodes?).returns(true)
+ @compiler.parser.stubs(:nodes).returns(@nodes)
+
+ # Set some names for our test
+ @node.stubs(:names).returns(%w{a b c})
+ @nodes.stubs(:[]).with("a").returns(nil)
+ @nodes.stubs(:[]).with("b").returns(nil)
+ @nodes.stubs(:[]).with("c").returns(nil)
+
+ # It should check this last, of course.
+ @nodes.stubs(:[]).with("default").returns(nil)
+ end
+
+ it "should fail if the named node cannot be found" do
+ proc { @compiler.send(:evaluate_ast_node) }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should evaluate the first node class matching the node name" do
+ node_class = stub 'node', :classname => "c", :evaluate_code => nil
+ @nodes.stubs(:[]).with("c").returns(node_class)
+
+ node_resource = stub 'node resource', :ref => "Node[c]", :evaluate => nil
+ node_class.expects(:evaluate).returns(node_resource)
+
+ @compiler.compile
+ end
+
+ it "should match the default node if no matching node can be found" do
+ node_class = stub 'node', :classname => "default", :evaluate_code => nil
+ @nodes.stubs(:[]).with("default").returns(node_class)
+
+ node_resource = stub 'node resource', :ref => "Node[default]", :evaluate => nil
+ node_class.expects(:evaluate).returns(node_resource)
+
+ @compiler.compile
+ end
+
+ it "should evaluate the node resource immediately rather than using lazy evaluation" do
+ node_class = stub 'node', :classname => "c"
+ @nodes.stubs(:[]).with("c").returns(node_class)
+
+ node_resource = stub 'node resource', :ref => "Node[c]"
+ node_class.expects(:evaluate).returns(node_resource)
+
+ node_resource.expects(:evaluate)
+
+ @compiler.send(:evaluate_ast_node)
+ end
+
+ it "should set the node's scope as the top scope" do
+ node_resource = stub 'node resource', :ref => "Node[c]", :evaluate => nil
+ node_class = stub 'node', :classname => "c", :evaluate => node_resource
+
+ @nodes.stubs(:[]).with("c").returns(node_class)
+
+ # The #evaluate method normally does this.
+ scope = stub 'scope', :source => "mysource"
+ @compiler.class_set(node_class.classname, scope)
+ node_resource.stubs(:evaluate)
+
+ @compiler.compile
+
+ @compiler.topscope.should equal(scope)
+ end
+ end
+
+ describe Puppet::Parser::Compiler, "when storing compiled resources" do
+
+ it "should store the resources" do
+ Puppet.features.expects(:rails?).returns(true)
+ Puppet::Rails.expects(:connect)
+
+ @compiler.catalog.expects(:vertices).returns(:resources)
+
+ @compiler.expects(:store_to_active_record).with(@node, :resources)
+ @compiler.send(:store)
+ end
+
+ it "should store to active_record" do
+ @node.expects(:name).returns("myname")
+ Puppet::Rails::Host.stubs(:transaction).yields
+ Puppet::Rails::Host.expects(:store).with(@node, :resources)
+ @compiler.send(:store_to_active_record, @node, :resources)
+ end
+ end
+
+ describe Puppet::Parser::Compiler, "when managing resource overrides" do
+
+ before do
+ @override = stub 'override', :ref => "My[ref]"
+ @resource = stub 'resource', :ref => "My[ref]", :builtin? => true
+ end
+
+ it "should be able to store overrides" do
+ lambda { @compiler.add_override(@override) }.should_not raise_error
+ end
+
+ it "should apply overrides to the appropriate resources" do
+ @compiler.add_resource(@scope, @resource)
+ @resource.expects(:merge).with(@override)
+
+ @compiler.add_override(@override)
+
+ @compiler.compile
+ end
+
+ it "should accept overrides before the related resource has been created" do
+ @resource.expects(:merge).with(@override)
+
+ # First store the override
+ @compiler.add_override(@override)
+
+ # Then the resource
+ @compiler.add_resource(@scope, @resource)
+
+ # And compile, so they get resolved
+ @compiler.compile
+ end
+
+ it "should fail if the compile is finished and resource overrides have not been applied" do
+ @compiler.add_override(@override)
+
+ lambda { @compiler.compile }.should raise_error(Puppet::ParseError)
+ end
+ end
+
+ # #620 - Nodes and classes should conflict, else classes don't get evaluated
+ describe Puppet::Parser::Compiler, "when evaluating nodes and classes with the same name (#620)" do
+
+ before do
+ @node = stub :nodescope? => true
+ @class = stub :nodescope? => false
+ end
+
+ it "should fail if a node already exists with the same name as the class being evaluated" do
+ @compiler.class_set("one", @node)
+ lambda { @compiler.class_set("one", @class) }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should fail if a class already exists with the same name as the node being evaluated" do
+ @compiler.class_set("one", @class)
+ lambda { @compiler.class_set("one", @node) }.should raise_error(Puppet::ParseError)
+ end
+ end
+end
diff --git a/spec/unit/parser/interpreter.rb b/spec/unit/parser/interpreter.rb
index ed30ced93..f2526c73d 100755
--- a/spec/unit/parser/interpreter.rb
+++ b/spec/unit/parser/interpreter.rb
@@ -2,147 +2,158 @@
require File.dirname(__FILE__) + '/../../spec_helper'
-describe Puppet::Parser::Interpreter, " when creating parser instances" do
+describe Puppet::Parser::Interpreter do
before do
@interp = Puppet::Parser::Interpreter.new
- @parser = mock('parser')
- end
-
- it "should create a parser with code if there is code defined in the :code setting" do
- Puppet.settings.stubs(:value).with(:code, :myenv).returns("mycode")
- @parser.expects(:string=).with("mycode")
- @parser.expects(:parse)
- Puppet::Parser::Parser.expects(:new).with(:environment => :myenv).returns(@parser)
- @interp.send(:create_parser, :myenv).object_id.should equal(@parser.object_id)
- end
-
- it "should create a parser with the main manifest when the code setting is an empty string" do
- Puppet.settings.stubs(:value).with(:code, :myenv).returns("")
- Puppet.settings.stubs(:value).with(:manifest, :myenv).returns("/my/file")
- @parser.expects(:parse)
- @parser.expects(:file=).with("/my/file")
- Puppet::Parser::Parser.expects(:new).with(:environment => :myenv).returns(@parser)
- @interp.send(:create_parser, :myenv).should equal(@parser)
- end
-
- it "should return nothing when new parsers fail" do
- Puppet::Parser::Parser.expects(:new).with(:environment => :myenv).raises(ArgumentError)
- proc { @interp.send(:create_parser, :myenv) }.should raise_error(Puppet::Error)
- end
-
- it "should create parsers with environment-appropriate manifests" do
- # Set our per-environment values. We can't just stub :value, because
- # it's called by too much of the rest of the code.
- text = "[env1]\nmanifest = /t/env1.pp\n[env2]\nmanifest = /t/env2.pp"
- file = mock 'file'
- file.stubs(:changed?).returns(true)
- file.stubs(:file).returns("/whatever")
- Puppet.settings.stubs(:read_file).with(file).returns(text)
- Puppet.settings.parse(file)
-
- parser1 = mock 'parser1'
- Puppet::Parser::Parser.expects(:new).with(:environment => :env1).returns(parser1)
- parser1.expects(:file=).with("/t/env1.pp")
- parser1.expects(:parse)
- @interp.send(:create_parser, :env1)
-
- parser2 = mock 'parser2'
- Puppet::Parser::Parser.expects(:new).with(:environment => :env2).returns(parser2)
- parser2.expects(:file=).with("/t/env2.pp")
- parser2.expects(:parse)
- @interp.send(:create_parser, :env2)
- end
-end
-
-describe Puppet::Parser::Interpreter, " when managing parser instances" do
- before do
- @interp = Puppet::Parser::Interpreter.new
- @parser = mock('parser')
- end
-
- it "should use the same parser when the parser does not need reparsing" do
- @interp.expects(:create_parser).with(:myenv).returns(@parser)
- @interp.send(:parser, :myenv).should equal(@parser)
-
- @parser.expects(:reparse?).returns(false)
- @interp.send(:parser, :myenv).should equal(@parser)
- end
-
- it "should create a new parser when reparse is true" do
- oldparser = mock('oldparser')
- newparser = mock('newparser')
- oldparser.expects(:reparse?).returns(true)
- oldparser.expects(:clear)
-
- @interp.expects(:create_parser).with(:myenv).returns(oldparser)
- @interp.send(:parser, :myenv).should equal(oldparser)
- @interp.expects(:create_parser).with(:myenv).returns(newparser)
- @interp.send(:parser, :myenv).should equal(newparser)
- end
-
- it "should fail intelligently if a parser cannot be created and one does not already exist" do
- @interp.expects(:create_parser).with(:myenv).raises(ArgumentError)
- proc { @interp.send(:parser, :myenv) }.should raise_error(ArgumentError)
- end
-
- it "should keep the old parser if a new parser cannot be created" do
- # Get the first parser in the hash.
- @interp.expects(:create_parser).with(:myenv).returns(@parser)
- @interp.send(:parser, :myenv).should equal(@parser)
-
- # Have it indicate something has changed
- @parser.expects(:reparse?).returns(true)
-
- # But fail to create a new parser
- @interp.expects(:create_parser).with(:myenv).raises(ArgumentError)
-
- # And make sure we still get the old valid parser
- @interp.send(:parser, :myenv).should equal(@parser)
- end
-
- it "should use different parsers for different environments" do
- # get one for the first env
- @interp.expects(:create_parser).with(:first_env).returns(@parser)
- @interp.send(:parser, :first_env).should equal(@parser)
-
- other_parser = mock('otherparser')
- @interp.expects(:create_parser).with(:second_env).returns(other_parser)
- @interp.send(:parser, :second_env).should equal(other_parser)
- end
-end
-
-describe Puppet::Parser::Interpreter, " when compiling catalog" do
- before do
- @interp = Puppet::Parser::Interpreter.new
- @node = stub 'node', :environment => :myenv
- @compile = mock 'compile'
@parser = mock 'parser'
end
- it "should create a compile with the node and parser" do
- @compile.expects(:compile).returns(:config)
- @interp.expects(:parser).with(:myenv).returns(@parser)
- Puppet::Parser::Compile.expects(:new).with(@node, @parser).returns(@compile)
- @interp.compile(@node)
- end
-
- it "should fail intelligently when no parser can be found" do
- @interp.expects(:parser).with(:myenv).returns(nil)
- proc { @interp.compile(@node) }.should raise_error(Puppet::ParseError)
- end
-end
-
-describe Puppet::Parser::Interpreter, " when returning catalog version" do
- before do
- @interp = Puppet::Parser::Interpreter.new
- end
-
- it "should ask the appropriate parser for the catalog version" do
- node = mock 'node'
- node.expects(:environment).returns(:myenv)
- parser = mock 'parser'
- parser.expects(:version).returns(:myvers)
- @interp.expects(:parser).with(:myenv).returns(parser)
- @interp.configuration_version(node).should equal(:myvers)
+ describe "when creating parser instances" do
+ it "should create a parser with code if there is code defined in the :code setting" do
+ Puppet.settings.stubs(:value).with(:code, :myenv).returns("mycode")
+ @parser.expects(:string=).with("mycode")
+ @parser.expects(:parse)
+ Puppet::Parser::Parser.expects(:new).with(:environment => :myenv).returns(@parser)
+ @interp.send(:create_parser, :myenv).object_id.should equal(@parser.object_id)
+ end
+
+ it "should create a parser with the main manifest when the code setting is an empty string" do
+ Puppet.settings.stubs(:value).with(:code, :myenv).returns("")
+ Puppet.settings.stubs(:value).with(:manifest, :myenv).returns("/my/file")
+ @parser.expects(:parse)
+ @parser.expects(:file=).with("/my/file")
+ Puppet::Parser::Parser.expects(:new).with(:environment => :myenv).returns(@parser)
+ @interp.send(:create_parser, :myenv).should equal(@parser)
+ end
+
+ it "should return nothing when new parsers fail" do
+ Puppet::Parser::Parser.expects(:new).with(:environment => :myenv).raises(ArgumentError)
+ proc { @interp.send(:create_parser, :myenv) }.should raise_error(Puppet::Error)
+ end
+
+ it "should create parsers with environment-appropriate manifests" do
+ # Set our per-environment values. We can't just stub :value, because
+ # it's called by too much of the rest of the code.
+ text = "[env1]\nmanifest = /t/env1.pp\n[env2]\nmanifest = /t/env2.pp"
+ file = mock 'file'
+ file.stubs(:changed?).returns(true)
+ file.stubs(:file).returns("/whatever")
+ Puppet.settings.stubs(:read_file).with(file).returns(text)
+ Puppet.settings.parse(file)
+
+ parser1 = mock 'parser1'
+ Puppet::Parser::Parser.expects(:new).with(:environment => :env1).returns(parser1)
+ parser1.expects(:file=).with("/t/env1.pp")
+ parser1.expects(:parse)
+ @interp.send(:create_parser, :env1)
+
+ parser2 = mock 'parser2'
+ Puppet::Parser::Parser.expects(:new).with(:environment => :env2).returns(parser2)
+ parser2.expects(:file=).with("/t/env2.pp")
+ parser2.expects(:parse)
+ @interp.send(:create_parser, :env2)
+ end
+ end
+
+ describe "when managing parser instances" do
+ it "should use the same parser when the parser does not need reparsing" do
+ @interp.expects(:create_parser).with(:myenv).returns(@parser)
+ @interp.send(:parser, :myenv).should equal(@parser)
+
+ @parser.expects(:reparse?).returns(false)
+ @interp.send(:parser, :myenv).should equal(@parser)
+ end
+
+ it "should fail intelligently if a parser cannot be created and one does not already exist" do
+ @interp.expects(:create_parser).with(:myenv).raises(ArgumentError)
+ proc { @interp.send(:parser, :myenv) }.should raise_error(ArgumentError)
+ end
+
+ it "should use different parsers for different environments" do
+ # get one for the first env
+ @interp.expects(:create_parser).with(:first_env).returns(@parser)
+ @interp.send(:parser, :first_env).should equal(@parser)
+
+ other_parser = mock('otherparser')
+ @interp.expects(:create_parser).with(:second_env).returns(other_parser)
+ @interp.send(:parser, :second_env).should equal(other_parser)
+ end
+
+ describe "when files need reparsing" do
+ it "should create a new parser" do
+ oldparser = mock('oldparser')
+ newparser = mock('newparser')
+ oldparser.expects(:reparse?).returns(true)
+ oldparser.expects(:clear)
+
+ @interp.expects(:create_parser).with(:myenv).returns(oldparser)
+ @interp.send(:parser, :myenv).should equal(oldparser)
+ @interp.expects(:create_parser).with(:myenv).returns(newparser)
+ @interp.send(:parser, :myenv).should equal(newparser)
+ end
+
+ it "should keep the old parser if a new parser cannot be created" do
+ # Get the first parser in the hash.
+ @interp.expects(:create_parser).with(:myenv).returns(@parser)
+ @interp.send(:parser, :myenv).should equal(@parser)
+
+ # Have it indicate something has changed
+ @parser.expects(:reparse?).returns(true)
+
+ # But fail to create a new parser
+ @interp.expects(:create_parser).with(:myenv).raises(ArgumentError)
+
+ # And make sure we still get the old valid parser
+ @interp.send(:parser, :myenv).should equal(@parser)
+ end
+
+ it "should log syntax errors when using the old parser" do
+ # Get the first parser in the hash.
+ @interp.stubs(:create_parser).with(:myenv).returns(@parser)
+ @interp.send(:parser, :myenv)
+
+ # Have it indicate something has changed
+ @parser.stubs(:reparse?).returns(true)
+
+ # But fail to create a new parser
+ @interp.stubs(:create_parser).with(:myenv).raises(ArgumentError)
+
+ Puppet.expects(:err)
+
+ # And make sure we still get the old valid parser
+ @interp.send(:parser, :myenv)
+ end
+ end
+ end
+
+ describe "when compiling a catalog" do
+ before do
+ @node = stub 'node', :environment => :myenv
+ @compiler = mock 'compile'
+ end
+
+ it "should create a compile with the node and parser" do
+ @compiler.expects(:compile).returns(:config)
+ @interp.expects(:parser).with(:myenv).returns(@parser)
+ Puppet::Parser::Compiler.expects(:new).with(@node, @parser).returns(@compiler)
+ @interp.compile(@node)
+ end
+
+ it "should fail intelligently when no parser can be found" do
+ @node.stubs(:name).returns("whatever")
+ @interp.expects(:parser).with(:myenv).returns(nil)
+ proc { @interp.compile(@node) }.should raise_error(Puppet::ParseError)
+ end
+ end
+
+ describe "when returning catalog version" do
+ it "should ask the appropriate parser for the catalog version" do
+ node = mock 'node'
+ node.expects(:environment).returns(:myenv)
+ parser = mock 'parser'
+ parser.expects(:version).returns(:myvers)
+ @interp.expects(:parser).with(:myenv).returns(parser)
+ @interp.configuration_version(node).should equal(:myvers)
+ end
end
end
diff --git a/spec/unit/parser/lexer.rb b/spec/unit/parser/lexer.rb
new file mode 100755
index 000000000..9972f7268
--- /dev/null
+++ b/spec/unit/parser/lexer.rb
@@ -0,0 +1,465 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+require 'puppet/parser/lexer'
+
+describe Puppet::Parser::Lexer::Token do
+ before do
+ @token = Puppet::Parser::Lexer::Token.new(%r{something}, :NAME)
+ end
+
+ [:regex, :name, :string, :skip, :incr_line, :skip_text].each do |param|
+ it "should have a #{param.to_s} reader" do
+ @token.should be_respond_to(param)
+ end
+
+ it "should have a #{param.to_s} writer" do
+ @token.should be_respond_to(param.to_s + "=")
+ end
+ end
+end
+
+describe Puppet::Parser::Lexer::Token, "when initializing" do
+ it "should create a regex if the first argument is a string" do
+ Puppet::Parser::Lexer::Token.new("something", :NAME).regex.should == %r{something}
+ end
+
+ it "should set the string if the first argument is one" do
+ Puppet::Parser::Lexer::Token.new("something", :NAME).string.should == "something"
+ end
+
+ it "should set the regex if the first argument is one" do
+ Puppet::Parser::Lexer::Token.new(%r{something}, :NAME).regex.should == %r{something}
+ end
+end
+
+describe Puppet::Parser::Lexer::TokenList do
+ before do
+ @list = Puppet::Parser::Lexer::TokenList.new
+ end
+
+ it "should have a method for retrieving tokens by the name" do
+ token = @list.add_token :name, "whatever"
+ @list[:name].should equal(token)
+ end
+
+ it "should have a method for retrieving string tokens by the string" do
+ token = @list.add_token :name, "whatever"
+ @list.lookup("whatever").should equal(token)
+ end
+
+ it "should add tokens to the list when directed" do
+ token = @list.add_token :name, "whatever"
+ @list[:name].should equal(token)
+ end
+
+ it "should have a method for adding multiple tokens at once" do
+ @list.add_tokens "whatever" => :name, "foo" => :bar
+ @list[:name].should_not be_nil
+ @list[:bar].should_not be_nil
+ end
+
+ it "should fail to add tokens sharing a name with an existing token" do
+ @list.add_token :name, "whatever"
+ lambda { @list.add_token :name, "whatever" }.should raise_error(ArgumentError)
+ end
+
+ it "should set provided options on tokens being added" do
+ token = @list.add_token :name, "whatever", :skip_text => true
+ token.skip_text.should == true
+ end
+
+ it "should define any provided blocks as a :convert method" do
+ token = @list.add_token(:name, "whatever") do "foo" end
+ token.convert.should == "foo"
+ end
+
+ it "should store all string tokens in the :string_tokens list" do
+ one = @list.add_token(:name, "1")
+ @list.string_tokens.should be_include(one)
+ end
+
+ it "should store all regex tokens in the :regex_tokens list" do
+ one = @list.add_token(:name, %r{one})
+ @list.regex_tokens.should be_include(one)
+ end
+
+ it "should not store string tokens in the :regex_tokens list" do
+ one = @list.add_token(:name, "1")
+ @list.regex_tokens.should_not be_include(one)
+ end
+
+ it "should not store regex tokens in the :string_tokens list" do
+ one = @list.add_token(:name, %r{one})
+ @list.string_tokens.should_not be_include(one)
+ end
+
+ it "should sort the string tokens inversely by length when asked" do
+ one = @list.add_token(:name, "1")
+ two = @list.add_token(:other, "12")
+ @list.sort_tokens
+ @list.string_tokens.should == [two, one]
+ end
+end
+
+describe Puppet::Parser::Lexer::TOKENS do
+ before do
+ @lexer = Puppet::Parser::Lexer.new()
+ end
+
+ {
+ :LBRACK => '[',
+ :RBRACK => ']',
+ :LBRACE => '{',
+ :RBRACE => '}',
+ :LPAREN => '(',
+ :RPAREN => ')',
+ :EQUALS => '=',
+ :ISEQUAL => '==',
+ :GREATEREQUAL => '>=',
+ :GREATERTHAN => '>',
+ :LESSTHAN => '<',
+ :LESSEQUAL => '<=',
+ :NOTEQUAL => '!=',
+ :NOT => '!',
+ :COMMA => ',',
+ :DOT => '.',
+ :COLON => ':',
+ :AT => '@',
+ :LLCOLLECT => '<<|',
+ :RRCOLLECT => '|>>',
+ :LCOLLECT => '<|',
+ :RCOLLECT => '|>',
+ :SEMIC => ';',
+ :QMARK => '?',
+ :BACKSLASH => '\\',
+ :FARROW => '=>',
+ :PARROW => '+>'
+ }.each do |name, string|
+ it "should have a token named #{name.to_s}" do
+ Puppet::Parser::Lexer::TOKENS[name].should_not be_nil
+ end
+
+ it "should match '#{string}' for the token #{name.to_s}" do
+ Puppet::Parser::Lexer::TOKENS[name].string.should == string
+ end
+ end
+
+ {
+ "case" => :CASE,
+ "class" => :CLASS,
+ "default" => :DEFAULT,
+ "define" => :DEFINE,
+ "import" => :IMPORT,
+ "if" => :IF,
+ "elsif" => :ELSIF,
+ "else" => :ELSE,
+ "inherits" => :INHERITS,
+ "node" => :NODE,
+ "and" => :AND,
+ "or" => :OR,
+ "undef" => :UNDEF,
+ "false" => :FALSE,
+ "true" => :TRUE
+ }.each do |string, name|
+ it "should have a keyword named #{name.to_s}" do
+ Puppet::Parser::Lexer::KEYWORDS[name].should_not be_nil
+ end
+
+ it "should have the keyword for #{name.to_s} set to #{string}" do
+ Puppet::Parser::Lexer::KEYWORDS[name].string.should == string
+ end
+ end
+
+ # These tokens' strings don't matter, just that the tokens exist.
+ [:DQTEXT, :SQTEXT, :BOOLEAN, :NAME, :NUMBER, :COMMENT, :RETURN, :SQUOTE, :DQUOTE, :VARIABLE].each do |name|
+ it "should have a token named #{name.to_s}" do
+ Puppet::Parser::Lexer::TOKENS[name].should_not be_nil
+ end
+ end
+end
+
+describe Puppet::Parser::Lexer::TOKENS[:NAME] do
+ before { @token = Puppet::Parser::Lexer::TOKENS[:NAME] }
+
+ it "should match against lower-case alpha-numeric terms" do
+ @token.regex.should =~ "one-two"
+ end
+
+ it "should return itself and the value if the matched term is not a keyword" do
+ Puppet::Parser::Lexer::KEYWORDS.expects(:lookup).returns(nil)
+ @token.convert(stub("lexer"), "myval").should == [Puppet::Parser::Lexer::TOKENS[:NAME], "myval"]
+ end
+
+ it "should return the keyword token and the value if the matched term is a keyword" do
+ keyword = stub 'keyword', :name => :testing
+ Puppet::Parser::Lexer::KEYWORDS.expects(:lookup).returns(keyword)
+ @token.convert(stub("lexer"), "myval").should == [keyword, "myval"]
+ end
+
+ it "should return the BOOLEAN token and 'true' if the matched term is the string 'true'" do
+ keyword = stub 'keyword', :name => :TRUE
+ Puppet::Parser::Lexer::KEYWORDS.expects(:lookup).returns(keyword)
+ @token.convert(stub('lexer'), "true").should == [Puppet::Parser::Lexer::TOKENS[:BOOLEAN], true]
+ end
+
+ it "should return the BOOLEAN token and 'false' if the matched term is the string 'false'" do
+ keyword = stub 'keyword', :name => :FALSE
+ Puppet::Parser::Lexer::KEYWORDS.expects(:lookup).returns(keyword)
+ @token.convert(stub('lexer'), "false").should == [Puppet::Parser::Lexer::TOKENS[:BOOLEAN], false]
+ end
+end
+
+describe Puppet::Parser::Lexer::TOKENS[:NUMBER] do
+ before { @token = Puppet::Parser::Lexer::TOKENS[:NUMBER] }
+
+ it "should match against numeric terms" do
+ @token.regex.should =~ "2982383139"
+ end
+
+ it "should return the NAME token and the value" do
+ @token.convert(stub("lexer"), "myval").should == [Puppet::Parser::Lexer::TOKENS[:NAME], "myval"]
+ end
+end
+
+describe Puppet::Parser::Lexer::TOKENS[:COMMENT] do
+ before { @token = Puppet::Parser::Lexer::TOKENS[:COMMENT] }
+
+ it "should match against lines starting with '#'" do
+ @token.regex.should =~ "# this is a comment"
+ end
+
+ it "should be marked to get skipped" do
+ @token.skip?.should be_true
+ end
+end
+
+describe Puppet::Parser::Lexer::TOKENS[:RETURN] do
+ before { @token = Puppet::Parser::Lexer::TOKENS[:RETURN] }
+
+ it "should match against carriage returns" do
+ @token.regex.should =~ "\n"
+ end
+
+ it "should be marked to initiate text skipping" do
+ @token.skip_text.should be_true
+ end
+
+ it "should be marked to increment the line" do
+ @token.incr_line.should be_true
+ end
+end
+
+describe Puppet::Parser::Lexer::TOKENS[:SQUOTE] do
+ before { @token = Puppet::Parser::Lexer::TOKENS[:SQUOTE] }
+
+ it "should match against single quotes" do
+ @token.regex.should =~ "'"
+ end
+
+ it "should slurp the rest of the quoted string" do
+ lexer = stub("lexer")
+ lexer.expects(:slurpstring).with("myval").returns("otherval")
+ @token.convert(lexer, "myval")
+ end
+
+ it "should return the SQTEXT token with the slurped string" do
+ lexer = stub("lexer")
+ lexer.stubs(:slurpstring).with("myval").returns("otherval")
+ @token.convert(lexer, "myval").should == [Puppet::Parser::Lexer::TOKENS[:SQTEXT], "otherval"]
+ end
+end
+
+describe Puppet::Parser::Lexer::TOKENS[:DQUOTE] do
+ before { @token = Puppet::Parser::Lexer::TOKENS[:DQUOTE] }
+
+ it "should match against single quotes" do
+ @token.regex.should =~ '"'
+ end
+
+ it "should slurp the rest of the quoted string" do
+ lexer = stub("lexer")
+ lexer.expects(:slurpstring).with("myval").returns("otherval")
+ @token.convert(lexer, "myval")
+ end
+
+ it "should return the DQTEXT token with the slurped string" do
+ lexer = stub("lexer")
+ lexer.stubs(:slurpstring).with("myval").returns("otherval")
+ @token.convert(lexer, "myval").should == [Puppet::Parser::Lexer::TOKENS[:DQTEXT], "otherval"]
+ end
+end
+
+describe Puppet::Parser::Lexer::TOKENS[:VARIABLE] do
+ before { @token = Puppet::Parser::Lexer::TOKENS[:VARIABLE] }
+
+ it "should match against alpha words prefixed with '$'" do
+ @token.regex.should =~ '$this_var'
+ end
+
+ it "should return the VARIABLE token and the variable name stripped of the '$'" do
+ @token.convert(stub("lexer"), "$myval").should == [Puppet::Parser::Lexer::TOKENS[:VARIABLE], "myval"]
+ end
+end
+
+# FIXME: We need to rewrite all of these tests, but I just don't want to take the time right now.
+describe "Puppet::Parser::Lexer in the old tests" do
+ before { @lexer = Puppet::Parser::Lexer.new }
+
+ it "should do simple lexing" do
+ strings = {
+%q{\\} => [[:BACKSLASH,"\\"],[false,false]],
+%q{simplest scanner test} => [[:NAME,"simplest"],[:NAME,"scanner"],[:NAME,"test"],[false,false]],
+%q{returned scanner test
+} => [[:NAME,"returned"],[:NAME,"scanner"],[:NAME,"test"],[false,false]]
+ }
+ strings.each { |str,ary|
+ @lexer.string = str
+ @lexer.fullscan().should == ary
+ }
+ end
+
+ it "should correctly lex quoted strings" do
+ strings = {
+%q{a simple "scanner" test
+} => [[:NAME,"a"],[:NAME,"simple"],[:DQTEXT,"scanner"],[:NAME,"test"],[false,false]],
+%q{a simple 'single quote scanner' test
+} => [[:NAME,"a"],[:NAME,"simple"],[:SQTEXT,"single quote scanner"],[:NAME,"test"],[false,false]],
+%q{a harder 'a $b \c"'
+} => [[:NAME,"a"],[:NAME,"harder"],[:SQTEXT,'a $b \c"'],[false,false]],
+%q{a harder "scanner test"
+} => [[:NAME,"a"],[:NAME,"harder"],[:DQTEXT,"scanner test"],[false,false]],
+%q{a hardest "scanner \"test\""
+} => [[:NAME,"a"],[:NAME,"hardest"],[:DQTEXT,'scanner "test"'],[false,false]],
+%q{a hardestest "scanner \"test\"
+"
+} => [[:NAME,"a"],[:NAME,"hardestest"],[:DQTEXT,'scanner "test"
+'],[false,false]],
+%q{function("call")} => [[:NAME,"function"],[:LPAREN,"("],[:DQTEXT,'call'],[:RPAREN,")"],[false,false]]
+}
+ strings.each { |str,array|
+ @lexer.string = str
+ @lexer.fullscan().should == array
+ }
+ end
+
+ it "should fail usefully" do
+ strings = %w{
+ ^
+ }
+ strings.each { |str|
+ @lexer.string = str
+ lambda { @lexer.fullscan() }.should raise_error(RuntimeError)
+ }
+ end
+
+ it "should fail if the string is not set" do
+ lambda { @lexer.fullscan() }.should raise_error(Puppet::LexError)
+ end
+
+ it "should correctly identify keywords" do
+ @lexer.string = "case"
+ @lexer.fullscan.should == [[:CASE, "case"], [false, false]]
+ end
+
+ it "should correctly match strings" do
+ names = %w{this is a bunch of names}
+ types = %w{Many Different Words A Word}
+ words = %w{differently Cased words A a}
+
+ names.each { |t|
+ @lexer.string = t
+ @lexer.fullscan.should == [[:NAME,t],[false,false]]
+ }
+ types.each { |t|
+ @lexer.string = t
+ @lexer.fullscan.should == [[:CLASSREF,t],[false,false]]
+ }
+ end
+
+ it "should correctly parse empty strings" do
+ bit = '$var = ""'
+
+ @lexer.string = bit
+
+ lambda { @lexer.fullscan }.should_not raise_error
+ end
+
+ it "should correctly parse virtual resources" do
+ string = "@type {"
+
+ @lexer.string = string
+
+ @lexer.fullscan.should == [[:AT, "@"], [:NAME, "type"], [:LBRACE, "{"], [false,false]]
+ end
+
+ it "should correctly deal with namespaces" do
+ @lexer.string = %{class myclass}
+
+ @lexer.fullscan
+
+ @lexer.namespace.should == "myclass"
+
+ @lexer.namepop
+
+ @lexer.namespace.should == ""
+
+ @lexer.string = "class base { class sub { class more"
+
+ @lexer.fullscan
+
+ @lexer.namespace.should == "base::sub::more"
+
+ @lexer.namepop
+
+ @lexer.namespace.should == "base::sub"
+ end
+
+ it "should correctly handle fully qualified names" do
+ @lexer.string = "class base { class sub::more {"
+
+ @lexer.fullscan
+
+ @lexer.namespace.should == "base::sub::more"
+
+ @lexer.namepop
+
+ @lexer.namespace.should == "base"
+ end
+
+ it "should correctly lex variables" do
+ ["$variable", "$::variable", "$qualified::variable", "$further::qualified::variable"].each do |string|
+ @lexer.string = string
+
+ @lexer.scan do |t, s|
+ t.should == :VARIABLE
+ string.sub(/^\$/, '').should == s
+ break
+ end
+ end
+ end
+
+ # #774
+ it "should correctly parse the CLASSREF token" do
+ string = ["Foo", "::Foo","Foo::Bar","::Foo::Bar"]
+
+ string.each do |foo|
+ @lexer.string = foo
+ @lexer.fullscan[0].should == [:CLASSREF, foo]
+ end
+ end
+end
+
+require 'puppettest/support/utils'
+describe "Puppet::Parser::Lexer in the old tests when lexing example files" do
+ extend PuppetTest
+ extend PuppetTest::Support::Utils
+ textfiles() do |file|
+ it "should correctly lex #{file}" do
+ lexer = Puppet::Parser::Lexer.new()
+ lexer.file = file
+ lambda { lexer.fullscan() }.should_not raise_error
+ end
+ end
+end
diff --git a/spec/unit/parser/resource.rb b/spec/unit/parser/resource.rb
index 3d048f7e6..776e9c742 100755
--- a/spec/unit/parser/resource.rb
+++ b/spec/unit/parser/resource.rb
@@ -4,86 +4,316 @@ require File.dirname(__FILE__) + '/../../spec_helper'
# LAK: FIXME This is just new tests for resources; I have
# not moved all tests over yet.
-describe Puppet::Parser::Resource, " when evaluating" do
- before do
- @type = Puppet::Parser::Resource
+describe Puppet::Parser::Resource do
+ before do
@parser = Puppet::Parser::Parser.new :Code => ""
@source = @parser.newclass ""
- @definition = @parser.newdefine "mydefine"
- @class = @parser.newclass "myclass"
- @nodedef = @parser.newnode("mynode")[0]
@node = Puppet::Node.new("yaynode")
- @compile = Puppet::Parser::Compile.new(@node, @parser)
- @scope = @compile.topscope
+ @compiler = Puppet::Parser::Compiler.new(@node, @parser)
+ @scope = @compiler.topscope
end
- it "should evaluate the associated AST definition" do
- res = @type.new(:type => "mydefine", :title => "whatever", :scope => @scope, :source => @source)
- @definition.expects(:evaluate).with(:scope => @scope, :resource => res)
+ def mkresource(args = {})
+ args[:source] ||= "source"
+ args[:scope] ||= stub('scope', :source => mock('source'))
+
+ {:type => "resource", :title => "testing", :source => "source", :scope => "scope"}.each do |param, value|
+ args[param] ||= value
+ end
+
+ params = args[:params] || {:one => "yay", :three => "rah"}
+ if args[:params] == :none
+ args.delete(:params)
+ else
+ args[:params] = paramify(args[:source], params)
+ end
- res.evaluate
+ Puppet::Parser::Resource.new(args)
end
- it "should evaluate the associated AST class" do
- res = @type.new(:type => "class", :title => "myclass", :scope => @scope, :source => @source)
- @class.expects(:evaluate).with(:scope => @scope, :resource => res)
- res.evaluate
+ def param(name, value, source)
+ Puppet::Parser::Resource::Param.new(:name => name, :value => value, :source => source)
end
- it "should evaluate the associated AST node" do
- res = @type.new(:type => "node", :title => "mynode", :scope => @scope, :source => @source)
- @nodedef.expects(:evaluate).with(:scope => @scope, :resource => res)
- res.evaluate
+ def paramify(source, hash)
+ hash.collect do |name, value|
+ Puppet::Parser::Resource::Param.new(
+ :name => name, :value => value, :source => source
+ )
+ end
end
-end
-describe Puppet::Parser::Resource, " when finishing" do
- before do
- @parser = Puppet::Parser::Parser.new :Code => ""
- @source = @parser.newclass ""
- @definition = @parser.newdefine "mydefine"
- @class = @parser.newclass "myclass"
- @nodedef = @parser.newnode("mynode")[0]
- @node = Puppet::Node.new("yaynode")
- @compile = Puppet::Parser::Compile.new(@node, @parser)
- @scope = @compile.topscope
+ it "should be isomorphic if it is builtin and models an isomorphic type" do
+ Puppet::Type.type(:file).expects(:isomorphic?).returns(true)
+ @resource = Puppet::Parser::Resource.new(:type => "file", :title => "whatever", :scope => @scope, :source => @source).isomorphic?.should be_true
+ end
+
+ it "should not be isomorphic if it is builtin and models a non-isomorphic type" do
+ Puppet::Type.type(:file).expects(:isomorphic?).returns(false)
+ @resource = Puppet::Parser::Resource.new(:type => "file", :title => "whatever", :scope => @scope, :source => @source).isomorphic?.should be_false
+ end
- @resource = Puppet::Parser::Resource.new(:type => "mydefine", :title => "whatever", :scope => @scope, :source => @source)
+ it "should be isomorphic if it is not builtin" do
+ @parser.newdefine "whatever"
+ @resource = Puppet::Parser::Resource.new(:type => "whatever", :title => "whatever", :scope => @scope, :source => @source).isomorphic?.should be_true
end
- it "should copy metaparams from its scope" do
- @scope.setvar("noop", "true")
+ it "should have a array-indexing method for retrieving parameter values" do
+ @resource = mkresource
+ @resource[:one].should == "yay"
+ end
+
+ describe "when initializing" do
+ before do
+ @arguments = {:type => "resource", :title => "testing", :scope => stub('scope', :source => mock('source'))}
+ end
- @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams }
+ [:type, :title, :scope].each do |name|
+ it "should fail unless #{name.to_s} is specified" do
+ try = @arguments.dup
+ try.delete(name)
+ lambda { Puppet::Parser::Resource.new(try) }.should raise_error(ArgumentError)
+ end
+ end
- @resource["noop"].should == "true"
+ it "should set the reference correctly" do
+ res = Puppet::Parser::Resource.new(@arguments)
+ res.ref.should == "Resource[testing]"
+ end
end
- it "should not copy metaparams that it already has" do
- @resource.class.publicize_methods(:set_parameter) { @resource.set_parameter("noop", "false") }
- @scope.setvar("noop", "true")
+ describe "when evaluating" do
+ before do
+ @type = Puppet::Parser::Resource
+
+ @definition = @parser.newdefine "mydefine"
+ @class = @parser.newclass "myclass"
+ @nodedef = @parser.newnode("mynode")[0]
+ end
+
+ it "should evaluate the associated AST definition" do
+ res = @type.new(:type => "mydefine", :title => "whatever", :scope => @scope, :source => @source)
+ @definition.expects(:evaluate_code).with(res)
+
+ res.evaluate
+ end
+
+ it "should evaluate the associated AST class" do
+ res = @type.new(:type => "class", :title => "myclass", :scope => @scope, :source => @source)
+ @class.expects(:evaluate_code).with(res)
+ res.evaluate
+ end
+
+ it "should evaluate the associated AST node" do
+ res = @type.new(:type => "node", :title => "mynode", :scope => @scope, :source => @source)
+ @nodedef.expects(:evaluate_code).with(res)
+ res.evaluate
+ end
+ end
+
+ describe "when finishing" do
+ before do
+ @class = @parser.newclass "myclass"
+ @nodedef = @parser.newnode("mynode")[0]
+
+ @resource = Puppet::Parser::Resource.new(:type => "file", :title => "whatever", :scope => @scope, :source => @source)
+ end
+
+ it "should do nothing if it has already been finished" do
+ @resource.finish
+ @resource.expects(:add_metaparams).never
+ @resource.finish
+ end
+
+ it "should add all defaults available from the scope" do
+ @resource.scope.expects(:lookupdefaults).with(@resource.type).returns(:owner => param(:owner, "default", @resource.source))
+ @resource.finish
+
+ @resource[:owner].should == "default"
+ end
+
+ it "should not replace existing parameters with defaults" do
+ @resource.set_parameter :owner, "oldvalue"
+ @resource.scope.expects(:lookupdefaults).with(@resource.type).returns(:owner => :replaced)
+ @resource.finish
+
+ @resource[:owner].should == "oldvalue"
+ end
+
+ it "should add a copy of each default, rather than the actual default parameter instance" do
+ newparam = param(:owner, "default", @resource.source)
+ other = newparam.dup
+ other.value = "other"
+ newparam.expects(:dup).returns(other)
+ @resource.scope.expects(:lookupdefaults).with(@resource.type).returns(:owner => newparam)
+ @resource.finish
+
+ @resource[:owner].should == "other"
+ end
+
+ it "should copy metaparams from its scope" do
+ @scope.setvar("noop", "true")
+
+ @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams }
- @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams }
+ @resource["noop"].should == "true"
+ end
- @resource["noop"].should == "false"
+ it "should not copy metaparams that it already has" do
+ @resource.set_parameter("noop", "false")
+ @scope.setvar("noop", "true")
+
+ @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams }
+
+ @resource["noop"].should == "false"
+ end
+
+ it "should stack relationship metaparams from its container if it already has them" do
+ @resource.set_parameter("require", "resource")
+ @scope.setvar("require", "container")
+
+ @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams }
+
+ @resource["require"].sort.should == %w{container resource}
+ end
+
+ it "should flatten the array resulting from stacking relationship metaparams" do
+ @resource.set_parameter("require", ["resource1", "resource2"])
+ @scope.setvar("require", %w{container1 container2})
+
+ @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams }
+
+ @resource["require"].sort.should == %w{container1 container2 resource1 resource2}
+ end
+
+ it "should add any tags from the scope resource" do
+ scope_resource = stub 'scope_resource', :tags => %w{one two}
+ @scope.stubs(:resource).returns(scope_resource)
+
+ @resource.class.publicize_methods(:add_scope_tags) { @resource.add_scope_tags }
+
+ @resource.tags.should be_include("one")
+ @resource.tags.should be_include("two")
+ end
end
- it "should stack relationship metaparams from its container if it already has them" do
- @resource.class.publicize_methods(:set_parameter) { @resource.set_parameter("require", "resource") }
- @scope.setvar("require", "container")
+ describe "when being tagged" do
+ before do
+ @scope_resource = stub 'scope_resource', :tags => %w{srone srtwo}
+ @scope = stub 'scope', :resource => @scope_resource
+ @resource = Puppet::Parser::Resource.new(:type => "file", :title => "yay", :scope => @scope, :source => mock('source'))
+ end
+
+ it "should get tagged with the resource type" do
+ @resource.tags.should be_include("file")
+ end
+
+ it "should get tagged with the title" do
+ @resource.tags.should be_include("yay")
+ end
+
+ it "should get tagged with each name in the title if the title is a qualified class name" do
+ resource = Puppet::Parser::Resource.new(:type => "file", :title => "one::two", :scope => @scope, :source => mock('source'))
+ resource.tags.should be_include("one")
+ resource.tags.should be_include("two")
+ end
+
+ it "should get tagged with each name in the type if the type is a qualified class name" do
+ resource = Puppet::Parser::Resource.new(:type => "one::two", :title => "whatever", :scope => @scope, :source => mock('source'))
+ resource.tags.should be_include("one")
+ resource.tags.should be_include("two")
+ end
+
+ it "should not get tagged with non-alphanumeric titles" do
+ resource = Puppet::Parser::Resource.new(:type => "file", :title => "this is a test", :scope => @scope, :source => mock('source'))
+ resource.tags.should_not be_include("this is a test")
+ end
- @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams }
+ it "should fail on tags containing '*' characters" do
+ lambda { @resource.tag("bad*tag") }.should raise_error(Puppet::ParseError)
+ end
- @resource["require"].sort.should == %w{container resource}
+ it "should fail on tags starting with '-' characters" do
+ lambda { @resource.tag("-badtag") }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should fail on tags containing ' ' characters" do
+ lambda { @resource.tag("bad tag") }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should allow alpha tags" do
+ lambda { @resource.tag("good_tag") }.should_not raise_error(Puppet::ParseError)
+ end
end
- it "should flatten the array resulting from stacking relationship metaparams" do
- @resource.class.publicize_methods(:set_parameter) { @resource.set_parameter("require", ["resource1", "resource2"]) }
- @scope.setvar("require", %w{container1 container2})
+ describe "when merging overrides" do
+ before do
+ @source = "source1"
+ @resource = mkresource :source => @source
+ @override = mkresource :source => @source
+ end
+
+ it "should fail when the override was not created by a parent class" do
+ @override.source = "source2"
+ @override.source.expects(:child_of?).with("source1").returns(false)
+ lambda { @resource.merge(@override) }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should succeed when the override was created in the current scope" do
+ @resource.source = "source3"
+ @override.source = @resource.source
+ @override.source.expects(:child_of?).with("source3").never
+ params = {:a => :b, :c => :d}
+ @override.expects(:params).returns(params)
+ @resource.expects(:override_parameter).with(:b)
+ @resource.expects(:override_parameter).with(:d)
+ @resource.merge(@override)
+ end
+
+ it "should succeed when a parent class created the override" do
+ @resource.source = "source3"
+ @override.source = "source4"
+ @override.source.expects(:child_of?).with("source3").returns(true)
+ params = {:a => :b, :c => :d}
+ @override.expects(:params).returns(params)
+ @resource.expects(:override_parameter).with(:b)
+ @resource.expects(:override_parameter).with(:d)
+ @resource.merge(@override)
+ end
+
+ it "should add new parameters when the parameter is not set" do
+ @source.stubs(:child_of?).returns true
+ @override.set_parameter(:testing, "value")
+ @resource.merge(@override)
+
+ @resource[:testing].should == "value"
+ end
+
+ it "should replace existing parameter values" do
+ @source.stubs(:child_of?).returns true
+ @resource.set_parameter(:testing, "old")
+ @override.set_parameter(:testing, "value")
+
+ @resource.merge(@override)
+
+ @resource[:testing].should == "value"
+ end
+
+ it "should add values to the parameter when the override was created with the '+>' syntax" do
+ @source.stubs(:child_of?).returns true
+ param = Puppet::Parser::Resource::Param.new(:name => :testing, :value => "testing", :source => @resource.source)
+ param.add = true
+
+ @override.set_parameter(param)
+
+ @resource.set_parameter(:testing, "other")
+
+ @resource.merge(@override)
+
+ @resource[:testing].should == %w{other testing}
+ end
- @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams }
- @resource["require"].sort.should == %w{container1 container2 resource1 resource2}
end
end
diff --git a/spec/unit/parser/resource/reference.rb b/spec/unit/parser/resource/reference.rb
index e7385f796..147f772d1 100755
--- a/spec/unit/parser/resource/reference.rb
+++ b/spec/unit/parser/resource/reference.rb
@@ -52,23 +52,23 @@ describe Puppet::Parser::Resource::Reference, " when modeling defined types" do
@nodedef = @parser.newnode("mynode")[0]
@node = Puppet::Node.new("yaynode")
- @compile = Puppet::Parser::Compile.new(@node, @parser)
+ @compiler = Puppet::Parser::Compiler.new(@node, @parser)
end
it "should be able to find defined types" do
- ref = @type.new(:type => "mydefine", :title => "/tmp/yay", :scope => @compile.topscope)
+ ref = @type.new(:type => "mydefine", :title => "/tmp/yay", :scope => @compiler.topscope)
ref.builtin?.should be_false
ref.definedtype.should equal(@definition)
end
it "should be able to find classes" do
- ref = @type.new(:type => "class", :title => "myclass", :scope => @compile.topscope)
+ ref = @type.new(:type => "class", :title => "myclass", :scope => @compiler.topscope)
ref.builtin?.should be_false
ref.definedtype.should equal(@class)
end
it "should be able to find nodes" do
- ref = @type.new(:type => "node", :title => "mynode", :scope => @compile.topscope)
+ ref = @type.new(:type => "node", :title => "mynode", :scope => @compiler.topscope)
ref.builtin?.should be_false
ref.definedtype.object_id.should == @nodedef.object_id
end
diff --git a/spec/unit/ral/provider/interface/redhat.rb b/spec/unit/ral/provider/interface/redhat.rb
index 0b3b75ffc..9bf1b9722 100755
--- a/spec/unit/ral/provider/interface/redhat.rb
+++ b/spec/unit/ral/provider/interface/redhat.rb
@@ -5,9 +5,6 @@
require File.dirname(__FILE__) + '/../../../../spec_helper'
-require 'puppet/provider/interface/redhat'
-
-
provider_class = Puppet::Type.type(:interface).provider(:redhat)
describe provider_class do
diff --git a/spec/unit/ral/provider/mount.rb b/spec/unit/ral/provider/mount.rb
index 65aaf7053..0b90d53c9 100755
--- a/spec/unit/ral/provider/mount.rb
+++ b/spec/unit/ral/provider/mount.rb
@@ -4,8 +4,8 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/provider/mount'
-module MountModuleTesting
- def setup
+describe Puppet::Provider::Mount do
+ before :each do
@mounter = Object.new
@mounter.extend(Puppet::Provider::Mount)
@@ -16,119 +16,115 @@ module MountModuleTesting
@mounter.stubs(:resource).returns(@resource)
end
-end
-describe Puppet::Provider::Mount, " when mounting" do
- include MountModuleTesting
+ describe Puppet::Provider::Mount, " when mounting" do
- it "should use the 'mountcmd' method to mount" do
- @mounter.stubs(:options).returns(nil)
- @mounter.expects(:mountcmd)
+ it "should use the 'mountcmd' method to mount" do
+ @mounter.stubs(:options).returns(nil)
+ @mounter.expects(:mountcmd)
- @mounter.mount
- end
+ @mounter.mount
+ end
- it "should flush before mounting if a flush method exists" do
- @mounter.meta_def(:flush) { }
- @mounter.expects(:flush)
- @mounter.stubs(:mountcmd)
- @mounter.stubs(:options).returns(nil)
+ it "should flush before mounting if a flush method exists" do
+ @mounter.meta_def(:flush) { }
+ @mounter.expects(:flush)
+ @mounter.stubs(:mountcmd)
+ @mounter.stubs(:options).returns(nil)
- @mounter.mount
- end
+ @mounter.mount
+ end
- it "should add the options following '-o' if they exist and are not set to :absent" do
- @mounter.stubs(:options).returns("ro")
- @mounter.expects(:mountcmd).with { |*ary| ary[0] == "-o" and ary[1] == "ro" }
+ it "should add the options following '-o' if they exist and are not set to :absent" do
+ @mounter.stubs(:options).returns("ro")
+ @mounter.expects(:mountcmd).with { |*ary| ary[0] == "-o" and ary[1] == "ro" }
- @mounter.mount
- end
+ @mounter.mount
+ end
- it "should specify the filesystem name to the mount command" do
- @mounter.stubs(:options).returns(nil)
- @mounter.expects(:mountcmd).with { |*ary| ary[-1] == @name }
+ it "should specify the filesystem name to the mount command" do
+ @mounter.stubs(:options).returns(nil)
+ @mounter.expects(:mountcmd).with { |*ary| ary[-1] == @name }
- @mounter.mount
+ @mounter.mount
+ end
end
-end
-describe Puppet::Provider::Mount, " when remounting" do
- include MountModuleTesting
-
- it "should use '-o remount' if the resource specifies it supports remounting" do
- @mounter.stubs(:info)
- @resource.stubs(:[]).with(:remounts).returns(:true)
- @mounter.expects(:mountcmd).with("-o", "remount", @name)
- @mounter.remount
+ describe Puppet::Provider::Mount, " when remounting" do
+
+ it "should use '-o remount' if the resource specifies it supports remounting" do
+ @mounter.stubs(:info)
+ @resource.stubs(:[]).with(:remounts).returns(:true)
+ @mounter.expects(:mountcmd).with("-o", "remount", @name)
+ @mounter.remount
+ end
+
+ it "should unmount and mount if the resource does not specify it supports remounting" do
+ @mounter.stubs(:info)
+ @resource.stubs(:[]).with(:remounts).returns(false)
+ @mounter.expects(:unmount)
+ @mounter.expects(:mount)
+ @mounter.remount
+ end
+
+ it "should log that it is remounting" do
+ @resource.stubs(:[]).with(:remounts).returns(:true)
+ @mounter.stubs(:mountcmd)
+ @mounter.expects(:info).with("Remounting")
+ @mounter.remount
+ end
end
- it "should unmount and mount if the resource does not specify it supports remounting" do
- @mounter.stubs(:info)
- @resource.stubs(:[]).with(:remounts).returns(false)
- @mounter.expects(:unmount)
- @mounter.expects(:mount)
- @mounter.remount
- end
+ describe Puppet::Provider::Mount, " when unmounting" do
- it "should log that it is remounting" do
- @resource.stubs(:[]).with(:remounts).returns(:true)
- @mounter.stubs(:mountcmd)
- @mounter.expects(:info).with("Remounting")
- @mounter.remount
+ it "should call the :umount command with the resource name" do
+ @mounter.expects(:umount).with(@name)
+ @mounter.unmount
+ end
end
-end
-describe Puppet::Provider::Mount, " when unmounting" do
- include MountModuleTesting
+ describe Puppet::Provider::Mount, " when determining if it is mounted" do
- it "should call the :umount command with the resource name" do
- @mounter.expects(:umount).with(@name)
- @mounter.unmount
- end
-end
-
-describe Puppet::Provider::Mount, " when determining if it is mounted" do
- include MountModuleTesting
+ it "should parse the results of running the mount command with no arguments" do
+ Facter.stubs(:value).returns("whatever")
+ @mounter.expects(:mountcmd).returns("")
- it "should parse the results of running the mount command with no arguments" do
- Facter.stubs(:value).returns("whatever")
- @mounter.expects(:mountcmd).returns("")
-
- @mounter.mounted?
- end
+ @mounter.mounted?
+ end
- it "should match ' on /private/var/automount<name>' if the operating system is Darwin" do
- Facter.stubs(:value).with("operatingsystem").returns("Darwin")
- @mounter.expects(:mountcmd).returns("/dev/whatever on /private/var/automount/\ndevfs on /dev")
+ it "should match ' on /private/var/automount<name>' if the operating system is Darwin" do
+ Facter.stubs(:value).with("operatingsystem").returns("Darwin")
+ @mounter.expects(:mountcmd).returns("/dev/whatever on /private/var/automount/\ndevfs on /dev")
- @mounter.should be_mounted
- end
+ @mounter.should be_mounted
+ end
- it "should match ' on <name>' if the operating system is Darwin" do
- Facter.stubs(:value).with("operatingsystem").returns("Darwin")
- @mounter.expects(:mountcmd).returns("/dev/disk03 on / (local, journaled)\ndevfs on /dev")
+ it "should match ' on <name>' if the operating system is Darwin" do
+ Facter.stubs(:value).with("operatingsystem").returns("Darwin")
+ @mounter.expects(:mountcmd).returns("/dev/disk03 on / (local, journaled)\ndevfs on /dev")
- @mounter.should be_mounted
- end
+ @mounter.should be_mounted
+ end
- it "should match '^<name> on' if the operating system is Solaris" do
- Facter.stubs(:value).with("operatingsystem").returns("Solaris")
- @mounter.expects(:mountcmd).returns("/ on /dev/dsk/whatever\n/var on /dev/dsk/other")
+ it "should match '^<name> on' if the operating system is Solaris" do
+ Facter.stubs(:value).with("operatingsystem").returns("Solaris")
+ @mounter.expects(:mountcmd).returns("/ on /dev/dsk/whatever\n/var on /dev/dsk/other")
- @mounter.should be_mounted
- end
+ @mounter.should be_mounted
+ end
- it "should match ' on <name>' if the operating system is not Darwin or Solaris" do
- Facter.stubs(:value).with("operatingsystem").returns("Debian")
- @mounter.expects(:mountcmd).returns("/dev/dsk/whatever on / and stuff\n/dev/other/disk on /var and stuff")
+ it "should match ' on <name>' if the operating system is not Darwin or Solaris" do
+ Facter.stubs(:value).with("operatingsystem").returns("Debian")
+ @mounter.expects(:mountcmd).returns("/dev/dsk/whatever on / and stuff\n/dev/other/disk on /var and stuff")
- @mounter.should be_mounted
- end
+ @mounter.should be_mounted
+ end
- it "should not be considered mounted if it did not match the mount output" do
- Facter.stubs(:value).with("operatingsystem").returns("Debian")
- @mounter.expects(:mountcmd).returns("/dev/dsk/whatever on /something/else and stuff\n/dev/other/disk on /var and stuff")
+ it "should not be considered mounted if it did not match the mount output" do
+ Facter.stubs(:value).with("operatingsystem").returns("Debian")
+ @mounter.expects(:mountcmd).returns("/dev/dsk/whatever on /something/else and stuff\n/dev/other/disk on /var and stuff")
- @mounter.should_not be_mounted
+ @mounter.should_not be_mounted
+ end
end
end
diff --git a/spec/unit/ral/provider/mount/parsed.rb b/spec/unit/ral/provider/mount/parsed.rb
index 2fd15a543..b7f08a464 100755
--- a/spec/unit/ral/provider/mount/parsed.rb
+++ b/spec/unit/ral/provider/mount/parsed.rb
@@ -12,11 +12,6 @@ module ParsedMountTesting
include PuppetTest::Support::Utils
include PuppetTest::FileParsing
- def setup
- @mount_class = Puppet.type(:mount)
- @provider_class = @mount_class.provider(:parsed)
- end
-
def fake_fstab
os = Facter['operatingsystem']
if os == "Solaris"
@@ -79,100 +74,108 @@ end
provider_class = Puppet::Type.type(:mount).provider(:parsed)
describe provider_class do
- include ParsedMountTesting
+ before :each do
+ @mount_class = Puppet.type(:mount)
+ @provider_class = @mount_class.provider(:parsed)
+ end
- it "should be able to parse all of the example mount tabs" do
- tab = fake_fstab
- @provider = @provider_class
- # LAK:FIXME Again, a relatively bad test, but I don't know how to rspec-ify this.
- # I suppose this is more of an integration test? I dunno.
- fakedataparse(tab) do
- # Now just make we've got some mounts we know will be there
- hashes = @provider_class.target_records(tab).find_all { |i| i.is_a? Hash }
- (hashes.length > 0).should be_true
- root = hashes.find { |i| i[:name] == "/" }
+ describe provider_class do
+ include ParsedMountTesting
- proc { @provider_class.to_file(hashes) }.should_not raise_error
- end
- end
+ it "should be able to parse all of the example mount tabs" do
+ tab = fake_fstab
+ @provider = @provider_class
+
+ # LAK:FIXME Again, a relatively bad test, but I don't know how to rspec-ify this.
+ # I suppose this is more of an integration test? I dunno.
+ fakedataparse(tab) do
+ # Now just make we've got some mounts we know will be there
+ hashes = @provider_class.target_records(tab).find_all { |i| i.is_a? Hash }
+ (hashes.length > 0).should be_true
+ root = hashes.find { |i| i[:name] == "/" }
- # LAK:FIXME I can't mock Facter because this test happens at parse-time.
- it "should default to /etc/vfstab on Solaris and /etc/fstab everywhere else" do
- should = case Facter.value(:operatingsystem)
- when "Solaris": "/etc/vfstab"
- else
- "/etc/fstab"
+ proc { @provider_class.to_file(hashes) }.should_not raise_error
end
- Puppet::Type.type(:mount).provider(:parsed).default_target.should == should
+ end
+
+ # LAK:FIXME I can't mock Facter because this test happens at parse-time.
+ it "should default to /etc/vfstab on Solaris and /etc/fstab everywhere else" do
+ should = case Facter.value(:operatingsystem)
+ when "Solaris": "/etc/vfstab"
+ else
+ "/etc/fstab"
+ end
+ Puppet::Type.type(:mount).provider(:parsed).default_target.should == should
+ end
end
-end
-describe provider_class, " when mounting an absent filesystem" do
- include ParsedMountTesting
+ describe provider_class, " when mounting an absent filesystem" do
+ include ParsedMountTesting
- # #730 - Make sure 'flush' is called when a mount is moving from absent to mounted
- it "should flush the fstab to disk" do
- mount = mkmount
+ # #730 - Make sure 'flush' is called when a mount is moving from absent to mounted
+ it "should flush the fstab to disk" do
+ mount = mkmount
- # Mark the mount as absent
- mount.property_hash[:ensure] = :absent
+ # Mark the mount as absent
+ mount.property_hash[:ensure] = :absent
- mount.stubs(:mountcmd) # just so we don't actually try to mount anything
+ mount.stubs(:mountcmd) # just so we don't actually try to mount anything
- mount.expects(:flush)
- mount.mount
+ mount.expects(:flush)
+ mount.mount
+ end
end
-end
-describe provider_class, " when modifying the filesystem tab" do
- include ParsedMountTesting
- before do
- @mount = mkmount
- @target = @provider_class.default_target
+ describe provider_class, " when modifying the filesystem tab" do
+ include ParsedMountTesting
+ before do
+ @mount = mkmount
+ @target = @provider_class.default_target
- # Never write to disk, only to RAM.
- @provider_class.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram))
- end
+ # Never write to disk, only to RAM.
+ @provider_class.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram))
+ end
- it "should write the mount to disk when :flush is called" do
- @mount.flush
+ it "should write the mount to disk when :flush is called" do
+ @mount.flush
- text = @provider_class.target_object(@provider_class.default_target).read
- text.should == @mount.class.to_line(@mount.property_hash) + "\n"
+ text = @provider_class.target_object(@provider_class.default_target).read
+ text.should == @mount.class.to_line(@mount.property_hash) + "\n"
+ end
end
-end
-describe provider_class, " when parsing information about the root filesystem" do
- confine "Mount type not tested on Darwin" => Facter["operatingsystem"].value != "Darwin"
- include ParsedMountTesting
+ describe provider_class, " when parsing information about the root filesystem" do
+ confine "Mount type not tested on Darwin" => Facter["operatingsystem"].value != "Darwin"
+ include ParsedMountTesting
- before do
- @mount = @mount_class.create :name => "/"
- @provider = @mount.provider
- end
+ before do
+ @mount = @mount_class.create :name => "/"
+ @provider = @mount.provider
+ end
- it "should have a filesystem tab" do
- FileTest.should be_exist(@provider_class.default_target)
- end
+ it "should have a filesystem tab" do
+ FileTest.should be_exist(@provider_class.default_target)
+ end
- it "should find the root filesystem" do
- @provider_class.prefetch("/" => @mount)
- @mount.provider.property_hash[:ensure].should == :present
- end
+ it "should find the root filesystem" do
+ @provider_class.prefetch("/" => @mount)
+ @mount.provider.property_hash[:ensure].should == :present
+ end
- it "should determine that the root fs is mounted" do
- @provider_class.prefetch("/" => @mount)
- @mount.provider.should be_mounted
+ it "should determine that the root fs is mounted" do
+ @provider_class.prefetch("/" => @mount)
+ @mount.provider.should be_mounted
+ end
end
-end
-describe provider_class, " when mounting and unmounting" do
- include ParsedMountTesting
+ describe provider_class, " when mounting and unmounting" do
+ include ParsedMountTesting
- it "should call the 'mount' command to mount the filesystem"
+ it "should call the 'mount' command to mount the filesystem"
- it "should call the 'unmount' command to unmount the filesystem"
+ it "should call the 'unmount' command to unmount the filesystem"
- it "should specify the filesystem when remounting a filesystem"
+ it "should specify the filesystem when remounting a filesystem"
+ end
end
diff --git a/spec/unit/ral/type.rb b/spec/unit/ral/type.rb
index 25f8cbaf1..5980167d6 100755
--- a/spec/unit/ral/type.rb
+++ b/spec/unit/ral/type.rb
@@ -11,8 +11,8 @@ describe Puppet::Type, " when in a configuration" do
@catalog.add_resource @container
@catalog.add_resource @one
@catalog.add_resource @two
- @catalog.add_edge! @container, @one
- @catalog.add_edge! @container, @two
+ @catalog.add_edge @container, @one
+ @catalog.add_edge @container, @two
end
it "should have no parent if there is no in edge" do
diff --git a/spec/unit/ral/types/exec.rb b/spec/unit/ral/type/exec.rb
index 260804227..260804227 100755
--- a/spec/unit/ral/types/exec.rb
+++ b/spec/unit/ral/type/exec.rb
diff --git a/spec/unit/ral/type/file.rb b/spec/unit/ral/type/file.rb
new file mode 100755
index 000000000..83546bef0
--- /dev/null
+++ b/spec/unit/ral/type/file.rb
@@ -0,0 +1,96 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+describe Puppet::Type.type(:file) do
+ before do
+ @path = Tempfile.new("puppetspec")
+ @path.close!()
+ @path = @path.path
+ @file = Puppet::Type::File.create(:name => @path)
+ end
+
+ describe "when used with content and replace=>false" do
+ before do
+ @file[:content] = "foo"
+ @file[:replace] = false
+ end
+
+ it "should be insync if the file exists and the content is different" do
+ File.open(@path, "w") do |f| f.puts "bar" end
+ @file.property(:content).insync?("bar").should be_true
+ end
+
+ it "should be insync if the file exists and the content is right" do
+ File.open(@path, "w") do |f| f.puts "foo" end
+ @file.property(:content).insync?("foo").should be_true
+ end
+
+ it "should not be insync if the file does not exist" do
+ @file.property(:content).insync?(:nil).should be_false
+ end
+ end
+
+ describe "when retrieving remote files" do
+ before do
+ @filesource = Puppet::Type::File::FileSource.new
+ @filesource.server = mock 'fileserver'
+
+ @file.stubs(:uri2obj).returns(@filesource)
+
+ @file[:source] = "puppet:///test"
+ end
+
+ it "should fail without writing if it cannot retrieve remote contents" do
+ # create the file, because we only get the problem when it starts
+ # out absent.
+ File.open(@file[:path], "w") { |f| f.puts "a" }
+ @file.expects(:write).never
+
+ @filesource.server.stubs(:describe).returns("493\tfile\t100\t0\t{md5}3f5fef3bddbc4398c46a7bd7ba7b3af7")
+ @filesource.server.stubs(:retrieve).raises(RuntimeError)
+ @file.property(:source).retrieve
+ lambda { @file.property(:source).sync }.should raise_error(Puppet::Error)
+ end
+ end
+
+ describe "when managing links" do
+ require 'puppettest/support/assertions'
+ include PuppetTest
+ require 'tempfile'
+
+ before do
+ @basedir = tempfile
+ Dir.mkdir(@basedir)
+ @file = File.join(@basedir, "file")
+ @link = File.join(@basedir, "link")
+
+ File.open(@file, "w", 0644) { |f| f.puts "yayness"; f.flush }
+ File.symlink(@file, @link)
+
+ @resource = Puppet.type(:file).create(
+ :path => @link,
+ :mode => "755"
+ )
+ @catalog = Puppet::Node::Catalog.new
+ @catalog.add_resource @resource
+ end
+
+ after do
+ remove_tmp_files
+ end
+
+ it "should default to managing the link" do
+ @catalog.apply
+ # I convert them to strings so they display correctly if there's an error.
+ ("%o" % (File.stat(@file).mode & 007777)).should == "%o" % 0644
+ end
+
+ it "should be able to follow links" do
+ @resource[:links] = :follow
+ @catalog.apply
+
+ ("%o" % (File.stat(@file).mode & 007777)).should == "%o" % 0755
+ end
+ end
+end
diff --git a/spec/unit/ral/types/interface.rb b/spec/unit/ral/type/interface.rb
index e51465a0c..e51465a0c 100755
--- a/spec/unit/ral/types/interface.rb
+++ b/spec/unit/ral/type/interface.rb
diff --git a/spec/unit/ral/type/mount.rb b/spec/unit/ral/type/mount.rb
new file mode 100755
index 000000000..b1a01749d
--- /dev/null
+++ b/spec/unit/ral/type/mount.rb
@@ -0,0 +1,184 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/type/mount'
+
+describe Puppet::Type::Mount do
+ it "should have a :refreshable feature that requires the :remount method" do
+ Puppet::Type::Mount.provider_feature(:refreshable).methods.should == [:remount]
+ end
+
+ it "should have no default value for :ensure" do
+ mount = Puppet::Type::Mount.create(:name => "yay")
+ mount.should(:ensure).should be_nil
+ end
+end
+
+describe Puppet::Type::Mount, "when validating attributes" do
+ [:name, :remounts].each do |param|
+ it "should have a #{param} parameter" do
+ Puppet::Type::Mount.attrtype(param).should == :param
+ end
+ end
+
+ [:ensure, :device, :blockdevice, :fstype, :options, :pass, :dump, :atboot, :target].each do |param|
+ it "should have a #{param} property" do
+ Puppet::Type::Mount.attrtype(param).should == :property
+ end
+ end
+end
+
+describe Puppet::Type::Mount::Ensure, "when validating values" do
+ before do
+ @provider = stub 'provider', :class => Puppet::Type::Mount.defaultprovider, :clear => nil
+ Puppet::Type::Mount.defaultprovider.expects(:new).returns(@provider)
+ end
+
+ it "should support :present as a value to :ensure" do
+ Puppet::Type::Mount.create(:name => "yay", :ensure => :present)
+ end
+
+ it "should alias :unmounted to :present as a value to :ensure" do
+ mount = Puppet::Type::Mount.create(:name => "yay", :ensure => :unmounted)
+ mount.should(:ensure).should == :present
+ end
+
+ it "should support :absent as a value to :ensure" do
+ Puppet::Type::Mount.create(:name => "yay", :ensure => :absent)
+ end
+
+ it "should support :mounted as a value to :ensure" do
+ Puppet::Type::Mount.create(:name => "yay", :ensure => :mounted)
+ end
+end
+
+describe Puppet::Type::Mount::Ensure do
+ before :each do
+ @provider = stub 'provider', :class => Puppet::Type::Mount.defaultprovider, :clear => nil, :satisfies? => true, :name => :mock
+ Puppet::Type::Mount.defaultprovider.stubs(:new).returns(@provider)
+ @mount = Puppet::Type::Mount.create(:name => "yay", :check => :ensure)
+
+ @ensure = @mount.property(:ensure)
+ end
+
+ def mount_stub(params)
+ Puppet::Type::Mount.validproperties.each do |prop|
+ unless params[prop]
+ params[prop] = :absent
+ @mount[prop] = :absent
+ end
+ end
+
+ params.each do |param, value|
+ @provider.stubs(param).returns(value)
+ end
+ end
+
+ describe Puppet::Type::Mount::Ensure, "when retrieving its current state" do
+
+ it "should return the provider's value if it is :absent" do
+ @provider.expects(:ensure).returns(:absent)
+ @ensure.retrieve.should == :absent
+ end
+
+ it "should return :mounted if the provider indicates it is mounted and the value is not :absent" do
+ @provider.expects(:ensure).returns(:present)
+ @provider.expects(:mounted?).returns(true)
+ @ensure.retrieve.should == :mounted
+ end
+
+ it "should return :present if the provider indicates it is not mounted and the value is not :absent" do
+ @provider.expects(:ensure).returns(:present)
+ @provider.expects(:mounted?).returns(false)
+ @ensure.retrieve.should == :present
+ end
+ end
+
+ describe Puppet::Type::Mount::Ensure, "when changing the host" do
+
+ it "should destroy itself if it should be absent" do
+ @provider.stubs(:mounted?).returns(false)
+ @provider.expects(:destroy)
+ @ensure.should = :absent
+ @ensure.sync
+ end
+
+ it "should unmount itself before destroying if it is mounted and should be absent" do
+ @provider.expects(:mounted?).returns(true)
+ @provider.expects(:unmount)
+ @provider.expects(:destroy)
+ @ensure.should = :absent
+ @ensure.sync
+ end
+
+ it "should create itself if it is absent and should be present" do
+ @provider.stubs(:mounted?).returns(false)
+ @provider.expects(:create)
+ @ensure.should = :present
+ @ensure.sync
+ end
+
+ it "should unmount itself if it is mounted and should be present" do
+ @provider.stubs(:mounted?).returns(true)
+
+ # The interface here is just too much work to test right now.
+ @ensure.stubs(:syncothers)
+ @provider.expects(:unmount)
+ @ensure.should = :present
+ @ensure.sync
+ end
+
+ it "should create and mount itself if it does not exist and should be mounted" do
+ @provider.stubs(:ensure).returns(:absent)
+ @provider.stubs(:mounted?).returns(false)
+ @provider.expects(:create)
+ @ensure.stubs(:syncothers)
+ @provider.expects(:mount)
+ @ensure.should = :mounted
+ @ensure.sync
+ end
+
+ it "should mount itself if it is present and should be mounted" do
+ @provider.stubs(:ensure).returns(:present)
+ @provider.stubs(:mounted?).returns(false)
+ @ensure.stubs(:syncothers)
+ @provider.expects(:mount)
+ @ensure.should = :mounted
+ @ensure.sync
+ end
+
+ it "should create but not mount itself if it is absent and mounted and should be mounted" do
+ @provider.stubs(:ensure).returns(:absent)
+ @provider.stubs(:mounted?).returns(true)
+ @ensure.stubs(:syncothers)
+ @provider.expects(:create)
+ @ensure.should = :mounted
+ @ensure.sync
+ end
+ end
+
+ describe Puppet::Type::Mount, "when responding to events" do
+
+ it "should remount if it is currently mounted" do
+ @provider.expects(:mounted?).returns(true)
+ @provider.expects(:remount)
+
+ @mount.refresh
+ end
+
+ it "should not remount if it is not currently mounted" do
+ @provider.expects(:mounted?).returns(false)
+ @provider.expects(:remount).never
+
+ @mount.refresh
+ end
+
+ it "should not remount swap filesystems" do
+ @mount[:fstype] = "swap"
+ @provider.expects(:remount).never
+
+ @mount.refresh
+ end
+ end
+end
diff --git a/spec/unit/ral/types/nagios.rb b/spec/unit/ral/type/nagios.rb
index 8aca7d401..8aca7d401 100755
--- a/spec/unit/ral/types/nagios.rb
+++ b/spec/unit/ral/type/nagios.rb
diff --git a/spec/unit/ral/type/noop_metaparam.rb b/spec/unit/ral/type/noop_metaparam.rb
new file mode 100755
index 000000000..0cbed3714
--- /dev/null
+++ b/spec/unit/ral/type/noop_metaparam.rb
@@ -0,0 +1,38 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/metatype/metaparams'
+
+describe Puppet::Type.type(:file).attrclass(:noop) do
+ before do
+ @file = Puppet::Type.newfile :path => "/what/ever"
+ end
+
+ after { Puppet::Type::File.clear }
+
+ it "should accept true as a value" do
+ lambda { @file[:noop] = true }.should_not raise_error
+ end
+
+ it "should accept false as a value" do
+ lambda { @file[:noop] = false }.should_not raise_error
+ end
+
+ describe "when set on a resource" do
+ it "should default to the :noop setting" do
+ Puppet.settings.expects(:value).with(:noop).returns "myval"
+ @file.noop.should == "myval"
+ end
+
+ it "should prefer true values from the attribute" do
+ @file[:noop] = true
+ @file.noop.should be_true
+ end
+
+ it "should prefer false values from the attribute" do
+ @file[:noop] = false
+ @file.noop.should be_false
+ end
+ end
+end
diff --git a/spec/unit/ral/types/package.rb b/spec/unit/ral/type/package.rb
index e9e3b9e4e..8cc11cc2c 100755
--- a/spec/unit/ral/types/package.rb
+++ b/spec/unit/ral/type/package.rb
@@ -92,13 +92,19 @@ describe Puppet::Type::Package, "when validating attribute values" do
proc { Puppet::Type::Package.create(:name => "yay", :ensure => "1.0") }.should raise_error(Puppet::Error)
end
- it "should only accept files and URLs as values to :source" do
- proc { Puppet::Type::Package.create(:name => "yay", :source => "stuff") }.should raise_error(Puppet::Error)
+ it "should accept any string as an argument to :source" do
+ proc { Puppet::Type::Package.create(:name => "yay", :source => "stuff") }.should_not raise_error(Puppet::Error)
end
end
module PackageEvaluationTesting
- def setup
+ def setprops(properties)
+ @provider.stubs(:properties).returns(properties)
+ end
+end
+
+describe Puppet::Type::Package do
+ before :each do
@provider = stub 'provider', :class => Puppet::Type::Package.defaultprovider, :clear => nil, :satisfies? => true, :name => :mock
Puppet::Type::Package.defaultprovider.stubs(:new).returns(@provider)
@package = Puppet::Type::Package.create(:name => "yay")
@@ -107,129 +113,125 @@ module PackageEvaluationTesting
@catalog.add_resource(@package)
end
- def setprops(properties)
- @provider.stubs(:properties).returns(properties)
- end
-end
-
-describe Puppet::Type::Package, "when it should be purged" do
- include PackageEvaluationTesting
+ describe Puppet::Type::Package, "when it should be purged" do
+ include PackageEvaluationTesting
- before { @package[:ensure] = :purged }
+ before { @package[:ensure] = :purged }
- it "should do nothing if it is :purged" do
- @provider.expects(:properties).returns(:ensure => :purged)
- @catalog.apply
- end
-
- [:absent, :installed, :present, :latest].each do |state|
- it "should purge if it is #{state.to_s}" do
- @provider.stubs(:properties).returns(:ensure => state)
- @provider.expects(:purge)
+ it "should do nothing if it is :purged" do
+ @provider.expects(:properties).returns(:ensure => :purged)
@catalog.apply
end
+
+ [:absent, :installed, :present, :latest].each do |state|
+ it "should purge if it is #{state.to_s}" do
+ @provider.stubs(:properties).returns(:ensure => state)
+ @provider.expects(:purge)
+ @catalog.apply
+ end
+ end
end
-end
-describe Puppet::Type::Package, "when it should be absent" do
- include PackageEvaluationTesting
+ describe Puppet::Type::Package, "when it should be absent" do
+ include PackageEvaluationTesting
- before { @package[:ensure] = :absent }
+ before { @package[:ensure] = :absent }
- [:purged, :absent].each do |state|
- it "should do nothing if it is #{state.to_s}" do
- @provider.expects(:properties).returns(:ensure => state)
- @catalog.apply
+ [:purged, :absent].each do |state|
+ it "should do nothing if it is #{state.to_s}" do
+ @provider.expects(:properties).returns(:ensure => state)
+ @catalog.apply
+ end
end
- end
- [:installed, :present, :latest].each do |state|
- it "should uninstall if it is #{state.to_s}" do
- @provider.stubs(:properties).returns(:ensure => state)
- @provider.expects(:uninstall)
- @catalog.apply
+ [:installed, :present, :latest].each do |state|
+ it "should uninstall if it is #{state.to_s}" do
+ @provider.stubs(:properties).returns(:ensure => state)
+ @provider.expects(:uninstall)
+ @catalog.apply
+ end
end
end
-end
-describe Puppet::Type::Package, "when it should be present" do
- include PackageEvaluationTesting
+ describe Puppet::Type::Package, "when it should be present" do
+ include PackageEvaluationTesting
- before { @package[:ensure] = :present }
+ before { @package[:ensure] = :present }
- [:present, :latest, "1.0"].each do |state|
- it "should do nothing if it is #{state.to_s}" do
- @provider.expects(:properties).returns(:ensure => state)
- @catalog.apply
+ [:present, :latest, "1.0"].each do |state|
+ it "should do nothing if it is #{state.to_s}" do
+ @provider.expects(:properties).returns(:ensure => state)
+ @catalog.apply
+ end
end
- end
- [:purged, :absent].each do |state|
- it "should install if it is #{state.to_s}" do
- @provider.stubs(:properties).returns(:ensure => state)
- @provider.expects(:install)
- @catalog.apply
+ [:purged, :absent].each do |state|
+ it "should install if it is #{state.to_s}" do
+ @provider.stubs(:properties).returns(:ensure => state)
+ @provider.expects(:install)
+ @catalog.apply
+ end
end
end
-end
-describe Puppet::Type::Package, "when it should be latest" do
- include PackageEvaluationTesting
+ describe Puppet::Type::Package, "when it should be latest" do
+ include PackageEvaluationTesting
- before { @package[:ensure] = :latest }
+ before { @package[:ensure] = :latest }
- [:purged, :absent].each do |state|
- it "should upgrade if it is #{state.to_s}" do
- @provider.stubs(:properties).returns(:ensure => state)
+ [:purged, :absent].each do |state|
+ it "should upgrade if it is #{state.to_s}" do
+ @provider.stubs(:properties).returns(:ensure => state)
+ @provider.expects(:update)
+ @catalog.apply
+ end
+ end
+
+ it "should upgrade if the current version is not equal to the latest version" do
+ @provider.stubs(:properties).returns(:ensure => "1.0")
+ @provider.stubs(:latest).returns("2.0")
@provider.expects(:update)
@catalog.apply
end
- end
- it "should upgrade if the current version is not equal to the latest version" do
- @provider.stubs(:properties).returns(:ensure => "1.0")
- @provider.stubs(:latest).returns("2.0")
- @provider.expects(:update)
- @catalog.apply
- end
+ it "should do nothing if it is equal to the latest version" do
+ @provider.stubs(:properties).returns(:ensure => "1.0")
+ @provider.stubs(:latest).returns("1.0")
+ @provider.expects(:update).never
+ @catalog.apply
+ end
- it "should do nothing if it is equal to the latest version" do
- @provider.stubs(:properties).returns(:ensure => "1.0")
- @provider.stubs(:latest).returns("1.0")
- @provider.expects(:update).never
- @catalog.apply
+ it "should do nothing if the provider returns :present as the latest version" do
+ @provider.stubs(:properties).returns(:ensure => :present)
+ @provider.stubs(:latest).returns("1.0")
+ @provider.expects(:update).never
+ @catalog.apply
+ end
end
- it "should do nothing if the provider returns :present as the latest version" do
- @provider.stubs(:properties).returns(:ensure => :present)
- @provider.stubs(:latest).returns("1.0")
- @provider.expects(:update).never
- @catalog.apply
- end
-end
+ describe Puppet::Type::Package, "when it should be a specific version" do
+ include PackageEvaluationTesting
-describe Puppet::Type::Package, "when it should be a specific version" do
- include PackageEvaluationTesting
+ before { @package[:ensure] = "1.0" }
- before { @package[:ensure] = "1.0" }
+ [:purged, :absent].each do |state|
+ it "should install if it is #{state.to_s}" do
+ @provider.stubs(:properties).returns(:ensure => state)
+ @provider.expects(:install)
+ @catalog.apply
+ end
+ end
- [:purged, :absent].each do |state|
- it "should install if it is #{state.to_s}" do
- @provider.stubs(:properties).returns(:ensure => state)
- @provider.expects(:install)
+ it "should do nothing if the current version is equal to the desired version" do
+ @provider.stubs(:properties).returns(:ensure => "1.0")
+ @provider.expects(:install).never
@catalog.apply
end
- end
- it "should do nothing if the current version is equal to the desired version" do
- @provider.stubs(:properties).returns(:ensure => "1.0")
- @provider.expects(:install).never
- @catalog.apply
- end
-
- it "should install if the current version is not equal to the specified version" do
- @provider.stubs(:properties).returns(:ensure => "2.0")
- @provider.expects(:install)
- @catalog.apply
+ it "should install if the current version is not equal to the specified version" do
+ @provider.stubs(:properties).returns(:ensure => "2.0")
+ @provider.expects(:install)
+ @catalog.apply
+ end
end
end
diff --git a/spec/unit/ral/type/schedule.rb b/spec/unit/ral/type/schedule.rb
new file mode 100755
index 000000000..e53138c5e
--- /dev/null
+++ b/spec/unit/ral/type/schedule.rb
@@ -0,0 +1,335 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/type/schedule'
+
+module ScheduleTesting
+
+ def format(time)
+ time.strftime("%H:%M:%S")
+ end
+
+ def diff(unit, incr, method, count)
+ diff = Time.now.to_i.send(method, incr * count)
+ Time.at(diff)
+ end
+
+ def month(method, count)
+ diff(:hour, 3600 * 24 * 30, method, count)
+ end
+
+ def week(method, count)
+ diff(:hour, 3600 * 24 * 7, method, count)
+ end
+
+ def day(method, count)
+ diff(:hour, 3600 * 24, method, count)
+ end
+
+ def hour(method, count)
+ diff(:hour, 3600, method, count)
+ end
+
+ def min(method, count)
+ diff(:min, 60, method, count)
+ end
+
+ def sec(method, count)
+ diff(:sec, 1, method, count)
+ end
+
+end
+
+describe Puppet::Type::Schedule do
+ before :each do
+ Puppet.settings.stubs(:value).with(:ignoreschedules).returns(false)
+
+ @schedule = Puppet::Type::Schedule.create(:name => "testing")
+ end
+
+ describe Puppet::Type::Schedule do
+ include ScheduleTesting
+
+ it "should default to :distance for period-matching" do
+ @schedule[:periodmatch].should == :distance
+ end
+
+ it "should default to a :repeat of 1" do
+ @schedule[:repeat].should == 1
+ end
+
+ it "should never match when the period is :never" do
+ @schedule[:period] = :never
+ @schedule.match?.should be_false
+ end
+ end
+
+ describe Puppet::Type::Schedule, "when producing default schedules" do
+ include ScheduleTesting
+
+ %w{hourly daily weekly monthly never}.each do |period|
+ period = period.to_sym
+ it "should produce a #{period} schedule with the period set appropriately" do
+ schedules = Puppet::Type::Schedule.mkdefaultschedules
+ schedules.find { |s| s[:name] == period.to_s and s[:period] == period }.should be_instance_of(Puppet::Type::Schedule)
+ end
+ end
+
+ it "should produce a schedule named puppet with a period of hourly and a repeat of 2" do
+ schedules = Puppet::Type::Schedule.mkdefaultschedules
+ schedules.find { |s|
+ s[:name] == "puppet" and s[:period] == :hourly and s[:repeat] == 2
+ }.should be_instance_of(Puppet::Type::Schedule)
+ end
+ end
+
+ describe Puppet::Type::Schedule, "when matching ranges" do
+ include ScheduleTesting
+
+ it "should match when the start time is before the current time and the end time is after the current time" do
+ @schedule[:range] = "%s - %s" % [format(Time.now - 10), format(Time.now + 10)]
+ @schedule.match?.should be_true
+ end
+
+ it "should not match when the start time is after the current time" do
+ @schedule[:range] = "%s - %s" % [format(Time.now + 5), format(Time.now + 10)]
+ @schedule.match?.should be_false
+ end
+
+ it "should not match when the end time is previous to the current time" do
+ @schedule[:range] = "%s - %s" % [format(Time.now - 10), format(Time.now - 5)]
+ @schedule.match?.should be_false
+ end
+ end
+
+ describe Puppet::Type::Schedule, "when matching hourly by distance" do
+ include ScheduleTesting
+
+ before do
+ @schedule[:period] = :hourly
+ @schedule[:periodmatch] = :distance
+ end
+
+ it "should match an hour ago" do
+ @schedule.match?(hour("-", 1)).should be_true
+ end
+
+ it "should not match now" do
+ @schedule.match?(Time.now).should be_false
+ end
+
+ it "should not match 59 minutes ago" do
+ @schedule.match?(min("-", 59)).should be_false
+ end
+ end
+
+ describe Puppet::Type::Schedule, "when matching daily by distance" do
+ include ScheduleTesting
+
+ before do
+ @schedule[:period] = :daily
+ @schedule[:periodmatch] = :distance
+ end
+
+ it "should match when the previous time was one day ago" do
+ @schedule.match?(day("-", 1)).should be_true
+ end
+
+ it "should not match when the previous time is now" do
+ @schedule.match?(Time.now).should be_false
+ end
+
+ it "should not match when the previous time was 23 hours ago" do
+ @schedule.match?(hour("-", 23)).should be_false
+ end
+ end
+
+ describe Puppet::Type::Schedule, "when matching weekly by distance" do
+ include ScheduleTesting
+
+ before do
+ @schedule[:period] = :weekly
+ @schedule[:periodmatch] = :distance
+ end
+
+ it "should match seven days ago" do
+ @schedule.match?(day("-", 7)).should be_true
+ end
+
+ it "should not match now" do
+ @schedule.match?(Time.now).should be_false
+ end
+
+ it "should not match six days ago" do
+ @schedule.match?(day("-", 6)).should be_false
+ end
+ end
+
+ describe Puppet::Type::Schedule, "when matching monthly by distance" do
+ include ScheduleTesting
+
+ before do
+ @schedule[:period] = :monthly
+ @schedule[:periodmatch] = :distance
+ end
+
+ it "should match 32 days ago" do
+ @schedule.match?(day("-", 32)).should be_true
+ end
+
+ it "should not match now" do
+ @schedule.match?(Time.now).should be_false
+ end
+
+ it "should not match 27 days ago" do
+ @schedule.match?(day("-", 27)).should be_false
+ end
+ end
+
+ describe Puppet::Type::Schedule, "when matching hourly by number" do
+ include ScheduleTesting
+
+ before do
+ @schedule[:period] = :hourly
+ @schedule[:periodmatch] = :number
+ end
+
+ it "should match if the times are one minute apart and the current minute is 0" do
+ current = Time.now
+
+ # Subtract an hour, reset the minute to zero, then add 59 minutes, so we're the previous hour plus 59 minutes.
+ previous = (current - 3600 - (current.min * 60) + (59 * 60))
+
+ # Now set the "current" time to the zero minute of the current hour.
+ now = (current - (current.min * 60))
+ Time.stubs(:now).returns(now)
+ @schedule.match?(previous).should be_true
+ end
+
+ it "should not match if the times are 58 minutes apart and the current minute is 59" do
+ current = Time.now
+
+ # reset the minute to zero
+ previous = current - (current.min * 60)
+
+ # Now set the "current" time to the 59th minute of the current hour.
+ now = (current - (current.min * 60) + (59 * 60))
+ Time.stubs(:now).returns(now)
+ @schedule.match?(previous).should be_false
+ end
+ end
+
+ describe Puppet::Type::Schedule, "when matching daily by number" do
+ include ScheduleTesting
+
+ before do
+ @schedule[:period] = :daily
+ @schedule[:periodmatch] = :number
+ end
+
+ it "should match if the times are one minute apart and the current minute and hour are 0" do
+ zero = Time.now
+
+ # Reset the current time to X:00:00
+ current = zero - (zero.hour * 3600) - (zero.min * 60) - zero.sec
+
+ # Now set the previous time to one minute before that
+ previous = current - 60
+
+ Time.stubs(:now).returns(current)
+ @schedule.match?(previous).should be_true
+ end
+
+ it "should not match if the times are 23 hours and 58 minutes apart and the current hour is 23 and the current minute is 59" do
+ zero = Time.now
+
+ # Reset the previous time to 00:00:00
+ previous = zero - (zero.hour * 3600) - (zero.min * 60) - zero.sec
+
+ # Set the current time to 23:59
+ now = previous + (23 * 3600) + (59 * 60)
+
+ Time.stubs(:now).returns(now)
+ @schedule.match?(previous).should be_false
+ end
+ end
+
+ describe Puppet::Type::Schedule, "when matching weekly by number" do
+ include ScheduleTesting
+
+ before do
+ @schedule[:period] = :weekly
+ @schedule[:periodmatch] = :number
+ end
+
+ it "should match if the previous time is prior to the most recent Sunday" do
+ now = Time.now
+
+ # Subtract the number days we've progressed into the week, plus one because we're zero-indexed.
+ previous = now - (3600 * 24 * (now.wday + 1))
+
+ @schedule.match?(previous).should be_true
+ end
+
+ it "should not match if the previous time is after the most recent Saturday" do
+ now = Time.now
+
+ # Subtract the number days we've progressed into the week
+ previous = now - (3600 * 24 * now.wday)
+
+ @schedule.match?(previous).should be_false
+ end
+ end
+
+ describe Puppet::Type::Schedule, "when matching monthly by number" do
+ include ScheduleTesting
+
+ before do
+ @schedule[:period] = :monthly
+ @schedule[:periodmatch] = :number
+ end
+
+ it "should match when the previous time is prior to the first day of this month" do
+ now = Time.now
+
+ # Subtract the number days we've progressed into the month
+ previous = now - (3600 * 24 * now.day)
+
+ @schedule.match?(previous).should be_true
+ end
+
+ it "should not match when the previous time is after the last day of last month" do
+ now = Time.now
+
+ # Subtract the number days we've progressed into the month, minus one
+ previous = now - (3600 * 24 * (now.day - 1))
+
+ @schedule.match?(previous).should be_false
+ end
+ end
+
+ describe Puppet::Type::Schedule, "when matching with a repeat greater than one" do
+ include ScheduleTesting
+
+ before do
+ @schedule[:period] = :daily
+ @schedule[:repeat] = 2
+ end
+
+ it "should fail if the periodmatch is 'number'" do
+ @schedule[:periodmatch] = :number
+ proc { @schedule[:repeat] = 2 }.should raise_error(Puppet::Error)
+ end
+
+ it "should match if the previous run was further away than the distance divided by the repeat" do
+ previous = Time.now - (3600 * 13)
+ @schedule.match?(previous).should be_true
+ end
+
+ it "should not match if the previous run was closer than the distance divided by the repeat" do
+ previous = Time.now - (3600 * 11)
+ @schedule.match?(previous).should be_false
+ end
+ end
+end
diff --git a/spec/unit/ral/types/service.rb b/spec/unit/ral/type/service.rb
index 3944f146c..17cb2105d 100755
--- a/spec/unit/ral/types/service.rb
+++ b/spec/unit/ral/type/service.rb
@@ -15,7 +15,7 @@ describe Puppet::Type::Service do
end
describe Puppet::Type::Service, "when validating attributes" do
- [:name, :binary, :hasstatus, :path, :pattern, :start, :restart, :stop, :status, :hasrestart].each do |param|
+ [:name, :binary, :hasstatus, :path, :pattern, :start, :restart, :stop, :status, :hasrestart, :control].each do |param|
it "should have a #{param} parameter" do
Puppet::Type::Service.attrtype(param).should == :param
end
@@ -30,7 +30,7 @@ end
describe Puppet::Type::Service, "when validating attribute values" do
before do
- @provider = stub 'provider', :class => Puppet::Type::Service.defaultprovider, :clear => nil
+ @provider = stub 'provider', :class => Puppet::Type::Service.defaultprovider, :clear => nil, :controllable? => false
Puppet::Type::Service.defaultprovider.stubs(:new).returns(@provider)
end
@@ -130,15 +130,22 @@ describe Puppet::Type::Service, "when setting default attribute values" do
svc[:path].should == ["testing"]
end
- it "should default to the binary for the pattern if one is provided" do
+ it "should default 'pattern' to the binary if one is provided" do
svc = Puppet::Type::Service.create(:name => "other", :binary => "/some/binary")
svc[:pattern].should == "/some/binary"
end
- it "should default to the name for the pattern if no pattern is provided" do
+ it "should default 'pattern' to the name if no pattern is provided" do
svc = Puppet::Type::Service.create(:name => "other")
svc[:pattern].should == "other"
end
+
+ it "should default 'control' to the upcased service name with periods replaced by underscores if the provider supports the 'controllable' feature" do
+ provider = stub 'provider', :controllable? => true, :class => Puppet::Type::Service.defaultprovider, :clear => nil
+ Puppet::Type::Service.defaultprovider.stubs(:new).returns(provider)
+ svc = Puppet::Type::Service.create(:name => "nfs.client")
+ svc[:control].should == "NFS_CLIENT_START"
+ end
end
describe Puppet::Type::Service, "when retrieving the host's current state" do
diff --git a/spec/unit/ral/types/user.rb b/spec/unit/ral/type/user.rb
index 4e43a8ceb..4e43a8ceb 100755
--- a/spec/unit/ral/types/user.rb
+++ b/spec/unit/ral/type/user.rb
diff --git a/spec/unit/ral/types/file.rb b/spec/unit/ral/types/file.rb
deleted file mode 100755
index 5ade79012..000000000
--- a/spec/unit/ral/types/file.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/usr/bin/env ruby
-
-require File.dirname(__FILE__) + '/../../../spec_helper'
-
-require 'puppet/type/pfile'
-
-describe Puppet::Type::File, " when used with replace=>false and content" do
- before do
- @path = Tempfile.new("puppetspec")
- @path.close!()
- @path = @path.path
- @file = Puppet::Type::File.create( { :name => @path, :content => "foo", :replace => :false } )
- end
-
- it "should be insync if the file exists and the content is different" do
- File.open(@path, "w") do |f| f.puts "bar" end
- @file.property(:content).insync?("bar").should be_true
- end
-
- it "should be insync if the file exists and the content is right" do
- File.open(@path, "w") do |f| f.puts "foo" end
- @file.property(:content).insync?("foo").should be_true
- end
-
- it "should not be insync if the file doesnot exist" do
- @file.property(:content).insync?(:nil).should be_false
- end
-end
diff --git a/spec/unit/ral/types/mount.rb b/spec/unit/ral/types/mount.rb
deleted file mode 100755
index 5965908cb..000000000
--- a/spec/unit/ral/types/mount.rb
+++ /dev/null
@@ -1,187 +0,0 @@
-#!/usr/bin/env ruby
-
-require File.dirname(__FILE__) + '/../../../spec_helper'
-
-require 'puppet/type/mount'
-
-describe Puppet::Type::Mount do
- it "should have a :refreshable feature that requires the :remount method" do
- Puppet::Type::Mount.provider_feature(:refreshable).methods.should == [:remount]
- end
-
- it "should have no default value for :ensure" do
- mount = Puppet::Type::Mount.create(:name => "yay")
- mount.should(:ensure).should be_nil
- end
-end
-
-describe Puppet::Type::Mount, "when validating attributes" do
- [:name, :remounts].each do |param|
- it "should have a #{param} parameter" do
- Puppet::Type::Mount.attrtype(param).should == :param
- end
- end
-
- [:ensure, :device, :blockdevice, :fstype, :options, :pass, :dump, :atboot, :target].each do |param|
- it "should have a #{param} property" do
- Puppet::Type::Mount.attrtype(param).should == :property
- end
- end
-end
-
-describe Puppet::Type::Mount::Ensure, "when validating values" do
- before do
- @provider = stub 'provider', :class => Puppet::Type::Mount.defaultprovider, :clear => nil
- Puppet::Type::Mount.defaultprovider.expects(:new).returns(@provider)
- end
-
- it "should support :present as a value to :ensure" do
- Puppet::Type::Mount.create(:name => "yay", :ensure => :present)
- end
-
- it "should alias :unmounted to :present as a value to :ensure" do
- mount = Puppet::Type::Mount.create(:name => "yay", :ensure => :unmounted)
- mount.should(:ensure).should == :present
- end
-
- it "should support :absent as a value to :ensure" do
- Puppet::Type::Mount.create(:name => "yay", :ensure => :absent)
- end
-
- it "should support :mounted as a value to :ensure" do
- Puppet::Type::Mount.create(:name => "yay", :ensure => :mounted)
- end
-end
-
-module MountEvaluationTesting
- def setup
- @provider = stub 'provider', :class => Puppet::Type::Mount.defaultprovider, :clear => nil, :satisfies? => true, :name => :mock
- Puppet::Type::Mount.defaultprovider.stubs(:new).returns(@provider)
- @mount = Puppet::Type::Mount.create(:name => "yay", :check => :ensure)
-
- @ensure = @mount.property(:ensure)
- end
-
- def mount_stub(params)
- Puppet::Type::Mount.validproperties.each do |prop|
- unless params[prop]
- params[prop] = :absent
- @mount[prop] = :absent
- end
- end
-
- params.each do |param, value|
- @provider.stubs(param).returns(value)
- end
- end
-end
-
-describe Puppet::Type::Mount::Ensure, "when retrieving its current state" do
- include MountEvaluationTesting
-
- it "should return the provider's value if it is :absent" do
- @provider.expects(:ensure).returns(:absent)
- @ensure.retrieve.should == :absent
- end
-
- it "should return :mounted if the provider indicates it is mounted and the value is not :absent" do
- @provider.expects(:ensure).returns(:present)
- @provider.expects(:mounted?).returns(true)
- @ensure.retrieve.should == :mounted
- end
-
- it "should return :present if the provider indicates it is not mounted and the value is not :absent" do
- @provider.expects(:ensure).returns(:present)
- @provider.expects(:mounted?).returns(false)
- @ensure.retrieve.should == :present
- end
-end
-
-describe Puppet::Type::Mount::Ensure, "when changing the host" do
- include MountEvaluationTesting
-
- it "should destroy itself if it should be absent" do
- @provider.stubs(:mounted?).returns(false)
- @provider.expects(:destroy)
- @ensure.should = :absent
- @ensure.sync
- end
-
- it "should unmount itself before destroying if it is mounted and should be absent" do
- @provider.expects(:mounted?).returns(true)
- @provider.expects(:unmount)
- @provider.expects(:destroy)
- @ensure.should = :absent
- @ensure.sync
- end
-
- it "should create itself if it is absent and should be present" do
- @provider.stubs(:mounted?).returns(false)
- @provider.expects(:create)
- @ensure.should = :present
- @ensure.sync
- end
-
- it "should unmount itself if it is mounted and should be present" do
- @provider.stubs(:mounted?).returns(true)
-
- # The interface here is just too much work to test right now.
- @ensure.stubs(:syncothers)
- @provider.expects(:unmount)
- @ensure.should = :present
- @ensure.sync
- end
-
- it "should create and mount itself if it does not exist and should be mounted" do
- @provider.stubs(:ensure).returns(:absent)
- @provider.stubs(:mounted?).returns(false)
- @provider.expects(:create)
- @ensure.stubs(:syncothers)
- @provider.expects(:mount)
- @ensure.should = :mounted
- @ensure.sync
- end
-
- it "should mount itself if it is present and should be mounted" do
- @provider.stubs(:ensure).returns(:present)
- @provider.stubs(:mounted?).returns(false)
- @ensure.stubs(:syncothers)
- @provider.expects(:mount)
- @ensure.should = :mounted
- @ensure.sync
- end
-
- it "should create but not mount itself if it is absent and mounted and should be mounted" do
- @provider.stubs(:ensure).returns(:absent)
- @provider.stubs(:mounted?).returns(true)
- @ensure.stubs(:syncothers)
- @provider.expects(:create)
- @ensure.should = :mounted
- @ensure.sync
- end
-end
-
-describe Puppet::Type::Mount, "when responding to events" do
- include MountEvaluationTesting
-
- it "should remount if it is currently mounted" do
- @provider.expects(:mounted?).returns(true)
- @provider.expects(:remount)
-
- @mount.refresh
- end
-
- it "should not remount if it is not currently mounted" do
- @provider.expects(:mounted?).returns(false)
- @provider.expects(:remount).never
-
- @mount.refresh
- end
-
- it "should not remount swap filesystems" do
- @mount[:fstype] = "swap"
- @provider.expects(:remount).never
-
- @mount.refresh
- end
-end
diff --git a/spec/unit/ral/types/schedule.rb b/spec/unit/ral/types/schedule.rb
deleted file mode 100755
index 856a73186..000000000
--- a/spec/unit/ral/types/schedule.rb
+++ /dev/null
@@ -1,370 +0,0 @@
-#!/usr/bin/env ruby
-
-require File.dirname(__FILE__) + '/../../../spec_helper'
-
-require 'puppet/type/schedule'
-
-module ScheduleTesting
- def setup
- Puppet.settings.stubs(:value).with(:ignoreschedules).returns(false)
-
- @schedule = Puppet::Type::Schedule.create(:name => "testing")
- end
-
- def format(time)
- time.strftime("%H:%M:%S")
- end
-
- def diff(unit, incr, method, count)
- diff = Time.now.to_i.send(method, incr * count)
- Time.at(diff)
- end
-
- def month(method, count)
- diff(:hour, 3600 * 24 * 30, method, count)
- end
-
- def week(method, count)
- diff(:hour, 3600 * 24 * 7, method, count)
- end
-
- def day(method, count)
- diff(:hour, 3600 * 24, method, count)
- end
-
- def hour(method, count)
- diff(:hour, 3600, method, count)
- end
-
- def min(method, count)
- diff(:min, 60, method, count)
- end
-
- def sec(method, count)
- diff(:sec, 1, method, count)
- end
-end
-
-describe Puppet::Type::Schedule do
- include ScheduleTesting
-
- it "should default to :distance for period-matching" do
- @schedule[:periodmatch].should == :distance
- end
-
- it "should default to a :repeat of 1" do
- @schedule[:repeat].should == 1
- end
-
- it "should never match when the period is :never" do
- @schedule[:period] = :never
- @schedule.match?.should be_false
- end
-end
-
-describe Puppet::Type::Schedule, "when producing default schedules" do
- include ScheduleTesting
-
- %w{hourly daily weekly monthly never}.each do |period|
- period = period.to_sym
- it "should produce a #{period} schedule with the period set appropriately" do
- schedules = Puppet::Type::Schedule.mkdefaultschedules
- schedules.find { |s| s[:name] == period.to_s and s[:period] == period }.should be_instance_of(Puppet::Type::Schedule)
- end
- end
-
- it "should produce a schedule named puppet with a period of hourly and a repeat of 2" do
- schedules = Puppet::Type::Schedule.mkdefaultschedules
- schedules.find { |s|
- s[:name] == "puppet" and s[:period] == :hourly and s[:repeat] == 2
- }.should be_instance_of(Puppet::Type::Schedule)
- end
-end
-
-describe Puppet::Type::Schedule, "when matching ranges" do
- include ScheduleTesting
-
- it "should match when the start time is before the current time and the end time is after the current time" do
- @schedule[:range] = "%s - %s" % [format(Time.now - 10), format(Time.now + 10)]
- @schedule.match?.should be_true
- end
-
- it "should not match when the start time is after the current time" do
- @schedule[:range] = "%s - %s" % [format(Time.now + 5), format(Time.now + 10)]
- @schedule.match?.should be_false
- end
-
- it "should not match when the end time is previous to the current time" do
- @schedule[:range] = "%s - %s" % [format(Time.now - 10), format(Time.now - 5)]
- @schedule.match?.should be_false
- end
-end
-
-describe Puppet::Type::Schedule, "when matching hourly by distance" do
- include ScheduleTesting
-
- before do
- @schedule[:period] = :hourly
- @schedule[:periodmatch] = :distance
- end
-
- it "should match an hour ago" do
- @schedule.match?(hour("-", 1)).should be_true
- end
-
- it "should not match now" do
- @schedule.match?(Time.now).should be_false
- end
-
- it "should not match 59 minutes ago" do
- @schedule.match?(min("-", 59)).should be_false
- end
-end
-
-describe Puppet::Type::Schedule, "when matching daily by distance" do
- include ScheduleTesting
-
- before do
- @schedule[:period] = :daily
- @schedule[:periodmatch] = :distance
- end
-
- it "should match when the previous time was one day ago" do
- @schedule.match?(day("-", 1)).should be_true
- end
-
- it "should not match when the previous time is now" do
- @schedule.match?(Time.now).should be_false
- end
-
- it "should not match when the previous time was 23 hours ago" do
- @schedule.match?(hour("-", 23)).should be_false
- end
-end
-
-describe Puppet::Type::Schedule, "when matching weekly by distance" do
- include ScheduleTesting
-
- before do
- @schedule[:period] = :weekly
- @schedule[:periodmatch] = :distance
- end
-
- it "should match seven days ago" do
- @schedule.match?(day("-", 7)).should be_true
- end
-
- it "should not match now" do
- @schedule.match?(Time.now).should be_false
- end
-
- it "should not match six days ago" do
- @schedule.match?(day("-", 6)).should be_false
- end
-end
-
-describe Puppet::Type::Schedule, "when matching monthly by distance" do
- include ScheduleTesting
-
- before do
- @schedule[:period] = :monthly
- @schedule[:periodmatch] = :distance
- end
-
- it "should match 32 days ago" do
- @schedule.match?(day("-", 32)).should be_true
- end
-
- it "should not match now" do
- @schedule.match?(Time.now).should be_false
- end
-
- it "should not match 27 days ago" do
- @schedule.match?(day("-", 27)).should be_false
- end
-end
-
-describe Puppet::Type::Schedule, "when matching hourly by number" do
- include ScheduleTesting
-
- before do
- @schedule[:period] = :hourly
- @schedule[:periodmatch] = :number
- end
-
- it "should match if the times are one minute apart and the current minute is 0" do
- current = Time.now
-
- # Subtract an hour, reset the minute to zero, then add 59 minutes, so we're the previous hour plus 59 minutes.
- previous = (current - 3600 - (current.min * 60) + (59 * 60))
-
- # Now set the "current" time to the zero minute of the current hour.
- now = (current - (current.min * 60))
- Time.stubs(:now).returns(now)
- @schedule.match?(previous).should be_true
- end
-
- it "should not match if the times are 58 minutes apart and the current minute is 59" do
- current = Time.now
-
- # reset the minute to zero
- previous = current - (current.min * 60)
-
- # Now set the "current" time to the 59th minute of the current hour.
- now = (current - (current.min * 60) + (59 * 60))
- Time.stubs(:now).returns(now)
- @schedule.match?(previous).should be_false
- end
-end
-
-describe Puppet::Type::Schedule, "when matching daily by number" do
- include ScheduleTesting
-
- before do
- @schedule[:period] = :daily
- @schedule[:periodmatch] = :number
- end
-
- it "should match if the times are one minute apart and the current minute and hour are 0" do
- zero = Time.now
-
- # Reset the current time to X:00:00
- current = zero - (zero.hour * 3600) - (zero.min * 60) - zero.sec
-
- # Now set the previous time to one minute before that
- previous = current - 60
-
- Time.stubs(:now).returns(current)
- @schedule.match?(previous).should be_true
- end
-
- it "should not match if the times are 23 hours and 58 minutes apart and the current hour is 23 and the current minute is 59" do
- zero = Time.now
-
- # Reset the previous time to 00:00:00
- previous = zero - (zero.hour * 3600) - (zero.min * 60) - zero.sec
-
- # Set the current time to 23:59
- now = previous + (23 * 3600) + (59 * 60)
-
- Time.stubs(:now).returns(now)
- @schedule.match?(previous).should be_false
- end
-end
-
-describe Puppet::Type::Schedule, "when matching weekly by number" do
- include ScheduleTesting
-
- before do
- @schedule[:period] = :weekly
- @schedule[:periodmatch] = :number
- end
-
- it "should match if the previous time is prior to the most recent Sunday" do
- now = Time.now
-
- # Subtract the number days we've progressed into the week, plus one because we're zero-indexed.
- previous = now - (3600 * 24 * (now.wday + 1))
-
- @schedule.match?(previous).should be_true
- end
-
- it "should not match if the previous time is after the most recent Saturday" do
- now = Time.now
-
- # Subtract the number days we've progressed into the week
- previous = now - (3600 * 24 * now.wday)
-
- @schedule.match?(previous).should be_false
- end
-end
-
-describe Puppet::Type::Schedule, "when matching monthly by number" do
- include ScheduleTesting
-
- before do
- @schedule[:period] = :monthly
- @schedule[:periodmatch] = :number
- end
-
- it "should match when the previous time is prior to the first day of this month" do
- now = Time.now
-
- # Subtract the number days we've progressed into the month
- previous = now - (3600 * 24 * now.day)
-
- @schedule.match?(previous).should be_true
- end
-
- it "should not match when the previous time is after the last day of last month" do
- now = Time.now
-
- # Subtract the number days we've progressed into the month, minus one
- previous = now - (3600 * 24 * (now.day - 1))
-
- @schedule.match?(previous).should be_false
- end
-end
-
-describe Puppet::Type::Schedule, "when matching with a repeat greater than one" do
- include ScheduleTesting
-
- before do
- @schedule[:period] = :daily
- @schedule[:repeat] = 2
- end
-
- it "should fail if the periodmatch is 'number'" do
- @schedule[:periodmatch] = :number
- proc { @schedule[:repeat] = 2 }.should raise_error(Puppet::Error)
- end
-
- it "should match if the previous run was further away than the distance divided by the repeat" do
- previous = Time.now - (3600 * 13)
- @schedule.match?(previous).should be_true
- end
-
- it "should not match if the previous run was closer than the distance divided by the repeat" do
- previous = Time.now - (3600 * 11)
- @schedule.match?(previous).should be_false
- end
-end
-
-module OldTesting
- def mksched
- @stype.create(:name => "testsched")
- end
-
- def test_period_with_repeat
- previous = @now
-
- s = mksched
- s[:period] = :hourly
-
- assert_nothing_raised("Was not able to set periodmatch") {
- s[:periodmatch] = :number
- }
- assert_raise(Puppet::Error) {
- s[:repeat] = 2
- }
- assert_nothing_raised("Was not able to reset periodmatch") {
- s[:periodmatch] = :distance
- }
-
- assert(! s.match?(min("-", 40)), "matched minus 40 minutes")
-
- assert_nothing_raised("Was not able to set period") {
- s[:repeat] = 2
- }
-
- assert(! s.match?(min("-", 20)), "matched minus 20 minutes with half-hourly")
- assert(s.match?(min("-", 40)), "Did not match minus 40 with half-hourly")
-
- assert_nothing_raised("Was not able to set period") {
- s[:repeat] = 3
- }
-
- assert(! s.match?(min("-", 15)), "matched minus 15 minutes with half-hourly")
- assert(s.match?(min("-", 25)), "Did not match minus 25 with half-hourly")
- end
-end
diff --git a/spec/unit/resource_reference.rb b/spec/unit/resource_reference.rb
index e629d0b82..ee71a5077 100755
--- a/spec/unit/resource_reference.rb
+++ b/spec/unit/resource_reference.rb
@@ -40,6 +40,12 @@ describe Puppet::ResourceReference do
ref.type.should == "Foo::Bar"
ref.title.should == "yay"
end
+
+ it "should interpret the title as a reference and assign appropriately if the type is nil and the title contains nested square brackets" do
+ ref = Puppet::ResourceReference.new(nil, "foo::bar[baz[yay]]")
+ ref.type.should == "Foo::Bar"
+ ref.title.should =="baz[yay]"
+ end
end
describe Puppet::ResourceReference, "when resolving resources with a catalog" do
diff --git a/spec/unit/simple_graph.rb b/spec/unit/simple_graph.rb
index 061a07458..e1e42e40f 100755
--- a/spec/unit/simple_graph.rb
+++ b/spec/unit/simple_graph.rb
@@ -9,8 +9,8 @@ require 'puppet/simple_graph'
describe Puppet::SimpleGraph do
it "should return the number of its vertices as its length" do
@graph = Puppet::SimpleGraph.new
- @graph.add_vertex!("one")
- @graph.add_vertex!("two")
+ @graph.add_vertex("one")
+ @graph.add_vertex("two")
@graph.size.should == 2
end
@@ -20,13 +20,13 @@ describe Puppet::SimpleGraph do
it "should provide a method for reversing the graph" do
@graph = Puppet::SimpleGraph.new
- @graph.add_edge!(:one, :two)
+ @graph.add_edge(:one, :two)
@graph.reversal.edge?(:two, :one).should be_true
end
it "should be able to produce a dot graph" do
@graph = Puppet::SimpleGraph.new
- @graph.add_edge!(:one, :two)
+ @graph.add_edge(:one, :two)
proc { @graph.to_dot_graph }.should_not raise_error
end
@@ -38,17 +38,17 @@ describe Puppet::SimpleGraph, " when managing vertices" do
end
it "should provide a method to add a vertex" do
- @graph.add_vertex!(:test)
+ @graph.add_vertex(:test)
@graph.vertex?(:test).should be_true
end
it "should ignore already-present vertices when asked to add a vertex" do
- @graph.add_vertex!(:test)
- proc { @graph.add_vertex!(:test) }.should_not raise_error
+ @graph.add_vertex(:test)
+ proc { @graph.add_vertex(:test) }.should_not raise_error
end
it "should return true when asked if a vertex is present" do
- @graph.add_vertex!(:test)
+ @graph.add_vertex(:test)
@graph.vertex?(:test).should be_true
end
@@ -57,15 +57,15 @@ describe Puppet::SimpleGraph, " when managing vertices" do
end
it "should return all set vertices when asked" do
- @graph.add_vertex!(:one)
- @graph.add_vertex!(:two)
+ @graph.add_vertex(:one)
+ @graph.add_vertex(:two)
@graph.vertices.length.should == 2
@graph.vertices.should include(:one)
@graph.vertices.should include(:two)
end
it "should remove a given vertex when asked" do
- @graph.add_vertex!(:one)
+ @graph.add_vertex(:one)
@graph.remove_vertex!(:one)
@graph.vertex?(:one).should be_false
end
@@ -86,49 +86,49 @@ describe Puppet::SimpleGraph, " when managing edges" do
it "should provide a method to add an edge as an instance of the edge class" do
edge = Puppet::Relationship.new(:one, :two)
- @graph.add_edge!(edge)
+ @graph.add_edge(edge)
@graph.edge?(:one, :two).should be_true
end
it "should provide a method to add an edge by specifying the two vertices" do
- @graph.add_edge!(:one, :two)
+ @graph.add_edge(:one, :two)
@graph.edge?(:one, :two).should be_true
end
it "should provide a method to add an edge by specifying the two vertices and a label" do
- @graph.add_edge!(:one, :two, :stuff => :awesome)
+ @graph.add_edge(:one, :two, :stuff => :awesome)
@graph.edge?(:one, :two).should be_true
end
it "should provide a method for retrieving an edge label" do
edge = Puppet::Relationship.new(:one, :two, :stuff => :awesome)
- @graph.add_edge!(edge)
+ @graph.add_edge(edge)
@graph.edge_label(:one, :two).should == {:stuff => :awesome}
end
it "should provide a method for retrieving an edge" do
edge = Puppet::Relationship.new(:one, :two)
- @graph.add_edge!(edge)
+ @graph.add_edge(edge)
@graph.edge(:one, :two).should equal(edge)
end
it "should add the edge source as a vertex if it is not already" do
edge = Puppet::Relationship.new(:one, :two)
- @graph.add_edge!(edge)
+ @graph.add_edge(edge)
@graph.vertex?(:one).should be_true
end
it "should add the edge target as a vertex if it is not already" do
edge = Puppet::Relationship.new(:one, :two)
- @graph.add_edge!(edge)
+ @graph.add_edge(edge)
@graph.vertex?(:two).should be_true
end
it "should return all edges as edge instances when asked" do
one = Puppet::Relationship.new(:one, :two)
two = Puppet::Relationship.new(:two, :three)
- @graph.add_edge!(one)
- @graph.add_edge!(two)
+ @graph.add_edge(one)
+ @graph.add_edge(two)
edges = @graph.edges
edges.length.should == 2
edges.should include(one)
@@ -137,7 +137,7 @@ describe Puppet::SimpleGraph, " when managing edges" do
it "should remove an edge when asked" do
edge = Puppet::Relationship.new(:one, :two)
- @graph.add_edge!(edge)
+ @graph.add_edge(edge)
@graph.remove_edge!(edge)
@graph.edge?(edge.source, edge.target).should be_false
end
@@ -145,8 +145,8 @@ describe Puppet::SimpleGraph, " when managing edges" do
it "should remove all related edges when a vertex is removed" do
one = Puppet::Relationship.new(:one, :two)
two = Puppet::Relationship.new(:two, :three)
- @graph.add_edge!(one)
- @graph.add_edge!(two)
+ @graph.add_edge(one)
+ @graph.add_edge(two)
@graph.remove_vertex!(:two)
@graph.edge?(:one, :two).should be_false
@graph.edge?(:two, :three).should be_false
@@ -160,9 +160,9 @@ describe Puppet::SimpleGraph, " when finding adjacent vertices" do
@one_two = Puppet::Relationship.new(:one, :two)
@two_three = Puppet::Relationship.new(:two, :three)
@one_three = Puppet::Relationship.new(:one, :three)
- @graph.add_edge!(@one_two)
- @graph.add_edge!(@one_three)
- @graph.add_edge!(@two_three)
+ @graph.add_edge(@one_two)
+ @graph.add_edge(@one_three)
+ @graph.add_edge(@two_three)
end
it "should return adjacent vertices" do
@@ -193,8 +193,8 @@ describe Puppet::SimpleGraph, " when clearing" do
@graph = Puppet::SimpleGraph.new
one = Puppet::Relationship.new(:one, :two)
two = Puppet::Relationship.new(:two, :three)
- @graph.add_edge!(one)
- @graph.add_edge!(two)
+ @graph.add_edge(one)
+ @graph.add_edge(two)
@graph.clear
end
@@ -214,18 +214,18 @@ describe Puppet::SimpleGraph, " when reversing graphs" do
end
it "should provide a method for reversing the graph" do
- @graph.add_edge!(:one, :two)
+ @graph.add_edge(:one, :two)
@graph.reversal.edge?(:two, :one).should be_true
end
it "should add all vertices to the reversed graph" do
- @graph.add_edge!(:one, :two)
+ @graph.add_edge(:one, :two)
@graph.vertex?(:one).should be_true
@graph.vertex?(:two).should be_true
end
it "should retain labels on edges" do
- @graph.add_edge!(:one, :two, :stuff => :awesome)
+ @graph.add_edge(:one, :two, :stuff => :awesome)
edge = @graph.reversal.edge(:two, :one)
edge.label.should == {:stuff => :awesome}
end
@@ -238,7 +238,7 @@ describe Puppet::SimpleGraph, " when sorting the graph" do
def add_edges(hash)
hash.each do |a,b|
- @graph.add_edge!(a, b)
+ @graph.add_edge(a, b)
end
end
@@ -266,4 +266,15 @@ describe Puppet::SimpleGraph, " when sorting the graph" do
add_edges :a => :b, :b => :e, :c => :a, :d => :c
proc { @graph.topsort }.should_not raise_error
end
+
+ # Our graph's add_edge method is smart enough not to add
+ # duplicate edges, so we use the objects, which it doesn't
+ # check.
+ it "should be able to sort graphs with duplicate edges" do
+ one = Puppet::Relationship.new(:a, :b)
+ @graph.add_edge(one)
+ two = Puppet::Relationship.new(:a, :b)
+ @graph.add_edge(two)
+ proc { @graph.topsort }.should_not raise_error
+ end
end
diff --git a/spec/unit/util/checksums.rb b/spec/unit/util/checksums.rb
new file mode 100755
index 000000000..0e0d06c0d
--- /dev/null
+++ b/spec/unit/util/checksums.rb
@@ -0,0 +1,99 @@
+#!/usr/bin/env ruby
+#
+# Created by Luke Kanies on 2007-9-22.
+# Copyright (c) 2007. All rights reserved.
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+require 'puppet/util/checksums'
+
+describe Puppet::Util::Checksums do
+ before do
+ @summer = Object.new
+ @summer.extend(Puppet::Util::Checksums)
+ end
+
+ content_sums = [:md5, :md5lite, :sha1, :sha1lite]
+ file_only = [:ctime, :mtime]
+
+ content_sums.each do |sumtype|
+ it "should be able to calculate %s sums from strings" % sumtype do
+ @summer.should be_respond_to(sumtype)
+ end
+ end
+
+ [content_sums, file_only].flatten.each do |sumtype|
+ it "should be able to calculate %s sums from files" % sumtype do
+ @summer.should be_respond_to(sumtype.to_s + "_file")
+ end
+ end
+
+ {:md5 => Digest::MD5, :sha1 => Digest::SHA1}.each do |sum, klass|
+ describe("when using %s" % sum) do
+ it "should use #{klass} to calculate string checksums" do
+ klass.expects(:hexdigest).with("mycontent").returns "whatever"
+ @summer.send(sum, "mycontent").should == "whatever"
+ end
+
+ it "should use incremental #{klass} sums to calculate file checksums" do
+ digest = mock 'digest'
+ klass.expects(:new).returns digest
+
+ file = "/path/to/my/file"
+
+ fh = mock 'filehandle'
+ fh.expects(:read).with(512).times(3).returns("firstline").then.returns("secondline").then.returns(nil)
+ #fh.expects(:read).with(512).returns("secondline")
+ #fh.expects(:read).with(512).returns(nil)
+
+ File.expects(:open).with(file, "r").yields(fh)
+
+ digest.expects(:<<).with "firstline"
+ digest.expects(:<<).with "secondline"
+ digest.expects(:hexdigest).returns :mydigest
+
+ @summer.send(sum.to_s + "_file", file).should == :mydigest
+ end
+ end
+ end
+
+ {:md5lite => Digest::MD5, :sha1lite => Digest::SHA1}.each do |sum, klass|
+ describe("when using %s" % sum) do
+ it "should use #{klass} to calculate string checksums from the first 512 characters of the string" do
+ content = "this is a test" * 100
+ klass.expects(:hexdigest).with(content[0..511]).returns "whatever"
+ @summer.send(sum, content).should == "whatever"
+ end
+
+ it "should use #{klass} to calculate a sum from the first 512 characters in the file" do
+ digest = mock 'digest'
+ klass.expects(:new).returns digest
+
+ file = "/path/to/my/file"
+
+ fh = mock 'filehandle'
+ fh.expects(:read).with(512).returns('my content')
+
+ File.expects(:open).with(file, "r").yields(fh)
+
+ digest.expects(:<<).with "my content"
+ digest.expects(:hexdigest).returns :mydigest
+
+ @summer.send(sum.to_s + "_file", file).should == :mydigest
+ end
+ end
+ end
+
+ [:ctime, :mtime].each do |sum|
+ describe("when using %s" % sum) do
+ it "should use the '#{sum}' on the file to determine the ctime" do
+ file = "/my/file"
+ stat = mock 'stat', sum => "mysum"
+
+ File.expects(:stat).with(file).returns(stat)
+
+ @summer.send(sum.to_s + "_file", file).should == "mysum"
+ end
+ end
+ end
+end
diff --git a/spec/unit/util/constant_inflector.rb b/spec/unit/util/constant_inflector.rb
new file mode 100755
index 000000000..5112e730f
--- /dev/null
+++ b/spec/unit/util/constant_inflector.rb
@@ -0,0 +1,70 @@
+#!/usr/bin/env ruby
+#
+# Created by Luke Kanies on 2008-02-12.
+# Copyright (c) 2007. All rights reserved.
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+require 'puppet/util/constant_inflector'
+
+describe Puppet::Util::ConstantInflector, "when converting file names to constants" do
+ before do
+ @inflector = Object.new
+ @inflector.extend(Puppet::Util::ConstantInflector)
+ end
+
+ it "should capitalize terms" do
+ @inflector.file2constant("file").should == "File"
+ end
+
+ it "should switch all '/' characters to double colons" do
+ @inflector.file2constant("file/other").should == "File::Other"
+ end
+
+ it "should remove underscores and capitalize the proceeding letter" do
+ @inflector.file2constant("file_other").should == "FileOther"
+ end
+
+ it "should correctly replace as many underscores as exist in the file name" do
+ @inflector.file2constant("two_under_scores/with_some_more_underscores").should == "TwoUnderScores::WithSomeMoreUnderscores"
+ end
+
+ it "should collapse multiple underscores" do
+ @inflector.file2constant("many___scores").should == "ManyScores"
+ end
+
+ it "should correctly handle file names deeper than two directories" do
+ @inflector.file2constant("one_two/three_four/five_six").should == "OneTwo::ThreeFour::FiveSix"
+ end
+end
+
+describe Puppet::Util::ConstantInflector, "when converting constnats to file names" do
+ before do
+ @inflector = Object.new
+ @inflector.extend(Puppet::Util::ConstantInflector)
+ end
+
+ it "should convert them to a string if necessary" do
+ @inflector.constant2file(Puppet::Util::ConstantInflector).should be_instance_of(String)
+ end
+
+ it "should accept string inputs" do
+ @inflector.constant2file("Puppet::Util::ConstantInflector").should be_instance_of(String)
+ end
+
+ it "should downcase all terms" do
+ @inflector.constant2file("Puppet").should == "puppet"
+ end
+
+ it "should convert '::' to '/'" do
+ @inflector.constant2file("Puppet::Util::Constant").should == "puppet/util/constant"
+ end
+
+ it "should convert mid-word capitalization to an underscore" do
+ @inflector.constant2file("OneTwo::ThreeFour").should == "one_two/three_four"
+ end
+
+ it "should correctly handle constants with more than two parts" do
+ @inflector.constant2file("OneTwoThree::FourFiveSixSeven").should == "one_two_three/four_five_six_seven"
+ end
+end
diff --git a/spec/unit/util/settings.rb b/spec/unit/util/settings.rb
index 540743d7e..9f7018697 100755
--- a/spec/unit/util/settings.rb
+++ b/spec/unit/util/settings.rb
@@ -284,11 +284,6 @@ describe Puppet::Util::Settings, " when parsing its configuration" do
lambda { @settings.parse(file) }.should_not raise_error
end
- it "should support an old parse method when per-executable configuration files still exist" do
- # I'm not going to bother testing this method.
- @settings.should respond_to(:old_parse)
- end
-
it "should convert booleans in the configuration file into Ruby booleans" do
text = "[main]
one = true
@@ -481,7 +476,7 @@ describe Puppet::Util::Settings, " when being used to manage the host machine" d
def stub_transaction
@bucket = mock 'bucket'
- @config = mock 'config'
+ @config = mock 'config', :clear => nil
@trans = mock 'transaction'
@settings.expects(:to_transportable).with(:whatever).returns(@bucket)
@@ -597,6 +592,72 @@ describe Puppet::Util::Settings, " when being used to manage the host machine" d
file.should be_nil
end
+ it "should not try to manage files in memory" do
+ main = Puppet::Type.type(:file).create(:path => "/maindir")
+
+ trans = @settings.to_transportable
+
+ lambda { trans.to_catalog }.should_not raise_error
+ end
+
+ it "should do nothing if a catalog cannot be created" do
+ bucket = mock 'bucket'
+ catalog = mock 'catalog'
+
+ @settings.expects(:to_transportable).returns bucket
+ bucket.expects(:to_catalog).raises RuntimeError
+ catalog.expects(:apply).never
+
+ @settings.use(:mysection)
+ end
+
+ it "should clear the catalog after applying" do
+ bucket = mock 'bucket'
+ catalog = mock 'catalog'
+
+ @settings.expects(:to_transportable).returns bucket
+ bucket.expects(:to_catalog).returns catalog
+ catalog.stubs(:host_config=)
+ catalog.stubs(:apply)
+ catalog.expects(:clear)
+
+ @settings.use(:mysection)
+ end
+
+ it "should clear the catalog even if there is an exception during applying" do
+ bucket = mock 'bucket'
+ catalog = mock 'catalog'
+
+ @settings.expects(:to_transportable).returns bucket
+ bucket.expects(:to_catalog).returns catalog
+ catalog.stubs(:host_config=)
+ catalog.expects(:apply).raises(ArgumentError)
+ catalog.expects(:clear)
+
+ # We don't care about the raised exception, we just care that
+ # we clear the catalog even with the exception
+ lambda { @settings.use(:mysection) }.should raise_error
+ end
+
+ it "should do nothing if all specified sections have already been used" do
+ bucket = mock 'bucket'
+ catalog = mock 'catalog'
+
+ @settings.expects(:to_transportable).once.returns(bucket)
+ bucket.expects(:to_catalog).returns catalog
+ catalog.stub_everything
+
+ @settings.use(:whatever)
+
+ @settings.use(:whatever)
+ end
+
+ it "should ignore file settings whose values are not strings" do
+ @settings[:maindir] = false
+
+ lambda { trans = @settings.to_transportable }.should_not raise_error
+ end
+
it "should be able to turn the current configuration into a parseable manifest"
it "should convert octal numbers correctly when producing a manifest"
@@ -635,4 +696,6 @@ describe Puppet::Util::Settings, " when being used to manage the host machine" d
proc { @settings.use(:whatever) }.should raise_error(RuntimeError)
end
+
+ after { Puppet::Type.allclear }
end
diff --git a/spec/unit/util/tagging.rb b/spec/unit/util/tagging.rb
new file mode 100755
index 000000000..d61ee8ccb
--- /dev/null
+++ b/spec/unit/util/tagging.rb
@@ -0,0 +1,92 @@
+#!/usr/bin/env ruby
+#
+# Created by Luke Kanies on 2008-01-19.
+# Copyright (c) 2007. All rights reserved.
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+require 'puppet/util/tagging'
+
+describe Puppet::Util::Tagging, "when adding tags" do
+ before do
+ @tagger = Object.new
+ @tagger.extend(Puppet::Util::Tagging)
+ end
+
+ it "should have a method for adding tags" do
+ @tagger.should be_respond_to(:tag)
+ end
+
+ it "should have a method for returning all tags" do
+ @tagger.should be_respond_to(:tags)
+ end
+
+ it "should add tags to the returned tag list" do
+ @tagger.tag("one")
+ @tagger.tags.should be_include("one")
+ end
+
+ it "should not add duplicate tags to the returned tag list" do
+ @tagger.tag("one")
+ @tagger.tag("one")
+ @tagger.tags.should == ["one"]
+ end
+
+ it "should return a duplicate of the tag list, rather than the original" do
+ @tagger.tag("one")
+ tags = @tagger.tags
+ tags << "two"
+ @tagger.tags.should_not be_include("two")
+ end
+
+ it "should add all provided tags to the tag list" do
+ @tagger.tag("one", "two")
+ @tagger.tags.should be_include("one")
+ @tagger.tags.should be_include("two")
+ end
+
+ it "should fail on tags containing '*' characters" do
+ lambda { @tagger.tag("bad*tag") }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should fail on tags starting with '-' characters" do
+ lambda { @tagger.tag("-badtag") }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should fail on tags containing ' ' characters" do
+ lambda { @tagger.tag("bad tag") }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should allow alpha tags" do
+ lambda { @tagger.tag("good_tag") }.should_not raise_error(Puppet::ParseError)
+ end
+
+ it "should allow tags containing '.' characters" do
+ lambda { @tagger.tag("good.tag") }.should_not raise_error(Puppet::ParseError)
+ end
+
+ it "should provide a method for testing tag validity" do
+ @tagger.metaclass.publicize_methods(:valid_tag?) { @tagger.should be_respond_to(:valid_tag?) }
+ end
+
+ it "should add qualified classes as tags" do
+ @tagger.tag("one::two")
+ @tagger.tags.should be_include("one::two")
+ end
+
+ it "should add each part of qualified classes as tags" do
+ @tagger.tag("one::two::three")
+ @tagger.tags.should be_include("one")
+ @tagger.tags.should be_include("two")
+ @tagger.tags.should be_include("three")
+ end
+
+ it "should indicate when the object is tagged with a provided tag" do
+ @tagger.tag("one")
+ @tagger.should be_tagged("one")
+ end
+
+ it "should indicate when the object is not tagged with a provided tag" do
+ @tagger.should_not be_tagged("one")
+ end
+end