jet_black 0.4.0 → 0.7.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3cb06cc77894ad09aa2a5c00da5226227b6416624ac7c02a0d0c558e457667c1
4
- data.tar.gz: 494d96406354c2d46fd34ea105830ee54f2b84da23fe43167446d9ab41d3cad9
3
+ metadata.gz: '059fc435c59412f13bc2fe11be1e7d9c83c691bdb1ff64dcc1851de10285ddcd'
4
+ data.tar.gz: f5b67925853b78170d6129745c7bbdc72a855c6a263a3f89c73e16878e8cf3bb
5
5
  SHA512:
6
- metadata.gz: b27d58676baaa1ef5d3513b0515398798aa137461e5eb649a8cd598e51bd24e344db543e67d68c2a12449e44808a775abc769fcc0adffd5e7bc0c0a22404f463
7
- data.tar.gz: 99451118f6c55638e989f41c8ef83773c5f9e6fa86d281ae0087282e2ea6694788eed7637d47e02f9e431c4472782f10007cc4fcd1d6a9ccbf7720268075679a
6
+ metadata.gz: 20c2774abd978220ed19c4c0cd6e7992c409d8deb1f257eab013f2b6ec6e5002b09dbff7e380e67c65aa5d0553b2d6c2b88b4ad7fb56c02847873a7e6215d55a
7
+ data.tar.gz: 459626286ba5ca1f8b6c76c20f19268fc4c994519a9c493fde2011157f14ce2843379e75dd83e2f3845ba4a62c39ee8c5f77f41f4e118c97b2900e89c9ef72d1
data/.circleci/config.yml CHANGED
@@ -16,7 +16,9 @@ base_job: &base_job
16
16
 
17
17
  - run:
18
18
  name: install dependencies
19
- command: bundle install --jobs=4 --retry=3 --path vendor/bundle
19
+ command: |
20
+ gem install bundler
21
+ bundle install --jobs=4 --retry=3 --path vendor/bundle
20
22
 
21
23
  - save_cache:
22
24
  paths:
@@ -49,14 +51,31 @@ jobs:
49
51
  <<: *base_job
50
52
  docker:
51
53
  - image: circleci/ruby:2.5
54
+ ruby-2.6:
55
+ <<: *base_job
56
+ docker:
57
+ - image: circleci/ruby:2.6
58
+ ruby-2.7:
59
+ <<: *base_job
60
+ docker:
61
+ - image: circleci/ruby:2.7
52
62
  environment:
53
63
  ENABLE_COVERAGE: 1
64
+ ruby-3.0:
65
+ <<: *base_job
66
+ docker:
67
+ - image: circleci/ruby:3.0
54
68
 
55
69
  #-------------------------------------------------------------------------------
56
70
 
71
+ # TODO: Migrate to CircleCI matrix
72
+
57
73
  workflows:
58
74
  version: 2
59
75
  multiple-rubies:
60
76
  jobs:
61
- - ruby-2.5
62
77
  - ruby-2.4
78
+ - ruby-2.5
79
+ - ruby-2.6
80
+ - ruby-2.7
81
+ - ruby-3.0
data/CHANGELOG.md CHANGED
@@ -1,8 +1,32 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.7.1
4
+
5
+ - Fix file descriptor leak in `run_interactive`
6
+
7
+ ## v0.7.0
8
+
9
+ - Adds `run_interactive` to allow pseudo-terminal interaction
10
+
11
+ ## v0.6.0
12
+
13
+ - Freeze string literals
14
+ - Fix deprecation warning: `Bundler.with_clean_env` has been deprecated in
15
+ favor of `Bundler.with_unbundled_env`
16
+
17
+ ## v0.5.1
18
+
19
+ - Fix missing `bundler` require - thanks @lpender via [#6][pr-6]
20
+
21
+ [pr-6]: https://github.com/odlp/jet_black/pull/6
22
+
23
+ ## v0.5.0
24
+
25
+ - `stdout` and `stderr` now keep any trailing newlines at the end of the string.
26
+
3
27
  ## v0.4.0
4
28
 
5
- - Scrub ANSI escape sequences in stdout and stderr
29
+ - Scrub ANSI escape sequences in `stdout` and `stderr`
6
30
  - Allow environment variables to be unset
7
31
 
8
32
  ## v0.3.0
data/Dockerfile CHANGED
@@ -1,8 +1,4 @@
1
- FROM ruby:2.5-alpine
2
-
3
- RUN apk update && \
4
- apk add git && \
5
- mkdir -p /app/lib/jet_black
1
+ FROM ruby:2.7
6
2
 
7
3
  WORKDIR /app
8
4
 
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source "https://rubygems.org"
2
4
 
3
5
  # Specify your gem's dependencies in jet_black.gemspec
data/Gemfile.lock CHANGED
@@ -1,69 +1,63 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- jet_black (0.4.0)
4
+ jet_black (0.7.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
9
  coderay (1.1.2)
10
- coveralls (0.7.2)
11
- multi_json (~> 1.3)
12
- rest-client (= 1.6.7)
13
- simplecov (>= 0.7)
14
- term-ansicolor (= 1.2.2)
15
- thor (= 0.18.1)
10
+ coveralls (0.8.22)
11
+ json (>= 1.8, < 3)
12
+ simplecov (~> 0.16.1)
13
+ term-ansicolor (~> 1.3)
14
+ thor (~> 0.19.4)
15
+ tins (~> 1.6)
16
16
  diff-lcs (1.3)
17
- docile (1.3.0)
18
- json (2.1.0)
17
+ docile (1.3.1)
18
+ json (2.3.1)
19
19
  method_source (0.9.0)
20
- mime-types (3.1)
21
- mime-types-data (~> 3.2015)
22
- mime-types-data (3.2016.0521)
23
- multi_json (1.13.1)
24
20
  pry (0.11.3)
25
21
  coderay (~> 1.1.0)
26
22
  method_source (~> 0.9.0)
27
- rake (10.5.0)
28
- rest-client (1.6.7)
29
- mime-types (>= 1.16)
30
- rspec (3.7.0)
31
- rspec-core (~> 3.7.0)
32
- rspec-expectations (~> 3.7.0)
33
- rspec-mocks (~> 3.7.0)
34
- rspec-core (3.7.1)
35
- rspec-support (~> 3.7.0)
36
- rspec-expectations (3.7.0)
23
+ rake (13.0.1)
24
+ rspec (3.8.0)
25
+ rspec-core (~> 3.8.0)
26
+ rspec-expectations (~> 3.8.0)
27
+ rspec-mocks (~> 3.8.0)
28
+ rspec-core (3.8.0)
29
+ rspec-support (~> 3.8.0)
30
+ rspec-expectations (3.8.1)
37
31
  diff-lcs (>= 1.2.0, < 2.0)
38
- rspec-support (~> 3.7.0)
39
- rspec-mocks (3.7.0)
32
+ rspec-support (~> 3.8.0)
33
+ rspec-mocks (3.8.0)
40
34
  diff-lcs (>= 1.2.0, < 2.0)
41
- rspec-support (~> 3.7.0)
42
- rspec-support (3.7.1)
43
- rspec_junit_formatter (0.3.0)
35
+ rspec-support (~> 3.8.0)
36
+ rspec-support (3.8.0)
37
+ rspec_junit_formatter (0.4.1)
44
38
  rspec-core (>= 2, < 4, != 2.12.0)
45
39
  simplecov (0.16.1)
46
40
  docile (~> 1.1)
47
41
  json (>= 1.8, < 3)
48
42
  simplecov-html (~> 0.10.0)
49
43
  simplecov-html (0.10.2)
50
- term-ansicolor (1.2.2)
51
- tins (~> 0.8)
52
- thor (0.18.1)
53
- tins (0.13.2)
44
+ term-ansicolor (1.6.0)
45
+ tins (~> 1.0)
46
+ thor (0.19.4)
47
+ tins (1.16.3)
54
48
 
55
49
  PLATFORMS
56
50
  ruby
57
51
 
58
52
  DEPENDENCIES
59
- bundler (~> 1.16)
53
+ bundler (>= 1.16, < 3)
60
54
  coveralls
61
55
  jet_black!
62
56
  pry
63
- rake (~> 10.0)
57
+ rake (>= 12.0)
64
58
  rspec (~> 3.0)
65
59
  rspec_junit_formatter
66
60
  simplecov
67
61
 
68
62
  BUNDLED WITH
69
- 1.16.1
63
+ 2.1.4
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # JetBlack
2
2
 
3
- [![CircleCI](https://circleci.com/gh/odlp/jet_black.svg?style=svg)](https://circleci.com/gh/odlp/jet_black) [![Coverage Status](https://coveralls.io/repos/github/odlp/jet_black/badge.svg?branch=master)](https://coveralls.io/github/odlp/jet_black?branch=master)
3
+ [![Gem Version](https://badge.fury.io/rb/jet_black.svg)](https://rubygems.org/gems/jet_black) [![CircleCI](https://circleci.com/gh/odlp/jet_black.svg?style=shield)](https://circleci.com/gh/odlp/jet_black) [![Coverage Status](https://coveralls.io/repos/github/odlp/jet_black/badge.svg?branch=master)](https://coveralls.io/github/odlp/jet_black?branch=master)
4
4
 
5
5
  A black-box testing utility for command line tools and gems. Written in Ruby,
6
6
  with [RSpec] in mind. Features:
@@ -11,6 +11,7 @@ with [RSpec] in mind. Features:
11
11
  - Synchronously [run commands](#running-commands) then write assertions on:
12
12
  - The `stdout` / `stderr` content
13
13
  - The exit status of the process
14
+ - Exercise [interactive command line interfaces](#running-interactive-commands)
14
15
  - Manipulate files in the temporary directory:
15
16
  - [Create files](#file-manipulation)
16
17
  - [Create executable files](#file-manipulation)
@@ -73,7 +74,7 @@ require "jet_black"
73
74
  session = JetBlack::Session.new
74
75
  result = session.run("echo foo")
75
76
 
76
- result.stdout # => "foo"
77
+ result.stdout # => "foo\n"
77
78
  result.stderr # => ""
78
79
  result.exit_status # => 0
79
80
  ```
@@ -85,6 +86,38 @@ session = JetBlack::Session.new
85
86
  session.run("./hello-world", stdin: "Alice")
86
87
  ```
87
88
 
89
+ ### Running interactive commands
90
+
91
+ ```ruby
92
+ session = JetBlack::Session.new
93
+
94
+ result = session.run_interactive("./hello-world") do |terminal|
95
+ terminal.expect("What's your name?", reply: "Alice")
96
+ terminal.expect("What's your location?", reply: "Wonderland")
97
+ end
98
+
99
+ expect(result.exit_status).to eq 0
100
+ expect(result.stdout).to eq <<~TXT
101
+ What's your name?
102
+ Alice
103
+ What's your location?
104
+ Wonderland
105
+ Hello Alice in Wonderland
106
+ TXT
107
+ ```
108
+
109
+ If you don't want to wait for a process to finish, you can end the interactive
110
+ session early:
111
+
112
+ ```ruby
113
+ session = JetBlack::Session.new
114
+
115
+ result = session.run_interactive("./long-cli-flow") do |terminal|
116
+ terminal.expect("Question 1", reply: "Y")
117
+ terminal.end_session(signal: "INT")
118
+ end
119
+ ```
120
+
88
121
  ### File manipulation
89
122
 
90
123
  ```ruby
@@ -145,7 +178,7 @@ non-human-readable file.
145
178
 
146
179
  ```ruby
147
180
  session = JetBlack::Session.new
148
- result = subject.run("echo $FOO", env: { FOO: "bar" })
181
+ result = session.run("printf $FOO", env: { FOO: "bar" })
149
182
 
150
183
  result.stdout # => "bar"
151
184
  ```
@@ -159,15 +192,19 @@ but you want to run commands like `bundle install` and `bundle exec` with a
159
192
  different Gemfile in a given spec, you can configure the session or individual
160
193
  commands to run with a clean Bundler environment.
161
194
 
195
+ Per command:
196
+
162
197
  ```ruby
163
- # Per command
164
198
  session = JetBlack::Session.new
165
- subject.run("bundle install", options: { clean_bundler_env: true })
199
+ session.run("bundle install", options: { clean_bundler_env: true })
200
+ ```
201
+
202
+ Per session:
166
203
 
167
- # Per session
204
+ ```ruby
168
205
  session = JetBlack::Session.new(options: { clean_bundler_env: true })
169
- subject.run("bundle install")
170
- subject.run("bundle exec rake")
206
+ session.run("bundle install")
207
+ session.run("bundle exec rake")
171
208
  ```
172
209
 
173
210
  ### `$PATH` prefix
@@ -250,3 +287,10 @@ RSpec.describe "my command line tool" do
250
287
  end
251
288
  end
252
289
  ```
290
+
291
+ ## More examples
292
+
293
+ - JetBlack's own [higher-level tests](https://github.com/odlp/jet_black/tree/master/spec/features)
294
+ - A more complex scenario testing a [gem in a fresh Rails app](https://github.com/thoughtbot/capybara_discoball/blob/master/spec/black_box/rails_app_spec.rb#L8-L39). Shows how to:
295
+ - Include the [gem-under-test via the Rails app's Gemfile](https://github.com/thoughtbot/capybara_discoball/blob/4e89bfe5531eea1bf6dac42c46c26d0c687d6ddf/spec/black_box/rails_app_spec.rb#L99-L104)
296
+ - Use a [clean Bundler environment](https://github.com/thoughtbot/capybara_discoball/blob/4e89bfe5531eea1bf6dac42c46c26d0c687d6ddf/spec/black_box/rails_app_spec.rb#L5) to use the Gemfile of the new Rails app (instead of the Bundler context of the gem's test suite)
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "bundler/gem_tasks"
2
4
  require "rspec/core/rake_task"
3
5
 
data/jet_black.gemspec CHANGED
@@ -18,10 +18,10 @@ Gem::Specification.new do |spec|
18
18
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_development_dependency "bundler", "~> 1.16"
21
+ spec.add_development_dependency "bundler", ">= 1.16", "< 3"
22
22
  spec.add_development_dependency "coveralls"
23
23
  spec.add_development_dependency "pry"
24
- spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "rake", ">= 12.0"
25
25
  spec.add_development_dependency "rspec_junit_formatter"
26
26
  spec.add_development_dependency "rspec", "~> 3.0"
27
27
  spec.add_development_dependency "simplecov"
data/lib/jet_black.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "jet_black/configuration"
2
4
  require "jet_black/session"
3
5
  require "jet_black/version"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module JetBlack
2
4
  class Configuration
3
5
  attr_accessor :fixture_directory, :path_prefix
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module JetBlack
2
4
  class Environment
3
5
  def initialize(raw_env)
@@ -13,9 +15,9 @@ module JetBlack
13
15
  attr_reader :raw_env
14
16
 
15
17
  def stringify_env(env)
16
- env.map do |key, value|
17
- [key.to_s, value&.to_s]
18
- end.to_h
18
+ env.each_with_object({}) do |(key, value), memo|
19
+ memo[key.to_s] = value&.to_s
20
+ end
19
21
  end
20
22
 
21
23
  def apply_path_prefix(env)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module JetBlack
2
4
  class Error < ::StandardError
3
5
  end
@@ -31,4 +33,17 @@ module JetBlack
31
33
  MSG
32
34
  end
33
35
  end
36
+
37
+ class TerminalSessionTimeoutError < Error
38
+ attr_reader :terminal
39
+
40
+ def initialize(terminal, expected_value, timeout)
41
+ @terminal = terminal
42
+
43
+ super <<~MSG
44
+ Interactive terminal session timed out after #{timeout} second(s).
45
+ Waiting for: '#{expected_value}'
46
+ MSG
47
+ end
48
+ end
34
49
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative "ansi_scrubber"
2
4
 
3
5
  module JetBlack
@@ -25,7 +27,7 @@ module JetBlack
25
27
  private
26
28
 
27
29
  def scrub(output_string)
28
- AnsiScrubber.call(output_string.to_s.chomp)
30
+ AnsiScrubber.call(output_string.to_s)
29
31
  end
30
32
  end
31
33
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "fileutils"
2
4
  require_relative "errors"
3
5
 
@@ -0,0 +1,24 @@
1
+ require_relative "environment"
2
+ require_relative "terminal_session"
3
+
4
+ module JetBlack
5
+ class InteractiveCommand
6
+ def call(raw_command:, raw_env:, directory:, block:)
7
+ env = Environment.new(raw_env).to_h
8
+ terminal = TerminalSession.new(raw_command, env: env, directory: directory)
9
+
10
+ unless block.nil?
11
+ block.call(terminal)
12
+ end
13
+
14
+ terminal.wait_for_finish
15
+
16
+ ExecutedCommand.new(
17
+ raw_command: raw_command,
18
+ stdout: terminal.stdout,
19
+ stderr: terminal.stderr,
20
+ exit_status: terminal.exit_status,
21
+ )
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,21 @@
1
+ require "open3"
2
+ require_relative "environment"
3
+
4
+ module JetBlack
5
+ class NonInteractiveCommand
6
+ def call(raw_command:, stdin:, raw_env:, directory:)
7
+ env = Environment.new(raw_env).to_h
8
+
9
+ stdout, stderr, exit_status = Open3.capture3(
10
+ env, raw_command, chdir: directory, stdin_data: stdin
11
+ )
12
+
13
+ ExecutedCommand.new(
14
+ raw_command: raw_command,
15
+ stdout: stdout,
16
+ stderr: stderr,
17
+ exit_status: exit_status,
18
+ )
19
+ end
20
+ end
21
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "rspec/core"
2
4
  require_relative "rspec/matchers"
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "rspec/expectations"
2
4
 
3
5
  module JetBlack
@@ -1,13 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "bundler"
3
4
  require "fileutils"
4
5
  require "forwardable"
5
- require "open3"
6
6
  require "tmpdir"
7
- require_relative "environment"
8
7
  require_relative "errors"
9
8
  require_relative "executed_command"
10
9
  require_relative "file_helper"
10
+ require_relative "non_interactive_command"
11
+ require_relative "interactive_command"
11
12
 
12
13
  module JetBlack
13
14
  class Session
@@ -26,38 +27,52 @@ module JetBlack
26
27
  end
27
28
 
28
29
  def run(command, stdin: nil, env: {}, options: {})
29
- combined_options = session_options.merge(options)
30
- executed_command = exec_command(command, stdin, env, combined_options)
31
- commands << executed_command
32
- executed_command
30
+ exec_non_interactive(raw_command: command, stdin: stdin, raw_env: env, options: options).tap do |executed_command|
31
+ commands << executed_command
32
+ end
33
+ end
34
+
35
+ def run_interactive(command, env: {}, options: {}, &block)
36
+ exec_interactive(raw_command: command, raw_env: env, options: options, block: block).tap do |executed_command|
37
+ commands << executed_command
38
+ end
33
39
  end
34
40
 
35
41
  private
36
42
 
37
43
  attr_reader :session_options, :file_helper
38
44
 
39
- def exec_command(raw_command, stdin, raw_env, options)
40
- env = Environment.new(raw_env).to_h
45
+ def exec_non_interactive(raw_command:, stdin:, raw_env:, options:)
46
+ combined_options = session_options.merge(options)
47
+
48
+ execution_context(combined_options) do
49
+ NonInteractiveCommand.new.call(raw_command: raw_command, stdin: stdin, raw_env: raw_env, directory: directory)
50
+ end
51
+ end
41
52
 
42
- command_context(options) do
43
- stdout, stderr, exit_status =
44
- Open3.capture3(env, raw_command, chdir: directory, stdin_data: stdin)
53
+ def exec_interactive(raw_command:, raw_env:, options:, block:)
54
+ combined_options = session_options.merge(options)
45
55
 
46
- ExecutedCommand.new(
47
- raw_command: raw_command,
48
- stdout: stdout,
49
- stderr: stderr,
50
- exit_status: exit_status,
51
- )
56
+ execution_context(combined_options) do
57
+ InteractiveCommand.new.call(raw_command: raw_command, raw_env: raw_env, directory: directory, block: block)
52
58
  end
53
59
  end
54
60
 
55
- def command_context(options)
61
+ def execution_context(options)
56
62
  if options[:clean_bundler_env]
57
- Bundler.with_clean_env { yield }
63
+ Bundler.public_send(bundler_clean_environment_method) { yield }
58
64
  else
59
65
  yield
60
66
  end
61
67
  end
68
+
69
+ def bundler_clean_environment_method
70
+ # Bundler 2.x
71
+ if Bundler.respond_to?(:with_unbundled_env)
72
+ :with_unbundled_env
73
+ else
74
+ :with_clean_env
75
+ end
76
+ end
62
77
  end
63
78
  end
@@ -0,0 +1,92 @@
1
+ require "pty"
2
+ require "expect"
3
+ require_relative "errors"
4
+
5
+ module JetBlack
6
+ class TerminalSession
7
+ DEFAULT_TIMEOUT = 10
8
+
9
+ attr_reader :exit_status
10
+
11
+ def initialize(raw_command, env:, directory:)
12
+ @stderr_reader, @stderr_writer = IO.pipe
13
+ @output, @input, @pid = PTY.spawn(env, raw_command, chdir: directory, err: stderr_writer.fileno)
14
+ self.raw_stdout = []
15
+ end
16
+
17
+ def expect(expected_value, reply: nil, timeout: DEFAULT_TIMEOUT, signal_on_timeout: "KILL")
18
+ output_matches = output.expect(expected_value, timeout)
19
+
20
+ if output_matches.nil?
21
+ end_session(signal: signal_on_timeout)
22
+ raise TerminalSessionTimeoutError.new(self, expected_value, timeout)
23
+ end
24
+
25
+ raw_stdout.concat(output_matches)
26
+
27
+ if reply != nil
28
+ input.puts(reply)
29
+ end
30
+ end
31
+
32
+ def stdout
33
+ raw_stdout.join.gsub("\r", "")
34
+ end
35
+
36
+ def stderr
37
+ raw_std_err
38
+ end
39
+
40
+ def wait_for_finish
41
+ return if finished?
42
+
43
+ finalize_io
44
+
45
+ self.exit_status = wait_for_exit_status
46
+ end
47
+
48
+ def end_session(signal: "INT")
49
+ Process.kill(signal, pid)
50
+ finalize_io
51
+
52
+ self.exit_status = wait_for_exit_status
53
+ end
54
+
55
+ def finished?
56
+ !exit_status.nil?
57
+ end
58
+
59
+ private
60
+
61
+ attr_accessor :raw_stdout, :raw_std_err
62
+ attr_reader :input, :output, :pid, :stderr_reader, :stderr_writer
63
+ attr_writer :exit_status
64
+
65
+ def finalize_io
66
+ drain_stdout
67
+ drain_stderr
68
+ end
69
+
70
+ def wait_for_exit_status
71
+ _, pty_status = Process.waitpid2(pid)
72
+ pty_status.exitstatus || pty_status.termsig
73
+ end
74
+
75
+ def drain_stdout
76
+ until output.eof? do
77
+ raw_stdout << output.readline
78
+ end
79
+
80
+ input.close
81
+ output.close
82
+ rescue Errno::EIO => e # https://github.com/ruby/ruby/blob/57fb2199059cb55b632d093c2e64c8a3c60acfbb/ext/pty/pty.c#L521
83
+ warn("Rescued #{e.message}") if ENV.key?("DEBUG")
84
+ end
85
+
86
+ def drain_stderr
87
+ stderr_writer.close
88
+ self.raw_std_err = stderr_reader.read
89
+ stderr_reader.close
90
+ end
91
+ end
92
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module JetBlack
2
- VERSION = "0.4.0"
4
+ VERSION = "0.7.1"
3
5
  end
metadata CHANGED
@@ -1,29 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jet_black
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oli Peate
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-06-22 00:00:00.000000000 Z
11
+ date: 2021-02-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.16'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '3'
20
23
  type: :development
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - "~>"
27
+ - - ">="
25
28
  - !ruby/object:Gem::Version
26
29
  version: '1.16'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '3'
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: coveralls
29
35
  requirement: !ruby/object:Gem::Requirement
@@ -56,16 +62,16 @@ dependencies:
56
62
  name: rake
57
63
  requirement: !ruby/object:Gem::Requirement
58
64
  requirements:
59
- - - "~>"
65
+ - - ">="
60
66
  - !ruby/object:Gem::Version
61
- version: '10.0'
67
+ version: '12.0'
62
68
  type: :development
63
69
  prerelease: false
64
70
  version_requirements: !ruby/object:Gem::Requirement
65
71
  requirements:
66
- - - "~>"
72
+ - - ">="
67
73
  - !ruby/object:Gem::Version
68
- version: '10.0'
74
+ version: '12.0'
69
75
  - !ruby/object:Gem::Dependency
70
76
  name: rspec_junit_formatter
71
77
  requirement: !ruby/object:Gem::Requirement
@@ -108,8 +114,8 @@ dependencies:
108
114
  - - ">="
109
115
  - !ruby/object:Gem::Version
110
116
  version: '0'
111
- description:
112
- email:
117
+ description:
118
+ email:
113
119
  executables: []
114
120
  extensions: []
115
121
  extra_rdoc_files: []
@@ -135,15 +141,18 @@ files:
135
141
  - lib/jet_black/errors.rb
136
142
  - lib/jet_black/executed_command.rb
137
143
  - lib/jet_black/file_helper.rb
144
+ - lib/jet_black/interactive_command.rb
145
+ - lib/jet_black/non_interactive_command.rb
138
146
  - lib/jet_black/rspec.rb
139
147
  - lib/jet_black/rspec/matchers.rb
140
148
  - lib/jet_black/session.rb
149
+ - lib/jet_black/terminal_session.rb
141
150
  - lib/jet_black/version.rb
142
151
  homepage: https://github.com/odlp/jet_black
143
152
  licenses:
144
153
  - MIT
145
154
  metadata: {}
146
- post_install_message:
155
+ post_install_message:
147
156
  rdoc_options: []
148
157
  require_paths:
149
158
  - lib
@@ -158,9 +167,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
158
167
  - !ruby/object:Gem::Version
159
168
  version: '0'
160
169
  requirements: []
161
- rubyforge_project:
162
- rubygems_version: 2.7.6
163
- signing_key:
170
+ rubygems_version: 3.1.4
171
+ signing_key:
164
172
  specification_version: 4
165
173
  summary: Black box testing
166
174
  test_files: []