From be7849ec387b1cb4bcf4181afc4dc6128f53b727 Mon Sep 17 00:00:00 2001 From: "ara.t.howard" Date: Mon, 5 Mar 2012 08:00:01 -0700 Subject: first commit of platform independent test suite --- test/systemu_test.rb | 64 +++++++++++++++++ test/testing.rb | 195 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 259 insertions(+) create mode 100644 test/systemu_test.rb create mode 100644 test/testing.rb diff --git a/test/systemu_test.rb b/test/systemu_test.rb new file mode 100644 index 0000000..19fac1d --- /dev/null +++ b/test/systemu_test.rb @@ -0,0 +1,64 @@ + +Testing SystemU do + +## +# + testing 'that simple usage works' do + status, stdout, stderr = assert{ systemu :bin/:ls } + assert{ status == 0 } + assert{ stdout['lib'] } + assert{ stderr.strip.empty? } + end + + testing 'program with stdin' do + stdin = '42' + status, stdout, stderr = assert{ systemu :bin/:cat, :stdin => stdin } + assert{ status == 0 } + assert{ stdout == stdin } + end + +end + + + + + +BEGIN { + +# silly hax to build commands we can shell out to on any platform. since +# tests might run on windoze we assume only that 'ruby' is available and build +# other command-line programs from it. +# + module Kernel + private + def bin(which, options = {}, &block) + case which.to_s + when 'ls' + %| ruby -e'puts Dir.glob("*").sort' | + + when 'cat' + %| ruby -e'STDOUT.write(ARGF.read)' | + + when 'find' + %| ruby -e'puts Dir.glob("**/**").sort' | + end + end + end + +# just let's us write: :bin/:ls +# + class Symbol + def / other, options = {}, &block + eval "#{ self }(:#{ other }, options, &block)" + end + end + + testdir = File.dirname(File.expand_path(__FILE__)) + rootdir = File.dirname(testdir) + libdir = File.join(rootdir, 'lib') + require File.join(libdir, 'systemu') + require File.join(testdir, 'testing') + + + Dir.chdir(rootdir) +} diff --git a/test/testing.rb b/test/testing.rb new file mode 100644 index 0000000..d7870fc --- /dev/null +++ b/test/testing.rb @@ -0,0 +1,195 @@ +require 'test/unit' + +testdir = File.expand_path(File.dirname(__FILE__)) +rootdir = File.dirname(testdir) +libdir = File.join(rootdir, 'lib') + +STDOUT.sync = true + +$:.unshift(testdir) unless $:.include?(testdir) +$:.unshift(libdir) unless $:.include?(libdir) +$:.unshift(rootdir) unless $:.include?(rootdir) + +class Testing + class Slug < ::String + def Slug.for(*args) + string = args.flatten.compact.join('-') + words = string.to_s.scan(%r/\w+/) + words.map!{|word| word.gsub %r/[^0-9a-zA-Z_-]/, ''} + words.delete_if{|word| word.nil? or word.strip.empty?} + new(words.join('-').downcase) + end + end + + class Context + attr_accessor :name + + def initialize(name, *args) + @name = name + end + + def to_s + Slug.for(name) + end + end +end + +def Testing(*args, &block) + Class.new(::Test::Unit::TestCase) do + + ## class methods + # + class << self + def contexts + @contexts ||= [] + end + + def context(*args, &block) + return contexts.last if(args.empty? and block.nil?) + + context = Testing::Context.new(*args) + contexts.push(context) + + begin + block.call(context) + ensure + contexts.pop + end + end + + def slug_for(*args) + string = [context, args].flatten.compact.join('-') + words = string.to_s.scan(%r/\w+/) + words.map!{|word| word.gsub %r/[^0-9a-zA-Z_-]/, ''} + words.delete_if{|word| word.nil? or word.strip.empty?} + words.join('-').downcase.sub(/_$/, '') + end + + def name() const_get(:Name) end + + def testno() + '%05d' % (@testno ||= 0) + ensure + @testno += 1 + end + + def testing(*args, &block) + method = ["test", testno, slug_for(*args)].delete_if{|part| part.empty?}.join('_') + define_method(method, &block) + end + + def test(*args, &block) + testing(*args, &block) + end + + def setup(&block) + define_method(:setup, &block) if block + end + + def teardown(&block) + define_method(:teardown, &block) if block + end + + def prepare(&block) + @prepare ||= [] + @prepare.push(block) if block + @prepare + end + + def cleanup(&block) + @cleanup ||= [] + @cleanup.push(block) if block + @cleanup + end + end + + ## configure the subclass! + # + const_set(:Testno, '0') + slug = slug_for(*args).gsub(%r/-/,'_') + name = ['TESTING', '%03d' % const_get(:Testno), slug].delete_if{|part| part.empty?}.join('_') + name = name.upcase! + const_set(:Name, name) + const_set(:Missing, Object.new.freeze) + + ## instance methods + # + alias_method('__assert__', 'assert') + + def assert(*args, &block) + if args.size == 1 and args.first.is_a?(Hash) + options = args.first + expected = getopt(:expected, options){ missing } + actual = getopt(:actual, options){ missing } + if expected == missing and actual == missing + actual, expected, *ignored = options.to_a.flatten + end + expected = expected.call() if expected.respond_to?(:call) + actual = actual.call() if actual.respond_to?(:call) + assert_equal(expected, actual) + end + + if block + label = "assert(#{ args.join(' ') })" + result = nil + assert_nothing_raised{ result = block.call } + __assert__(result, label) + result + else + result = args.shift + label = "assert(#{ args.join(' ') })" + __assert__(result, label) + result + end + end + + def missing + self.class.const_get(:Missing) + end + + def getopt(opt, hash, options = nil, &block) + [opt.to_s, opt.to_s.to_sym].each do |key| + return hash[key] if hash.has_key?(key) + end + default = + if block + block.call + else + options.is_a?(Hash) ? options[:default] : nil + end + return default + end + + def subclass_of exception + class << exception + def ==(other) super or self > other end + end + exception + end + + ## + # + module_eval(&block) + + self.setup() + self.prepare.each{|b| b.call()} + + at_exit{ + self.teardown() + self.cleanup.each{|b| b.call()} + } + + self + end +end + + +if $0 == __FILE__ + + Testing 'Testing' do + testing('foo'){ assert true } + test{ assert true } + p instance_methods.grep(/test/) + end + +end -- cgit v1.2.1