tango 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/Gemfile.lock +1 -1
- data/README.md +45 -0
- data/bin/tango +3 -5
- data/lib/tango.rb +3 -4
- data/lib/tango/as_user.rb +17 -0
- data/lib/tango/logger.rb +4 -1
- data/lib/tango/met_and_meet.rb +28 -0
- data/lib/tango/namespace.rb +41 -0
- data/lib/tango/version.rb +1 -1
- data/spec/met_and_meet_spec.rb +74 -0
- data/spec/{dance_spec.rb → namespace_spec.rb} +21 -28
- metadata +12 -15
- data/lib/tango/dance.rb +0 -22
- data/lib/tango/dance_card.rb +0 -32
- data/lib/tango/errors.rb +0 -6
- data/lib/tango/noop_logger.rb +0 -15
- data/lib/tango/step_runner.rb +0 -50
- data/spec/dance_card_spec.rb +0 -56
- data/spec/step_runner_spec.rb +0 -67
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
Credit Where It's Due
|
2
|
+
---------------------
|
3
|
+
|
4
|
+
This is a re-invention of Ben Hoskings's excellent
|
5
|
+
[Babushka](https://github.com/benhoskings/babushka).
|
6
|
+
|
7
|
+
There are a bunch of things I love about Babushka, and a bunch of other things
|
8
|
+
that really don't fit with the way we want to use it at
|
9
|
+
[Envato](http://envato.com/). Tango is an experiment in changing around a few
|
10
|
+
of Babushka's fundamentals to try to find a better fit.
|
11
|
+
|
12
|
+
|
13
|
+
Example
|
14
|
+
-------
|
15
|
+
|
16
|
+
class Homebrew < Tango::Namespace
|
17
|
+
def installed?(formula)
|
18
|
+
`brew info #{formula}` !~ /Not installed/
|
19
|
+
end
|
20
|
+
|
21
|
+
step "bootstrap" do
|
22
|
+
met? { system "brew info" }
|
23
|
+
meet { system %{ruby -e "$(curl -fsSL https://gist.github.com/raw/323731/install_homebrew.rb)"} }
|
24
|
+
end
|
25
|
+
|
26
|
+
step "install" do |formula|
|
27
|
+
met? { installed?(formula) }
|
28
|
+
meet { system "brew install #{formula}" }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class MyNamespace < Tango::Namespace
|
33
|
+
step "install" do
|
34
|
+
Homebrew.run "bootstrap"
|
35
|
+
Homebrew.run "install", "git"
|
36
|
+
Homebrew.run "install", "mysql"
|
37
|
+
run "install mtr"
|
38
|
+
end
|
39
|
+
|
40
|
+
step "install mtr" do
|
41
|
+
met? { Homebrew.installed?("mtr") }
|
42
|
+
meet { system "brew install --no-gtk mtr" }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
data/bin/tango
CHANGED
@@ -3,10 +3,8 @@
|
|
3
3
|
$LOAD_PATH << File.expand_path(File.dirname(__FILE__) + "/../lib")
|
4
4
|
require 'tango'
|
5
5
|
|
6
|
-
def dance(name, &block)
|
7
|
-
Tango::DanceCard.instance.dance(name, &block)
|
8
|
-
end
|
9
|
-
|
10
6
|
load ARGV[0]
|
11
7
|
|
12
|
-
|
8
|
+
namespace_name, step_name = ARGV[1].split(".")
|
9
|
+
|
10
|
+
Object.const_get(namespace_name).run(step_name)
|
data/lib/tango.rb
CHANGED
@@ -0,0 +1,17 @@
|
|
1
|
+
module Tango
|
2
|
+
module AsUser
|
3
|
+
|
4
|
+
def as(username)
|
5
|
+
info = Etc.getpwent(username)
|
6
|
+
uid, gid = Process.euid, Process.egid
|
7
|
+
Process::Sys.seteuid(0) if uid != 0
|
8
|
+
Process::Sys.setegid(info.gid)
|
9
|
+
Process::Sys.seteuid(info.uid)
|
10
|
+
yield
|
11
|
+
ensure
|
12
|
+
Process::Sys.seteuid(uid)
|
13
|
+
Process::Sys.setegid(gid)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
data/lib/tango/logger.rb
CHANGED
@@ -0,0 +1,28 @@
|
|
1
|
+
module Tango
|
2
|
+
class CouldNotMeetError < RuntimeError; end
|
3
|
+
class MeetWithoutMetError < RuntimeError; end
|
4
|
+
|
5
|
+
module MetAndMeet
|
6
|
+
|
7
|
+
def met?(&met_block)
|
8
|
+
@met_block = met_block
|
9
|
+
end
|
10
|
+
|
11
|
+
def meet(&meet_block)
|
12
|
+
raise MeetWithoutMetError if @met_block.nil?
|
13
|
+
|
14
|
+
if instance_eval(&@met_block)
|
15
|
+
log "already met."
|
16
|
+
else
|
17
|
+
log "not already met."
|
18
|
+
instance_eval(&meet_block)
|
19
|
+
if instance_eval(&@met_block)
|
20
|
+
log "met."
|
21
|
+
else
|
22
|
+
raise CouldNotMeetError
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'tango/as_user'
|
2
|
+
require 'tango/met_and_meet'
|
3
|
+
|
4
|
+
module Tango
|
5
|
+
class Namespace
|
6
|
+
include AsUser
|
7
|
+
include MetAndMeet
|
8
|
+
|
9
|
+
def self.step(step_name, &block)
|
10
|
+
define_method(step_name, &block)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.run(step_name, *args)
|
14
|
+
description = "#{name}.#{step_name}"
|
15
|
+
description << "(" + args.map {|arg| arg.inspect }.join(", ") + ")" unless args.empty?
|
16
|
+
|
17
|
+
logger.enter(description)
|
18
|
+
new.send(step_name, *args)
|
19
|
+
logger.leave(description)
|
20
|
+
end
|
21
|
+
|
22
|
+
def run(step_name, *args)
|
23
|
+
self.class.run(step_name, *args)
|
24
|
+
end
|
25
|
+
|
26
|
+
def log(message)
|
27
|
+
self.class.logger.log(message)
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.method_missing(method, *args)
|
31
|
+
new.send(method, *args)
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def self.logger
|
37
|
+
Logger.instance
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
data/lib/tango/version.rb
CHANGED
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'tango'
|
2
|
+
|
3
|
+
module Tango
|
4
|
+
describe MetAndMeet do
|
5
|
+
|
6
|
+
before do
|
7
|
+
@stub = Class.new do
|
8
|
+
include MetAndMeet
|
9
|
+
|
10
|
+
def log(message); end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should check the met?, run the meet, then check the met? again" do
|
15
|
+
met_block_calls = 0
|
16
|
+
meet_block_calls = 0
|
17
|
+
|
18
|
+
@stub.new.instance_eval do
|
19
|
+
met? do
|
20
|
+
met_block_calls += 1
|
21
|
+
meet_block_calls > 0
|
22
|
+
end
|
23
|
+
meet { meet_block_calls += 1 }
|
24
|
+
end
|
25
|
+
|
26
|
+
met_block_calls.should == 2
|
27
|
+
meet_block_calls.should == 1
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should not run the meet if the met? succeeds the first time" do
|
31
|
+
met_block_calls = 0
|
32
|
+
meet_block_calls = 0
|
33
|
+
|
34
|
+
@stub.new.instance_eval do
|
35
|
+
met? do
|
36
|
+
met_block_calls += 1
|
37
|
+
true
|
38
|
+
end
|
39
|
+
meet { meet_block_calls += 1 }
|
40
|
+
end
|
41
|
+
|
42
|
+
met_block_calls.should == 1
|
43
|
+
meet_block_calls.should == 0
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should raise if the met? block fails twice" do
|
47
|
+
met_block_calls = 0
|
48
|
+
meet_block_calls = 0
|
49
|
+
|
50
|
+
expect do
|
51
|
+
@stub.new.instance_eval do
|
52
|
+
met? do
|
53
|
+
met_block_calls += 1
|
54
|
+
false
|
55
|
+
end
|
56
|
+
meet { meet_block_calls += 1 }
|
57
|
+
end
|
58
|
+
end.should raise_error(CouldNotMeetError)
|
59
|
+
|
60
|
+
met_block_calls.should == 2
|
61
|
+
meet_block_calls.should == 1
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should raise an error if there's a meet block without a met block" do
|
65
|
+
expect do
|
66
|
+
@stub.new.instance_eval do
|
67
|
+
meet { }
|
68
|
+
end
|
69
|
+
end.should raise_error(MeetWithoutMetError)
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
@@ -1,25 +1,37 @@
|
|
1
1
|
require 'tango'
|
2
2
|
|
3
|
+
class StubLogger
|
4
|
+
def enter(name); end
|
5
|
+
def leave(name); end
|
6
|
+
def log(message); end
|
7
|
+
end
|
8
|
+
|
9
|
+
class StubbedNamespace < Tango::Namespace
|
10
|
+
def self.logger
|
11
|
+
@logger ||= StubLogger.new
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
3
15
|
module Tango
|
4
|
-
describe
|
16
|
+
describe Namespace do
|
5
17
|
|
6
18
|
it "should run a step" do
|
7
19
|
step_run = false
|
8
20
|
|
9
|
-
|
21
|
+
namespace = Class.new(StubbedNamespace) do
|
10
22
|
step "example step" do
|
11
23
|
step_run = true
|
12
24
|
end
|
13
25
|
end
|
14
26
|
|
15
|
-
|
27
|
+
namespace.run "example step"
|
16
28
|
step_run.should be_true
|
17
29
|
end
|
18
30
|
|
19
31
|
it "should run one step from within another" do
|
20
32
|
inner_step_run = false
|
21
33
|
|
22
|
-
|
34
|
+
namespace = Class.new(StubbedNamespace) do
|
23
35
|
step "outer step" do
|
24
36
|
run "inner step"
|
25
37
|
end
|
@@ -29,24 +41,24 @@ module Tango
|
|
29
41
|
end
|
30
42
|
end
|
31
43
|
|
32
|
-
|
44
|
+
namespace.run "outer step"
|
33
45
|
inner_step_run.should be_true
|
34
46
|
end
|
35
47
|
|
36
48
|
context "passing arguments" do
|
37
49
|
it "should pass arguments to a step" do
|
38
|
-
|
50
|
+
namespace = Class.new(StubbedNamespace) do
|
39
51
|
step "example step" do |a, b|
|
40
52
|
a.should == 1
|
41
53
|
b.should == 2
|
42
54
|
end
|
43
55
|
end
|
44
56
|
|
45
|
-
|
57
|
+
namespace.run "example step", 1, 2
|
46
58
|
end
|
47
59
|
|
48
60
|
it "should pass arguments when running other steps" do
|
49
|
-
|
61
|
+
namespace = Class.new(StubbedNamespace) do
|
50
62
|
step "outer step" do
|
51
63
|
run "inner step", 1, 2
|
52
64
|
end
|
@@ -57,26 +69,7 @@ module Tango
|
|
57
69
|
end
|
58
70
|
end
|
59
71
|
|
60
|
-
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
context "error handling" do
|
65
|
-
it "should raise an error on an attempt to redefine a step" do
|
66
|
-
expect do
|
67
|
-
Dance.new do
|
68
|
-
step "example step" do; end
|
69
|
-
step "example step" do; end
|
70
|
-
end
|
71
|
-
end.should raise_error(StepAlreadyDefinedError)
|
72
|
-
end
|
73
|
-
|
74
|
-
it "should raise an error on an attempt to run an undefined step" do
|
75
|
-
dance = Dance.new do; end
|
76
|
-
|
77
|
-
expect do
|
78
|
-
dance.run "undefined step"
|
79
|
-
end.should raise_error(UndefinedStepError)
|
72
|
+
namespace.run "outer step"
|
80
73
|
end
|
81
74
|
end
|
82
75
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tango
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 4
|
10
|
+
version: 0.0.4
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Pete Yandell
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-03-
|
18
|
+
date: 2011-03-30 00:00:00 +11:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -46,20 +46,18 @@ files:
|
|
46
46
|
- .rspec
|
47
47
|
- Gemfile
|
48
48
|
- Gemfile.lock
|
49
|
+
- README.md
|
49
50
|
- Rakefile
|
50
51
|
- bin/tango
|
51
52
|
- lib/tango.rb
|
52
|
-
- lib/tango/
|
53
|
-
- lib/tango/dance_card.rb
|
54
|
-
- lib/tango/errors.rb
|
53
|
+
- lib/tango/as_user.rb
|
55
54
|
- lib/tango/logger.rb
|
56
|
-
- lib/tango/
|
57
|
-
- lib/tango/
|
55
|
+
- lib/tango/met_and_meet.rb
|
56
|
+
- lib/tango/namespace.rb
|
58
57
|
- lib/tango/version.rb
|
59
|
-
- spec/dance_card_spec.rb
|
60
|
-
- spec/dance_spec.rb
|
61
58
|
- spec/logger_spec.rb
|
62
|
-
- spec/
|
59
|
+
- spec/met_and_meet_spec.rb
|
60
|
+
- spec/namespace_spec.rb
|
63
61
|
- tango.gemspec
|
64
62
|
has_rdoc: true
|
65
63
|
homepage: ""
|
@@ -96,7 +94,6 @@ signing_key:
|
|
96
94
|
specification_version: 3
|
97
95
|
summary: Experiment in deployment tools.
|
98
96
|
test_files:
|
99
|
-
- spec/dance_card_spec.rb
|
100
|
-
- spec/dance_spec.rb
|
101
97
|
- spec/logger_spec.rb
|
102
|
-
- spec/
|
98
|
+
- spec/met_and_meet_spec.rb
|
99
|
+
- spec/namespace_spec.rb
|
data/lib/tango/dance.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
module Tango
|
2
|
-
class Dance
|
3
|
-
|
4
|
-
def initialize(dance_card = nil, &block)
|
5
|
-
@dance_card = dance_card
|
6
|
-
@steps = {}
|
7
|
-
instance_eval(&block)
|
8
|
-
end
|
9
|
-
|
10
|
-
def step(name, &block)
|
11
|
-
raise StepAlreadyDefinedError, "Step #{name} already defined" if @steps.has_key?(name)
|
12
|
-
@steps[name] = block
|
13
|
-
end
|
14
|
-
|
15
|
-
def run(step_name, *args)
|
16
|
-
step = @steps[step_name]
|
17
|
-
raise UndefinedStepError, "Step #{step_name} not defined" if step.nil?
|
18
|
-
StepRunner.new(@dance_card || self).instance_exec(*args, &step)
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
22
|
-
end
|
data/lib/tango/dance_card.rb
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
require 'tango/logger'
|
2
|
-
require 'tango/noop_logger'
|
3
|
-
|
4
|
-
module Tango
|
5
|
-
class DanceCard
|
6
|
-
|
7
|
-
def self.instance
|
8
|
-
@dance_card ||= DanceCard.new(Logger.new)
|
9
|
-
end
|
10
|
-
|
11
|
-
def initialize(logger = nil)
|
12
|
-
@logger = logger || NoopLogger.new
|
13
|
-
@dances = {}
|
14
|
-
end
|
15
|
-
|
16
|
-
def dance(name, &block)
|
17
|
-
@dances[name] = Dance.new(self, &block)
|
18
|
-
end
|
19
|
-
|
20
|
-
def run(name, *args)
|
21
|
-
dance_name, step_name = *name.split(":")
|
22
|
-
@logger.enter(name)
|
23
|
-
@dances[dance_name].run(step_name, *args)
|
24
|
-
@logger.leave(name)
|
25
|
-
end
|
26
|
-
|
27
|
-
def log(message)
|
28
|
-
@logger.log(message)
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|
32
|
-
end
|
data/lib/tango/errors.rb
DELETED
data/lib/tango/noop_logger.rb
DELETED
data/lib/tango/step_runner.rb
DELETED
@@ -1,50 +0,0 @@
|
|
1
|
-
module Tango
|
2
|
-
# A step's block is instance_execed against one of these. It provides all the
|
3
|
-
# methods accessible from within the step.
|
4
|
-
class StepRunner
|
5
|
-
|
6
|
-
def initialize(context = nil)
|
7
|
-
@context = context
|
8
|
-
end
|
9
|
-
|
10
|
-
def met?(&met_block)
|
11
|
-
@met_block = met_block
|
12
|
-
end
|
13
|
-
|
14
|
-
def meet(&meet_block)
|
15
|
-
raise MeetWithoutMetError if @met_block.nil?
|
16
|
-
if instance_eval(&@met_block)
|
17
|
-
log "already met."
|
18
|
-
else
|
19
|
-
log "not already met."
|
20
|
-
instance_eval(&meet_block)
|
21
|
-
if instance_eval(&@met_block)
|
22
|
-
log "met."
|
23
|
-
else
|
24
|
-
raise CouldNotMeetError
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def run(step_name, *args)
|
30
|
-
@context.run(step_name, *args)
|
31
|
-
end
|
32
|
-
|
33
|
-
def as(username)
|
34
|
-
info = Etc.getpwent(username)
|
35
|
-
uid, gid = Process.euid, Process.egid
|
36
|
-
Process::Sys.seteuid(0) if uid != 0
|
37
|
-
Process::Sys.setegid(info.gid)
|
38
|
-
Process::Sys.seteuid(info.uid)
|
39
|
-
yield
|
40
|
-
ensure
|
41
|
-
Process::Sys.seteuid(uid)
|
42
|
-
Process::Sys.setegid(gid)
|
43
|
-
end
|
44
|
-
|
45
|
-
def log(message)
|
46
|
-
@context.log(message) unless @context.nil?
|
47
|
-
end
|
48
|
-
|
49
|
-
end
|
50
|
-
end
|
data/spec/dance_card_spec.rb
DELETED
@@ -1,56 +0,0 @@
|
|
1
|
-
require 'tango'
|
2
|
-
|
3
|
-
module Tango
|
4
|
-
describe DanceCard do
|
5
|
-
|
6
|
-
it "should run a step in a dance by name" do
|
7
|
-
step_run = false
|
8
|
-
card = DanceCard.new
|
9
|
-
card.dance "example dance" do
|
10
|
-
step "example step" do
|
11
|
-
step_run = true
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
card.run "example dance:example step"
|
16
|
-
|
17
|
-
step_run.should be_true
|
18
|
-
end
|
19
|
-
|
20
|
-
it "should pass arguments to a step" do
|
21
|
-
card = DanceCard.new
|
22
|
-
card.dance "example dance" do
|
23
|
-
step "example step" do |a, b|
|
24
|
-
a.should == 1
|
25
|
-
b.should == 2
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
card.run "example dance:example step", 1, 2
|
30
|
-
end
|
31
|
-
|
32
|
-
it "should call a step in another dance by name" do
|
33
|
-
step_run = false
|
34
|
-
|
35
|
-
card = DanceCard.new
|
36
|
-
|
37
|
-
card.dance "foxtrot" do
|
38
|
-
step "foxtrot step" do
|
39
|
-
step_run = true
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
card.dance "flamenco" do
|
44
|
-
step "flamenco step" do
|
45
|
-
run "foxtrot:foxtrot step"
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
card.run "flamenco:flamenco step"
|
50
|
-
|
51
|
-
step_run.should be_true
|
52
|
-
end
|
53
|
-
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
data/spec/step_runner_spec.rb
DELETED
@@ -1,67 +0,0 @@
|
|
1
|
-
require 'tango'
|
2
|
-
|
3
|
-
module Tango
|
4
|
-
describe StepRunner do
|
5
|
-
|
6
|
-
context "with a meet block and a met block" do
|
7
|
-
it "should check the met?, run the meet, then check the met? again" do
|
8
|
-
met_block_calls = 0
|
9
|
-
meet_block_calls = 0
|
10
|
-
|
11
|
-
StepRunner.new.instance_eval do
|
12
|
-
met? do
|
13
|
-
met_block_calls += 1
|
14
|
-
meet_block_calls > 0
|
15
|
-
end
|
16
|
-
meet { meet_block_calls += 1 }
|
17
|
-
end
|
18
|
-
|
19
|
-
met_block_calls.should == 2
|
20
|
-
meet_block_calls.should == 1
|
21
|
-
end
|
22
|
-
|
23
|
-
it "should not run the meet if the met? succeeds the first time" do
|
24
|
-
met_block_calls = 0
|
25
|
-
meet_block_calls = 0
|
26
|
-
|
27
|
-
StepRunner.new.instance_eval do
|
28
|
-
met? do
|
29
|
-
met_block_calls += 1
|
30
|
-
true
|
31
|
-
end
|
32
|
-
meet { meet_block_calls += 1 }
|
33
|
-
end
|
34
|
-
|
35
|
-
met_block_calls.should == 1
|
36
|
-
meet_block_calls.should == 0
|
37
|
-
end
|
38
|
-
|
39
|
-
it "should raise if the met? block fails twice" do
|
40
|
-
met_block_calls = 0
|
41
|
-
meet_block_calls = 0
|
42
|
-
|
43
|
-
expect do
|
44
|
-
StepRunner.new.instance_eval do
|
45
|
-
met? do
|
46
|
-
met_block_calls += 1
|
47
|
-
false
|
48
|
-
end
|
49
|
-
meet { meet_block_calls += 1 }
|
50
|
-
end
|
51
|
-
end.should raise_error(CouldNotMeetError)
|
52
|
-
|
53
|
-
met_block_calls.should == 2
|
54
|
-
meet_block_calls.should == 1
|
55
|
-
end
|
56
|
-
|
57
|
-
it "should raise an error if there's a meet block without a met block" do
|
58
|
-
expect do
|
59
|
-
StepRunner.new.instance_eval do
|
60
|
-
meet { }
|
61
|
-
end
|
62
|
-
end.should raise_error(MeetWithoutMetError)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
end
|
67
|
-
end
|