test-cmd.rb 0.8.0 → 0.9.2

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: 3271a0fc385b5c2ec050a4295cfd9c67b662dca479a1e5c197610fb0f773fb8b
4
- data.tar.gz: da1a24b436cfde2e63a6fccdaf6ac5d597f180f10b578319549713e64992a095
3
+ metadata.gz: 3d07ddf04e4a028f4c745b1583b0fb54a8d0a66c6545be5ae06a36fe2bed5d44
4
+ data.tar.gz: fc37608b53d4648fcc580c8845af31a8d423087816fdc862662e6e9dda99d29f
5
5
  SHA512:
6
- metadata.gz: bf4e1638056aa03ce82db25547efe1ad9c2bbb2ac737a3ec13b9f8c23576c090101b59c19ce7adf554a2b47e9ae16d9fac6439e730c74423a8fe37e317be745d
7
- data.tar.gz: 82c83edc676b854ffa3e96930a6d6b6d51e3ab484df093f1919529e5abc9914e6ff0bc65180733ed0434d48fdee15be93bbe5ff7526e422f2ff57e56c061a4c7
6
+ metadata.gz: b170b84a449b49991d94f902b4d60aa9030f257e3123335e2eb42718b8116ff27200d396738c83cfe38c03eeb762bf07f47887e0508f0a5f88cb4185b4ea7e82
7
+ data.tar.gz: 07e946aa6b365bfc17e6337eb3c0c7fd773783a8e3b7cdb80dbdf88e91cdfb1550a086d727ea5b14ab350d259c2ad46038ea7683ada3146066dd34cd6d792dc9
data/.rubocop.yml CHANGED
@@ -17,3 +17,7 @@ AllCops:
17
17
  Style/MultilineIfModifier:
18
18
  Exclude:
19
19
  - 'lib/test-cmd.rb'
20
+
21
+ Layout/MultilineMethodCallIndentation:
22
+ Exclude:
23
+ - 'test/*.rb'
data/README.md CHANGED
@@ -1,10 +1,24 @@
1
1
  ## About
2
2
 
3
- test-cmd.rb provides an object-oriented interface for spawning
3
+ test-cmd.rb provides an object-oriented interface for spawning
4
4
  a process.
5
5
 
6
6
  ## Examples
7
7
 
8
+ ### Callbacks
9
+
10
+ The success and failure callbacks provide hooks for when
11
+ a command exits successfully or unsuccessfully. The callback
12
+ is passed an instance of
13
+ [Test::Cmd](https://0x1eef.github.io/x/test-cmd.rb/Test/Cmd.html):
14
+
15
+ ``` ruby
16
+ require "test/cmd"
17
+ cmd("ruby", "-e", "exit 0")
18
+ .success { print "The command [#{_1.pid}] was successful", "\n" }
19
+ .failure { print "The command [#{_1.pid}] was unsuccessful", "\n" }
20
+ ```
21
+
8
22
  ### Test::Unit
9
23
 
10
24
  The following example demonstrates how tests might be written with
@@ -35,22 +49,6 @@ class CmdTest < Test::Unit::TestCase
35
49
  end
36
50
  ```
37
51
 
38
- ### Builder
39
-
40
- test-cmd.rb provides an API that is similar to Rust's
41
- [Command API](https://doc.rust-lang.org/std/process/struct.Command.html).
42
- <br>
43
- The
44
- [API reference](https://0x1eef.github.io/x/test-cmd.rb)
45
- covers it in more-depth:
46
-
47
- ``` ruby
48
- require "test/cmd"
49
- puts cmd("du")
50
- .argv("-s", "-h")
51
- .stdout
52
- ```
53
-
54
52
  ### IO#sync
55
53
 
56
54
  Sometimes it can be neccessary to bypass Ruby's internal buffer and flush
@@ -93,14 +91,14 @@ p cmd("ruby", "test.rb").stdout # => "foo\nbar\n"
93
91
 
94
92
  ## Documentation
95
93
 
96
- A complete API reference is available at
94
+ A complete API reference is available at
97
95
  [0x1eef.github.io/x/test-cmd.rb](https://0x1eef.github.io/x/test-cmd.rb).
98
96
 
99
97
  ## Install
100
98
 
101
99
  **Rubygems.org**
102
100
 
103
- test-cmd.rb can be installed via rubygems.org.
101
+ test-cmd.rb can be installed via rubygems.org:
104
102
 
105
103
  gem install test-cmd.rb
106
104
 
data/lib/test/cmd.rb CHANGED
@@ -1 +1,133 @@
1
1
  require_relative "../test-cmd"
2
+
3
+ ##
4
+ # test-cmd.rb provides an object oriented interface
5
+ # for spawning a command.
6
+ class Test::Cmd
7
+ require "tempfile"
8
+
9
+ ##
10
+ # @param [String] cmd
11
+ # A command to spawn
12
+ # @param [Array<String>] argv
13
+ # Zero or more command-line arguments
14
+ # @return [Test::Cmd]
15
+ def initialize(cmd, *argv)
16
+ @cmd = cmd
17
+ @argv = argv.dup
18
+ @status = nil
19
+ @spawned = false
20
+ end
21
+
22
+ ##
23
+ # @param [Array<String, #to_s>] argv
24
+ # Command-line arguments
25
+ # @return [Test::Cmd]
26
+ def argv(*argv)
27
+ tap { @argv.concat(argv) }
28
+ end
29
+
30
+ ##
31
+ # Spawns a command
32
+ # @return [Test::Cmd]
33
+ def spawn
34
+ return self if @spawned
35
+
36
+ tap do
37
+ @spawned = true
38
+ @out_io, @err_io = spawn_io
39
+ Process.spawn(@cmd, *@argv, {out: @out_io, err: @err_io})
40
+ Process.wait
41
+ @status = $?
42
+ end
43
+ end
44
+
45
+ ##
46
+ # @return [String]
47
+ # Returns the contents of stdout
48
+ def stdout
49
+ @stdout ||= begin
50
+ spawn
51
+ out_io.tap(&:rewind).read.tap { out_io.close }
52
+ end
53
+ end
54
+
55
+ ##
56
+ # @return [String]
57
+ # Returns the contents of stderr
58
+ def stderr
59
+ @stderr ||= begin
60
+ spawn
61
+ err_io.tap(&:rewind).read.tap { err_io.close }
62
+ end
63
+ end
64
+
65
+ ##
66
+ # @return [Process::Status]
67
+ # Returns the status of a process
68
+ def status
69
+ spawn
70
+ @status
71
+ end
72
+
73
+ ##
74
+ # @return [Integer]
75
+ # Returns the process ID of a spawned command
76
+ def pid
77
+ status.pid
78
+ end
79
+
80
+ ##
81
+ # @return [Integer]
82
+ # Returns the exit status of a process
83
+ def exit_status
84
+ status.exitstatus
85
+ end
86
+
87
+ ##
88
+ # Yields an instance of {Test::Cmd Test::Cmd}.
89
+ #
90
+ # @example
91
+ # cmd("ruby", "-e", "exit 0")
92
+ # .success { print "Command exited successfully: #{_1.exit_status}", "\n" }
93
+ # .failure { }
94
+ #
95
+ # @return [Test::Cmd]
96
+ def success
97
+ tap do
98
+ spawn
99
+ status.success? ? yield(self) : nil
100
+ end
101
+ end
102
+
103
+ ##
104
+ # Yields an instance of {Test::Cmd Test::Cmd}.
105
+ #
106
+ # @example
107
+ # cmd("ruby", "-e", "exit 1")
108
+ # .success { }
109
+ # .failure { print "Command exited unsuccessfully: #{_1.exit_status}", "\n" }
110
+ #
111
+ # @return [Test::Cmd]
112
+ def failure
113
+ tap do
114
+ spawn
115
+ status.success? ? nil : yield(self)
116
+ end
117
+ end
118
+
119
+ private
120
+
121
+ attr_reader :out_io, :err_io
122
+
123
+ def spawn_io
124
+ [
125
+ %W[#{object_id} testcmd.out],
126
+ %W[#{object_id} testcmd.err]
127
+ ].map {
128
+ file = Tempfile.new(_1)
129
+ File.chmod(0, file.path)
130
+ file.tap(&:unlink)
131
+ }
132
+ end
133
+ end
data/lib/test-cmd.rb CHANGED
@@ -1,109 +1,11 @@
1
1
  module Test
2
2
  end unless defined?(Test)
3
3
 
4
- ##
5
- # test-cmd.rb is a library for accessing the output streams
6
- # (both stdout and stderr) of a spawned process.
7
- class Test::Cmd
8
- require "tempfile"
9
-
10
- ##
11
- # @param [String] cmd
12
- # A command to spawn.
13
- # @param [Array<String>] argv
14
- # A variable number of command-line arguments.
15
- # @return [Test::Cmd]
16
- def initialize(cmd, *argv)
17
- @cmd = cmd
18
- @argv = argv.dup
19
- @out = unlink!(Tempfile.new("cmd-stdout"))
20
- @err = unlink!(Tempfile.new("cmd-stderr"))
21
- @status = nil
22
- @spawned = false
23
- end
24
-
25
- ##
26
- # @param [Array<String, #to_s>] argv
27
- # One or more command-line arguments.
28
- # @return [Test::Cmd]
29
- def argv(*argv)
30
- tap do
31
- @argv.concat(argv)
32
- end
33
- end
34
-
35
- ##
36
- # Spawns a command.
37
- # @return [Test::Cmd]
38
- def spawn
39
- tap do
40
- @spawned = true
41
- Process.wait Process.spawn(@cmd, *@argv, {out: @out, err: @err})
42
- @status = $?
43
- end
44
- ensure
45
- [stdout,stderr]
46
- end
47
-
48
- ##
49
- # @return [String]
50
- # Returns the contents of stdout.
51
- def stdout
52
- spawn unless @spawned
53
- @stdout ||= @out.tap(&:rewind).read
54
- ensure
55
- @out.close unless @out.closed?
56
- end
57
-
58
- ##
59
- # @return [String]
60
- # Returns the contents of stderr.
61
- def stderr
62
- spawn unless @spawned
63
- @stderr ||= @err.tap(&:rewind).read
64
- ensure
65
- @err.close unless @err.closed?
66
- end
67
-
68
- ##
69
- # @return [Process::Status]
70
- # Returns the status of a process
71
- def status
72
- spawn unless @spawned
73
- @status
74
- end
75
-
76
- ##
77
- # @return [Integer]
78
- # Returns the exit status of a process
79
- def exit_status
80
- status.exitstatus
81
- end
82
-
83
- ##
84
- # @param [Symbol] io
85
- # The output stream as a Symbol (:stdout, :stderr).
86
- # @return [Enumerator]
87
- # Returns an Enumerator when a block is not given.
88
- def each_line(io = :stdout)
89
- return enum_for(:each_line, io) unless block_given?
90
- spawn unless @spawned
91
- public_send(io).each_line { yield(_1) }
92
- end
93
-
94
- private
95
-
96
- ##
97
- # @api private
98
- def unlink!(file)
99
- file.tap do
100
- File.chmod(0, file.path)
101
- file.unlink
102
- end
103
- end
4
+ module Test
5
+ require_relative "test/cmd"
104
6
  end
105
7
 
106
- module Test::Cmd::Mixin
8
+ module Kernel
107
9
  ##
108
10
  # @param (see Test::Cmd#initialize)
109
11
  # @return (see Test::Cmd#initialize)
@@ -111,7 +13,3 @@ module Test::Cmd::Mixin
111
13
  Test::Cmd.new(cmd, *argv)
112
14
  end
113
15
  end
114
-
115
- module Kernel
116
- include Test::Cmd::Mixin
117
- end
@@ -17,6 +17,28 @@ class CmdTest < Test::Unit::TestCase
17
17
  assert_equal 1, cmd("ruby", "-e", "exit 1").exit_status
18
18
  end
19
19
 
20
+ def test_ruby_success_status
21
+ assert_equal true, cmd("ruby", "-e", "exit 0").status.success?
22
+ end
23
+
24
+ def test_ruby_success_callback
25
+ call_ok, call_fail = [false, false]
26
+ cmd("ruby", "-e", "exit 0")
27
+ .success { call_ok = true }
28
+ .failure { call_fail = true }
29
+ assert_equal true, call_ok
30
+ assert_equal false, call_fail
31
+ end
32
+
33
+ def test_ruby_failure_callback
34
+ call_ok, call_fail = [false, false]
35
+ cmd("ruby", "-e", "exit 1")
36
+ .success { call_ok = true }
37
+ .failure { call_fail = true }
38
+ assert_equal true, call_fail
39
+ assert_equal false, call_ok
40
+ end
41
+
20
42
  def test_stdout_with_fork
21
43
  code = <<-CODE.each_line.map { _1.chomp.strip }.join(";")
22
44
  $stdout.sync = true
@@ -30,31 +52,6 @@ class CmdTest < Test::Unit::TestCase
30
52
  assert_equal "foo\nbar\n", cmd("ruby", "-e", code).stdout
31
53
  end
32
54
 
33
- def test_each_line_stdout
34
- run = false
35
- cmd("ruby", "-e", "puts 'FooBar'")
36
- .each_line do
37
- run = true
38
- assert_equal "FooBar\n", _1
39
- end
40
- assert run
41
- end
42
-
43
- def test_each_line_stderr
44
- run = false
45
- cmd("ruby", "-e", "warn 'BarFoo'")
46
- .each_line(:stderr) do
47
- run = true
48
- assert_equal "BarFoo\n", _1
49
- end
50
- assert run
51
- end
52
-
53
- def test_each_line_returns_enum
54
- assert_instance_of Enumerator,
55
- cmd("ruby", "-e", "puts 'FooBar'").each_line
56
- end
57
-
58
55
  def test_cmd_with_argv
59
56
  assert_equal "42\n", cmd("ruby")
60
57
  .argv("-e", "warn 42")
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.0"
8
+ gem.version = "0.9.2"
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 process."
13
+ gem.summary = "An object-oriented interface for spawning a process"
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.8.0
4
+ version: 0.9.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - '0x1eef'
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-04-01 00:00:00.000000000 Z
11
+ date: 2024-05-12 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 process.
83
+ description: An object-oriented interface for spawning a process
84
84
  email:
85
85
  - 0x1eef@protonmail.com
86
86
  executables: []
@@ -121,8 +121,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
121
121
  - !ruby/object:Gem::Version
122
122
  version: '0'
123
123
  requirements: []
124
- rubygems_version: 3.5.3
124
+ rubygems_version: 3.5.9
125
125
  signing_key:
126
126
  specification_version: 4
127
- summary: An object-oriented interface for spawning a process.
127
+ summary: An object-oriented interface for spawning a process
128
128
  test_files: []