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.
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/toys/testing.rb', line 157 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.
97 98 99 100 101 |
# File 'lib/toys/testing.rb', line 97 def toys_run_tool(cmd, cli: nil) cli ||= toys_cli cmd = ::Shellwords.split(cmd) if cmd.is_a?(::String) cli.run(*cmd) end |