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 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
@@ -0,0 +1,7 @@
1
+ *.gem
2
+ .gems
3
+ .bundle
4
+ Gemfile.lock
5
+ .yardoc/
6
+ doc/
7
+ pkg/
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
@@ -0,0 +1,2 @@
1
+ source "https://rubygems.org"
2
+ gemspec
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,3 @@
1
+ require "bundler/setup"
2
+ require "test/unit"
3
+ require "test/cmd"
@@ -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
@@ -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: []