CodeMonkeySteve-mustard 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +21 -0
- data/README.rdoc +8 -0
- data/Rakefile +20 -0
- data/lib/mustard.rb +55 -0
- data/lib/mustard/assertion.rb +32 -0
- data/lib/mustard/context.rb +55 -0
- data/lib/mustard/scope.rb +65 -0
- data/lib/mustard/test.rb +42 -0
- data/test/test_stuff.rb +33 -0
- metadata +64 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Copyright (c) 2006-2009 Steve Sloan
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
data/README.rdoc
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
= Mustard
|
2
|
+
|
3
|
+
Mustard is a unit testing framework inspired by Shoulda[http://thoughtbot.com/projects/shoulda/], but without the inefficiencies of Test::Unit.
|
4
|
+
|
5
|
+
Author:: Steve Sloan (mailto:steve@finagle.org)
|
6
|
+
Website:: http://github.com/CodeMonkeySteve/mustard
|
7
|
+
Copyright:: Copyright (c) 2009 Steve Sloan
|
8
|
+
License:: MIT
|
data/Rakefile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/clean'
|
3
|
+
require 'rake/testtask'
|
4
|
+
require 'rake/rdoctask'
|
5
|
+
|
6
|
+
Rake::TestTask.new do |t|
|
7
|
+
t.test_files = FileList['test/test_*.rb']
|
8
|
+
t.verbose = true
|
9
|
+
end
|
10
|
+
|
11
|
+
Rake::RDocTask.new :rdoc do |rdoc|
|
12
|
+
rdoc.rdoc_dir = 'html'
|
13
|
+
rdoc.title = "Mustard -- The Testing Secret Sauce"
|
14
|
+
rdoc.options += ['--line-numbers', '--inline-source', '--main', 'README.rdoc' ]
|
15
|
+
rdoc.rdoc_files.include 'README.rdoc', 'MIT-LICENSE'
|
16
|
+
rdoc.rdoc_files.include 'lib/**/*.rb'
|
17
|
+
end
|
18
|
+
|
19
|
+
task :default => [ :test ]
|
20
|
+
|
data/lib/mustard.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'mustard/test'
|
2
|
+
|
3
|
+
module Mustard
|
4
|
+
|
5
|
+
@@autorun = false
|
6
|
+
def self.autorun?( enabled = nil )
|
7
|
+
@@autorun = enabled unless enabled.nil?
|
8
|
+
@@autorun
|
9
|
+
end
|
10
|
+
|
11
|
+
module Squeeze
|
12
|
+
|
13
|
+
def scope( *args, &blk )
|
14
|
+
Scope.use( *args, &blk )
|
15
|
+
end
|
16
|
+
|
17
|
+
def test( *args, &blk )
|
18
|
+
t = Test.use( *args, &blk )
|
19
|
+
@@tests ||= []
|
20
|
+
@@tests << t unless @@tests.include?(t)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.included( into )
|
24
|
+
Mustard.autorun? true
|
25
|
+
at_exit do
|
26
|
+
exit( into.autotest ? 0 : 1 ) if Mustard.autorun?
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
protected
|
31
|
+
def autotest
|
32
|
+
return true if @@tests.empty?
|
33
|
+
$stderr.sync = true
|
34
|
+
context = Context.new
|
35
|
+
passed = failed = 0
|
36
|
+
start = Time.now
|
37
|
+
|
38
|
+
@@tests.all? do |t|
|
39
|
+
t.assert!(context) do |assrtn, pass, ctx|
|
40
|
+
if pass
|
41
|
+
passed += 1
|
42
|
+
$stderr.print '.'
|
43
|
+
else
|
44
|
+
failed += 1
|
45
|
+
$stderr.puts '!', "in: #{ctx} (#{assrtn.file}:#{assrtn.line})", "failed: #{assrtn.name}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
$stderr.puts '' if failed.zero?
|
50
|
+
$stderr.puts "#{failed} failed, #{passed} passed, in #{Time.now - start}s"
|
51
|
+
failed.zero?
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Mustard
|
2
|
+
|
3
|
+
class Assertion
|
4
|
+
def self.on_success( &blk )
|
5
|
+
(@@success_callbacks ||= []) << blk if blk
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.on_failure( &blk )
|
9
|
+
(@@failure_callbacks ||= []) << blk if blk
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
attr_accessor :name, :file, :line
|
14
|
+
|
15
|
+
def initialize( name, scope, file, line, &blk )
|
16
|
+
@name, @scope, @file, @line, @blk = name, scope, file, line, blk
|
17
|
+
end
|
18
|
+
|
19
|
+
def call( context = nil )
|
20
|
+
@scope.use! context do |ctx|
|
21
|
+
context.eval( &@blk )
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def assert!( context = nil, &callbk )
|
26
|
+
context ||= Context.new
|
27
|
+
res = self.call context
|
28
|
+
yield( self, res, context ) if callbk
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Mustard
|
2
|
+
|
3
|
+
class Context
|
4
|
+
class Workspace ; end
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@scopes = []
|
8
|
+
@workspaces = []
|
9
|
+
@workspace = nil
|
10
|
+
end
|
11
|
+
|
12
|
+
def open?( scope )
|
13
|
+
@scopes.include? scope
|
14
|
+
end
|
15
|
+
|
16
|
+
def closed?( scope )
|
17
|
+
! open? scope
|
18
|
+
end
|
19
|
+
|
20
|
+
def open( scope, &blk )
|
21
|
+
#puts "open: #{scope.name.inspect}"
|
22
|
+
unless open? scope
|
23
|
+
if @workspace
|
24
|
+
@workspaces.push @workspace
|
25
|
+
@workspace = @workspace.dup
|
26
|
+
else
|
27
|
+
@workspace = Workspace.new
|
28
|
+
end
|
29
|
+
yield if blk
|
30
|
+
end
|
31
|
+
@scopes.push scope
|
32
|
+
#puts "(#{self})"
|
33
|
+
end
|
34
|
+
|
35
|
+
def close( scope, &blk )
|
36
|
+
#puts "close: #{scope.name.inspect}"
|
37
|
+
raise "Mismatched context: got #{scope.name.inspect}, expected #{@scopes.last.name.inspect}" unless scope == @scopes.last
|
38
|
+
@scopes.pop
|
39
|
+
if closed? scope
|
40
|
+
yield if blk
|
41
|
+
@workspace = @workspaces.pop
|
42
|
+
end
|
43
|
+
#puts "(#{self})"
|
44
|
+
end
|
45
|
+
|
46
|
+
def eval( &blk )
|
47
|
+
@workspace.instance_eval( &blk )
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_s
|
51
|
+
@scopes.map { |s| s.name.inspect }.join(', ')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'mustard/context'
|
2
|
+
|
3
|
+
module Mustard
|
4
|
+
|
5
|
+
class Scope
|
6
|
+
@@all = {}
|
7
|
+
def self.[]( name )
|
8
|
+
name && @@all[name]
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.use( name = nil, *scopes, &defn )
|
12
|
+
s = Scope[name] || Scope.new( name, *scopes )
|
13
|
+
s.instance_eval( &defn ) if defn
|
14
|
+
s
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_reader :name
|
18
|
+
|
19
|
+
def initialize( name = nil, *scopes, &defn )
|
20
|
+
@name, @scopes = name, scopes
|
21
|
+
@setup, @teardown = [], [], []
|
22
|
+
|
23
|
+
@@all[@name] = self if @name
|
24
|
+
self.instance_eval( &defn ) if defn
|
25
|
+
end
|
26
|
+
|
27
|
+
def setup( &blk )
|
28
|
+
@setup << blk
|
29
|
+
end
|
30
|
+
|
31
|
+
def teardown( &blk )
|
32
|
+
@teardown << blk
|
33
|
+
end
|
34
|
+
|
35
|
+
def with( name, *scopes, &defn )
|
36
|
+
@scopes << Scope.use( name, *scopes, &defn )
|
37
|
+
end
|
38
|
+
|
39
|
+
def use!( context = nil, &blk )
|
40
|
+
context ||= Context.new
|
41
|
+
open! context
|
42
|
+
res = yield( context )
|
43
|
+
close! context
|
44
|
+
res
|
45
|
+
end
|
46
|
+
|
47
|
+
protected
|
48
|
+
|
49
|
+
def open!( context )
|
50
|
+
context.open self do
|
51
|
+
@scopes.each { |scope| scope.open! context }
|
52
|
+
@setup.each { |blk| context.eval( &blk ) }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def close!( context )
|
57
|
+
context.close self do
|
58
|
+
@teardown.reverse.each { |blk| context.eval( &blk ) }
|
59
|
+
@scopes.reverse.each { |scope| scope.close! context }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
data/lib/mustard/test.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'mustard/scope'
|
2
|
+
require 'mustard/assertion'
|
3
|
+
|
4
|
+
module Mustard
|
5
|
+
|
6
|
+
class Test < Scope
|
7
|
+
@@all = {}
|
8
|
+
def self.use( name = nil, *scopes, &defn )
|
9
|
+
t = Scope[name] || Test.new( name, *scopes )
|
10
|
+
t.instance_eval( &defn ) if defn
|
11
|
+
t
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize( name, *scopes, &defn )
|
15
|
+
@assertions = []
|
16
|
+
super name, *scopes, &defn
|
17
|
+
end
|
18
|
+
|
19
|
+
def must( name = nil, file = __FILE__, line = __LINE__, &blk )
|
20
|
+
@assertions << Assertion.new( name, self, file, line, &blk )
|
21
|
+
end
|
22
|
+
|
23
|
+
def must_not( name = nil, file = __FILE__, line = __LINE__, &blk )
|
24
|
+
@assertions << Assertion.new( (name && "not #{name}"), self, file, line ) { ! instance_eval(&blk) }
|
25
|
+
end
|
26
|
+
|
27
|
+
# def go( name, &blk )
|
28
|
+
# Test.new "#{self.name}+#{name}", self, &blk
|
29
|
+
# end
|
30
|
+
|
31
|
+
def test( name = nil, &defn )
|
32
|
+
@assertions << Test.new( name, self, &defn )
|
33
|
+
end
|
34
|
+
|
35
|
+
def assert!( context = nil, &callbk )
|
36
|
+
use! context do |ctx|
|
37
|
+
@assertions.each { |a| a.assert!( ctx, &callbk ) }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
data/test/test_stuff.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'mustard'
|
2
|
+
include Mustard::Squeeze
|
3
|
+
|
4
|
+
class Numeric
|
5
|
+
def even? ; (self % 2).zero? ; end
|
6
|
+
def odd? ; (self % 2).nonzero? ; end
|
7
|
+
end
|
8
|
+
|
9
|
+
test 'prime number test' do
|
10
|
+
with 'prime number' do
|
11
|
+
setup do
|
12
|
+
@prime_number = 97
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
must('be true') { @prime_number }
|
17
|
+
must('be odd') { @prime_number.odd? }
|
18
|
+
must_not('be even') { @prime_number.even? }
|
19
|
+
|
20
|
+
test 'add one' do
|
21
|
+
setup do
|
22
|
+
@prime_number += 1
|
23
|
+
end
|
24
|
+
must('be even') { @prime_number.even? }
|
25
|
+
must_not('be odd') { @prime_number.odd? }
|
26
|
+
end
|
27
|
+
|
28
|
+
must('be odd again') { @prime_number.odd? }
|
29
|
+
end
|
30
|
+
|
31
|
+
#test 'failing test' do
|
32
|
+
# must 'fail' do false end
|
33
|
+
#end
|
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: CodeMonkeySteve-mustard
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: "0.1"
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Steve Sloan
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-07-27 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: An efficient unit testing framework inspired by Shoulda
|
17
|
+
email: steve@finagle.org
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.rdoc
|
24
|
+
files:
|
25
|
+
- MIT-LICENSE
|
26
|
+
- README.rdoc
|
27
|
+
- Rakefile
|
28
|
+
- lib/mustard.rb
|
29
|
+
- lib/mustard/assertion.rb
|
30
|
+
- lib/mustard/context.rb
|
31
|
+
- lib/mustard/scope.rb
|
32
|
+
- lib/mustard/test.rb
|
33
|
+
has_rdoc: false
|
34
|
+
homepage: http://github.com/CodeMonkeySteve/mustard
|
35
|
+
licenses:
|
36
|
+
post_install_message:
|
37
|
+
rdoc_options:
|
38
|
+
- --main
|
39
|
+
- README.rdoc
|
40
|
+
- --inline-source
|
41
|
+
- --line-numbers
|
42
|
+
require_paths:
|
43
|
+
- lib
|
44
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: "0"
|
49
|
+
version:
|
50
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: "0"
|
55
|
+
version:
|
56
|
+
requirements: []
|
57
|
+
|
58
|
+
rubyforge_project:
|
59
|
+
rubygems_version: 1.3.5
|
60
|
+
signing_key:
|
61
|
+
specification_version: 3
|
62
|
+
summary: An efficient unit testing framework inspired by Shoulda
|
63
|
+
test_files:
|
64
|
+
- test/test_stuff.rb
|