webmat-capture_fu 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.
- data/README +27 -0
- data/Rakefile +71 -0
- data/TODO +12 -0
- data/lib/capture_fu.rb +58 -0
- data/test/functional/capture_output_test.rb +47 -0
- data/test/functional/capture_process_output_test.rb +45 -0
- data/test/unit/intrusiveness_test.rb +31 -0
- metadata +65 -0
data/README
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
capture_fu is a small library that facilitates capture of stdout and stderr outputs.
|
2
|
+
|
3
|
+
This can be useful for testing console output of command-line tools or to wrap the use of another command-line tool inside your program.
|
4
|
+
|
5
|
+
|
6
|
+
Usage
|
7
|
+
|
8
|
+
Let's simply go by example:
|
9
|
+
out = capture_output{ puts 'normal output' ; $stderr.puts 'error' ; 'the return value of the block' }
|
10
|
+
#=> ["the return value of the block", "normal output\n", "error\n"]
|
11
|
+
|
12
|
+
Or if you prefer:
|
13
|
+
ret, out, err = capture_output{ puts 'normal output' ; $stderr.puts 'error' ; 'the return value of the block' }
|
14
|
+
|
15
|
+
|
16
|
+
Note that the output generated inside capture_output's block is not displayed at the console.
|
17
|
+
|
18
|
+
|
19
|
+
Installation
|
20
|
+
|
21
|
+
gem install webmat-capture_fu --source=http://gems.github.com
|
22
|
+
and
|
23
|
+
require 'capture_fu'
|
24
|
+
|
25
|
+
|
26
|
+
Authors
|
27
|
+
- Mathieu Martin, webmat@gmail.com
|
data/Rakefile
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
require 'rake'
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'rake/gempackagetask'
|
6
|
+
|
7
|
+
require 'yaml'
|
8
|
+
|
9
|
+
require "#{File.dirname(__FILE__)}/lib/capture_fu"
|
10
|
+
|
11
|
+
|
12
|
+
NAME = 'capture_fu'
|
13
|
+
|
14
|
+
windows = (RUBY_PLATFORM =~ /win32|cygwin/) rescue nil
|
15
|
+
install_home = ENV['GEM_HOME'] ? "-i #{ENV['GEM_HOME']}" : ""
|
16
|
+
SUDO = windows ? "" : "sudo"
|
17
|
+
|
18
|
+
|
19
|
+
spec = Gem::Specification.new do |s|
|
20
|
+
s.name = NAME
|
21
|
+
s.version = CaptureFu::VERSION
|
22
|
+
s.summary = "capture_fu facilitates the capture of stdout and stderr output"
|
23
|
+
|
24
|
+
s.authors << "Mathieu Martin"
|
25
|
+
s.email = "webmat@gmail.com"
|
26
|
+
s.homepage = "http://github.com/webmat/capture_fu"
|
27
|
+
s.description = "capture_fu is a small library that facilitates capture of stdout " +
|
28
|
+
"and stderr output, of either subprocesses or plain old Ruby code."
|
29
|
+
|
30
|
+
s.files = Dir['lib/**/*.rb', 'bin/*', '[A-Z]*', 'test/**/*.rb']
|
31
|
+
s.test_files = Dir['test/**/*.rb']
|
32
|
+
|
33
|
+
s.has_rdoc = false
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
Rake::TestTask.new(:test) do |t|
|
38
|
+
t.pattern = 'test/**/*_test.rb'
|
39
|
+
t.verbose = true
|
40
|
+
end
|
41
|
+
|
42
|
+
task :default => :test
|
43
|
+
|
44
|
+
|
45
|
+
namespace :gem do
|
46
|
+
|
47
|
+
##Friggin' task doesn't work! wtf?
|
48
|
+
#task(:update_gemspec) do
|
49
|
+
# File.open("#{NAME}.gemspec", 'w') do |f|
|
50
|
+
# f.write(spec.to_yaml)
|
51
|
+
# end
|
52
|
+
#end
|
53
|
+
|
54
|
+
#Creates clobber_package, gem, package, repackage tasks
|
55
|
+
#Note on clobber_package: fortunately, this will clobber the CODE package
|
56
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
57
|
+
pkg.need_tar = true
|
58
|
+
end
|
59
|
+
|
60
|
+
#Tasks gleaned from merb-core's Rakefile
|
61
|
+
|
62
|
+
desc "Run :package and install the resulting .gem"
|
63
|
+
task :install => :gem do
|
64
|
+
sh %{#{SUDO} gem install #{install_home} --local pkg/#{NAME}-#{CaptureFu::VERSION}.gem --no-rdoc --no-ri}
|
65
|
+
end
|
66
|
+
|
67
|
+
desc "Run :clean and uninstall the .gem"
|
68
|
+
task :uninstall do
|
69
|
+
sh %{#{SUDO} gem uninstall #{NAME}}
|
70
|
+
end
|
71
|
+
end
|
data/TODO
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
- capture_warnings(&block)
|
2
|
+
|
3
|
+
- ability to capture stdout and stderr separately
|
4
|
+
- use pipe & filter to have them both separate as well as the final result in order :-)
|
5
|
+
- make it possible to call in verbose mode and display the output at the console
|
6
|
+
in addition to capturing it
|
7
|
+
|
8
|
+
- Documentation
|
9
|
+
|
10
|
+
- For subprocess stderr redirect detection:
|
11
|
+
- add flexibility related to spaces between elements describing the redirect?
|
12
|
+
- check out http://tldp.org/LDP/abs/html/io-redirection.html for more info on redirection
|
data/lib/capture_fu.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
module CaptureFu
|
2
|
+
VERSION = '0.0.1'
|
3
|
+
|
4
|
+
def capture_output(&block)
|
5
|
+
real_out, real_err = $stdout, $stderr
|
6
|
+
result = fake_out = fake_err = nil
|
7
|
+
begin
|
8
|
+
fake_out, fake_err = Helpers::PipeStealer.new, Helpers::PipeStealer.new
|
9
|
+
$stdout, $stderr = fake_out, fake_err
|
10
|
+
result = yield
|
11
|
+
ensure
|
12
|
+
$stdout, $stderr = real_out, real_err
|
13
|
+
end
|
14
|
+
return result, fake_out.captured, fake_err.captured
|
15
|
+
end
|
16
|
+
|
17
|
+
# This first implementation is only intended for batch executions.
|
18
|
+
# You can't pipe stuff programmatically to the child process.
|
19
|
+
def capture_process_output(command)
|
20
|
+
|
21
|
+
#capture stderr in the same stream
|
22
|
+
command << ' 2>&1' unless Helpers.stderr_already_redirected(command)
|
23
|
+
|
24
|
+
out = `#{command}`
|
25
|
+
return $?.exitstatus, out
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
module Helpers
|
32
|
+
|
33
|
+
def self.stderr_already_redirected(command)
|
34
|
+
#Already redirected to stdout (valid for Windows)
|
35
|
+
return true if command =~ /2>&1\s*\Z/
|
36
|
+
|
37
|
+
#Redirected to /dev/null (this is clearly POSIX-dependent)
|
38
|
+
return true if command =~ /2>\/dev\/null\s*\Z/
|
39
|
+
|
40
|
+
return false
|
41
|
+
end
|
42
|
+
|
43
|
+
class PipeStealer < File
|
44
|
+
attr_reader :captured
|
45
|
+
def initialize
|
46
|
+
@captured = ''
|
47
|
+
end
|
48
|
+
def write(s)
|
49
|
+
@captured << s
|
50
|
+
end
|
51
|
+
def captured
|
52
|
+
return nil if @captured.empty?
|
53
|
+
@captured.dup
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end #Helper module
|
58
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
class CaptureOutputTest < Test::Unit::TestCase
|
4
|
+
include CaptureFu
|
5
|
+
|
6
|
+
def setup
|
7
|
+
super
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_stdout
|
11
|
+
res, out, err = capture_output do
|
12
|
+
puts 'jeez'
|
13
|
+
end
|
14
|
+
assert_nil res
|
15
|
+
assert_equal "jeez\n", out
|
16
|
+
assert_nil err
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_stderr
|
20
|
+
res, out, err = capture_output do
|
21
|
+
$stderr.puts 'jeez'
|
22
|
+
end
|
23
|
+
assert_nil res
|
24
|
+
assert_nil out
|
25
|
+
assert_equal "jeez\n", err
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_return_value
|
29
|
+
res, out, err = capture_output do
|
30
|
+
'jeez'
|
31
|
+
end
|
32
|
+
assert_equal 'jeez', res
|
33
|
+
assert_nil out
|
34
|
+
assert_nil err
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_all_outputs_at_the_same_time
|
38
|
+
res, out, err = capture_output do
|
39
|
+
puts 'jeez'
|
40
|
+
$stderr.puts 'jeez'
|
41
|
+
'jeez'
|
42
|
+
end
|
43
|
+
assert_equal 'jeez', res
|
44
|
+
assert_equal "jeez\n", out
|
45
|
+
assert_equal "jeez\n", err
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
class CaptureProcessOutputTest < Test::Unit::TestCase
|
4
|
+
include CaptureFu
|
5
|
+
|
6
|
+
def setup
|
7
|
+
super
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_successful_execution
|
11
|
+
res, out = capture_process_output('echo jeez')
|
12
|
+
assert_equal 0, res
|
13
|
+
assert_equal "jeez\n", out
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_when_output_to_stderr
|
17
|
+
res, out = capture_process_output('ewrewrtegfdghg') #This shouldn't be a valid command on too many OSes
|
18
|
+
|
19
|
+
# Should be reasonably OS-independent
|
20
|
+
assert_not_equal 0, res
|
21
|
+
assert_instance_of String, out
|
22
|
+
|
23
|
+
# Some of the following is probably strongly OS-dependent.
|
24
|
+
# I'm developing on OSX.
|
25
|
+
# Comments welcome.
|
26
|
+
assert_equal 127, res
|
27
|
+
assert !out.empty?
|
28
|
+
assert_match /ewrewrtegfdghg/, out
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_ignored_stderr
|
32
|
+
res, out = capture_process_output('ewrewrtegfdghg 2>/dev/null')
|
33
|
+
|
34
|
+
#May not be OS-independent
|
35
|
+
assert out.empty?
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_already_redirected_stderr
|
39
|
+
res, out = capture_process_output('ewrewrtegfdghg 2>&1')
|
40
|
+
|
41
|
+
#May not be OS-independent
|
42
|
+
assert !out.empty?
|
43
|
+
assert_match /ewrewrtegfdghg/, out
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
#These test names are made for rSpec, I know.
|
4
|
+
|
5
|
+
class CaptureFuNotIncludedByDefaultTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
def test__method__not_polluting_namespace_when_not_explicitly_included
|
8
|
+
assert_raise(NoMethodError) do
|
9
|
+
res, out, err = capture_output do
|
10
|
+
puts 'jeez'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class CaptureFuNotIntrusiveWhenIncludedTest < Test::Unit::TestCase
|
17
|
+
include CaptureFu
|
18
|
+
|
19
|
+
def test__utility_classes__not_polluting_namespace_when_not_explicitly_included
|
20
|
+
assert_raise(NameError) do
|
21
|
+
PipeStealer.new
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def test__utility_methods__not_polluting_namespace
|
26
|
+
assert_raise(NoMethodError) do
|
27
|
+
stderr_already_redirected('echo jeez')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
metadata
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: webmat-capture_fu
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mathieu Martin
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-05-14 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: capture_fu is a small library that facilitates capture of stdout and stderr output, of either subprocesses or plain old Ruby code.
|
17
|
+
email: webmat@gmail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- Rakefile
|
26
|
+
- README
|
27
|
+
- TODO
|
28
|
+
- lib/capture_fu.rb
|
29
|
+
- test/capture_output_test.rb
|
30
|
+
- test/functional/capture_output_test.rb
|
31
|
+
- test/functional/capture_process_output_test.rb
|
32
|
+
- test/unit/capture_output_test.rb
|
33
|
+
- test/unit/intrusiveness_test.rb
|
34
|
+
has_rdoc: false
|
35
|
+
homepage: http://github.com/webmat/capture_fu
|
36
|
+
post_install_message:
|
37
|
+
rdoc_options: []
|
38
|
+
|
39
|
+
require_paths:
|
40
|
+
- lib
|
41
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: "0"
|
46
|
+
version:
|
47
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: "0"
|
52
|
+
version:
|
53
|
+
requirements: []
|
54
|
+
|
55
|
+
rubyforge_project:
|
56
|
+
rubygems_version: 1.0.1
|
57
|
+
signing_key:
|
58
|
+
specification_version: 2
|
59
|
+
summary: capture_fu facilitates the capture of stdout and stderr output
|
60
|
+
test_files:
|
61
|
+
- test/capture_output_test.rb
|
62
|
+
- test/functional/capture_output_test.rb
|
63
|
+
- test/functional/capture_process_output_test.rb
|
64
|
+
- test/unit/capture_output_test.rb
|
65
|
+
- test/unit/intrusiveness_test.rb
|