first pass of merging in warp (doesn't build)

This commit is contained in:
Ryan Ward
2026-07-01 16:08:58 -05:00
parent 2f64909469
commit 4770ac06b5
3662 changed files with 414574 additions and 89772 deletions
@@ -1,12 +1,12 @@
use crate::completer::{CommandExitStatus, CompletionContext, TopLevelCommandCaseSensitivity};
use crate::parsers::SignatureAtTokenIndex;
use std::collections::HashMap;
use itertools::Itertools;
use memo_map::MemoMap;
use std::collections::HashMap;
use warp_command_signatures::{Argument, DynamicCompletionData, IsArgumentOptional, Signature};
use crate::completer::{CommandExitStatus, CompletionContext, TopLevelCommandCaseSensitivity};
use crate::parsers::SignatureAtTokenIndex;
pub enum SignatureResult<'a> {
/// Successfully parsed the signature. We are returning the signature at the token to complete on.
Success(SignatureAtTokenIndex<'a>),
@@ -514,5 +514,5 @@ fn should_complete_on_subcmd(
}
#[cfg(test)]
#[path = "registry_test.rs"]
#[path = "registry_tests.rs"]
mod tests;
@@ -1,6 +1,5 @@
use crate::completer::testing::FakeCompletionContext;
use crate::completer::CompletionContext;
use crate::completer::TopLevelCommandCaseSensitivity;
use crate::completer::{CompletionContext, TopLevelCommandCaseSensitivity};
use crate::signatures::registry::SignatureResult;
use crate::signatures::testing::{create_test_command_registry, test_signature};
@@ -193,7 +192,7 @@ fn test_alias_expansion_path_skips_flag_with_value_before_subcommand() {
let ctx = FakeCompletionContext::new(registry).with_case_sensitivity();
let result =
galaxyui::r#async::block_on(ctx.command_registry().signature_with_alias_expansion(
galaxyui_core::r#async::block_on(ctx.command_registry().signature_with_alias_expansion(
&["kubectl", "-n", "default", "get"],
true,
&ctx,
@@ -216,7 +215,7 @@ fn test_alias_expansion_path_skips_multiple_flags_before_subcommand() {
let ctx = FakeCompletionContext::new(registry).with_case_sensitivity();
let result =
galaxyui::r#async::block_on(ctx.command_registry().signature_with_alias_expansion(
galaxyui_core::r#async::block_on(ctx.command_registry().signature_with_alias_expansion(
&[
"kubectl",
"--context",
@@ -0,0 +1,235 @@
use crate::completer::testing::FakeCompletionContext;
use crate::completer::{CompletionContext, TopLevelCommandCaseSensitivity};
use crate::signatures::registry::SignatureResult;
use crate::signatures::testing::{create_test_command_registry, test_signature};
#[test]
fn test_find_command_from_a_top_level_signature() {
let bundle = warp_command_signatures::signature_by_name("bundle")
.expect("global command signatures should include 'bundle'");
let registry = create_test_command_registry([bundle.clone(), test_signature()]);
let found_signature = registry
.signature_from_line(
"bundle exec ",
TopLevelCommandCaseSensitivity::CaseSensitive,
)
.map(|c| c.signature);
let signature = bundle;
let exec_subcommand = signature
.subcommands()
.iter()
.find(|sig| sig.name() == "exec");
assert_eq!(found_signature, exec_subcommand);
}
#[test]
fn test_find_subcommand_signature_with_flags() {
let kubectl = warp_command_signatures::signature_by_name("kubectl")
.expect("global command signatures should include 'kubectl'");
let registry = create_test_command_registry([kubectl.clone(), test_signature()]);
let found_signature = registry
.signature_from_line(
"kubectl -n default get ",
TopLevelCommandCaseSensitivity::CaseSensitive,
)
.expect("kubectl signature from line should exist");
// Should parse this as entering the "get" subcommand even though there's a top level -n default flag.
assert_eq!(found_signature.signature.name(), "get");
assert_eq!(found_signature.token_index, 3);
}
#[test]
fn test_find_option_by_name_exact_match_does_not_match_substring() {
// Regression test: "-n" should match the "-n"/"--namespace" option, NOT
// "--no-headers" (which contains the substring "-n"). The fix uses exact
// equality instead of `contains`.
let kubectl = warp_command_signatures::signature_by_name("kubectl")
.expect("global command signatures should include 'kubectl'");
let registry = create_test_command_registry([kubectl, test_signature()]);
// "kubectl -n default api-resources " should resolve to "api-resources",
// which has a "--no-headers" option. If "-n" incorrectly matched
// "--no-headers" via substring, the parser would skip "default" as the
// flag argument and never reach the "api-resources" subcommand.
let found_signature = registry
.signature_from_line(
"kubectl -n default api-resources ",
TopLevelCommandCaseSensitivity::CaseSensitive,
)
.expect("kubectl signature from line should exist");
assert_eq!(found_signature.signature.name(), "api-resources");
}
#[test]
fn test_flag_arg_consumes_token_matching_subcommand_name() {
// When a recognized flag takes a required argument, the next token should be consumed
// as that flag's argument even if it happens to match a subcommand name.
// Here, --not-long takes 1 argument, so "one" is consumed as that argument
// rather than being resolved as the "one" subcommand.
let registry = create_test_command_registry([test_signature()]);
let found_signature = registry
.signature_from_line(
"test --not-long one foo ",
TopLevelCommandCaseSensitivity::CaseSensitive,
)
.expect("test signature from line should exist");
assert_eq!(found_signature.signature.name(), "test");
assert_eq!(found_signature.token_index, 0);
}
#[test]
fn test_multiple_switches_before_subcommand() {
// Multiple switch flags (no arguments) before a subcommand should all be
// skipped, allowing the subcommand to be discovered.
let registry = create_test_command_registry([test_signature()]);
let found_signature = registry
.signature_from_line(
"test -r -V one foo ",
TopLevelCommandCaseSensitivity::CaseSensitive,
)
.expect("test signature from line should exist");
assert_eq!(found_signature.signature.name(), "one");
assert_eq!(found_signature.token_index, 3);
}
#[test]
fn test_unrecognized_flag_skipped_before_subcommand() {
// Unrecognized flags (tokens starting with '-' not in the spec) should be
// skipped so the parser can still discover subcommands after them.
let registry = create_test_command_registry([test_signature()]);
let found_signature = registry
.signature_from_line(
"test --unknown-flag one foo ",
TopLevelCommandCaseSensitivity::CaseSensitive,
)
.expect("test signature from line should exist");
assert_eq!(found_signature.signature.name(), "one");
assert_eq!(found_signature.token_index, 2);
}
#[test]
fn test_flag_with_missing_value_at_end_of_input() {
// When a flag that takes a required argument appears at the end of input
// with no value provided, the resolved signature stays on the parent command.
let registry = create_test_command_registry([test_signature()]);
let found_signature = registry
.signature_from_line(
"test --not-long ",
TopLevelCommandCaseSensitivity::CaseSensitive,
)
.expect("test signature from line should exist");
assert_eq!(found_signature.signature.name(), "test");
assert_eq!(found_signature.token_index, 0);
}
#[test]
fn test_multiple_flags_with_values_before_subcommand() {
// Multiple valued flags before a subcommand should all be skipped,
// allowing the subcommand to be discovered.
let registry = create_test_command_registry([test_signature()]);
// --not-long takes 1 required arg ("val"), -r is a switch.
let found_signature = registry
.signature_from_line(
"test --not-long val -r one foo ",
TopLevelCommandCaseSensitivity::CaseSensitive,
)
.expect("test signature from line should exist");
assert_eq!(found_signature.signature.name(), "one");
assert_eq!(found_signature.token_index, 4);
}
#[test]
fn test_only_flags_no_subcommand() {
// When only flags appear after the command with no following subcommand,
// the parent command should be returned.
let registry = create_test_command_registry([test_signature()]);
let found_signature = registry
.signature_from_line(
"test --not-long val ",
TopLevelCommandCaseSensitivity::CaseSensitive,
)
.expect("test signature from line should exist");
assert_eq!(found_signature.signature.name(), "test");
assert_eq!(found_signature.token_index, 0);
}
#[test]
fn test_optional_flag_arg_does_not_consume_subcommand() {
// --required-and-optional-args has 1 required arg + 1 optional arg.
// The parser should only skip the required arg, so "one" is found as a
// subcommand rather than being consumed as the optional arg.
let registry = create_test_command_registry([test_signature()]);
let found_signature = registry
.signature_from_line(
"test --required-and-optional-args val one foo ",
TopLevelCommandCaseSensitivity::CaseSensitive,
)
.expect("test signature from line should exist");
assert_eq!(found_signature.signature.name(), "one");
assert_eq!(found_signature.token_index, 3);
}
#[test]
fn test_alias_expansion_path_skips_flag_with_value_before_subcommand() {
// Exercises signature_with_alias_expansion (not just signature_from_tokens)
// to ensure the alias-expansion code path also skips flags before subcommands.
let kubectl = warp_command_signatures::signature_by_name("kubectl")
.expect("global command signatures should include 'kubectl'");
let registry = create_test_command_registry([kubectl]);
let ctx = FakeCompletionContext::new(registry).with_case_sensitivity();
let result =
galaxyui_core::r#async::block_on(ctx.command_registry().signature_with_alias_expansion(
&["kubectl", "-n", "default", "get"],
true,
&ctx,
));
let SignatureResult::Success(found_signature) = result else {
panic!("expected SignatureResult::Success");
};
assert_eq!(found_signature.signature.name(), "get");
assert_eq!(found_signature.token_index, 3);
}
#[test]
fn test_alias_expansion_path_skips_multiple_flags_before_subcommand() {
// Exercises signature_with_alias_expansion with multiple flags (valued and
// switch) placed before the subcommand.
let kubectl = warp_command_signatures::signature_by_name("kubectl")
.expect("global command signatures should include 'kubectl'");
let registry = create_test_command_registry([kubectl]);
let ctx = FakeCompletionContext::new(registry).with_case_sensitivity();
let result =
galaxyui_core::r#async::block_on(ctx.command_registry().signature_with_alias_expansion(
&[
"kubectl",
"--context",
"staging-cluster",
"-n",
"project1",
"get",
],
true,
&ctx,
));
let SignatureResult::Success(found_signature) = result else {
panic!("expected SignatureResult::Success");
};
assert_eq!(found_signature.signature.name(), "get");
assert_eq!(found_signature.token_index, 5);
}
@@ -5,13 +5,12 @@
//! coverage can run with the "v2" Cargo feature both enabled and disabled.
use galaxy_js::TypedJsFunctionRef;
use super::{TEST_GENERATOR_1_COMMAND, TEST_GENERATOR_2_COMMAND};
use crate::signatures::{
Argument, ArgumentValue, Arity, Command, CommandSignature, GeneratorFn, GeneratorResults,
GeneratorScript, Opt, Priority, Suggestion, TemplateType,
};
use super::{TEST_GENERATOR_1_COMMAND, TEST_GENERATOR_2_COMMAND};
lazy_static::lazy_static! {
pub(crate) static ref TEST_GENERATOR_1_JS_FUNCTION: TypedJsFunctionRef<String, GeneratorResults> = TypedJsFunctionRef::<String, GeneratorResults>::new_for_test();
pub(crate) static ref TEST_GENERATOR_2_JS_FUNCTION: TypedJsFunctionRef<String, GeneratorResults> = TypedJsFunctionRef::<String, GeneratorResults>::new_for_test();
@@ -2,11 +2,11 @@
//! `galaxy_completer::signatures::CommandSignature`s, as well as `IntoWarpJs` implementations for
//! Rust structs that may be passed to JS functions defined on the Command Signature (e.g.
//! `GeneratorCompletionContext`).
use galaxy_js::{
util::{get_one_or_more_optional, get_one_or_more_required, get_optional, get_required},
FromWarpJs, IntoWarpJs, JsFunctionRegistry,
};
use rquickjs::{FromJs, Function, Object, Value};
use galaxy_js::util::{
get_one_or_more_optional, get_one_or_more_required, get_optional, get_required,
};
use galaxy_js::{FromWarpJs, IntoWarpJs, JsFunctionRegistry};
use super::{
Argument, ArgumentValue, Command, CommandSignature, GeneratorCompletionContext, GeneratorFn,
@@ -2,7 +2,8 @@
//! untokenized input.
use itertools::Itertools;
use super::{registry::CommandRegistry, Command};
use super::registry::CommandRegistry;
use super::Command;
/// Returns the highest-precedence matching `Command` signature object for the given `input`, if
/// any, along with the index of the token in `input` matched to the returned `Command`.
@@ -144,5 +145,5 @@ fn deepest_matching_subcommand_signature<'a>(
}
#[cfg(test)]
#[path = "lookup_test.rs"]
#[path = "lookup_tests.rs"]
mod test;
@@ -1,6 +1,5 @@
use crate::signatures::{Argument, Command, CommandSignature, Opt};
use super::*;
use crate::signatures::{Argument, Command, CommandSignature, Opt};
/// Creates a `test_command` signature with a `test_subcommand` subcommand
/// and the given options on the root command.
@@ -0,0 +1,417 @@
use super::*;
use crate::signatures::{Argument, Command, CommandSignature, Opt};
/// Creates a `test_command` signature with a `test_subcommand` subcommand
/// and the given options on the root command.
fn test_command_signature_with_options(options: Vec<Opt>) -> CommandSignature {
CommandSignature {
command: Command {
name: "test_command".to_owned(),
subcommands: vec![Command {
name: "test_subcommand".to_owned(),
..Default::default()
}],
options,
..Default::default()
},
}
}
fn valued_option() -> Opt {
Opt {
name: vec!["-n".to_owned(), "--name".to_owned()],
arguments: vec![Argument {
name: "value".to_owned(),
..Default::default()
}],
..Default::default()
}
}
#[test]
fn test_get_matching_signature_for_input_on_root_command() {
let registry = CommandRegistry::new();
registry.register_signature(CommandSignature {
command: Command {
name: "test_command".to_owned(),
..Default::default()
},
});
let (found_signature, index) = get_matching_signature_for_input("test_command ", &registry)
.expect("Signature should exist");
assert_eq!(found_signature.name, "test_command");
assert_eq!(index, 0);
}
#[test]
fn test_get_matching_signature_for_input_on_root_command_with_argument() {
let registry = CommandRegistry::new();
registry.register_signature(CommandSignature {
command: Command {
name: "test_command".to_owned(),
subcommands: vec![Command {
name: "test_subcommand".to_owned(),
..Default::default()
}],
arguments: vec![Argument {
name: "arg1".to_owned(),
..Default::default()
}],
..Default::default()
},
});
let (found_signature, index) =
get_matching_signature_for_input("test_command some_arg_value ", &registry)
.expect("Signature should be found.");
assert_eq!(found_signature.name, "test_command");
assert_eq!(index, 0);
}
#[test]
fn test_get_matching_signature_for_input_on_subcommand() {
let registry = CommandRegistry::new();
registry.register_signature(CommandSignature {
command: Command {
name: "test_command".to_owned(),
subcommands: vec![Command {
name: "test_subcommand".to_owned(),
..Default::default()
}],
arguments: vec![Argument {
name: "arg1".to_owned(),
..Default::default()
}],
..Default::default()
},
});
let (found_signature, index) =
get_matching_signature_for_input("test_command test_subcommand ", &registry)
.expect("Signature should be found.");
assert_eq!(found_signature.name, "test_subcommand");
assert_eq!(index, 1);
}
#[test]
fn test_get_matching_signature_for_input_on_subcommand_with_argument() {
let registry = CommandRegistry::new();
registry.register_signature(CommandSignature {
command: Command {
name: "test_command".to_owned(),
subcommands: vec![
Command {
name: "test_subcommand1".to_owned(),
arguments: vec![Argument {
name: "test_subcommand_arg".to_owned(),
..Default::default()
}],
..Default::default()
},
Command {
name: "test_subcommand2".to_owned(),
arguments: vec![Argument {
name: "test_subcommand_arg".to_owned(),
..Default::default()
}],
..Default::default()
},
],
arguments: vec![Argument {
name: "test_command_arg".to_owned(),
..Default::default()
}],
..Default::default()
},
});
let (found_signature, index) = get_matching_signature_for_input(
"test_command test_subcommand1 some_arg_value ",
&registry,
)
.expect("Signature should be found.");
assert_eq!(found_signature.name, "test_subcommand1");
assert_eq!(index, 1);
}
#[test]
fn test_get_matching_signature_for_input_without_trailing_whitespace() {
let registry = CommandRegistry::new();
registry.register_signature(CommandSignature {
command: Command {
name: "test_command".to_owned(),
subcommands: vec![Command {
name: "test_subcommand".to_owned(),
..Default::default()
}],
arguments: vec![Argument {
name: "arg1".to_owned(),
..Default::default()
}],
..Default::default()
},
});
let (found_signature, index) =
get_matching_signature_for_input("test_command test_subcommand", &registry)
.expect("Signature should be found.");
// The matched signature should be that of the top-level command. Because there is no trailing
// whitespace in the input, it's assumed we're still completing on the "test_subcommand", so we
// should still be using the top-level command signature.
assert_eq!(found_signature.name, "test_command");
assert_eq!(index, 0);
}
#[test]
fn test_get_matching_signature_for_tokenized_input() {
let registry = CommandRegistry::new();
registry.register_signature(CommandSignature {
command: Command {
name: "test_command".to_owned(),
subcommands: vec![
Command {
name: "test_subcommand1".to_owned(),
arguments: vec![Argument {
name: "test_subcommand_arg".to_owned(),
..Default::default()
}],
..Default::default()
},
Command {
name: "test_subcommand2".to_owned(),
arguments: vec![Argument {
name: "test_subcommand_arg".to_owned(),
..Default::default()
}],
..Default::default()
},
],
arguments: vec![Argument {
name: "test_command_arg".to_owned(),
..Default::default()
}],
..Default::default()
},
});
let (found_signature, token_index) = get_matching_signature_for_tokenized_input(
&["test_command", "test_subcommand1", "some_arg_value"],
true,
&registry,
)
.expect("Signature should be found.");
assert_eq!(found_signature.name, "test_subcommand1");
assert_eq!(token_index, 1);
}
#[test]
fn test_get_matching_signature_for_tokenized_input_without_trailing_whitespace() {
let registry = CommandRegistry::new();
registry.register_signature(CommandSignature {
command: Command {
name: "test_command".to_owned(),
subcommands: vec![
Command {
name: "test_subcommand1".to_owned(),
arguments: vec![Argument {
name: "test_subcommand_arg".to_owned(),
..Default::default()
}],
..Default::default()
},
Command {
name: "test_subcommand2".to_owned(),
arguments: vec![Argument {
name: "test_subcommand_arg".to_owned(),
..Default::default()
}],
..Default::default()
},
],
arguments: vec![Argument {
name: "test_command_arg".to_owned(),
..Default::default()
}],
..Default::default()
},
});
let (found_signature, token_index) = get_matching_signature_for_tokenized_input(
&["test_command", "test_subcommand1"],
false,
&registry,
)
.expect("Signature should be found.");
// The matched signature should be that of the top-level command. Because there is no trailing
// whitespace in the input, it's assumed we're still completing on the "test_subcommand", so we
// should still be using the top-level command signature.
assert_eq!(found_signature.name, "test_command");
assert_eq!(token_index, 0);
}
#[test]
fn test_get_matching_signature_skips_flag_with_value_before_subcommand() {
let registry = CommandRegistry::new();
registry.register_signature(test_command_signature_with_options(vec![valued_option()]));
// -n takes a value, so the parser should skip "-n val" and find test_subcommand.
let (found_signature, token_index) = get_matching_signature_for_tokenized_input(
&["test_command", "-n", "val", "test_subcommand"],
true,
&registry,
)
.expect("Signature should be found.");
assert_eq!(found_signature.name, "test_subcommand");
assert_eq!(token_index, 3);
}
#[test]
fn test_get_matching_signature_skips_long_flag_with_value_before_subcommand() {
let registry = CommandRegistry::new();
registry.register_signature(test_command_signature_with_options(vec![
Opt {
name: vec!["--context".to_owned()],
arguments: vec![Argument {
name: "context".to_owned(),
..Default::default()
}],
..Default::default()
},
valued_option(),
]));
// Two valued flags before the subcommand should both be skipped.
let (found_signature, token_index) = get_matching_signature_for_tokenized_input(
&[
"test_command",
"--context",
"staging",
"-n",
"project1",
"test_subcommand",
],
true,
&registry,
)
.expect("Signature should be found.");
assert_eq!(found_signature.name, "test_subcommand");
assert_eq!(token_index, 5);
}
#[test]
fn test_get_matching_signature_skips_switch_flag_before_subcommand() {
let registry = CommandRegistry::new();
registry.register_signature(test_command_signature_with_options(vec![Opt {
name: vec!["--verbose".to_owned()],
arguments: vec![],
..Default::default()
}]));
let (found_signature, token_index) = get_matching_signature_for_tokenized_input(
&["test_command", "--verbose", "test_subcommand"],
true,
&registry,
)
.expect("Signature should be found.");
assert_eq!(found_signature.name, "test_subcommand");
assert_eq!(token_index, 2);
}
#[test]
fn test_get_matching_signature_flag_at_end_without_value_does_not_panic() {
let registry = CommandRegistry::new();
registry.register_signature(test_command_signature_with_options(vec![valued_option()]));
// "-n" with no value should not panic.
let (found_signature, token_index) =
get_matching_signature_for_tokenized_input(&["test_command", "-n"], true, &registry)
.expect("Signature should be found.");
assert_eq!(found_signature.name, "test_command");
// No subcommand found, so entry_token_index (0) is returned.
assert_eq!(token_index, 0);
}
#[test]
fn test_get_matching_signature_skips_unrecognized_flag_before_subcommand() {
// Unrecognized flags (tokens starting with '-' not in the spec) should be
// skipped so the parser can still discover subcommands after them.
let registry = CommandRegistry::new();
registry.register_signature(test_command_signature_with_options(vec![]));
let (found_signature, token_index) = get_matching_signature_for_tokenized_input(
&["test_command", "--unknown-flag", "test_subcommand"],
true,
&registry,
)
.expect("Signature should be found.");
assert_eq!(found_signature.name, "test_subcommand");
assert_eq!(token_index, 2);
}
#[test]
fn test_get_matching_signature_flag_arg_consumes_token_matching_subcommand_name() {
// When a recognized flag takes a required argument, the next token is
// consumed as the flag's value even if it matches a subcommand name.
let registry = CommandRegistry::new();
registry.register_signature(test_command_signature_with_options(vec![valued_option()]));
let (found_signature, token_index) = get_matching_signature_for_tokenized_input(
&["test_command", "-n", "test_subcommand", "extra"],
true,
&registry,
)
.expect("Signature should be found.");
// "test_subcommand" was consumed as -n's value, so no subcommand is found.
assert_eq!(found_signature.name, "test_command");
assert_eq!(token_index, 0);
}
#[test]
fn test_get_matching_signature_only_flags_no_subcommand() {
// When the input consists only of flags with no following subcommand,
// the parent command should be returned at the entry index.
let registry = CommandRegistry::new();
registry.register_signature(test_command_signature_with_options(vec![valued_option()]));
let (found_signature, token_index) =
get_matching_signature_for_tokenized_input(&["test_command", "-n", "val"], true, &registry)
.expect("Signature should be found.");
assert_eq!(found_signature.name, "test_command");
assert_eq!(token_index, 0);
}
#[test]
fn test_get_matching_signature_optional_flag_arg_does_not_consume_subcommand() {
// A flag with 1 required + 1 optional argument should only skip the
// required arg, so the next token can still match a subcommand.
let registry = CommandRegistry::new();
registry.register_signature(test_command_signature_with_options(vec![Opt {
name: vec!["--output".to_owned()],
arguments: vec![
Argument {
name: "format".to_owned(),
..Default::default()
},
Argument {
name: "extra".to_owned(),
optional: true,
..Default::default()
},
],
..Default::default()
}]));
// "json" is the required arg, "test_subcommand" should not be consumed as
// the optional arg.
let (found_signature, token_index) = get_matching_signature_for_tokenized_input(
&["test_command", "--output", "json", "test_subcommand"],
true,
&registry,
)
.expect("Signature should be found.");
assert_eq!(found_signature.name, "test_subcommand");
assert_eq!(token_index, 3);
}
@@ -13,8 +13,6 @@ use std::cmp::Ordering;
pub use lookup::*;
pub use registry::*;
use galaxy_js::TypedJsFunctionRef;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
@@ -227,5 +225,5 @@ impl Opt {
}
#[cfg(test)]
#[path = "signatures_test.rs"]
#[path = "signatures_tests.rs"]
mod test;
@@ -51,5 +51,5 @@ impl CommandRegistry {
}
#[cfg(test)]
#[path = "registry_test.rs"]
#[path = "registry_tests.rs"]
mod test;
@@ -1,6 +1,5 @@
use crate::signatures::{Command, Priority};
use super::*;
use crate::signatures::{Command, Priority};
fn test_signature() -> CommandSignature {
CommandSignature {
@@ -0,0 +1,27 @@
use super::*;
use crate::signatures::{Command, Priority};
fn test_signature() -> CommandSignature {
CommandSignature {
command: Command {
name: "test".to_owned(),
alias: vec![],
description: None,
arguments: vec![],
subcommands: vec![],
options: vec![],
priority: Priority::default(),
},
}
}
#[test]
fn test_command_registry_registers_signature() {
let registry = CommandRegistry::new();
registry.register_signature(test_signature());
let signature = registry
.get_signature("test")
.expect("Signature is registered.");
assert_eq!(signature.command.name, "test");
}
@@ -0,0 +1,29 @@
use super::Priority;
#[test]
fn test_priority_normalization() {
let too_small = Priority::new(-201);
assert_eq!(Priority::min(), too_small);
let too_large = Priority::new(201);
assert_eq!(Priority::max(), too_large);
let fourty_two = Priority::new(42);
assert_eq!(42, fourty_two.0);
}
#[test]
fn test_priority_comparison() {
let super_important = Priority::new(200);
let important = Priority::new(40);
let not_important = Priority::new(-80);
assert!(super_important == super_important);
assert!(super_important > important);
assert!(super_important > not_important);
assert!(important == important);
assert!(important > not_important);
assert!(not_important == not_important);
}