command_test 0.0.1

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.
@@ -0,0 +1,3 @@
1
+ == 0.0.1 2010-08-25
2
+
3
+ * Hi.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 George Ogata
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.
@@ -0,0 +1,109 @@
1
+ # Command Test
2
+
3
+ Test that your app runs or does not run commands.
4
+
5
+ ## Why?
6
+
7
+ Ruby has a bucket of ways to run commands:
8
+
9
+ * Kernel#system
10
+ * Kernel#`
11
+ * Kernel.open
12
+ * IO.popen
13
+ * Open3.popen3
14
+
15
+ Mocking becomes impractical because you seldom care *how* a command is
16
+ run, just that it *is* run (or not run). Methods that run the command
17
+ through the shell are also tricky to mock correctly, as extra shell
18
+ syntax can easily throw off the test.
19
+
20
+ ## How
21
+
22
+ ### RSpec
23
+
24
+ lambda do
25
+ ...
26
+ end.should run_command('convert', 'bad.gif', 'good.png')
27
+
28
+ ### Test::Unit
29
+
30
+ assert_runs_command 'convert', 'bad.gif', 'good.png' do
31
+ ...
32
+ end
33
+
34
+ assert_does_not_run_command 'convert', 'bad.gif', 'good.png' do
35
+ ...
36
+ end
37
+
38
+ ### Other frameworks
39
+
40
+ Not really using them myself, but I'll bet they're easy to add. Patch
41
+ me and be famous!
42
+
43
+ ## Tricks
44
+
45
+ ### Regexps
46
+
47
+ You can match arguments against regexps:
48
+
49
+ lambda do
50
+ ...
51
+ end.should run_command('convert', /.gif\z/, /.png\z/)
52
+
53
+ ### Wildcards
54
+
55
+ An integer, `n`, matches any `n` arguments:
56
+
57
+ lambda do
58
+ system 'diff', 'old.txt', 'new.txt')
59
+ end.should run_command('diff', 2)
60
+
61
+ An range matches any number of arguments in that range:
62
+
63
+ lambda do
64
+ system 'diff', '-w', 'one.txt', 'two.txt', 'three.txt'
65
+ end.should run_command('diff', '-w', 2..3)
66
+
67
+ `:*` matches any number of arguments:
68
+
69
+ lamdba do
70
+ system 'hostname'
71
+ end.should run_command('convert', :*, 'target.png')
72
+
73
+ `:+` matches at least one argument:
74
+
75
+ lamdba do
76
+ system 'hostname'
77
+ end.should run_command('gem', 'install', :+)
78
+
79
+ Any combination of wildcards can be used together.
80
+
81
+ ### Recording
82
+
83
+ You can record the commands run during a block:
84
+
85
+ commands = CommandTest.record do
86
+ system 'convert', 'bad.gif', 'good.png'
87
+ system 'identify', 'good.png'
88
+ end
89
+ commands # [['convert', 'bad.gif', 'good.png'], ['identify', 'good.png']]
90
+
91
+ And then match them yourself:
92
+
93
+ CommandTest.match?(commands.first, ['convert', :*])
94
+
95
+ You can use this to check that commands were run in a certain order, a
96
+ certain number of times, in a pretty pattern, ... the possibilities
97
+ are endless!
98
+
99
+ ## Contributing
100
+
101
+ * Bug reports: http://github.com/oggy/command_test/issues
102
+ * Source: http://github.com/oggy/command_test
103
+ * Patches: Fork on Github, send pull request.
104
+ * Ensure patch includes tests.
105
+ * Leave the version alone, or bump it in a separate commit.
106
+
107
+ ## Copyright
108
+
109
+ Copyright (c) 2010 George Ogata. See LICENSE for details.
@@ -0,0 +1,8 @@
1
+ require 'ritual'
2
+
3
+ spec_task :spec do |t|
4
+ t.pattern = 'spec/unit/**/*_spec.rb'
5
+ t.libs << 'lib' << 'spec'
6
+ end
7
+
8
+ cuke_task :cucumber
@@ -0,0 +1,60 @@
1
+ Feature: RSpec Integration
2
+
3
+ As a developer who uses RSpec
4
+ I want to use Command Test
5
+ So I can write beautiful tests
6
+
7
+ Scenario: Using run_command
8
+ Given I have a file "spec.rb" containing:
9
+ """
10
+ require 'command_test'
11
+
12
+ describe "#run_command" do
13
+ describe "when using should" do
14
+ it "should pass if the command is run" do
15
+ lambda do
16
+ system 'sh', '-c', ''
17
+ end.should run_command('sh', '-c', '')
18
+ end
19
+
20
+ it "should fail if the command is not run" do
21
+ lambda do
22
+ system 'sh', '-c', 'true'
23
+ end.should run_command('sh', '-c', '')
24
+ end
25
+ end
26
+
27
+ describe "when using should_not" do
28
+ it "should pass if the command is not run" do
29
+ lambda do
30
+ system 'sh', '-c', 'true'
31
+ end.should_not run_command('sh', '-c', '')
32
+ end
33
+
34
+ it "should fail if the command is run" do
35
+ lambda do
36
+ system 'sh', '-c', ''
37
+ end.should_not run_command('sh', '-c', '')
38
+ end
39
+ end
40
+ end
41
+ """
42
+ When I run "spec" on "spec.rb"
43
+ Then the output should contain ".F.F"
44
+ And the output should contain:
45
+ """
46
+ This command should have been run, but was not:
47
+ "sh" "-c" ""
48
+ These were the commands run:
49
+ "sh" "-c" "true"
50
+ """
51
+ And the output should contain:
52
+ """
53
+ This command should not have been run, but was:
54
+ "sh" "-c" ""
55
+ These were the commands run:
56
+ "sh" "-c" ""
57
+ """
58
+ And the output should contain in this order
59
+ | This command should have been run, but was not |
60
+ | This command should not have been run, but was |
@@ -0,0 +1,24 @@
1
+ Given /^I have a file "(.*?)" containing:$/ do |file_name, content|
2
+ path = "#{TMP}/#{file_name}"
3
+ open(path, 'w'){|f| f.print content}
4
+ end
5
+
6
+ When /^I run "(.*?)" on "(.*?)"$/ do |command, file_name|
7
+ Dir.chdir ROOT do
8
+ @output = `#{command} #{TMP}/#{file_name} 2>&1`
9
+ end
10
+ end
11
+
12
+ Then /^the output should contain "(.*?)"$/ do |fragment|
13
+ @output.should include(fragment)
14
+ end
15
+
16
+ Then /^the output should contain:$/ do |fragment|
17
+ @output.should include(fragment)
18
+ end
19
+
20
+ Then /^the output should contain in this order$/ do |table|
21
+ table.raw.inject(0) do |index, row|
22
+ index && @output.index(row.first, index)
23
+ end.should_not be_nil
24
+ end
@@ -0,0 +1,13 @@
1
+ require 'fileutils'
2
+ require 'spec/expectations'
3
+
4
+ ROOT = File.dirname(File.dirname(File.dirname(__FILE__)))
5
+ TMP = "#{ROOT}/features/tmp"
6
+
7
+ Before do
8
+ FileUtils.mkdir_p(TMP)
9
+ end
10
+
11
+ After do
12
+ FileUtils.rm_rf(TMP)
13
+ end
@@ -0,0 +1,58 @@
1
+ Feature: Test Unit Integration
2
+
3
+ As a developer who uses Test::Unit
4
+ I want to use Command Test
5
+ So I can write beautiful tests
6
+
7
+ Scenario: Using run_command
8
+ Given I have a file "test.rb" containing:
9
+ """
10
+ require 'test/unit'
11
+ require 'command_test'
12
+
13
+ class CommandTests < Test::Unit::TestCase
14
+ def test_assert_runs_command_passes_if_the_command_is_run
15
+ assert_runs_command 'sh', '-c', '' do
16
+ system 'sh', '-c', ''
17
+ end
18
+ end
19
+
20
+ def test_assert_runs_command_fails_if_the_command_is_not_run
21
+ assert_runs_command 'sh', '-c', '' do
22
+ system 'sh', '-c', 'true'
23
+ end
24
+ end
25
+
26
+ def test_assert_does_not_run_command_passes_if_the_command_is_not_run
27
+ assert_does_not_run_command 'sh', '-c', '' do
28
+ system 'sh', '-c', 'true'
29
+ end
30
+ end
31
+
32
+ def test_assert_does_not_run_command_fails_if_the_command_is_run
33
+ assert_does_not_run_command 'sh', '-c', '' do
34
+ system 'sh', '-c', ''
35
+ end
36
+ end
37
+ end
38
+ """
39
+ When I run "ruby -Ilib" on "test.rb"
40
+ # Test::Unit sorts tests alphabetically.
41
+ Then the output should contain "F.F."
42
+ And the output should contain:
43
+ """
44
+ This command should have been run, but was not:
45
+ "sh" "-c" ""
46
+ These were the commands run:
47
+ "sh" "-c" "true"
48
+ """
49
+ And the output should contain:
50
+ """
51
+ This command should not have been run, but was:
52
+ "sh" "-c" ""
53
+ These were the commands run:
54
+ "sh" "-c" ""
55
+ """
56
+ And the output should contain in this order
57
+ | This command should not have been run, but was |
58
+ | This command should have been run, but was not |
@@ -0,0 +1,70 @@
1
+ require 'shellwords'
2
+ require 'command_test/core_extensions'
3
+ require 'command_test/parser'
4
+ require 'command_test/matcher'
5
+ require 'command_test/adapters'
6
+ require 'command_test/tests'
7
+
8
+ module CommandTest
9
+ class << self
10
+ #
11
+ # Return the list of commands run during the given block.
12
+ #
13
+ # Each command is an Array of "words" (command and arguments).
14
+ #
15
+ def record
16
+ commands = []
17
+ recorders << lambda{|c| commands << c}
18
+ begin
19
+ yield
20
+ ensure
21
+ recorders.pop
22
+ end
23
+ commands
24
+ end
25
+
26
+ #
27
+ # Return true if the given +actual+ command matches the +expected+
28
+ # spec.
29
+ #
30
+ # The elements of +expected+ may be one of these:
31
+ #
32
+ # * A String in +expected+ matches the corresponding element in
33
+ # +actual+.
34
+ # * A Regexp must match the corresponding element in +actual+.
35
+ # * An Integer, n, matches the next n elements of +actual+.
36
+ # * A Range, a...b, can match the next i elements of +actual+,
37
+ # for a <= i < b.
38
+ # * :+ can match 1 or more elements in +actual+.
39
+ # * :* can match any number of elements (including zero) in
40
+ # +actual+.
41
+ #
42
+ def match?(expected, actual)
43
+ matcher.match?(expected, actual)
44
+ end
45
+
46
+ def record_command(command, *args) # :nodoc:
47
+ words = Shellwords.shellwords(command).concat(args)
48
+ recorders.each{|r| r.call(words)}
49
+ end
50
+
51
+ def record_interpreted_command(command) # :nodoc:
52
+ words = parser.parse(command)
53
+ recorders.each{|r| r.call(words)}
54
+ end
55
+
56
+ private
57
+
58
+ def recorders
59
+ Thread.current[:command_recorders] ||= []
60
+ end
61
+
62
+ def parser
63
+ @parser ||= Parser.new
64
+ end
65
+
66
+ def matcher
67
+ @matcher ||= Matcher.new
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,2 @@
1
+ require 'command_test/adapters/rspec' if Object.const_defined?(:Spec)
2
+ require 'command_test/adapters/test_unit' if Object.const_defined?(:Test) && Test.const_defined?(:Unit)
@@ -0,0 +1,41 @@
1
+ module CommandTest
2
+ module RSpec
3
+ module Matchers
4
+ #
5
+ # Matches if the proc runs the given command.
6
+ #
7
+ # lambda do
8
+ # ...
9
+ # end.should run_command('convert', 'evil.gif', 'good.png')
10
+ #
11
+ # Commands are matched according to CommandTest.match? .
12
+ #
13
+ def run_command(*command)
14
+ RunCommand.new(command)
15
+ end
16
+ end
17
+
18
+ class RunCommand
19
+ def initialize(expected)
20
+ @expected = expected
21
+ end
22
+
23
+ def matches?(proc)
24
+ @test = Tests::RunsCommand.new(@expected, &proc)
25
+ @test.matches?
26
+ end
27
+
28
+ def failure_message_for_should
29
+ @test.positive_failure_message
30
+ end
31
+
32
+ def failure_message_for_should_not
33
+ @test.negative_failure_message
34
+ end
35
+ end
36
+
37
+ ::Spec::Runner.configure do |config|
38
+ config.send :include, Matchers
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,43 @@
1
+ module CommandTest
2
+ module Adapters
3
+ module TestUnit
4
+ module Assertions
5
+ #
6
+ # Passes if the block runs the given command.
7
+ #
8
+ # assert_runs_command 'convert', 'evil.gif', 'good.png' do
9
+ # ...
10
+ # end
11
+ #
12
+ # Commands are matched according to CommandTest.match? .
13
+ #
14
+ def assert_runs_command(*expected, &block)
15
+ result = Tests::RunsCommand.new(expected, &block)
16
+ matches = result.matches?
17
+ assert_block(matches ? nil : result.positive_failure_message) do
18
+ matches
19
+ end
20
+ end
21
+
22
+ #
23
+ # Passes if the block does not run the given command.
24
+ #
25
+ # assert_does_not_run_command 'convert', 'evil.gif', 'good.png' do
26
+ # ...
27
+ # end
28
+ #
29
+ # Commands are matched according to CommandTest.match? .
30
+ #
31
+ def assert_does_not_run_command(*expected, &block)
32
+ result = Tests::RunsCommand.new(expected, &block)
33
+ matches = result.matches?
34
+ assert_block(matches ? result.negative_failure_message : nil) do
35
+ !matches
36
+ end
37
+ end
38
+ end
39
+
40
+ ::Test::Unit::TestCase.send :include, Assertions
41
+ end
42
+ end
43
+ end