cmd_line_test 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/MIT-LICENSE +22 -0
- data/README.rdoc +28 -0
- data/Rakefile +28 -0
- data/VERSION.yml +4 -0
- data/cmd_line_test.gemspec +49 -0
- data/lib/cmd_line_test.rb +128 -0
- data/test/cli_app.rb +31 -0
- data/test/shoulda/cli_test.rb +20 -0
- data/test/test.rb +65 -0
- data/test/test_helper.rb +3 -0
- data/test/unit/cli_test.rb +3 -0
- metadata +69 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2009, Fedor Kocherga <fkocherga@gmail.com>
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
4
|
+
obtaining a copy of this software and associated documentation
|
5
|
+
files (the "Software"), to deal in the Software without
|
6
|
+
restriction, including without limitation the rights to use,
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the
|
9
|
+
Software is furnished to do so, subject to the following
|
10
|
+
conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
= cmd_line_test - Extends Shoulda or Test::Unit with macros for testing command line apps
|
2
|
+
|
3
|
+
= Basic Usage
|
4
|
+
|
5
|
+
== Installation
|
6
|
+
$ sudo gem install cmd_line_test --source=http://gemcutter.org
|
7
|
+
|
8
|
+
== Example
|
9
|
+
If you are about to start writing new command line utility MyCommandLineApp, you probably want to specify its options and behavior, likely in form of tests. This gem is aimed to simplify creation of such tests:
|
10
|
+
|
11
|
+
|
12
|
+
requrie 'cmd_line_test'
|
13
|
+
|
14
|
+
class CliTest < Test::Unit::TestCase
|
15
|
+
run_command_line_as {MyCommandLineApp.run}
|
16
|
+
|
17
|
+
run_with_argv "--help" do
|
18
|
+
assert_successful_run
|
19
|
+
assert_out_contains /Usage:/
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
= Shortcumings
|
24
|
+
Only tested on the 1.8.7 Ruby implementation and with Shoulda 2.10.1
|
25
|
+
|
26
|
+
= License
|
27
|
+
cmd_line_test is released under the MIT license.
|
28
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
|
5
|
+
Rake::TestTask.new do |t|
|
6
|
+
t.libs << "test"
|
7
|
+
t.test_files = FileList['test/shoulda/cli_test.rb', 'test/unit/cli_test.rb']
|
8
|
+
t.verbose = true
|
9
|
+
end
|
10
|
+
|
11
|
+
begin
|
12
|
+
require 'jeweler'
|
13
|
+
gemspec = Gem::Specification.new do |s|
|
14
|
+
|
15
|
+
s.name = "cmd_line_test"
|
16
|
+
s.summary = "Extends Shoulda or Test::Unit with macros for testing command line apps."
|
17
|
+
s.email = "fkocherga@gmail.com"
|
18
|
+
s.homepage = "http://github.com/fkocherga/cmd_line_test"
|
19
|
+
s.description = <<END
|
20
|
+
Macros specific to command line Ruby apps testing. Works with Test::Unit or Shoulda.
|
21
|
+
END
|
22
|
+
s.authors = ["Fedor Kocherga"]
|
23
|
+
s.test_files = ['test/shoulda/cli_test.rb', 'test/unit/cli_test.rb']
|
24
|
+
end
|
25
|
+
Jeweler::Tasks.new gemspec
|
26
|
+
rescue LoadError
|
27
|
+
puts "Jeweler not available. Install it with: sudo gem install jeweler"
|
28
|
+
end
|
data/VERSION.yml
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{cmd_line_test}
|
5
|
+
s.version = "0.1.4"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Fedor Kocherga"]
|
9
|
+
s.date = %q{2009-10-03}
|
10
|
+
s.description = %q{Macros specific to command line Ruby apps testing. Works with Test::Unit or Shoulda.
|
11
|
+
}
|
12
|
+
s.email = %q{fkocherga@gmail.com}
|
13
|
+
s.extra_rdoc_files = [
|
14
|
+
"README.rdoc"
|
15
|
+
]
|
16
|
+
s.files = [
|
17
|
+
".gitignore",
|
18
|
+
"MIT-LICENSE",
|
19
|
+
"README.rdoc",
|
20
|
+
"Rakefile",
|
21
|
+
"VERSION.yml",
|
22
|
+
"cmd_line_test.gemspec",
|
23
|
+
"lib/cmd_line_test.rb",
|
24
|
+
"test/cli_app.rb",
|
25
|
+
"test/shoulda/cli_test.rb",
|
26
|
+
"test/test.rb",
|
27
|
+
"test/test_helper.rb",
|
28
|
+
"test/unit/cli_test.rb"
|
29
|
+
]
|
30
|
+
s.homepage = %q{http://github.com/fkocherga/cml_line_test}
|
31
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
32
|
+
s.require_paths = ["lib"]
|
33
|
+
s.rubygems_version = %q{1.3.5}
|
34
|
+
s.summary = %q{Extends Shoulda or Test::Unit with macros for testing command line apps.}
|
35
|
+
s.test_files = [
|
36
|
+
"test/shoulda/cli_test.rb",
|
37
|
+
"test/unit/cli_test.rb"
|
38
|
+
]
|
39
|
+
|
40
|
+
if s.respond_to? :specification_version then
|
41
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
42
|
+
s.specification_version = 3
|
43
|
+
|
44
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
45
|
+
else
|
46
|
+
end
|
47
|
+
else
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
module CmdLineTest
|
2
|
+
module ClassMethods
|
3
|
+
attr_accessor :cli_exit_status, :cli_output, :cli_error, :cli_error_stack, :cli_block, :show_output
|
4
|
+
|
5
|
+
def run_command_line_as(options = nil, &block)
|
6
|
+
self.show_output = options && options[:show_output] || false
|
7
|
+
self.cli_block = block
|
8
|
+
end
|
9
|
+
end #ClassMethods
|
10
|
+
|
11
|
+
module InstanceMethods
|
12
|
+
def run_with_argv(*args)
|
13
|
+
with_ARGV_set_to(*args) {execute}
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
def execute
|
18
|
+
self.class.cli_block.call
|
19
|
+
end
|
20
|
+
|
21
|
+
def with_ARGV_set_to(*args)
|
22
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
23
|
+
ignore_assignment_to_const_warning { Object.const_set(:ARGV, args) }
|
24
|
+
yield args, options
|
25
|
+
end
|
26
|
+
|
27
|
+
def ignore_assignment_to_const_warning
|
28
|
+
warnings_option = $-w
|
29
|
+
$-w = nil
|
30
|
+
begin
|
31
|
+
yield
|
32
|
+
ensure
|
33
|
+
$-w = warnings_option
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end #InstanceMethods
|
37
|
+
|
38
|
+
module Macros
|
39
|
+
def run_with_argv(*args, &block)
|
40
|
+
raise RuntimeError, "Command is not defined: 'run_command_line_as()' must be called first." unless
|
41
|
+
self.cli_block
|
42
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
43
|
+
argv = args
|
44
|
+
test_name = options[:name] || "after running with arguments '#{argv.join(', ')}'"
|
45
|
+
generate_test test_name do
|
46
|
+
with_ARGV_set_to *argv do
|
47
|
+
begin
|
48
|
+
self.class.cli_exit_status = 0
|
49
|
+
self.class.cli_error = ""
|
50
|
+
self.class.cli_error_stack = ""
|
51
|
+
self.class.cli_output = ""
|
52
|
+
$test_class = self.class
|
53
|
+
#It used to be $stdout = StringIO.new(...), but it does not work well with rdebug
|
54
|
+
class <<$stdout
|
55
|
+
alias_method :original_write, :write
|
56
|
+
def write(*s)
|
57
|
+
original_write(s) if $test_class.show_output
|
58
|
+
$test_class.cli_output << s.to_s if $test_class.cli_output
|
59
|
+
end
|
60
|
+
end
|
61
|
+
execute
|
62
|
+
rescue SystemExit => exit_error
|
63
|
+
self.class.cli_exit_status = exit_error.status
|
64
|
+
rescue Exception => error
|
65
|
+
self.class.cli_error_stack = error.backtrace.join("\n")
|
66
|
+
self.class.cli_error = error.message
|
67
|
+
ensure
|
68
|
+
class <<$stdout
|
69
|
+
remove_method :write, :original_write
|
70
|
+
end
|
71
|
+
end
|
72
|
+
instance_eval(&block)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def run_and_succeed(*args, &block)
|
78
|
+
run_with_argv(*args) do
|
79
|
+
assert_successful_run
|
80
|
+
instance_eval(&block) if block
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def run_and_fail(*args, &block)
|
85
|
+
run_with_argv(*args) do
|
86
|
+
assert_failed_run
|
87
|
+
instance_eval(&block) if block
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
def generate_test(name, &block)
|
93
|
+
if defined? Shoulda
|
94
|
+
should(name, &block)
|
95
|
+
else
|
96
|
+
test_name = ("test_".concat name).strip.to_sym
|
97
|
+
self.send(:define_method, test_name, &block)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end #Macros
|
101
|
+
|
102
|
+
module Assertions
|
103
|
+
def assert_successful_run
|
104
|
+
expect_message = "Should run successfully, but"
|
105
|
+
assert_equal 0, self.class.cli_exit_status, "#{expect_message} exit status is #{self.class.cli_exit_status}"
|
106
|
+
assert self.class.cli_error.empty?, "#{expect_message} exception '#{self.class.cli_error}' has been thrown. Exception stack:\n" + self.class.cli_error_stack
|
107
|
+
end
|
108
|
+
|
109
|
+
def assert_failed_run
|
110
|
+
flunk "Expects either thrown error or exit status not 0." if 0 == self.class.cli_exit_status && self.class.cli_error.empty?
|
111
|
+
end
|
112
|
+
|
113
|
+
def assert_out_contains regex
|
114
|
+
assert_match regex, self.class.cli_output
|
115
|
+
end
|
116
|
+
end #Assertions
|
117
|
+
end
|
118
|
+
|
119
|
+
module Test
|
120
|
+
module Unit
|
121
|
+
class TestCase
|
122
|
+
extend CmdLineTest::ClassMethods
|
123
|
+
include CmdLineTest::InstanceMethods
|
124
|
+
extend CmdLineTest::Macros
|
125
|
+
include CmdLineTest::Assertions
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
data/test/cli_app.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
module CliApp
|
4
|
+
class CliException < StandardError
|
5
|
+
end
|
6
|
+
class <<self
|
7
|
+
def run
|
8
|
+
OptionParser.new do |opts|
|
9
|
+
opts.banner = "Usage: cli.rb [options]\nCommand line test app."
|
10
|
+
|
11
|
+
opts.on( "--option OPTIONIAL", "run with OPTIONIAL") do |option|
|
12
|
+
puts option
|
13
|
+
end
|
14
|
+
|
15
|
+
opts.on( "--raise", "raise CliException") do
|
16
|
+
raise CliException, "CLI exception"
|
17
|
+
end
|
18
|
+
|
19
|
+
opts.on_tail("-h", "--help", "show help") do
|
20
|
+
puts opts
|
21
|
+
#exit NB!
|
22
|
+
end
|
23
|
+
end.parse!
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
if $0 == __FILE__
|
30
|
+
CliApp.run
|
31
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'shoulda'
|
3
|
+
require File.dirname(__FILE__) + '/../test'
|
4
|
+
|
5
|
+
class CliShouldaSpecificTest < Test::Unit::TestCase
|
6
|
+
run_command_line_as {CliApp.run}
|
7
|
+
|
8
|
+
context "outer" do
|
9
|
+
run_with_argv "--option", "OUTER" do
|
10
|
+
assert_out_contains /OUTER/
|
11
|
+
end
|
12
|
+
context "inner" do
|
13
|
+
run_with_argv "--option", "INNER" do
|
14
|
+
assert_out_contains /INNER/
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
|
data/test/test.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
class CliUsageTest < Test::Unit::TestCase
|
4
|
+
run_command_line_as {CliApp.run}
|
5
|
+
|
6
|
+
run_with_argv :name => 'no argv' do
|
7
|
+
assert_successful_run
|
8
|
+
end
|
9
|
+
|
10
|
+
run_and_succeed :name => 'no argv, shorter form'
|
11
|
+
|
12
|
+
run_and_succeed "--help" do
|
13
|
+
assert_out_contains /Usage:/
|
14
|
+
end
|
15
|
+
|
16
|
+
run_and_succeed "--option", "PRINT_THIS" do
|
17
|
+
assert_out_contains /PRINT_THIS/
|
18
|
+
end
|
19
|
+
|
20
|
+
run_and_succeed :name => "run_with_argv could be used within block" do
|
21
|
+
run_with_argv
|
22
|
+
end
|
23
|
+
|
24
|
+
run_and_fail "--invalid-option", :name => "running with invalid option" do
|
25
|
+
exception_raised = false
|
26
|
+
begin
|
27
|
+
assert_successful_run
|
28
|
+
rescue Exception
|
29
|
+
exception_raised = true
|
30
|
+
end
|
31
|
+
assert(exception_raised)
|
32
|
+
end
|
33
|
+
|
34
|
+
run_and_fail "--raise", :name => "raise exception" do
|
35
|
+
exception_raised = false
|
36
|
+
begin
|
37
|
+
assert_successful_run
|
38
|
+
rescue StandardError => error
|
39
|
+
assert error.to_s =~ /CLI exception/
|
40
|
+
exception_raised = true
|
41
|
+
end
|
42
|
+
assert(exception_raised)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class CliTestNoCommandLineDefined < Test::Unit::TestCase
|
47
|
+
def test_failure_when_command_line_defined
|
48
|
+
assert_raise(RuntimeError) {self.class.run_with_argv}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class CliTestShowOutput < Test::Unit::TestCase
|
53
|
+
|
54
|
+
run_command_line_as(:show_output => true) {CliApp.run}
|
55
|
+
|
56
|
+
@@captured_out = ""
|
57
|
+
@@original_stdout = $stdout
|
58
|
+
@@string_out = StringIO.new(@@captured_out)
|
59
|
+
$stdout = @@string_out
|
60
|
+
run_and_succeed "--help" do
|
61
|
+
$stdout.flush
|
62
|
+
$stdout = @@original_stdout
|
63
|
+
assert_match /Usage:/, @@captured_out
|
64
|
+
end
|
65
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cmd_line_test
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.4
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Fedor Kocherga
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-10-03 00:00:00 +04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: |
|
17
|
+
Macros specific to command line Ruby apps testing. Works with Test::Unit or Shoulda.
|
18
|
+
|
19
|
+
email: fkocherga@gmail.com
|
20
|
+
executables: []
|
21
|
+
|
22
|
+
extensions: []
|
23
|
+
|
24
|
+
extra_rdoc_files:
|
25
|
+
- README.rdoc
|
26
|
+
files:
|
27
|
+
- .gitignore
|
28
|
+
- MIT-LICENSE
|
29
|
+
- README.rdoc
|
30
|
+
- Rakefile
|
31
|
+
- VERSION.yml
|
32
|
+
- cmd_line_test.gemspec
|
33
|
+
- lib/cmd_line_test.rb
|
34
|
+
- test/cli_app.rb
|
35
|
+
- test/shoulda/cli_test.rb
|
36
|
+
- test/test.rb
|
37
|
+
- test/test_helper.rb
|
38
|
+
- test/unit/cli_test.rb
|
39
|
+
has_rdoc: true
|
40
|
+
homepage: http://github.com/fkocherga/cml_line_test
|
41
|
+
licenses: []
|
42
|
+
|
43
|
+
post_install_message:
|
44
|
+
rdoc_options:
|
45
|
+
- --charset=UTF-8
|
46
|
+
require_paths:
|
47
|
+
- lib
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: "0"
|
53
|
+
version:
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: "0"
|
59
|
+
version:
|
60
|
+
requirements: []
|
61
|
+
|
62
|
+
rubyforge_project:
|
63
|
+
rubygems_version: 1.3.5
|
64
|
+
signing_key:
|
65
|
+
specification_version: 3
|
66
|
+
summary: Extends Shoulda or Test::Unit with macros for testing command line apps.
|
67
|
+
test_files:
|
68
|
+
- test/shoulda/cli_test.rb
|
69
|
+
- test/unit/cli_test.rb
|