summaryrefslogtreecommitdiffstats
path: root/test/lib/spec/rake
diff options
context:
space:
mode:
authorluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2007-03-17 02:48:41 +0000
committerluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2007-03-17 02:48:41 +0000
commitba23a5ac276e59fdda8186750c6d0fd2cfecdeac (patch)
tree1e14b25ade74ea52d8da2788ede9b12b507867e8 /test/lib/spec/rake
parent8ea6adaeb1e3d0aa6348c2a2c3a385d185372d06 (diff)
Adding spec libs, so we can use them some day
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@2283 980ebf18-57e1-0310-9a29-db15c13687c0
Diffstat (limited to 'test/lib/spec/rake')
-rw-r--r--test/lib/spec/rake/spectask.rb173
-rw-r--r--test/lib/spec/rake/verify_rcov.rb47
2 files changed, 220 insertions, 0 deletions
diff --git a/test/lib/spec/rake/spectask.rb b/test/lib/spec/rake/spectask.rb
new file mode 100644
index 000000000..5c9b365c1
--- /dev/null
+++ b/test/lib/spec/rake/spectask.rb
@@ -0,0 +1,173 @@
+#!/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
+ #
+ class SpecTask < ::Rake::TaskLib
+
+ # 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')
+ attr_accessor :pattern
+
+ # Array of commandline options to pass to RSpec. Defaults to [].
+ attr_accessor :spec_opts
+
+ # Where RSpec's output is written. Defaults to STDOUT.
+ attr_accessor :out
+
+ # 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
+ 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 stdout when there are failures.
+ attr_accessor :failure_message
+
+ # Explicitly define the list of spec files to be included in a
+ # spec. +list+ 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.
+ def spec_files=(list)
+ @spec_files = list
+ end
+
+ # Create a specing task.
+ 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 = []
+ @out = nil
+ @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
+ 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 RSpec for #{actual_name}" + (@rcov ? " using RCov" : "")
+ end
+ task @name do
+ RakeFileUtils.verbose(@verbose) do
+ ruby_opts = @ruby_opts.clone
+ ruby_opts.push( "-I\"#{lib_path}\"" )
+ ruby_opts.push( "-S rcov" ) if @rcov
+ ruby_opts.push( "-w" ) if @warning
+
+ redirect = @out.nil? ? "" : " > \"#{@out}\""
+
+ unless spec_file_list.empty?
+ # ruby [ruby_opts] -Ilib -S rcov [rcov_opts] bin/spec -- [spec_opts] examples
+ # or
+ # ruby [ruby_opts] -Ilib bin/spec [spec_opts] examples
+ begin
+ ruby(
+ ruby_opts.join(" ") + " " +
+ rcov_option_list +
+ (@rcov ? %[ -o "#{@rcov_dir}" ] : "") +
+ '"' + spec_script + '"' + " " +
+ (@rcov ? "-- " : "") +
+ spec_file_list.collect { |fn| %["#{fn}"] }.join(' ') + " " +
+ spec_option_list + " " +
+ redirect
+ )
+ rescue => e
+ puts @failure_message if @failure_message
+ raise e 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['RCOVOPTS'] || @rcov_opts.join(" ") || ""
+ end
+
+ def spec_option_list # :nodoc:
+ ENV['RSPECOPTS'] || @spec_opts.join(" ") || ""
+ 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/test/lib/spec/rake/verify_rcov.rb b/test/lib/spec/rake/verify_rcov.rb
new file mode 100644
index 000000000..a05153e99
--- /dev/null
+++ b/test/lib/spec/rake/verify_rcov.rb
@@ -0,0 +1,47 @@
+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
+
+ def initialize(name=:verify_rcov)
+ @name = name
+ @index_html = 'coverage/index.html'
+ @verbose = 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
+ end
+ end
+ end
+end \ No newline at end of file