spex 0.5.2 → 0.6.0

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/Rakefile CHANGED
@@ -12,6 +12,7 @@ begin
12
12
  gem.authors = ["Bruce Williams"]
13
13
  gem.add_dependency "colored"
14
14
  gem.add_dependency "diff-lcs"
15
+ gem.add_dependency "facter"
15
16
  end
16
17
  Jeweler::GemcutterTasks.new
17
18
  rescue LoadError
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.2
1
+ 0.6.0
@@ -0,0 +1,16 @@
1
+ # Note: We use the more specific 'postfix/master' as the process name so
2
+ # we don't confused with spex running this file (postfix.rb)
3
+ scenario "Postfix process management" do
4
+ executing "sudo postfix start" do
5
+ assert 'postfix/master', :started => true
6
+ end
7
+ executing "sudo postfix stop" do
8
+ assert 'postfix/master', :stopped => true
9
+ end
10
+ executing "sudo postfix start" do
11
+ assert 'postfix/master', :started => true
12
+ end
13
+ executing "sudo postfix stop && sudo postfix start" do
14
+ assert 'postfix/master', :restarted => true
15
+ end
16
+ end
data/lib/spex.rb CHANGED
@@ -1,3 +1,9 @@
1
+ begin
2
+ require 'facter'
3
+ rescue LoadError
4
+ abort "Requires 'facter'"
5
+ end
6
+
1
7
  module Spex
2
8
  autoload :Assertion, 'spex/assertion'
3
9
  autoload :CLI, 'spex/cli'
@@ -0,0 +1,28 @@
1
+ module Spex
2
+ class ProcessAssertion < Assertion
3
+
4
+ def pattern
5
+ @pattern ||= target.is_a?(Regexp) ? target : Regexp.new(target)
6
+ end
7
+
8
+ def ps_executable
9
+ ps = Facter.value(:ps)
10
+ if ps && !ps.empty?
11
+ ps
12
+ else
13
+ abort "Facter does not support 'ps' fact."
14
+ end
15
+ end
16
+
17
+ def current_pid
18
+ table = IO.popen(ps_executable) { |ps| ps.readlines }
19
+ table.each do |line|
20
+ if pattern.match(line)
21
+ return line.sub(/^\s+/, '').split(/\s+/)[1]
22
+ end
23
+ end
24
+ nil
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,22 @@
1
+ module Spex
2
+ class RestartedAssertion < ProcessAssertion
3
+ as :restarted, 'process restart'
4
+ example "Process was restarted", "assert 'postfix', :restarted => true"
5
+ example "Process was not restarted", "assert 'postfix', :restarted => false"
6
+
7
+ def before
8
+ @before_pid = current_pid
9
+ assert @before_pid, "Process '#{target}' is not running"
10
+ end
11
+
12
+ def after
13
+ after_pid = current_pid
14
+ assert after_pid, "Process '#{target}' is not running"
15
+ if active?
16
+ assert_not_equal @before_pid, after_pid, "Process '#{target}' pid was not changed (still #{@before_pid})"
17
+ else
18
+ assert_equal @before_pid, after_pid, "Process '#{target}' pid was changed (was #{@before_pid}, now #{after_pid})"
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,21 @@
1
+ module Spex
2
+ class StartedAssertion < ProcessAssertion
3
+ as :started, 'process start'
4
+ example "Process was started", "assert 'postfix', :started => true"
5
+ example "Process was not started", "assert 'postfix', :started => false"
6
+
7
+ def before
8
+ pid = current_pid
9
+ assert !pid, "Process '#{target}' is already running (pid #{pid})"
10
+ end
11
+
12
+ def after
13
+ if active?
14
+ assert current_pid, "Process '#{target}' was not started"
15
+ else
16
+ pid = current_pid
17
+ assert_nil pid, "Process '#{target}' was started (pid #{pid})"
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,20 @@
1
+ module Spex
2
+ class StoppedAssertion < ProcessAssertion
3
+ as :stopped, 'process stop'
4
+ example "Process was stopped", "assert 'postfix', :stopped => true"
5
+ example "Process was not stopped", "assert 'postfix', :stopped => false"
6
+
7
+ def before
8
+ assert current_pid, "Process '#{target}' is not running (will not be stopped)"
9
+ end
10
+
11
+ def after
12
+ pid = current_pid
13
+ if active?
14
+ assert_nil pid, "Process '#{target}' is still running (pid #{pid})"
15
+ else
16
+ assert_not_nil pid, "Process '#{target}' was stopped"
17
+ end
18
+ end
19
+ end
20
+ end
data/lib/spex/runner.rb CHANGED
@@ -15,10 +15,10 @@ module Spex
15
15
  end
16
16
 
17
17
  def run
18
- puts %(Running scenario "#{scenario.name}").bold
18
+ puts %(Running scenario "#{scenario.name}").magenta.bold
19
19
  proceed = true
20
20
  scenario.each do |execution|
21
- puts "Checking pre-assertions"
21
+ puts %(Preparing to execute "#{execution.command}").bold
22
22
  execution.assertions.each do |assertion|
23
23
  print "Pre-assertions for #{assertion}: "
24
24
  assertion.prepare
@@ -26,24 +26,26 @@ module Spex
26
26
  break unless proceed
27
27
  end
28
28
  if proceed
29
- puts %(Executing "#{execution.command}")
29
+ print %(Executing "#{execution.command}": )
30
+ start = Time.now
30
31
  log = execute(execution)
32
+ elapsed = Time.now - start
33
+ puts 'DONE (%.2fs)' % elapsed
31
34
  passed = true
32
35
  execution.assertions.reverse.each do |assertion|
33
36
  print "Post-assertions for #{assertion}: "
34
37
  passed = report { assertion.after }
35
38
  break unless passed
36
39
  end
37
- if passed
38
- puts "SCENARIO PASSED".green.bold
39
- else
40
- abort "SCENARIO FAILED".red.bold
40
+ unless passed
41
+ abort "SCENARIO ASSERTIONS FAILED".red.bold
41
42
  end
42
43
  output_log(execution, log)
43
44
  else
44
45
  abort "SCENARIO FAILED (EXECUTION ABORTED)".red.bold
45
46
  end
46
47
  end
48
+ puts "SCENARIO PASSED".green.bold
47
49
  end
48
50
 
49
51
  def report(&block)
data/test/helper.rb CHANGED
@@ -7,6 +7,7 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
7
7
  $LOAD_PATH.unshift(File.dirname(__FILE__))
8
8
  require 'spex'
9
9
  require 'fakefs/safe'
10
+ require 'flexmock/test_unit'
10
11
 
11
12
  class Test::Unit::TestCase
12
13
 
@@ -23,10 +24,27 @@ class Test::Unit::TestCase
23
24
  @assertion.after
24
25
  end
25
26
 
27
+ def assertion_fails_before
28
+ assert_raises Test::Unit::AssertionFailedError do
29
+ @assertion.prepare
30
+ @assertion.before
31
+ end
32
+ end
33
+
26
34
  def assertion_fails(&block)
27
35
  assert_raises Test::Unit::AssertionFailedError do
28
36
  assertion_passes(&block)
29
37
  end
30
38
  end
39
+
40
+ def start_process!(pid = '100')
41
+ flexmock(@assertion).flexmock_teardown
42
+ flexmock(@assertion).should_receive(:current_pid).and_return(pid)
43
+ end
44
+
45
+ def stop_process!
46
+ flexmock(@assertion).flexmock_teardown
47
+ flexmock(@assertion).should_receive(:current_pid).and_return(nil)
48
+ end
31
49
 
32
50
  end
@@ -1,6 +1,6 @@
1
1
  require 'helper'
2
2
 
3
- class TestAssertion < Test::Unit::TestCase
3
+ class TestModifiedAssertion < Test::Unit::TestCase
4
4
 
5
5
  def set_assertion(options = {})
6
6
  @assertion = Spex::ModifiedAssertion.new(@filename, options)
@@ -0,0 +1,77 @@
1
+ require 'helper'
2
+
3
+ class TestRestartedAssertion < Test::Unit::TestCase
4
+
5
+ def set_assertion(options = {})
6
+ @assertion = Spex::RestartedAssertion.new('testproc', options)
7
+ end
8
+
9
+ context "Restarted Assertion" do
10
+ context "instances" do
11
+ context "set to true" do
12
+ setup do
13
+ set_assertion(true)
14
+ end
15
+ context "process running before execution" do
16
+ setup do
17
+ start_process!
18
+ end
19
+ context "and process running after execution" do
20
+ context "with the same pid" do
21
+ should 'fail' do
22
+ assertion_fails
23
+ end
24
+ end
25
+ context "with a different pid" do
26
+ should 'pass' do
27
+ assertion_passes { start_process!('101') }
28
+ end
29
+ end
30
+ end
31
+ context "but process not running after execution" do
32
+ should "fail" do
33
+ assertion_fails
34
+ end
35
+ end
36
+ end
37
+ context "process not running before execution" do
38
+ should "fail" do
39
+ assertion_fails_before
40
+ end
41
+ end
42
+ end
43
+ context "set to false" do
44
+ setup do
45
+ set_assertion(false)
46
+ end
47
+ context "process running before execution" do
48
+ setup do
49
+ start_process!
50
+ end
51
+ context "and process running after execution" do
52
+ context "with the same pid" do
53
+ should 'pass' do
54
+ assertion_passes
55
+ end
56
+ end
57
+ context "with a different pid" do
58
+ should 'fail' do
59
+ assertion_fails { start_process!('101') }
60
+ end
61
+ end
62
+ end
63
+ context "but process not running after execution" do
64
+ should "fail" do
65
+ assertion_fails { stop_process! }
66
+ end
67
+ end
68
+ end
69
+ context "process not running before execution" do
70
+ should "fail" do
71
+ assertion_fails_before
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,63 @@
1
+ require 'helper'
2
+
3
+ class TestStartedAssertion < Test::Unit::TestCase
4
+
5
+ def set_assertion(options = {})
6
+ @assertion = Spex::StartedAssertion.new('testproc', options)
7
+ end
8
+
9
+ context "Started Assertion" do
10
+ context "instances" do
11
+ context "set to true" do
12
+ setup do
13
+ set_assertion(true)
14
+ end
15
+ context "process running before execution" do
16
+ setup do
17
+ start_process!
18
+ end
19
+ should "fail" do
20
+ assertion_fails_before
21
+ end
22
+ end
23
+ context "process not running before execution" do
24
+ context "process running after execution" do
25
+ should "pass" do
26
+ assertion_passes { start_process! }
27
+ end
28
+ end
29
+ context "process not running after execution" do
30
+ should 'fail' do
31
+ assertion_fails
32
+ end
33
+ end
34
+ end
35
+ end
36
+ context "set to false" do
37
+ setup do
38
+ set_assertion(false)
39
+ end
40
+ context "process running before execution" do
41
+ setup do
42
+ start_process!
43
+ end
44
+ should "fail" do
45
+ assertion_fails_before
46
+ end
47
+ end
48
+ context "process not running before execution" do
49
+ context "but process running after execution" do
50
+ should "fail" do
51
+ assertion_fails { start_process! }
52
+ end
53
+ end
54
+ context "but process not running after execution" do
55
+ should 'pass' do
56
+ assertion_passes
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,63 @@
1
+ require 'helper'
2
+
3
+ class TestStoppedAssertion < Test::Unit::TestCase
4
+
5
+ def set_assertion(options = {})
6
+ @assertion = Spex::StoppedAssertion.new('testproc', options)
7
+ end
8
+
9
+ context "Stopped Assertion" do
10
+ context "instances" do
11
+ context "set to true" do
12
+ setup do
13
+ set_assertion(true)
14
+ end
15
+ context "process running before execution" do
16
+ setup do
17
+ start_process!
18
+ end
19
+ context "and process running after execution" do
20
+ should 'fail' do
21
+ assertion_fails
22
+ end
23
+ end
24
+ context "but process not running after execution" do
25
+ should "pass" do
26
+ assertion_passes { stop_process! }
27
+ end
28
+ end
29
+ end
30
+ context "process not running before execution" do
31
+ should "fail" do
32
+ assertion_fails_before
33
+ end
34
+ end
35
+ end
36
+ context "set to false" do
37
+ setup do
38
+ set_assertion(false)
39
+ end
40
+ context "process running before execution" do
41
+ setup do
42
+ start_process!
43
+ end
44
+ context "and process running after execution" do
45
+ should 'pass' do
46
+ assertion_passes
47
+ end
48
+ end
49
+ context "but process not running after execution" do
50
+ should "fail" do
51
+ assertion_fails { stop_process! }
52
+ end
53
+ end
54
+ end
55
+ context "process not running before execution" do
56
+ should "fail" do
57
+ assertion_fails_before
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 5
8
- - 2
9
- version: 0.5.2
7
+ - 6
8
+ - 0
9
+ version: 0.6.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Bruce Williams
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-04-14 00:00:00 -07:00
17
+ date: 2010-04-15 00:00:00 -07:00
18
18
  default_executable: spex
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -41,6 +41,18 @@ dependencies:
41
41
  version: "0"
42
42
  type: :runtime
43
43
  version_requirements: *id002
44
+ - !ruby/object:Gem::Dependency
45
+ name: facter
46
+ prerelease: false
47
+ requirement: &id003 !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ segments:
52
+ - 0
53
+ version: "0"
54
+ type: :runtime
55
+ version_requirements: *id003
44
56
  description: An easy-to-use test harness that runs assertions before and after and executable is run
45
57
  email: bruce@codefluency.com
46
58
  executables:
@@ -61,6 +73,7 @@ files:
61
73
  - examples/chgrp.rb
62
74
  - examples/chmod.rb
63
75
  - examples/chown.rb
76
+ - examples/postfix.rb
64
77
  - examples/puppet.rb
65
78
  - examples/touch.rb
66
79
  - examples/writing.rb
@@ -72,7 +85,11 @@ files:
72
85
  - lib/spex/assertions/created_assertion.rb
73
86
  - lib/spex/assertions/file_assertion.rb
74
87
  - lib/spex/assertions/modified_assertion.rb
88
+ - lib/spex/assertions/process_assertion.rb
75
89
  - lib/spex/assertions/removed_assertion.rb
90
+ - lib/spex/assertions/restarted_assertion.rb
91
+ - lib/spex/assertions/started_assertion.rb
92
+ - lib/spex/assertions/stopped_assertion.rb
76
93
  - lib/spex/cli.rb
77
94
  - lib/spex/execution.rb
78
95
  - lib/spex/runner.rb
@@ -81,7 +98,10 @@ files:
81
98
  - test/helper.rb
82
99
  - test/test_assertion.rb
83
100
  - test/test_modified_assertion.rb
101
+ - test/test_restarted_assertion.rb
84
102
  - test/test_script.rb
103
+ - test/test_started_assertion.rb
104
+ - test/test_stopped_assertion.rb
85
105
  has_rdoc: true
86
106
  homepage: http://github.com/bruce/spex
87
107
  licenses: []
@@ -116,10 +136,14 @@ test_files:
116
136
  - test/helper.rb
117
137
  - test/test_assertion.rb
118
138
  - test/test_modified_assertion.rb
139
+ - test/test_restarted_assertion.rb
119
140
  - test/test_script.rb
141
+ - test/test_started_assertion.rb
142
+ - test/test_stopped_assertion.rb
120
143
  - examples/chgrp.rb
121
144
  - examples/chmod.rb
122
145
  - examples/chown.rb
146
+ - examples/postfix.rb
123
147
  - examples/puppet.rb
124
148
  - examples/touch.rb
125
149
  - examples/writing.rb