test-cmd.rb 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
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: []