Module: Toys::Testing
- Defined in:
- lib/toys/testing.rb
Overview
Helpers for writing tool tests.
EXPERIMENTAL: Interfaces are subject to change.
Defined Under Namespace
Modules: ClassMethods
Instance Method Summary collapse
-
#toys_cli ⇒ Toys::CLI
Returns the Toys CLI for this test class.
-
#toys_exec_tool(cmd, cli: nil, **opts) {|controller| ... } ⇒ Toys::Utils::Exec::Result
(also: #exec_tool)
Runs the tool corresponding to the given command line, in a separate forked process, and returns a Exec::Result.
-
#toys_load_tool(cmd, cli: nil) {|tool| ... } ⇒ Object
Prepares the tool corresponding to the given command line, but instead of running it, yields the execution context to the given block.
-
#toys_run_tool(cmd, cli: nil) ⇒ Integer
Runs the tool corresponding to the given command line, in-process, and returns the result code.
Instance Method Details
#toys_cli ⇒ Toys::CLI
Returns the Toys CLI for this test class. By default, a single CLI and Loader are shared by all tests in a given class (or describe block).
18 19 20 |
# File 'lib/toys/testing.rb', line 18 def toys_cli self.class.toys_cli end |
#toys_exec_tool(cmd, cli: nil, **opts) {|controller| ... } ⇒ Toys::Utils::Exec::Result Also known as: exec_tool
Runs the tool corresponding to the given command line, in a separate forked process, and returns a Exec::Result. You can either provide a block to control the process, or simply let it run and capture its output.
By default, a single CLI is shared among the tests in each test class or
describe block. Thus, tools are loaded only once, and the loader is
shared across the tests. If you need to isolate loading for a test,
create a separate CLI and pass it in using the :cli keyword argument.
All other keyword arguments are the same as those defined by the Utils::Exec class. If a block is given, all streams are directed to a Utils::Exec::Controller which is yielded to the block. If no block is given, the output and error streams are captured and the input stream is closed.
This method uses "fork" to isolate the run of the tool. It will not work on environments such as JRuby or Ruby on Windows that do not support process forking.
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/toys/testing.rb', line 188 def toys_exec_tool(cmd, cli: nil, **opts, &block) cli ||= toys_cli cmd = ::Shellwords.split(cmd) if cmd.is_a?(::String) opts = if block { out: :controller, err: :controller, in: :controller, }.merge(opts) else { out: :capture, err: :capture, in: :close, }.merge(opts) end cli.loader.lookup(cmd) tool_caller = proc { ::Kernel.exit(cli.run(*cmd)) } self.class.toys_exec.exec_proc(tool_caller, **opts, &block) end |
#toys_load_tool(cmd, cli: nil) {|tool| ... } ⇒ Object
Prepares the tool corresponding to the given command line, but instead of running it, yields the execution context to the given block. This can be used to test individual methods in a tool.
By default, a single CLI is shared among the tests in each test class or
describe block. Thus, tools are loaded only once, and the loader is
shared across the tests. If you need to isolate loading for a test,
create a separate CLI and pass it in using the :cli keyword argument.
Note: this method runs the given block in-process. This means you can test assertions within the block, but any input or output performed by the tool's methods that you call, will manifest during your test. If this is a problem, you might consider redirecting the standard streams when calling this method, for example by using capture_subprocess_io.
72 73 74 75 76 |
# File 'lib/toys/testing.rb', line 72 def toys_load_tool(cmd, cli: nil, &block) cli ||= toys_cli cmd = ::Shellwords.split(cmd) if cmd.is_a?(::String) cli.load_tool(*cmd, &block) end |
#toys_run_tool(cmd, cli: nil) ⇒ Integer
Runs the tool corresponding to the given command line, in-process, and returns the result code.
By default, a single CLI is shared among the tests in each test class or
describe block. Thus, tools are loaded only once, and the loader is
shared across the tests. If you need to isolate loading for a test,
create a separate CLI and pass it in using the :cli keyword argument.
Note: This method runs the tool in-process. This is often faster than running it in a separate process with #toys_exec_tool, but it also means any input or output performed by the tool, will manifest during your test. If this is a problem, you might consider redirecting the standard streams when calling this method, for example by using capture_subprocess_io.
128 129 130 131 132 |
# File 'lib/toys/testing.rb', line 128 def toys_run_tool(cmd, cli: nil) cli ||= toys_cli cmd = ::Shellwords.split(cmd) if cmd.is_a?(::String) cli.run(*cmd) end |