test-cmd.rb 0.12.4 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9543aef60b39eebdd49dcd4a1a33b9f08841cdc7ad0176402266d0236bdb483c
4
- data.tar.gz: 44f38f751770d9cee2d734a768b07d10a67227d3841aec53648a9ecff89ca26a
3
+ metadata.gz: ceedd530e04b4429280815527f9c18213db595390d6c554854a843c9c9a7717e
4
+ data.tar.gz: 98ad59766cd5aa84d4fbed39ca8d2465fd6be4fa3d7895707f6341fbad37e6c4
5
5
  SHA512:
6
- metadata.gz: be9bba3851638c04d87a114f92fc2ee28b8683e3df14b13b9a37f7a9749ea0075589def7acf65c8b554e62f6e8575b9ccde4aa9f61b024f65a6455f360686559
7
- data.tar.gz: 04db2f4f1b84bb1ce41acfa570778bcec93d64593d58825356c1b9e48ff08b181f8c13c516bbfe70fa8065ecf18b83488df1a8ac1354632e3513765be24a47c6
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
- Style/MultilineIfModifier:
18
- Exclude:
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
- ### Callbacks
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
- ### Test::Unit
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
- * [GitHub](https://github.com/0x1eef/test-cmd.rb#readme)
72
- * [GitLab](https://gitlab.com/0x1eef/test-cmd.rb#about)
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
- unless defined?(Test)
2
- module Test
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
@@ -48,51 +46,19 @@ class Test::Cmd
48
46
  # @return [Test::Cmd]
49
47
  def spawn
50
48
  return self if @spawned
51
-
52
49
  tap do
53
- out, err = Pipe.pair, Pipe.pair
54
50
  @spawned = true
55
- t = Thread.new do
56
- Process.spawn(@cmd, *@argv, {out: out.w, err: err.w})
57
- Process.wait
58
- @status = $?
59
- rescue Errno::ENOENT => ex
60
- @cmd, @argv, @stderr = "false", [], ex.message
61
- @enoent = true
62
- retry
63
- end
64
- loop do
65
- io, _ = IO.select([out.r, err.r], nil, nil, 0.01)
66
- io&.include?(out.r) ? @stdout << out.r.read(1) : nil
67
- io&.include?(err.r) ? @stderr << err.r.read(1) : nil
68
- break unless t.alive? || IO.select([out.r, err.r], nil, nil, 0.01)
69
- end
70
- ensure
71
- [out, err].each(&:close)
51
+ @out, @err = Pipe.pair, Pipe.pair
52
+ produce(@out, @err)
72
53
  end
73
54
  end
74
55
 
75
- ##
76
- # @return [String]
77
- # Returns the contents of stdout
78
- def stdout
79
- spawn
80
- @stdout
81
- end
82
-
83
- ##
84
- # @return [String]
85
- # Returns the contents of stderr
86
- def stderr
87
- spawn
88
- @stderr
89
- end
90
-
91
56
  ##
92
57
  # @return [Process::Status]
93
58
  # Returns the status of a process
94
59
  def status
95
60
  spawn
61
+ consume(@producer, @out, @err)
96
62
  @status
97
63
  end
98
64
 
@@ -111,6 +77,31 @@ class Test::Cmd
111
77
  end
112
78
  alias_method :exitstatus, :exit_status
113
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
+
114
105
  ##
115
106
  # @return [Boolean]
116
107
  # Returns true when a command exited successfully
@@ -119,52 +110,117 @@ class Test::Cmd
119
110
  end
120
111
 
121
112
  ##
122
- # Yields an instance of {Test::Cmd Test::Cmd}.
123
- #
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}
124
152
  # @example
125
153
  # cmd("ruby", "-e", "exit 0")
126
154
  # .success { print "Command [#{_1.pid}] exited successfully", "\n" }
127
155
  # .failure { }
128
- #
129
156
  # @return [Test::Cmd]
130
157
  def success
131
158
  tap do
132
159
  spawn
160
+ consume(@producer, @out, @err)
133
161
  status.success? ? yield(self) : nil
134
162
  end
135
163
  end
136
164
 
137
165
  ##
138
- # Yields an instance of {Test::Cmd Test::Cmd}.
139
- #
166
+ # @yieldparam [Test::Cmd] cmd
167
+ # Yields an instance of {Test::Cmd Test::Cmd}
140
168
  # @example
141
169
  # cmd("ruby", "-e", "exit 1")
142
170
  # .success { }
143
171
  # .failure { print "Command [#{_1.pid}] exited unsuccessfully", "\n" }
144
- #
145
172
  # @return [Test::Cmd]
146
173
  def failure
147
174
  tap do
148
175
  spawn
176
+ consume(@producer, @out, @err)
149
177
  status.success? ? nil : yield(self)
150
178
  end
151
179
  end
180
+ # @endgroup
181
+
182
+ private
152
183
 
153
184
  ##
154
- # @return [Boolean]
155
- # Returns true when a command has been spawned
156
- def spawned?
157
- @spawned
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
158
201
  end
159
202
 
160
203
  ##
161
- # @return [Boolean]
162
- # Returns true when a command can't be found
163
- def command_not_found?
164
- spawn
165
- @enoent
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
166
223
  end
167
- alias_method :not_found?, :command_not_found?
168
224
  end
169
225
 
170
226
  module Kernel
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/0x1eef/test-cmd.rb#readme"
8
- gem.version = "0.12.4"
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 = "An object-oriented interface for spawning a command"
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.12.4
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: 2024-06-16 00:00:00.000000000 Z
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: An object-oriented interface for spawning a command
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/0x1eef/test-cmd.rb#readme
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: 3.5.9
125
- signing_key:
120
+ rubygems_version: 4.0.6
126
121
  specification_version: 4
127
- summary: An object-oriented interface for spawning a command
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