class Tryouts
May all your dreams come true!
==== Are you ready to run some drills?
* It stores all known instances of Tryouts objects in a class variable @@instances.
are modified to support DSL syntax by acting like setters when given arguments)
class methods are the handlers for the DSL syntax (some instance getter methods
* The tryouts and dreams DSLs are executed within its namespace. In general the
* It represents the Tryouts object which is a group of Tryout objects.
This class has three purposes:
= Tryouts
def self.command(*args)
Calls Tryouts#command on the current instance of Tryouts
def self.command(*args) @@instances.last.command(*args) end
def self.debug?; @@debug; end
def self.debug?; @@debug; end
def self.disable_debug; @@debug = false; end
def self.disable_debug; @@debug = false; end
def self.enable_debug; @@debug = true; end
def self.enable_debug; @@debug = true; end
def self.failed=(v); @@failed = v; end
def self.failed=(v); @@failed = v; end
def self.failed?; @@failed; end
def self.failed?; @@failed; end
def self.group(*args)
because the group name is taken from the name of the class. See inherited.
Raises a Tryouts::Exception. +group+ is not support in the standalone syntax
def self.group(*args) raise "Group is already set: #{@@instances.last.group}" end
def self.inherited(klass)
to +@@instances+.
of Tryouts, sets group to the name of the new class, and adds the instance
Called when a new class inherits from Tryouts. This creates a new instance
def self.inherited(klass) to = @@instances[ klass ] to ||= Tryouts.new to.paths << __FILE__ to.group = klass @@instances[to.group] = to end
def self.instances; @@instances; end
def self.instances; @@instances; end
def self.library(*args)
Calls Tryouts#library on the current instance of Tryouts
def self.library(*args) @@instances.last.library(*args) end
def self.parse_file(fpath)
Parse a +_tryouts.rb+ file. See Tryouts::CLI::Run for an example.
def self.parse_file(fpath) raise "No such file: #{fpath}" unless File.exists?(fpath) file_content = File.read(fpath) to = Tryouts.new begin to.paths << fpath to.instance_eval file_content, fpath # After parsing the DSL, we'll know the group name. # If a Tryouts object already exists for that group # we'll use that instead and re-parse the DSL. if @@instances.has_key? to.group to = @@instances[to.group] to.instance_eval file_content, fpath end rescue SyntaxError, LoadError, Exception, TypeError, RuntimeError, NoMethodError, NameError => ex to.errors << ex Tryouts.failed = true # It's helpful to display the group name file_content.match(/^group (.+?)$/) do |x,t| # We use eval as a quick cheat so we don't have # to parse all the various kinds of quotes. to.group = eval x.captures.first end end @@instances[to.group] = to to end
def self.run
Run all Tryout objects in +@tryouts+
def self.run @@instances.each_pair do |group, inst| inst.tryouts.each_pair do |name,to| to.run to.report STDOUT.flush end end end
def self.sysinfo; @@sysinfo; end
def self.sysinfo; @@sysinfo; end
def self.tryout(*args, &block)
Calls Tryouts#tryout on the current instance of Tryouts
def self.tryout(*args, &block) @@instances.last.tryout(*args, &block) end
def self.tryouts(*args, &block)
def self.tryouts(*args, &block) tryout(args, &block) end
def self.verbose; @@verbose; end
def self.verbose; @@verbose; end
def self.verbose=(v); @@verbose = (v == true) ? 1 : v; end
def self.verbose=(v); @@verbose = (v == true) ? 1 : v; end
def self.xtryout(*args, &block); end
This method does nothing. It provides a quick way to disable a tryout.
def self.xtryout(*args, &block); end
def self.xtryouts(*args, &block); end
This method does nothing. It provides a quick way to disable a tryout.
def self.xtryouts(*args, &block); end
def command(name=nil, path=nil)
Add a shell command to Rye::Cmd and save the command name
def command(name=nil, path=nil) raise "command testing is temporarily disabled" return @command if name.nil? @command = name.to_sym @dtype = :cli Rye::Cmd.module_eval do define_method(name) do |*args| cmd(path || name, *args) end end @command end
def find_tryout(name, dtype=nil)
Find matching Tryout objects by +name+ and filter by
def find_tryout(name, dtype=nil) by_name = @tryouts.values.select { |t| t.name == name } by_name = by_name.select { |t| t.dtype == dtype } if dtype by_name.first # by_name is an Array. We just want the Object. end
def from_block(b, &inline)
Populate this Tryouts from a block. The block should contain calls to
def from_block(b, &inline) instance_eval &b end
def group(name=nil)
def group(name=nil) return @group if name.nil? @group = name unless name.nil? @group end
def initialize(group=nil)
def initialize(group=nil) @group = group || "Default Group" @tryouts = HASH_TYPE.new @paths, @errors = [], [] @command = nil end
def library(name=nil, *path)
library __FILE__, '..', 'lib'
library '/an/absolute/path'
in specified in multiple arguments they are joined and expanded.
a specific copy of the library. Otherwise, it loads from the system path. If the path
* +path+ Add a path to the front of $LOAD_PATH (optional). Use this if you want to load
* +name+ The name of the library in question (required). Stored as a Symbol to +@library+.
Require +name+. If +path+ is supplied, it will "require path".
def library(name=nil, *path) return @library if name.nil? @library, @dtype = name.to_sym, :api path = File.expand_path(File.join *path) $LOAD_PATH.unshift path unless path.nil? begin require @library.to_s rescue LoadError => ex @errors << ex.exception("Cannot load library: #{@library} (#{path})") Tryouts.failed = true rescue SyntaxError, Exception, TypeError, RuntimeError, NoMethodError, NameError => ex @errors << ex Tryouts.failed = true end end
def report
def report successes = [] @tryouts.each_pair { |n,to| successes << to.report } puts $/, "All your dreams came true" unless successes.member?(false) end
def run; @tryouts.each_pair { |n,to| to.run }; end
def run; @tryouts.each_pair { |n,to| to.run }; end
def tryout(name, dtype=nil, command=nil, &block)
* +b+ is a block definition for the Tryout. See Tryout#from_block
* +command+ when type is :cli, this is the name of the Rye::Box method that we're testing. Otherwise ignored.
* +dtype+ is the default drill type for the Tryout.
* +name+ is the name of the Tryout
Create a new Tryout object and add it to the list for this Tryouts class.
def tryout(name, dtype=nil, command=nil, &block) return if name.nil? dtype ||= @dtype command ||= @command if dtype == :cli raise NoDrillType, name if dtype.nil? to = find_tryout(name, dtype) if to.nil? to = Tryouts::Tryout.new(name, dtype, command) @tryouts[name] = to end # Process the rest of the DSL begin to.from_block block if block rescue SyntaxError, LoadError, Exception, TypeError, RuntimeError, NoMethodError, NameError => ex @errors << ex Tryouts.failed = true end to end
def tryouts(*args, &block)
Also acts as a stub for Tryouts#tryout in case someone
Returns +@tryouts+.
def tryouts(*args, &block) return tryout(*args, &block) unless args.empty? @tryouts end
def xtryout(*args, &block); end
This method does nothing. It provides a quick way to disable a tryout.
def xtryout(*args, &block); end
def xtryouts(*args, &block); end
This method does nothing. It provides a quick way to disable a tryout.
def xtryouts(*args, &block); end