test-cmd.rb 0.12.3 → 1.0.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/.rubocop.yml +8 -4
- data/Gemfile +0 -0
- data/README.md +14 -7
- data/Rakefile.rb +0 -0
- data/lib/test/cmd.rb +116 -49
- data/test/cmd_test.rb +9 -0
- data/test-cmd.rb.gemspec +3 -4
- metadata +7 -12
- data/.gitlab-ci.yml +0 -16
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ceedd530e04b4429280815527f9c18213db595390d6c554854a843c9c9a7717e
|
|
4
|
+
data.tar.gz: 98ad59766cd5aa84d4fbed39ca8d2465fd6be4fa3d7895707f6341fbad37e6c4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f25e60111e111074f5dd1cdba6ba10f7074a5a2fbe9ddbf57ef08a3d1ecc1096e4119331c98ab74736b689aedf8c5f4b784cd18db7255bb7df01de314a1b1dd5
|
|
7
|
+
data.tar.gz: 368188e8228ea2974e2db19d284efabb70ce3a0a2c773d73e372078a82034fa93e69ff9e586c62fc570b49039f4bc759d1b0da1cf8e240ac7f3b631893d5dff3
|
data/.rubocop.yml
CHANGED
|
@@ -8,16 +8,20 @@ require:
|
|
|
8
8
|
inherit_gem:
|
|
9
9
|
standard: config/base.yml
|
|
10
10
|
|
|
11
|
+
##
|
|
12
|
+
# Enabled
|
|
11
13
|
AllCops:
|
|
12
14
|
TargetRubyVersion: 3.1
|
|
13
15
|
Include:
|
|
14
16
|
- 'lib/**/*.rb'
|
|
15
17
|
- 'test/**/*.rb'
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
- 'lib/test-cmd.rb'
|
|
20
|
-
|
|
19
|
+
##
|
|
20
|
+
# Disabled
|
|
21
21
|
Layout/MultilineMethodCallIndentation:
|
|
22
22
|
Exclude:
|
|
23
23
|
- 'test/*.rb'
|
|
24
|
+
Layout/ArgumentAlignment:
|
|
25
|
+
Enabled: false
|
|
26
|
+
Style/MultilineIfModifier:
|
|
27
|
+
Enabled: false
|
data/Gemfile
CHANGED
|
File without changes
|
data/README.md
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
## About
|
|
2
2
|
|
|
3
3
|
test-cmd.rb provides an object-oriented interface for spawning
|
|
4
|
-
a command.
|
|
4
|
+
a command on UNIX-like operating systems. The library is intended
|
|
5
|
+
to be simple, lightweight, and easy to use.
|
|
5
6
|
|
|
6
7
|
## Examples
|
|
7
8
|
|
|
8
|
-
###
|
|
9
|
+
### Commands
|
|
10
|
+
|
|
11
|
+
#### Callbacks
|
|
9
12
|
|
|
10
13
|
The success and failure callbacks provide hooks for when
|
|
11
14
|
a command exits successfully or unsuccessfully. The callbacks
|
|
12
15
|
are passed an instance of
|
|
13
|
-
[Test::Cmd](https://0x1eef.github.io/x/test-cmd.rb/Test/Cmd.html)
|
|
16
|
+
[Test::Cmd](https://0x1eef.github.io/x/test-cmd.rb/Test/Cmd.html)
|
|
17
|
+
that has access to the command's process ID, exit status,
|
|
18
|
+
standard ouput stream, and standard error stream:
|
|
14
19
|
|
|
15
20
|
``` ruby
|
|
16
21
|
require "test-cmd"
|
|
@@ -19,12 +24,14 @@ cmd("ruby", "-e", "exit 0")
|
|
|
19
24
|
.failure { print "The command [#{_1.pid}] was unsuccessful", "\n" }
|
|
20
25
|
```
|
|
21
26
|
|
|
22
|
-
|
|
27
|
+
#### Assertions
|
|
23
28
|
|
|
24
29
|
The following example demonstrates how tests might be written with
|
|
25
30
|
test-unit from the standard library. The
|
|
26
31
|
[`cmd`](https://0x1eef.github.io/x/test-cmd.rb/Kernel.html#cmd-instance_method)
|
|
27
|
-
method takes the name or path of a command, alongside any arguments
|
|
32
|
+
method takes the name or path of a command, alongside any arguments. The tests
|
|
33
|
+
assert against the exit status, standard output stream, and standard error
|
|
34
|
+
stream of the spawned ruby process:
|
|
28
35
|
|
|
29
36
|
```ruby
|
|
30
37
|
require "test/unit"
|
|
@@ -68,8 +75,8 @@ test-cmd.rb can be installed via rubygems.org:
|
|
|
68
75
|
|
|
69
76
|
## Sources
|
|
70
77
|
|
|
71
|
-
* [
|
|
72
|
-
* [
|
|
78
|
+
* [github.com/@0x1eef](https://github.com/0x1eef/test-cmd.rb#readme)
|
|
79
|
+
* [gitlab.com/@0x1eef](https://gitlab.com/0x1eef/test-cmd.rb#about)
|
|
73
80
|
|
|
74
81
|
## License
|
|
75
82
|
|
data/Rakefile.rb
CHANGED
|
File without changes
|
data/lib/test/cmd.rb
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
end
|
|
4
|
-
end
|
|
1
|
+
module Test
|
|
2
|
+
end unless defined?(Test)
|
|
5
3
|
|
|
6
4
|
##
|
|
7
5
|
# test-cmd.rb provides an object oriented interface
|
|
8
|
-
# for spawning a command
|
|
6
|
+
# for spawning a command
|
|
9
7
|
class Test::Cmd
|
|
10
8
|
##
|
|
11
9
|
# @api private
|
|
@@ -32,6 +30,7 @@ class Test::Cmd
|
|
|
32
30
|
@spawned = false
|
|
33
31
|
@stdout = ""
|
|
34
32
|
@stderr = ""
|
|
33
|
+
@enoent = false
|
|
35
34
|
end
|
|
36
35
|
|
|
37
36
|
##
|
|
@@ -47,50 +46,19 @@ class Test::Cmd
|
|
|
47
46
|
# @return [Test::Cmd]
|
|
48
47
|
def spawn
|
|
49
48
|
return self if @spawned
|
|
50
|
-
|
|
51
49
|
tap do
|
|
52
|
-
out, err = Pipe.pair, Pipe.pair
|
|
53
50
|
@spawned = true
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
Process.wait
|
|
57
|
-
@status = $?
|
|
58
|
-
rescue Errno::ENOENT => ex
|
|
59
|
-
@cmd, @argv, @stderr = "false", [], ex.message
|
|
60
|
-
retry
|
|
61
|
-
end
|
|
62
|
-
loop do
|
|
63
|
-
io, _ = IO.select([out.r, err.r], nil, nil, 0.01)
|
|
64
|
-
io&.include?(out.r) ? @stdout << out.r.read(1) : nil
|
|
65
|
-
io&.include?(err.r) ? @stderr << err.r.read(1) : nil
|
|
66
|
-
break unless t.alive? || IO.select([out.r, err.r], nil, nil, 0.01)
|
|
67
|
-
end
|
|
68
|
-
ensure
|
|
69
|
-
[out, err].each(&:close)
|
|
51
|
+
@out, @err = Pipe.pair, Pipe.pair
|
|
52
|
+
produce(@out, @err)
|
|
70
53
|
end
|
|
71
54
|
end
|
|
72
55
|
|
|
73
|
-
##
|
|
74
|
-
# @return [String]
|
|
75
|
-
# Returns the contents of stdout
|
|
76
|
-
def stdout
|
|
77
|
-
spawn
|
|
78
|
-
@stdout
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
##
|
|
82
|
-
# @return [String]
|
|
83
|
-
# Returns the contents of stderr
|
|
84
|
-
def stderr
|
|
85
|
-
spawn
|
|
86
|
-
@stderr
|
|
87
|
-
end
|
|
88
|
-
|
|
89
56
|
##
|
|
90
57
|
# @return [Process::Status]
|
|
91
58
|
# Returns the status of a process
|
|
92
59
|
def status
|
|
93
60
|
spawn
|
|
61
|
+
consume(@producer, @out, @err)
|
|
94
62
|
@status
|
|
95
63
|
end
|
|
96
64
|
|
|
@@ -109,6 +77,31 @@ class Test::Cmd
|
|
|
109
77
|
end
|
|
110
78
|
alias_method :exitstatus, :exit_status
|
|
111
79
|
|
|
80
|
+
##
|
|
81
|
+
# @group IO
|
|
82
|
+
|
|
83
|
+
##
|
|
84
|
+
# @return [String]
|
|
85
|
+
# Returns the contents of stdout
|
|
86
|
+
def stdout
|
|
87
|
+
spawn
|
|
88
|
+
consume(@producer, @out, @err)
|
|
89
|
+
@stdout
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
##
|
|
93
|
+
# @return [String]
|
|
94
|
+
# Returns the contents of stderr
|
|
95
|
+
def stderr
|
|
96
|
+
spawn
|
|
97
|
+
consume(@producer, @out, @err)
|
|
98
|
+
@stderr
|
|
99
|
+
end
|
|
100
|
+
# @endgroup
|
|
101
|
+
|
|
102
|
+
##
|
|
103
|
+
# @group Predicates
|
|
104
|
+
|
|
112
105
|
##
|
|
113
106
|
# @return [Boolean]
|
|
114
107
|
# Returns true when a command exited successfully
|
|
@@ -117,42 +110,116 @@ class Test::Cmd
|
|
|
117
110
|
end
|
|
118
111
|
|
|
119
112
|
##
|
|
120
|
-
#
|
|
121
|
-
#
|
|
113
|
+
# @return [Boolean]
|
|
114
|
+
# Returns true when a command has been spawned
|
|
115
|
+
def spawned?
|
|
116
|
+
@spawned
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
##
|
|
120
|
+
# @return [Boolean]
|
|
121
|
+
# Returns true when a command is running
|
|
122
|
+
def alive?
|
|
123
|
+
@producer&.alive?
|
|
124
|
+
end
|
|
125
|
+
alias_method :running?, :alive?
|
|
126
|
+
|
|
127
|
+
##
|
|
128
|
+
# Sends SIGKILL to a running command
|
|
129
|
+
# @return [void]
|
|
130
|
+
def kill!
|
|
131
|
+
return unless alive?
|
|
132
|
+
Process.kill("SIGKILL", @pid)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
##
|
|
136
|
+
# @return [Boolean]
|
|
137
|
+
# Returns true when a command can't be found
|
|
138
|
+
def command_not_found?
|
|
139
|
+
spawn
|
|
140
|
+
consume(@producer, @out, @err)
|
|
141
|
+
@enoent
|
|
142
|
+
end
|
|
143
|
+
alias_method :not_found?, :command_not_found?
|
|
144
|
+
# @endgroup
|
|
145
|
+
|
|
146
|
+
##
|
|
147
|
+
# @group Callbacks
|
|
148
|
+
|
|
149
|
+
##
|
|
150
|
+
# @yieldparam [Test::Cmd] cmd
|
|
151
|
+
# Yields an instance of {Test::Cmd Test::Cmd}
|
|
122
152
|
# @example
|
|
123
153
|
# cmd("ruby", "-e", "exit 0")
|
|
124
154
|
# .success { print "Command [#{_1.pid}] exited successfully", "\n" }
|
|
125
155
|
# .failure { }
|
|
126
|
-
#
|
|
127
156
|
# @return [Test::Cmd]
|
|
128
157
|
def success
|
|
129
158
|
tap do
|
|
130
159
|
spawn
|
|
160
|
+
consume(@producer, @out, @err)
|
|
131
161
|
status.success? ? yield(self) : nil
|
|
132
162
|
end
|
|
133
163
|
end
|
|
134
164
|
|
|
135
165
|
##
|
|
136
|
-
#
|
|
137
|
-
#
|
|
166
|
+
# @yieldparam [Test::Cmd] cmd
|
|
167
|
+
# Yields an instance of {Test::Cmd Test::Cmd}
|
|
138
168
|
# @example
|
|
139
169
|
# cmd("ruby", "-e", "exit 1")
|
|
140
170
|
# .success { }
|
|
141
171
|
# .failure { print "Command [#{_1.pid}] exited unsuccessfully", "\n" }
|
|
142
|
-
#
|
|
143
172
|
# @return [Test::Cmd]
|
|
144
173
|
def failure
|
|
145
174
|
tap do
|
|
146
175
|
spawn
|
|
176
|
+
consume(@producer, @out, @err)
|
|
147
177
|
status.success? ? nil : yield(self)
|
|
148
178
|
end
|
|
149
179
|
end
|
|
180
|
+
# @endgroup
|
|
181
|
+
|
|
182
|
+
private
|
|
150
183
|
|
|
151
184
|
##
|
|
152
|
-
# @
|
|
153
|
-
#
|
|
154
|
-
|
|
155
|
-
|
|
185
|
+
# @param [Test::Cmd::Pipe] out
|
|
186
|
+
# A pipe for stdout
|
|
187
|
+
# @param [Test::Cmd::Pipe] err
|
|
188
|
+
# A pipe for stderr
|
|
189
|
+
# @return [Thread]
|
|
190
|
+
# Returns a thread for a spawned command
|
|
191
|
+
def produce(out, err)
|
|
192
|
+
@producer = Thread.new do
|
|
193
|
+
@pid = Process.spawn(@cmd, *@argv, {out: out.w, err: err.w})
|
|
194
|
+
Process.wait
|
|
195
|
+
@status = $?
|
|
196
|
+
rescue Errno::ENOENT => ex
|
|
197
|
+
@cmd, @argv, @stderr = "false", [], ex.message
|
|
198
|
+
@enoent = true
|
|
199
|
+
retry
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
##
|
|
204
|
+
# @param [Thread] thread
|
|
205
|
+
# A thread for a spawned command
|
|
206
|
+
# @param [Test::Cmd::Pipe] out
|
|
207
|
+
# A pipe for stdout
|
|
208
|
+
# @param [Test::Cmd::Pipe] err
|
|
209
|
+
# A pipe for stderr
|
|
210
|
+
# @return [void]
|
|
211
|
+
def consume(thread, out, err)
|
|
212
|
+
return if @consumed
|
|
213
|
+
sleep 0.01 while thread.alive?
|
|
214
|
+
loop do
|
|
215
|
+
io, _ = IO.select([out.r, err.r], nil, nil, 0.01)
|
|
216
|
+
io&.include?(out.r) ? @stdout << out.r.read(1) : nil
|
|
217
|
+
io&.include?(err.r) ? @stderr << err.r.read(1) : nil
|
|
218
|
+
break unless thread.alive? || IO.select([out.r, err.r], nil, nil, 0.01)
|
|
219
|
+
end
|
|
220
|
+
ensure
|
|
221
|
+
[out, err].each(&:close)
|
|
222
|
+
@consumed = true
|
|
156
223
|
end
|
|
157
224
|
end
|
|
158
225
|
|
data/test/cmd_test.rb
CHANGED
|
@@ -105,4 +105,13 @@ class Test::Cmd
|
|
|
105
105
|
assert_equal true, ruby("puts 42").tap(&:spawn).spawned?
|
|
106
106
|
end
|
|
107
107
|
end
|
|
108
|
+
|
|
109
|
+
##
|
|
110
|
+
# Test::Cmd#command_not_found?
|
|
111
|
+
class CommandNotFoundTest < Test
|
|
112
|
+
def test_command_not_found
|
|
113
|
+
assert_equal true, cmd("/a/path/that/is/not/found").command_not_found?
|
|
114
|
+
assert_equal true, cmd("/a/path/that/is/not/found").not_found?
|
|
115
|
+
end
|
|
116
|
+
end
|
|
108
117
|
end
|
data/test-cmd.rb.gemspec
CHANGED
|
@@ -4,14 +4,13 @@ Gem::Specification.new do |gem|
|
|
|
4
4
|
gem.name = "test-cmd.rb"
|
|
5
5
|
gem.authors = ["0x1eef"]
|
|
6
6
|
gem.email = ["0x1eef@protonmail.com"]
|
|
7
|
-
gem.homepage = "https://github.com/
|
|
8
|
-
gem.version = "0.
|
|
7
|
+
gem.homepage = "https://github.com/1robertrb/test-cmd.rb#readme"
|
|
8
|
+
gem.version = "1.0.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 = "
|
|
14
|
-
gem.metadata = { "documentation_uri" => "https://0x1eef.github.io/x/test-cmd.rb/" }
|
|
13
|
+
gem.summary = "test-cmd.rb provides an object-oriented interface for spawning a command"
|
|
15
14
|
gem.description = gem.summary
|
|
16
15
|
gem.add_development_dependency "test-unit", "~> 3.5.7"
|
|
17
16
|
gem.add_development_dependency "yard", "~> 0.9"
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: test-cmd.rb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 1.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- '0x1eef'
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: test-unit
|
|
@@ -80,7 +79,7 @@ dependencies:
|
|
|
80
79
|
- - "~>"
|
|
81
80
|
- !ruby/object:Gem::Version
|
|
82
81
|
version: '13.1'
|
|
83
|
-
description:
|
|
82
|
+
description: test-cmd.rb provides an object-oriented interface for spawning a command
|
|
84
83
|
email:
|
|
85
84
|
- 0x1eef@protonmail.com
|
|
86
85
|
executables: []
|
|
@@ -89,7 +88,6 @@ extra_rdoc_files: []
|
|
|
89
88
|
files:
|
|
90
89
|
- ".github/workflows/specs.yml"
|
|
91
90
|
- ".gitignore"
|
|
92
|
-
- ".gitlab-ci.yml"
|
|
93
91
|
- ".projectile"
|
|
94
92
|
- ".rubocop.yml"
|
|
95
93
|
- Gemfile
|
|
@@ -101,12 +99,10 @@ files:
|
|
|
101
99
|
- test-cmd.rb.gemspec
|
|
102
100
|
- test/cmd_test.rb
|
|
103
101
|
- test/setup.rb
|
|
104
|
-
homepage: https://github.com/
|
|
102
|
+
homepage: https://github.com/1robertrb/test-cmd.rb#readme
|
|
105
103
|
licenses:
|
|
106
104
|
- 0BSD
|
|
107
|
-
metadata:
|
|
108
|
-
documentation_uri: https://0x1eef.github.io/x/test-cmd.rb/
|
|
109
|
-
post_install_message:
|
|
105
|
+
metadata: {}
|
|
110
106
|
rdoc_options: []
|
|
111
107
|
require_paths:
|
|
112
108
|
- lib
|
|
@@ -121,8 +117,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
121
117
|
- !ruby/object:Gem::Version
|
|
122
118
|
version: '0'
|
|
123
119
|
requirements: []
|
|
124
|
-
rubygems_version:
|
|
125
|
-
signing_key:
|
|
120
|
+
rubygems_version: 4.0.6
|
|
126
121
|
specification_version: 4
|
|
127
|
-
summary:
|
|
122
|
+
summary: test-cmd.rb provides an object-oriented interface for spawning a command
|
|
128
123
|
test_files: []
|
data/.gitlab-ci.yml
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
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
|