test-cmd.rb 0.4.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.
- checksums.yaml +7 -0
- data/.github/workflows/specs.yml +23 -0
- data/.gitignore +7 -0
- data/.gitlab-ci.yml +16 -0
- data/.projectile +1 -0
- data/.rubocop.yml +19 -0
- data/Gemfile +2 -0
- data/LICENSE +15 -0
- data/README.md +118 -0
- data/lib/test/cmd.rb +1 -0
- data/lib/test-cmd.rb +76 -0
- data/test/setup.rb +3 -0
- data/test/test_cmd_test.rb +49 -0
- data/test-cmd.rb.gemspec +20 -0
- metadata +114 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 37a0fdfc106f74072dd6368cad33bdce7bd610a142a52b3996cf73e8a058e28e
|
4
|
+
data.tar.gz: f2eaa7173ee120d6bcf067554b3cabb8845b49efc555a8fc87083f30066992af
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ad30fbeb8c4800d9f111ab23540878dd7b5d8cffc2229f41a8e4991fee00ebae1f47f6113f1bd2b8be70ac1fcf0af98424f86c3bd14de31aacbed5109d9fa5ce
|
7
|
+
data.tar.gz: 178e1d4842f6855d05ad9e9630c98a63338eebab148bafe2b75f85d3fac0a13a1eac7d1f819552adebcc85d2e6033ef8f52f612ea1f518476addf58c146dfa69
|
@@ -0,0 +1,23 @@
|
|
1
|
+
name: test-cmd.rb
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ main ]
|
6
|
+
pull_request:
|
7
|
+
branches: [ main ]
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
specs:
|
11
|
+
strategy:
|
12
|
+
fail-fast: false
|
13
|
+
matrix:
|
14
|
+
os: [ubuntu-latest, macos-latest]
|
15
|
+
ruby: [3.1, 3.2]
|
16
|
+
runs-on: ${{ matrix.os }}
|
17
|
+
steps:
|
18
|
+
- uses: actions/checkout@v2
|
19
|
+
- uses: ruby/setup-ruby@v1
|
20
|
+
with:
|
21
|
+
ruby-version: ${{ matrix.ruby }}
|
22
|
+
- run: bundle install
|
23
|
+
- run: bundle exec ruby test/*_test.rb
|
data/.gitignore
ADDED
data/.gitlab-ci.yml
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
stages:
|
2
|
+
- test
|
3
|
+
|
4
|
+
test-ruby31:
|
5
|
+
stage: test
|
6
|
+
image: ruby:3.1.2
|
7
|
+
script:
|
8
|
+
- bundle install
|
9
|
+
- bundle exec ruby test/*_test.rb
|
10
|
+
|
11
|
+
test-ruby32:
|
12
|
+
stage: test
|
13
|
+
image: ruby:3.2.0
|
14
|
+
script:
|
15
|
+
- bundle install
|
16
|
+
- bundle exec ruby test/*_test.rb
|
data/.projectile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
-.gems/
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
##
|
2
|
+
# Plugins
|
3
|
+
require:
|
4
|
+
- standard
|
5
|
+
|
6
|
+
##
|
7
|
+
# Defaults: standard-rb
|
8
|
+
inherit_gem:
|
9
|
+
standard: config/base.yml
|
10
|
+
|
11
|
+
AllCops:
|
12
|
+
TargetRubyVersion: 3.1
|
13
|
+
Include:
|
14
|
+
- 'lib/**/*.rb'
|
15
|
+
- 'test/**/*.rb'
|
16
|
+
|
17
|
+
Style/MultilineIfModifier:
|
18
|
+
Exclude:
|
19
|
+
- 'lib/test-cmd.rb'
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
Copyright (C) 2023 by 0x1eef <0x1eef@protonmail.com>
|
2
|
+
|
3
|
+
Permission to use, copy, modify, and/or distribute this
|
4
|
+
software for any purpose with or without fee is hereby
|
5
|
+
granted.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS
|
8
|
+
ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
|
9
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
|
10
|
+
EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
11
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
|
12
|
+
RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
13
|
+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
14
|
+
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
15
|
+
OF THIS SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
## About
|
2
|
+
|
3
|
+
test-cmd.rb is a library for accessing the output streams
|
4
|
+
(both stdout and stderr) of a spawned process. The library was
|
5
|
+
first realized in a test environment, where it provided a path
|
6
|
+
for verifying that when code examples are run they produce the
|
7
|
+
expected output. The library can be generally useful outside a
|
8
|
+
test environment, too.
|
9
|
+
|
10
|
+
## Examples
|
11
|
+
|
12
|
+
### Test::Unit
|
13
|
+
|
14
|
+
The following example demonstrates how tests might be written with
|
15
|
+
test-unit from the standard library. The
|
16
|
+
[`Test::Cmd`](https://0x1eef.github.io/x/test-cmd.rb/Test/Cmd.html)
|
17
|
+
module implements a
|
18
|
+
[`cmd`](https://0x1eef.github.io/x/test-cmd.rb/Test/Cmd.html#cmd-class_method)
|
19
|
+
method that can be included into a
|
20
|
+
testcase. The
|
21
|
+
[`cmd`](https://0x1eef.github.io/x/test-cmd.rb/Test/Cmd.html#cmd-class_method)
|
22
|
+
method takes the command to run as its first and only argument:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
require "test/unit"
|
26
|
+
require "test/cmd"
|
27
|
+
|
28
|
+
class CmdTest < Test::Unit::TestCase
|
29
|
+
include Test::Cmd
|
30
|
+
|
31
|
+
def test_ruby_stdout
|
32
|
+
assert_equal "foo\n", cmd(%q(ruby -e '$stdout.puts "foo"')).stdout
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_ruby_stderr
|
36
|
+
assert_equal "bar\n", cmd(%q(ruby -e '$stderr.puts "bar"')).stderr
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_ruby_success_exit_status
|
40
|
+
assert_equal 0, cmd(%q(ruby -e 'exit 0')).exit_status
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_ruby_failure_exit_status
|
44
|
+
assert_equal 1, cmd(%q(ruby -e 'exit 1')).exit_status
|
45
|
+
end
|
46
|
+
end
|
47
|
+
```
|
48
|
+
|
49
|
+
### IO#sync
|
50
|
+
|
51
|
+
Sometimes it can be neccessary to bypass Ruby's internal buffer and flush
|
52
|
+
output to the operating system immediately, otherwise there can be unexpected
|
53
|
+
results. Consider the following example, where the output will be
|
54
|
+
`bar\nfoo\n` rather than `foo\nbar\n`:
|
55
|
+
|
56
|
+
``` ruby
|
57
|
+
##
|
58
|
+
# test.rb
|
59
|
+
pid = fork do
|
60
|
+
sleep(1)
|
61
|
+
puts "bar"
|
62
|
+
end
|
63
|
+
puts "foo"
|
64
|
+
Process.wait(pid)
|
65
|
+
|
66
|
+
##
|
67
|
+
# cmd.rb
|
68
|
+
p cmd("ruby test.rb").stdout # => "bar\nfoo\n"
|
69
|
+
```
|
70
|
+
|
71
|
+
And with output flushed to the operating system immediately:
|
72
|
+
|
73
|
+
``` ruby
|
74
|
+
##
|
75
|
+
# test.rb
|
76
|
+
$stdout.sync = true
|
77
|
+
pid = fork do
|
78
|
+
sleep(1)
|
79
|
+
puts "bar"
|
80
|
+
end
|
81
|
+
puts "foo"
|
82
|
+
Process.wait(pid)
|
83
|
+
|
84
|
+
##
|
85
|
+
# cmd.rb
|
86
|
+
p cmd("ruby test.rb").stdout # => "foo\nbar\n"
|
87
|
+
```
|
88
|
+
|
89
|
+
## Sources
|
90
|
+
|
91
|
+
* [Source code (GitHub)](https://github.com/0x1eef/test-cmd.rb#readme)
|
92
|
+
* [Source code (GitLab)](https://gitlab.com/0x1eef/test-cmd.rb#about)
|
93
|
+
|
94
|
+
## Install
|
95
|
+
|
96
|
+
test-cmd.rb is distributed as a RubyGem through its git repositories. <br>
|
97
|
+
[GitHub](https://github.com/0x1eef/test-cmd.rb),
|
98
|
+
and
|
99
|
+
[GitLab](https://gitlab.com/0x1eef/test-cmd.rb)
|
100
|
+
are available as sources.
|
101
|
+
|
102
|
+
``` ruby
|
103
|
+
# Gemfile
|
104
|
+
gem "test-cmd.rb", github: "0x1eef/test-cmd.rb", tag: "v0.4.1"
|
105
|
+
```
|
106
|
+
|
107
|
+
**Rubygems.org**
|
108
|
+
|
109
|
+
test-cmd.rb can also be installed via rubygems.org.
|
110
|
+
|
111
|
+
gem install test-cmd.rb
|
112
|
+
|
113
|
+
## License
|
114
|
+
|
115
|
+
[BSD Zero Clause](https://choosealicense.com/licenses/0bsd/).
|
116
|
+
<br>
|
117
|
+
See [LICENSE](./LICENSE).
|
118
|
+
|
data/lib/test/cmd.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require_relative "../test-cmd"
|
data/lib/test-cmd.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
module Test
|
2
|
+
end unless defined?(Test)
|
3
|
+
|
4
|
+
##
|
5
|
+
# test-cmd.rb is a library for accessing the output streams
|
6
|
+
# (both stdout and stderr) of a spawned process. The library was
|
7
|
+
# first realized in a test environment, where it provided a path
|
8
|
+
# for verifying that when code examples are run they produce the
|
9
|
+
# expected output. The library can be generally useful outside a
|
10
|
+
# test environment, too.
|
11
|
+
module Test::Cmd
|
12
|
+
class Result
|
13
|
+
require "tempfile"
|
14
|
+
##
|
15
|
+
# @return [String]
|
16
|
+
# Returns the contents of stdout
|
17
|
+
attr_reader :stdout
|
18
|
+
|
19
|
+
##
|
20
|
+
# @return [String]
|
21
|
+
# Returns the contents of stderr
|
22
|
+
attr_reader :stderr
|
23
|
+
|
24
|
+
## @return [Process::Status]
|
25
|
+
# Returns the status of a process
|
26
|
+
attr_reader :status
|
27
|
+
|
28
|
+
##
|
29
|
+
# @param [Tempfile] stdout
|
30
|
+
# @param [Tempfile] stderr
|
31
|
+
# @param [Process::Status] pstatus
|
32
|
+
# @return [Test::Cmd::Result]
|
33
|
+
def initialize(stdout, stderr, pstatus)
|
34
|
+
@stdout = stdout.tap(&:rewind).read
|
35
|
+
@stderr = stderr.tap(&:rewind).read
|
36
|
+
@status = pstatus
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# @return [Integer]
|
41
|
+
# Returns the exit status of a process
|
42
|
+
def exit_status
|
43
|
+
@status.exitstatus
|
44
|
+
end
|
45
|
+
|
46
|
+
##
|
47
|
+
# Yields each line of stdout when the command
|
48
|
+
# was successful, or each line of stderr when
|
49
|
+
# the command was not successful.
|
50
|
+
#
|
51
|
+
# @return [Enumerator]
|
52
|
+
# Returns an Enumerator when a block is not given.
|
53
|
+
def each_line
|
54
|
+
return enum_for(:each_line) unless block_given?
|
55
|
+
io = @status.success? ? @stdout : @stderr
|
56
|
+
io.each_line.each { yield(_1.chomp) }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
##
|
61
|
+
# @param [String] cmd
|
62
|
+
# A command to execute
|
63
|
+
#
|
64
|
+
# @return [Test::Cmd::Result]
|
65
|
+
# Returns an instance of {Test::Cmd::Result Test::Cmd::Result}
|
66
|
+
def cmd(cmd)
|
67
|
+
out = Tempfile.new("cmd-stdout").tap(&:unlink)
|
68
|
+
err = Tempfile.new("cmd-stderr").tap(&:unlink)
|
69
|
+
Process.wait spawn(cmd, {err:, out:})
|
70
|
+
Result.new(out, err, $?)
|
71
|
+
ensure
|
72
|
+
out.close
|
73
|
+
err.close
|
74
|
+
end
|
75
|
+
module_function :cmd
|
76
|
+
end
|
data/test/setup.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require_relative "setup"
|
2
|
+
|
3
|
+
class CmdTest < Test::Unit::TestCase
|
4
|
+
include Test::Cmd
|
5
|
+
|
6
|
+
def test_ruby_stdout
|
7
|
+
assert_equal "foo\n", cmd(%q(ruby -e '$stdout.puts "foo"')).stdout
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_ruby_stderr
|
11
|
+
assert_equal "bar\n", cmd(%q(ruby -e '$stderr.puts "bar"')).stderr
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_ruby_success_exit_status
|
15
|
+
assert_equal 0, cmd(%q(ruby -e 'exit 0')).exit_status
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_ruby_failure_exit_status
|
19
|
+
assert_equal 1, cmd(%q(ruby -e 'exit 1')).exit_status
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_stdout_with_fork
|
23
|
+
code = <<-CODE.each_line.map { _1.chomp.strip }.join(";")
|
24
|
+
$stdout.sync = true
|
25
|
+
pid = fork do
|
26
|
+
sleep(1)
|
27
|
+
puts "bar"
|
28
|
+
end
|
29
|
+
puts "foo"
|
30
|
+
Process.wait(pid)
|
31
|
+
CODE
|
32
|
+
assert_equal "foo\nbar\n", cmd(%Q(ruby -e '#{code}')).stdout
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_each_line_stdout
|
36
|
+
run = false
|
37
|
+
cmd(%q(ruby -e '$stdout.puts "FooBar"'))
|
38
|
+
.each_line do
|
39
|
+
run = true
|
40
|
+
assert_equal _1, "FooBar"
|
41
|
+
end
|
42
|
+
assert_equal true, run
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_each_line_returns_enum
|
46
|
+
assert_instance_of Enumerator,
|
47
|
+
cmd(%q(ruby -e '$stdout.puts "FooBar"')).each_line
|
48
|
+
end
|
49
|
+
end
|
data/test-cmd.rb.gemspec
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Gem::Specification.new do |gem|
|
4
|
+
gem.name = "test-cmd.rb"
|
5
|
+
gem.authors = ["0x1eef"]
|
6
|
+
gem.email = ["0x1eef@protonmail.com"]
|
7
|
+
gem.homepage = "https://github.com/0x1eef/test-cmd.rb#readme"
|
8
|
+
gem.version = "0.4.1"
|
9
|
+
gem.required_ruby_version = ">= 3.0"
|
10
|
+
gem.licenses = ["0BSD"]
|
11
|
+
gem.files = `git ls-files`.split($/)
|
12
|
+
gem.require_paths = ["lib"]
|
13
|
+
gem.summary = "test-cmd.rb provides access to the output streams " \
|
14
|
+
"(both stdout and stderr) of a spawned process."
|
15
|
+
gem.description = gem.summary
|
16
|
+
gem.add_development_dependency "test-unit", "~> 3.5.7"
|
17
|
+
gem.add_development_dependency "yard", "~> 0.9"
|
18
|
+
gem.add_development_dependency "redcarpet", "~> 3.5"
|
19
|
+
gem.add_development_dependency "standard", "~> 1.24"
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: test-cmd.rb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- '0x1eef'
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-01-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: test-unit
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 3.5.7
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 3.5.7
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: yard
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.9'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.9'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: redcarpet
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.5'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.5'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: standard
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.24'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.24'
|
69
|
+
description: test-cmd.rb provides access to the output streams (both stdout and stderr)
|
70
|
+
of a spawned process.
|
71
|
+
email:
|
72
|
+
- 0x1eef@protonmail.com
|
73
|
+
executables: []
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- ".github/workflows/specs.yml"
|
78
|
+
- ".gitignore"
|
79
|
+
- ".gitlab-ci.yml"
|
80
|
+
- ".projectile"
|
81
|
+
- ".rubocop.yml"
|
82
|
+
- Gemfile
|
83
|
+
- LICENSE
|
84
|
+
- README.md
|
85
|
+
- lib/test-cmd.rb
|
86
|
+
- lib/test/cmd.rb
|
87
|
+
- test-cmd.rb.gemspec
|
88
|
+
- test/setup.rb
|
89
|
+
- test/test_cmd_test.rb
|
90
|
+
homepage: https://github.com/0x1eef/test-cmd.rb#readme
|
91
|
+
licenses:
|
92
|
+
- 0BSD
|
93
|
+
metadata: {}
|
94
|
+
post_install_message:
|
95
|
+
rdoc_options: []
|
96
|
+
require_paths:
|
97
|
+
- lib
|
98
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '3.0'
|
103
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - ">="
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
requirements: []
|
109
|
+
rubygems_version: 3.5.3
|
110
|
+
signing_key:
|
111
|
+
specification_version: 4
|
112
|
+
summary: test-cmd.rb provides access to the output streams (both stdout and stderr)
|
113
|
+
of a spawned process.
|
114
|
+
test_files: []
|