jet_black 0.4.0 → 0.7.1

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