diff options
author | Daniel Mueller <deso@posteo.net> | 2019-01-05 21:41:22 -0800 |
---|---|---|
committer | Daniel Mueller <deso@posteo.net> | 2019-01-05 21:41:22 -0800 |
commit | 6d07a0c9d9a9b39247a9727dea2d90eba4e1fe9e (patch) | |
tree | 843fb189a543e6bc95ff9e5498f5ca2d09bc67a0 /nitrocli/src/main.rs | |
parent | b750c4b13272908a51b85072008554c344b25016 (diff) | |
download | nitrocli-6d07a0c9d9a9b39247a9727dea2d90eba4e1fe9e.tar.gz nitrocli-6d07a0c9d9a9b39247a9727dea2d90eba4e1fe9e.tar.bz2 |
Supply customizable stdio channels to argparse
In order to properly test the program we need to have a way to
intercept data printed to the stdio channels. There are different ways
to accomplish that task. While it is reasonably easy to just start the
program as a dedicated process doing so properly may be problematic from
inside a test because either the path to the binary has to be retrieved
or cargo -- the entity which knows the path -- be invoked. None of these
approaches is very appealing from a testing and code complexity point of
view: an additional fork means additional sources of errors and
flakiness, executing cargo has the potential to even cause rebuilds of
parts of the program, and while we are already testing against a slow I/O
device this additional code running is unlikely to go unnoticed in the
long-term.
Lastly, doing so also means that we leave Rust's type safety behind when
dealing with errors that could be nicely match'ed on when the test
invocation is just a function call.
To avoid all this complexity we instead strive for basically just
running the main function.
This patch marks a first step towards achieving this goal. It introduces
the infrastructure to supply custom Write objects to the argument
parsing functionality. Once more we piggy-back on the command execution
context and add objects representing stdout and stderr to it. We further
ensure that this context is passed to the argument parser invocations.
Diffstat (limited to 'nitrocli/src/main.rs')
-rw-r--r-- | nitrocli/src/main.rs | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/nitrocli/src/main.rs b/nitrocli/src/main.rs index 4f39fdb..ad79c6e 100644 --- a/nitrocli/src/main.rs +++ b/nitrocli/src/main.rs @@ -1,7 +1,7 @@ // main.rs // ************************************************************************* -// * Copyright (C) 2017-2018 Daniel Mueller (deso@posteo.net) * +// * Copyright (C) 2017-2019 Daniel Mueller (deso@posteo.net) * // * * // * This program is free software: you can redistribute it and/or modify * // * it under the terms of the GNU General Public License as published by * @@ -73,6 +73,8 @@ mod commands; mod error; mod pinentry; +use std::env; +use std::io; use std::process; use std::result; @@ -80,9 +82,16 @@ use crate::error::Error; type Result<T> = result::Result<T, Error>; -fn run() -> i32 { - let args = std::env::args().collect(); - match args::handle_arguments(args) { +/// The context used when running the program. +pub(crate) struct RunCtx<'io> { + /// The `Write` object used as standard output throughout the program. + pub stdout: &'io mut dyn io::Write, + /// The `Write` object used as standard error throughout the program. + pub stderr: &'io mut dyn io::Write, +} + +fn run<'ctx, 'io: 'ctx>(ctx: &'ctx mut RunCtx<'io>, args: Vec<String>) -> i32 { + match args::handle_arguments(ctx, args) { Ok(()) => 0, Err(err) => match err { Error::ArgparseError(err) => match err { @@ -100,5 +109,11 @@ fn run() -> i32 { } fn main() { - process::exit(run()); + let args = env::args().collect::<Vec<_>>(); + let ctx = &mut RunCtx { + stdout: &mut io::stdout(), + stderr: &mut io::stderr(), + }; + + process::exit(run(ctx, args)); } |