class QED::Session
The Session
class encapsulates a set of demonstrations and the procedure for looping through them and running each in turn.
Constants
- CODE_TYPES
- DEMO_TYPES
Default recognized demos file types.
Attributes
Returns instance of Settings
class.
Public Class Methods
Command line interface for running demos.
When running ‘qed` on the command line tool, QED
can use either a automatic configuration file, via the RC library, or setup configuration via an explicitly required file.
Using a master configuraiton file, add a ‘config :qed` entry. For example:
config :qed, :profile=>:simplecov do require 'simplecov' SimpleCov.start do coverage_dir 'log/coverage' end end
To not use RC, just create a requirable file such as ‘config/qed-coverage.rb`
QED.configure do |qed| require 'simplecov' SimpleCov.start do coverage_dir 'log/coverage' end end
Then when running qed use:
$ qed -r ./config/qed-coverage.rb
# File lib/qed/cli/qed.rb, line 47 def self.cli(*argv) require 'optparse' require 'shellwords' # we are loading this here instead of above so simplecov coverage works better # (actually, this is really not a problem anymore, but we'll leave it for now) require 'qed/session' Utils.load_config options = cli_parse(argv) settings = Settings.new(options) session = Session.new(settings) success = session.run exit -1 unless success end
Build an instance of OptionParser.
# File lib/qed/cli/qed.rb, line 69 def self.cli_parse(argv) options = {} parser = OptionParser.new do |opt| opt.banner = "Usage: qed [options] <files...>" opt.separator("Report Formats (pick one):") #opt.on('--dotprogress', '-d', "use dot-progress reporter [default]") do # options[:format] = :dotprogress #end opt.on('--verbatim', '-v', "shortcut for verbatim reporter") do options[:format] = :verbatim end opt.on('--tapy', '-y', "shortcut for TAP-Y reporter") do options[:format] = :tapy end #opt.on('--bullet', '-b', "use bullet-point reporter") do # options[:format] = :bullet #end #opt.on('--html', '-h', "use underlying HTML reporter") do # options[:format] = :html #end #opt.on('--script', "psuedo-reporter") do # options[:format] = :script # psuedo-reporter #end opt.on('--format', '-f FORMAT', "use custom reporter") do |format| options[:format] = format.to_sym end opt.separator("Control Options:") opt.on('-p', '--profile NAME', "load runtime profile") do |name| options[:profile] = name end opt.on('--comment', '-c', "run comment code") do options[:mode] = :comment end opt.on('--loadpath', "-I PATH", "add paths to $LOAD_PATH") do |paths| options[:loadpath] = paths.split(/[:;]/).map{|d| File.expand_path(d)} end opt.on('--require', "-r LIB", "require feature (immediately)") do |paths| requires = paths.split(/[:;]/) requires.each do |file| require file end end opt.on('--rooted', '-R', "run from project root instead of temporary directory") do options[:rooted] = true end opt.on('--trace', '-t [COUNT]', "number of backtraces for exceptions (0 for all)") do |cnt| #options[:trace] = true ENV['trace'] = cnt end opt.on('--warn', "run with warnings turned on") do $VERBOSE = true # wish this were called $WARN! end opt.on('--debug', "exit immediately upon raised exception") do $DEBUG = true end opt.separator("Optional Commands:") opt.on_tail('--version', "display version") do puts "QED #{QED::VERSION}" exit end opt.on_tail('--copyright', "display copyrights") do puts "Copyright (c) 2008 Thomas Sawyer, Apache 2.0 License" exit end opt.on_tail('--help', '-h', "display this help message") do puts opt unless settings.profiles.empty? puts "Available Profiles:" #require 'confection' QED.profiles.each do |name| next if name.strip == '' puts " -p #{name}" end end exit -1 end end parser.parse!(argv) options[:files] = argv unless argv.empty? return options end
New Session
# File lib/qed/session.rb, line 29 def initialize(settings={}) require_reporters case settings when Settings @settings = settings else @settings = Settings.new(settings) end end
Public Instance Methods
Clear temporary testing directory.
# File lib/qed/session.rb, line 162 def clear_directory settings.clear_directory end
Returns a list of demo files. The files returned depends on the files
attribute and if none given, then the current run mode.
# File lib/qed/session.rb, line 188 def demo_files @demo_files ||= ( if mode == :comment demo_files_in_comment_mode else demo_files_in_normal_mode end ) end
Collect default files to process in code comment mode.
TODO: Sure removing applique files is the best approach here?
# File lib/qed/session.rb, line 206 def demo_files_in_comment_mode files = demos_gather(CODE_TYPES) files = files.reject{ |f| f.index('applique/') } # don't include applique files ??? files end
Collect default files to process in normal demo mode.
# File lib/qed/session.rb, line 199 def demo_files_in_normal_mode demos_gather #(DEMO_TYPES) end
Returns an Array of Demo
instances.
# File lib/qed/session.rb, line 115 def demos @demos ||= demo_files.map{ |file| Demo.new(file, :mode=>mode, :at=>directory) } end
Gather list of demo files. Uses omit
to remove certain files based on the name of their parent directory.
# File lib/qed/session.rb, line 214 def demos_gather(extensions=DEMO_TYPES) files = self.files #files << default_location if files.empty? files = files.map{|pattern| Dir[pattern]}.flatten.uniq files = files.map do |file| if File.directory?(file) Dir[File.join(file,'**','*.{' + extensions.join(',') + '}')] else file end end files = files.flatten.uniq #files = files.reject{ |f| f =~ Regexp.new("/\/(#{omit.join('|')})\//") } files = files.reject{ |f| omit.any?{ |o| f.index("/#{o}/") } } files.map{|f| File.expand_path(f) }.uniq.sort end
# File lib/qed/session.rb, line 86 def directory settings.tmpdir end
Demonstration files (or globs).
# File lib/qed/session.rb, line 41 def files settings.files end
Output format.
# File lib/qed/session.rb, line 51 def format settings.format end
Paths to be added to $LOAD_PATH.
# File lib/qed/session.rb, line 66 def loadpath settings.loadpath end
Parse mode.
# File lib/qed/session.rb, line 61 def mode settings.mode end
List of observers to pass to the evaluator. Only includes the reporter instance, by default.
# File lib/qed/session.rb, line 122 def observers [reporter] end
File patterns to omit.
# File lib/qed/session.rb, line 46 def omit settings.omit end
Add to load path (from -I option).
# File lib/qed/session.rb, line 172 def prepare_loadpath loadpath.each{ |dir| $LOAD_PATH.unshift(File.expand_path(dir)) } end
Selected profile.
# File lib/qed/session.rb, line 81 def profile settings.profile end
Instance of selected Reporter
subclass.
# File lib/qed/session.rb, line 105 def reporter @reporter ||= ( name = Reporter.constants.find{ |c| /#{format}/ =~ c.to_s.downcase } Reporter.const_get(name).new(:trace => trace?) ) end
Require libraries (from -r option).
# File lib/qed/session.rb, line 177 def require_libraries requires.each{ |file| require(file) } end
Require all reporters.
# File lib/qed/session.rb, line 98 def require_reporters Dir[File.dirname(__FILE__) + '/reporter/*'].each do |file| require file end end
Libraries to be required.
# File lib/qed/session.rb, line 71 def requires settings.requires end
Set $ASSERTION_COUNTS to zero point.
# File lib/qed/session.rb, line 167 def reset_assertion_counts $ASSERTION_COUNTS = Hash.new{ |h,k| h[k] = 0 } end
Operate from project root?
# File lib/qed/session.rb, line 76 def rooted settings.rooted end
Run session.
# File lib/qed/session.rb, line 129 def run abort "No documents." if demo_files.empty? clear_directory reset_assertion_counts #require_profile # <-- finally runs the profile prepare_loadpath require_libraries Dir.chdir(directory) do # pre-parse demos demos.each{ |demo| demo.steps } # Let's do it. observers.each{ |o| o.before_session(self) } begin demos.each do |demo| Evaluator.run(demo, :observers=>observers, :settings=>settings) #demo.run(*observers) #pid = fork { demo.run(*observers) } #Process.detach(pid) end ensure observers.each{ |o| o.after_session(self) } end end reporter.success? end
Get the total test count. This method tallies up the number of assertive steps.
# File lib/qed/session.rb, line 241 def total_step_count count = 0 demos.each do |demo| demo.steps.each do |step| count += 1 if step.assertive? end end count end
Trace execution?
# File lib/qed/session.rb, line 56 def trace? settings.trace end