test-cmd.rb 0.9.3 → 0.11.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.
- checksums.yaml +4 -4
- data/README.md +13 -7
- data/lib/test/cmd.rb +31 -3
- data/lib/test-cmd.rb +1 -15
- data/test/test_cmd_test.rb +97 -37
- data/test-cmd.rb.gemspec +2 -2
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 633be9bbfd994b7e810172560fb9f63dd2671ac77b90132d37dba6bdf55a9a2c
|
|
4
|
+
data.tar.gz: cffe23b0fab98c782c910fae748179206869740df586bd4c8e321643cb8e12ff
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 38c743bb91c272ff67064b3b2c6f0e54bc62bc02876e25faf0d6876418b2001e8b77b7563ec6b4e5c14b8a7b40da43ea7399fe5bea54e158ec8773ea51d4b602
|
|
7
|
+
data.tar.gz: 632d756c4e8616cdcb619cbfa9d4cf3a1eaca19d3898dd6d54aeaa13b88975d5fc1a0ee5955eddc0fde70bf82ceffa2cf293193a309cb8a287dfe6f8dd0f6fec
|
data/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
## About
|
|
2
2
|
|
|
3
3
|
test-cmd.rb provides an object-oriented interface for spawning
|
|
4
|
-
a
|
|
4
|
+
a command.
|
|
5
5
|
|
|
6
6
|
## Examples
|
|
7
7
|
|
|
@@ -13,7 +13,7 @@ is passed an instance of
|
|
|
13
13
|
[Test::Cmd](https://0x1eef.github.io/x/test-cmd.rb/Test/Cmd.html):
|
|
14
14
|
|
|
15
15
|
``` ruby
|
|
16
|
-
require "test
|
|
16
|
+
require "test-cmd"
|
|
17
17
|
cmd("ruby", "-e", "exit 0")
|
|
18
18
|
.success { print "The command [#{_1.pid}] was successful", "\n" }
|
|
19
19
|
.failure { print "The command [#{_1.pid}] was unsuccessful", "\n" }
|
|
@@ -23,7 +23,7 @@ cmd("ruby", "-e", "exit 0")
|
|
|
23
23
|
|
|
24
24
|
The following example demonstrates how tests might be written with
|
|
25
25
|
test-unit from the standard library. The
|
|
26
|
-
[`cmd`](https://0x1eef.github.io/x/test-cmd.rb/
|
|
26
|
+
[`cmd`](https://0x1eef.github.io/x/test-cmd.rb/Kernel.html#cmd-instance_method)
|
|
27
27
|
method takes the name or path of a command, alongside any arguments:
|
|
28
28
|
|
|
29
29
|
```ruby
|
|
@@ -32,19 +32,25 @@ require "test/cmd"
|
|
|
32
32
|
|
|
33
33
|
class CmdTest < Test::Unit::TestCase
|
|
34
34
|
def test_ruby_stdout
|
|
35
|
-
assert_equal "42\n",
|
|
35
|
+
assert_equal "42\n", ruby("puts 42").stdout
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
def test_ruby_stderr
|
|
39
|
-
assert_equal "42\n",
|
|
39
|
+
assert_equal "42\n", ruby("warn 42").stderr
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
def test_ruby_success_exit_status
|
|
43
|
-
assert_equal 0,
|
|
43
|
+
assert_equal 0, ruby("exit 0").exit_status
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
def test_ruby_failure_exit_status
|
|
47
|
-
assert_equal 1,
|
|
47
|
+
assert_equal 1, ruby("exit 1").exit_status
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
def ruby(code)
|
|
53
|
+
cmd("ruby", "-e", code)
|
|
48
54
|
end
|
|
49
55
|
end
|
|
50
56
|
```
|
data/lib/test/cmd.rb
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
module Test
|
|
2
|
+
end unless defined?(Test)
|
|
2
3
|
|
|
3
4
|
##
|
|
4
5
|
# test-cmd.rb provides an object oriented interface
|
|
5
6
|
# for spawning a command.
|
|
6
7
|
class Test::Cmd
|
|
7
8
|
require "tempfile"
|
|
9
|
+
require "securerandom"
|
|
8
10
|
|
|
9
11
|
##
|
|
10
12
|
# @param [String] cmd
|
|
@@ -39,6 +41,8 @@ class Test::Cmd
|
|
|
39
41
|
Process.spawn(@cmd, *@argv, {out: @out_io, err: @err_io})
|
|
40
42
|
Process.wait
|
|
41
43
|
@status = $?
|
|
44
|
+
ensure
|
|
45
|
+
[stdout, stderr]
|
|
42
46
|
end
|
|
43
47
|
end
|
|
44
48
|
|
|
@@ -49,6 +53,8 @@ class Test::Cmd
|
|
|
49
53
|
@stdout ||= begin
|
|
50
54
|
spawn
|
|
51
55
|
out_io.tap(&:rewind).read.tap { out_io.close }
|
|
56
|
+
rescue IOError
|
|
57
|
+
@stdout
|
|
52
58
|
end
|
|
53
59
|
end
|
|
54
60
|
|
|
@@ -59,6 +65,8 @@ class Test::Cmd
|
|
|
59
65
|
@stderr ||= begin
|
|
60
66
|
spawn
|
|
61
67
|
err_io.tap(&:rewind).read.tap { err_io.close }
|
|
68
|
+
rescue IOError
|
|
69
|
+
@stderr
|
|
62
70
|
end
|
|
63
71
|
end
|
|
64
72
|
|
|
@@ -123,18 +131,38 @@ class Test::Cmd
|
|
|
123
131
|
end
|
|
124
132
|
end
|
|
125
133
|
|
|
134
|
+
##
|
|
135
|
+
# @return [Boolean]
|
|
136
|
+
# Returns true when a command has been spawned
|
|
137
|
+
def spawned?
|
|
138
|
+
@spawned
|
|
139
|
+
end
|
|
140
|
+
|
|
126
141
|
private
|
|
127
142
|
|
|
128
143
|
attr_reader :out_io, :err_io
|
|
129
144
|
|
|
130
145
|
def spawn_io
|
|
131
146
|
[
|
|
132
|
-
|
|
133
|
-
|
|
147
|
+
[".testcmd.stdout.#{ns}.", SecureRandom.alphanumeric(3)],
|
|
148
|
+
[".testcmd.stderr.#{ns}.", SecureRandom.alphanumeric(3)]
|
|
134
149
|
].map {
|
|
135
150
|
file = Tempfile.new(_1)
|
|
136
151
|
File.chmod(0, file.path)
|
|
137
152
|
file.tap(&:unlink)
|
|
138
153
|
}
|
|
139
154
|
end
|
|
155
|
+
|
|
156
|
+
def ns
|
|
157
|
+
[Process.pid, object_id].join(".")
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
module Kernel
|
|
162
|
+
##
|
|
163
|
+
# @param (see Test::Cmd#initialize)
|
|
164
|
+
# @return (see Test::Cmd#initialize)
|
|
165
|
+
def cmd(cmd, *argv)
|
|
166
|
+
Test::Cmd.new(cmd, *argv)
|
|
167
|
+
end
|
|
140
168
|
end
|
data/lib/test-cmd.rb
CHANGED
|
@@ -1,15 +1 @@
|
|
|
1
|
-
|
|
2
|
-
end unless defined?(Test)
|
|
3
|
-
|
|
4
|
-
module Test
|
|
5
|
-
require_relative "test/cmd"
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
module Kernel
|
|
9
|
-
##
|
|
10
|
-
# @param (see Test::Cmd#initialize)
|
|
11
|
-
# @return (see Test::Cmd#initialize)
|
|
12
|
-
def cmd(cmd, *argv)
|
|
13
|
-
Test::Cmd.new(cmd, *argv)
|
|
14
|
-
end
|
|
15
|
-
end
|
|
1
|
+
require_relative "test/cmd"
|
data/test/test_cmd_test.rb
CHANGED
|
@@ -1,47 +1,55 @@
|
|
|
1
1
|
require_relative "setup"
|
|
2
2
|
|
|
3
|
-
class
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
class Test::Cmd
|
|
4
|
+
class Test < Test::Unit::TestCase
|
|
5
|
+
private
|
|
6
|
+
def ruby(str)
|
|
7
|
+
cmd "ruby", "-e", str
|
|
8
|
+
end
|
|
6
9
|
end
|
|
10
|
+
end
|
|
7
11
|
|
|
8
|
-
|
|
9
|
-
|
|
12
|
+
class Test::Cmd
|
|
13
|
+
##
|
|
14
|
+
# Test::Cmd#argv
|
|
15
|
+
class ARGVTest < Test
|
|
16
|
+
def test_ruby_argv
|
|
17
|
+
assert_equal "42\n", cmd("ruby")
|
|
18
|
+
.argv("-e", "warn 42")
|
|
19
|
+
.stderr
|
|
20
|
+
end
|
|
10
21
|
end
|
|
11
22
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
23
|
+
##
|
|
24
|
+
# Test::Cmd#{exit_status, status, success?}
|
|
25
|
+
class ExitStatusTest < Test
|
|
26
|
+
def test_ruby_exit_status_success
|
|
27
|
+
assert_equal 0, ruby("exit 0").exit_status
|
|
28
|
+
end
|
|
15
29
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
30
|
+
def test_ruby_exit_status_failure
|
|
31
|
+
assert_equal 1, ruby("exit 1").exit_status
|
|
32
|
+
end
|
|
19
33
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
34
|
+
def test_ruby_exit_status_predicates
|
|
35
|
+
assert_equal true, ruby("exit 0").status.success?
|
|
36
|
+
assert_equal true, ruby("exit 0").success?
|
|
37
|
+
end
|
|
23
38
|
end
|
|
24
39
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
assert_equal false, call_fail
|
|
32
|
-
end
|
|
40
|
+
##
|
|
41
|
+
# Test::Cmd#{stdout,stderr}
|
|
42
|
+
class OutputTest < Test
|
|
43
|
+
def test_ruby_stdout
|
|
44
|
+
assert_equal "42\n", ruby("puts 42").stdout
|
|
45
|
+
end
|
|
33
46
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
.success { call_ok = true }
|
|
38
|
-
.failure { call_fail = true }
|
|
39
|
-
assert_equal true, call_fail
|
|
40
|
-
assert_equal false, call_ok
|
|
41
|
-
end
|
|
47
|
+
def test_ruby_stderr
|
|
48
|
+
assert_equal "42\n", ruby("warn 42").stderr
|
|
49
|
+
end
|
|
42
50
|
|
|
43
|
-
|
|
44
|
-
|
|
51
|
+
def test_ruby_stdout_fork
|
|
52
|
+
code = <<-CODE.each_line.map { _1.chomp.strip }.join(";")
|
|
45
53
|
$stdout.sync = true
|
|
46
54
|
fork do
|
|
47
55
|
sleep(1)
|
|
@@ -50,12 +58,64 @@ class CmdTest < Test::Unit::TestCase
|
|
|
50
58
|
puts "foo"
|
|
51
59
|
Process.wait
|
|
52
60
|
CODE
|
|
53
|
-
|
|
61
|
+
assert_equal "foo\nbar\n", ruby(code).stdout
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
##
|
|
66
|
+
# Test::Cmd#{success, failure}
|
|
67
|
+
class CallbackTest < Test
|
|
68
|
+
def test_ruby_success_callback
|
|
69
|
+
call_ok, call_fail = [false, false]
|
|
70
|
+
ruby("exit 0")
|
|
71
|
+
.success { call_ok = true }
|
|
72
|
+
.failure { call_fail = true }
|
|
73
|
+
assert_equal true, call_ok
|
|
74
|
+
assert_equal false, call_fail
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def test_ruby_failure_callback
|
|
78
|
+
call_ok, call_fail = [false, false]
|
|
79
|
+
ruby("exit 1")
|
|
80
|
+
.success { call_ok = true }
|
|
81
|
+
.failure { call_fail = true }
|
|
82
|
+
assert_equal true, call_fail
|
|
83
|
+
assert_equal false, call_ok
|
|
84
|
+
end
|
|
54
85
|
end
|
|
55
86
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
87
|
+
##
|
|
88
|
+
# Test::Cmd#spawn
|
|
89
|
+
class SpawnTest < Test
|
|
90
|
+
def test_io_closed_after_spawn
|
|
91
|
+
%i[out_io err_io].each do |io|
|
|
92
|
+
assert_equal true, spawned_command.send(io).closed?
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def test_io_unlink_after_spawn
|
|
97
|
+
%i[out_io err_io].each do |io|
|
|
98
|
+
path = spawned_command.send(io).__getobj__.path
|
|
99
|
+
assert_equal false, File.exist?(path)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
private
|
|
104
|
+
|
|
105
|
+
def spawned_command
|
|
106
|
+
ruby("puts 42").spawn
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
##
|
|
111
|
+
# Test::Cmd#spawned?
|
|
112
|
+
class SpawnedTest < Test
|
|
113
|
+
def test_spawned_before_spawn
|
|
114
|
+
assert_equal false, ruby("puts 42").spawned?
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def test_spawned_after_spawn
|
|
118
|
+
assert_equal true, ruby("puts 42").tap(&:spawn).spawned?
|
|
119
|
+
end
|
|
60
120
|
end
|
|
61
121
|
end
|
data/test-cmd.rb.gemspec
CHANGED
|
@@ -5,12 +5,12 @@ Gem::Specification.new do |gem|
|
|
|
5
5
|
gem.authors = ["0x1eef"]
|
|
6
6
|
gem.email = ["0x1eef@protonmail.com"]
|
|
7
7
|
gem.homepage = "https://github.com/0x1eef/test-cmd.rb#readme"
|
|
8
|
-
gem.version = "0.
|
|
8
|
+
gem.version = "0.11.0"
|
|
9
9
|
gem.required_ruby_version = ">= 3.0"
|
|
10
10
|
gem.licenses = ["0BSD"]
|
|
11
11
|
gem.files = `git ls-files`.split($/)
|
|
12
12
|
gem.require_paths = ["lib"]
|
|
13
|
-
gem.summary = "An object-oriented interface for spawning a
|
|
13
|
+
gem.summary = "An object-oriented interface for spawning a command"
|
|
14
14
|
gem.metadata = { "documentation_uri" => "https://0x1eef.github.io/x/test-cmd.rb/" }
|
|
15
15
|
gem.description = gem.summary
|
|
16
16
|
gem.add_development_dependency "test-unit", "~> 3.5.7"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: test-cmd.rb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.11.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- '0x1eef'
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2024-05-
|
|
11
|
+
date: 2024-05-16 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: test-unit
|
|
@@ -80,7 +80,7 @@ dependencies:
|
|
|
80
80
|
- - "~>"
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
82
|
version: '13.1'
|
|
83
|
-
description: An object-oriented interface for spawning a
|
|
83
|
+
description: An object-oriented interface for spawning a command
|
|
84
84
|
email:
|
|
85
85
|
- 0x1eef@protonmail.com
|
|
86
86
|
executables: []
|
|
@@ -124,5 +124,5 @@ requirements: []
|
|
|
124
124
|
rubygems_version: 3.5.9
|
|
125
125
|
signing_key:
|
|
126
126
|
specification_version: 4
|
|
127
|
-
summary: An object-oriented interface for spawning a
|
|
127
|
+
summary: An object-oriented interface for spawning a command
|
|
128
128
|
test_files: []
|