use crate::assert_diag_snapshot;
use facet::Facet;
use figue as args;
#[test]
fn test_subcommand_missing_required_positional() {
#[derive(Facet, Debug)]
struct Cli {
#[facet(args::subcommand)]
command: Command,
#[facet(flatten)]
builtins: args::FigueBuiltins,
}
#[derive(Facet, Debug)]
#[repr(u8)]
#[allow(dead_code)]
enum Command {
Init(InitArgs),
Build(BuildArgs),
}
#[derive(Facet, Debug)]
struct InitArgs {
#[facet(args::positional)]
name: String,
#[facet(args::named, args::short = 't', default)]
template: Option<String>,
}
#[derive(Facet, Debug)]
struct BuildArgs {
#[facet(args::named, args::short = 'r', default)]
release: bool,
}
let err = figue::from_slice::<Cli>(&["init"]).unwrap_err();
assert_diag_snapshot!(err);
}
#[test]
fn test_subcommand_with_partial_input() {
#[derive(Facet, Debug)]
struct Cli {
#[facet(args::subcommand)]
command: Command,
#[facet(flatten)]
builtins: args::FigueBuiltins,
}
#[derive(Facet, Debug)]
#[repr(u8)]
#[allow(dead_code)]
enum Command {
Init(InitArgs),
}
#[derive(Facet, Debug)]
struct InitArgs {
#[facet(args::positional)]
name: String,
#[facet(args::positional)]
description: String,
}
let err = figue::from_slice::<Cli>(&["init", "myproject"]).unwrap_err();
assert_diag_snapshot!(err);
}
#[test]
fn test_subcommand_unexpected_extra_positional() {
#[derive(Facet, Debug)]
struct Cli {
#[facet(args::subcommand)]
command: Command,
#[facet(flatten)]
builtins: args::FigueBuiltins,
}
#[derive(Facet, Debug)]
#[repr(u8)]
#[allow(dead_code)]
enum Command {
Init(InitArgs),
}
#[derive(Facet, Debug)]
struct InitArgs {
#[facet(args::positional)]
name: String,
}
let err = figue::from_slice::<Cli>(&["init", "myproject", "extra-arg"]).unwrap_err();
assert_diag_snapshot!(err);
}
#[test]
fn test_subcommand_multiple_missing_positionals() {
#[derive(Facet, Debug)]
struct Cli {
#[facet(args::subcommand)]
command: Command,
}
#[derive(Facet, Debug)]
#[repr(u8)]
#[allow(dead_code)]
enum Command {
Create(CreateArgs),
}
#[derive(Facet, Debug)]
struct CreateArgs {
#[facet(args::positional)]
resource_type: String,
#[facet(args::positional)]
resource_name: String,
#[facet(args::positional)]
location: String,
}
let err = figue::from_slice::<Cli>(&["create"]).unwrap_err();
assert_diag_snapshot!(err);
}
#[test]
fn test_subcommand_missing_required_named() {
#[derive(Facet, Debug)]
struct Cli {
#[facet(args::subcommand)]
command: Command,
}
#[derive(Facet, Debug)]
#[repr(u8)]
#[allow(dead_code)]
enum Command {
Connect(ConnectArgs),
}
#[derive(Facet, Debug)]
struct ConnectArgs {
#[facet(args::named)]
url: String,
#[facet(args::named, default)]
timeout: Option<u32>,
}
let err = figue::from_slice::<Cli>(&["connect"]).unwrap_err();
assert_diag_snapshot!(err);
}
#[test]
fn test_unknown_subcommand_with_suggestion() {
#[derive(Facet, Debug)]
struct Cli {
#[facet(args::subcommand)]
command: Command,
}
#[derive(Facet, Debug)]
#[repr(u8)]
#[allow(dead_code)]
enum Command {
Init(InitArgs),
Build(BuildArgs),
}
#[derive(Facet, Debug)]
struct InitArgs {
#[facet(args::positional)]
name: String,
}
#[derive(Facet, Debug)]
struct BuildArgs {
#[facet(args::named, default)]
release: bool,
}
let err = figue::from_slice::<Cli>(&["int"]).unwrap_err();
assert_diag_snapshot!(err);
}
#[test]
fn test_nested_subcommand_missing_required() {
#[derive(Facet, Debug)]
struct Cli {
#[facet(args::subcommand)]
command: Command,
}
#[derive(Facet, Debug)]
#[repr(u8)]
#[allow(dead_code)]
enum Command {
Repo(RepoArgs),
}
#[derive(Facet, Debug)]
struct RepoArgs {
#[facet(args::subcommand)]
action: RepoAction,
}
#[derive(Facet, Debug)]
#[repr(u8)]
#[allow(dead_code)]
enum RepoAction {
Clone(CloneArgs),
Push,
}
#[derive(Facet, Debug)]
struct CloneArgs {
#[facet(args::positional)]
url: String,
}
let err = figue::from_slice::<Cli>(&["repo", "clone"]).unwrap_err();
assert_diag_snapshot!(err);
}
#[test]
fn test_subcommand_mixed_missing_arguments() {
#[derive(Facet, Debug)]
struct Cli {
#[facet(args::subcommand)]
command: Command,
}
#[derive(Facet, Debug)]
#[repr(u8)]
#[allow(dead_code)]
enum Command {
Deploy(DeployArgs),
}
#[derive(Facet, Debug)]
struct DeployArgs {
#[facet(args::positional)]
environment: String,
#[facet(args::named)]
region: String,
#[facet(args::named, default)]
version: Option<String>,
}
let err = figue::from_slice::<Cli>(&["deploy", "production"]).unwrap_err();
assert_diag_snapshot!(err);
}
#[test]
fn test_no_subcommand_provided() {
#[derive(Facet, Debug)]
struct Cli {
#[facet(args::subcommand)]
command: Command,
#[facet(flatten)]
builtins: args::FigueBuiltins,
}
#[derive(Facet, Debug)]
#[repr(u8)]
#[allow(dead_code)]
enum Command {
Init(InitArgs),
Build(BuildArgs),
}
#[derive(Facet, Debug)]
struct InitArgs {
#[facet(args::positional)]
name: String,
}
#[derive(Facet, Debug)]
struct BuildArgs {
#[facet(args::named, default)]
release: bool,
}
let err = figue::from_slice::<Cli>(&[]).unwrap_err();
assert_diag_snapshot!(err);
}
#[test]
fn test_subcommand_positional_looks_like_flag() {
#[derive(Facet, Debug)]
struct Cli {
#[facet(args::subcommand)]
command: Command,
}
#[derive(Facet, Debug)]
#[repr(u8)]
#[allow(dead_code)]
enum Command {
Create(CreateArgs),
}
#[derive(Facet, Debug)]
struct CreateArgs {
#[facet(args::positional)]
name: String,
#[facet(args::named, default)]
description: Option<String>,
}
let err = figue::from_slice::<Cli>(&["create", "--help"]).unwrap_err();
assert_diag_snapshot!(err);
}
#[test]
fn test_nested_subcommand_not_provided() {
#[derive(Facet, Debug)]
struct Cli {
#[facet(args::subcommand)]
command: Command,
}
#[derive(Facet, Debug)]
#[repr(u8)]
#[allow(dead_code)]
enum Command {
Query(QueryArgs),
Serve,
}
#[derive(Facet, Debug)]
struct QueryArgs {
#[facet(args::subcommand)]
action: QueryAction,
}
#[derive(Facet, Debug)]
#[repr(u8)]
#[allow(dead_code)]
enum QueryAction {
Status,
Uncovered,
Untested,
Unmapped,
Rule(RuleArgs),
Config,
Validate,
}
#[derive(Facet, Debug)]
struct RuleArgs {
#[facet(args::positional)]
rule_id: String,
}
let err = figue::from_slice::<Cli>(&["query"]).unwrap_err();
assert_diag_snapshot!(err);
}
#[test]
fn test_nested_subcommand_not_provided_with_builtins() {
#[derive(Facet, Debug)]
struct Cli {
#[facet(args::subcommand)]
command: Command,
#[facet(flatten)]
builtins: args::FigueBuiltins,
}
#[derive(Facet, Debug)]
#[repr(u8)]
#[allow(dead_code)]
enum Command {
Repo(RepoArgs),
Build,
}
#[derive(Facet, Debug)]
struct RepoArgs {
#[facet(args::subcommand)]
action: RepoAction,
}
#[derive(Facet, Debug)]
#[repr(u8)]
#[allow(dead_code)]
enum RepoAction {
Clone(CloneArgs),
Push,
Pull,
}
#[derive(Facet, Debug)]
struct CloneArgs {
#[facet(args::positional)]
url: String,
}
let err = figue::from_slice::<Cli>(&["repo"]).unwrap_err();
assert_diag_snapshot!(err);
}