use moon_config::{GlobOutput, GlobPath, Output, test_utils::*};
mod output_shape {
use super::*;
mod parse_string {
use super::*;
#[test]
fn converts_backward_slashes() {
assert_eq!(
Output::parse("some\\file.txt").unwrap(),
Output::File(stub_file_output("some/file.txt"))
);
}
#[test]
fn token_funcs() {
assert_eq!(
Output::parse("@group(name)").unwrap(),
Output::TokenFunc("@group(name)".into())
);
assert_eq!(
Output::parse("@dirs(name)").unwrap(),
Output::TokenFunc("@dirs(name)".into())
);
assert_eq!(
Output::parse("@files(name)").unwrap(),
Output::TokenFunc("@files(name)".into())
);
assert_eq!(
Output::parse("@globs(name)").unwrap(),
Output::TokenFunc("@globs(name)".into())
);
assert_eq!(
Output::parse("@root(name)").unwrap(),
Output::TokenFunc("@root(name)".into())
);
}
#[test]
fn token_vars() {
assert_eq!(
Output::parse("$workspaceRoot").unwrap(),
Output::TokenVar("$workspaceRoot".into())
);
assert_eq!(
Output::parse("$projectLayer").unwrap(),
Output::TokenVar("$projectLayer".into())
);
}
#[test]
fn file_protocol() {
let mut output = stub_file_output("file.txt");
output.optional = Some(true);
assert_eq!(
Output::parse("file://file.txt?optional").unwrap(),
Output::File(output)
);
let mut output = stub_file_output("/file.txt");
output.optional = Some(false);
assert_eq!(
Output::parse("file:///file.txt?optional=false").unwrap(),
Output::File(output)
);
}
#[test]
fn file_project_relative() {
assert_eq!(
Output::parse("file.rs").unwrap(),
Output::File(stub_file_output("file.rs"))
);
assert_eq!(
Output::parse("dir/file.rs").unwrap(),
Output::File(stub_file_output("dir/file.rs"))
);
assert_eq!(
Output::parse("./file.rs").unwrap(),
Output::File(stub_file_output("file.rs"))
);
assert_eq!(
Output::parse("././dir/file.rs").unwrap(),
Output::File(stub_file_output("dir/file.rs"))
);
}
#[test]
fn file_project_relative_protocol() {
assert_eq!(
Output::parse("file://file.rs").unwrap(),
Output::File(stub_file_output("file.rs"))
);
assert_eq!(
Output::parse("file://dir/file.rs").unwrap(),
Output::File(stub_file_output("dir/file.rs"))
);
assert_eq!(
Output::parse("file://./file.rs").unwrap(),
Output::File(stub_file_output("file.rs"))
);
assert_eq!(
Output::parse("file://././dir/file.rs").unwrap(),
Output::File(stub_file_output("dir/file.rs"))
);
}
#[test]
fn file_workspace_relative() {
assert_eq!(
Output::parse("/file.rs").unwrap(),
Output::File(stub_file_output("/file.rs"))
);
assert_eq!(
Output::parse("/dir/file.rs").unwrap(),
Output::File(stub_file_output("/dir/file.rs"))
);
assert_eq!(
Output::parse("/.cache/$projectSource").unwrap(),
Output::File(stub_file_output("/.cache/$projectSource"))
);
}
#[test]
fn file_workspace_relative_protocol() {
assert_eq!(
Output::parse("file:///file.rs").unwrap(),
Output::File(stub_file_output("/file.rs"))
);
assert_eq!(
Output::parse("file:///dir/file.rs").unwrap(),
Output::File(stub_file_output("/dir/file.rs"))
);
assert_eq!(
Output::parse("file:///.cache/$projectSource").unwrap(),
Output::File(stub_file_output("/.cache/$projectSource"))
);
}
#[test]
fn glob_protocol() {
assert_eq!(
Output::parse("glob://file.*").unwrap(),
Output::Glob(stub_glob_output("file.*"))
);
assert_eq!(
Output::parse("glob:///file.*").unwrap(),
Output::Glob(stub_glob_output("/file.*"))
);
let mut output = stub_glob_output("/file.*");
output.optional = Some(true);
assert_eq!(
Output::parse("glob:///file.*?optional").unwrap(),
Output::Glob(output)
);
}
#[test]
fn glob_protocol_supports_all_syntax() {
for pat in [
"*.png",
"ba(r|z).txt",
"**/{*.{go,rs}}",
"**/*.{md,txt}",
"pkg/**/PKGBUILD",
"dir/{a?c,x?z,foo}",
"lib/[qa-cX-Z]/*",
"(?-i)photos/**/*.(?i){jpg,jpeg}",
"a/<b/**:1,>",
"file.tsx?",
] {
assert_eq!(
Output::Glob(GlobOutput {
glob: GlobPath(pat.into()),
optional: None,
}),
Output::Glob(stub_glob_output(pat))
);
}
}
#[test]
fn glob_project_relative() {
assert_eq!(
Output::parse("!file.*").unwrap(),
Output::Glob(stub_glob_output("!file.*"))
);
assert_eq!(
Output::parse("dir/**/*").unwrap(),
Output::Glob(stub_glob_output("dir/**/*"))
);
assert_eq!(
Output::parse("./dir/**/*").unwrap(),
Output::Glob(stub_glob_output("dir/**/*"))
);
assert_eq!(
Output::parse("$projectSource/**/*").unwrap(),
Output::Glob(stub_glob_output("$projectSource/**/*"))
);
}
#[test]
fn glob_project_relative_protocol() {
assert_eq!(
Output::parse("glob://!file.*").unwrap(),
Output::Glob(stub_glob_output("!file.*"))
);
assert_eq!(
Output::parse("glob://dir/**/*").unwrap(),
Output::Glob(stub_glob_output("dir/**/*"))
);
assert_eq!(
Output::parse("glob://./dir/**/*").unwrap(),
Output::Glob(stub_glob_output("dir/**/*"))
);
assert_eq!(
Output::parse("glob://$projectSource/**/*").unwrap(),
Output::Glob(stub_glob_output("$projectSource/**/*"))
);
}
#[test]
fn glob_workspace_relative() {
assert_eq!(
Output::parse("/!file.*").unwrap(),
Output::Glob(stub_glob_output("!/file.*"))
);
assert_eq!(
Output::parse("!/file.*").unwrap(),
Output::Glob(stub_glob_output("!/file.*"))
);
assert_eq!(
Output::parse("/dir/**/*").unwrap(),
Output::Glob(stub_glob_output("/dir/**/*"))
);
}
#[test]
fn glob_workspace_relative_protocol() {
assert_eq!(
Output::parse("glob:///!file.*").unwrap(),
Output::Glob(stub_glob_output("!/file.*"))
);
assert_eq!(
Output::parse("glob://!/file.*").unwrap(),
Output::Glob(stub_glob_output("!/file.*"))
);
assert_eq!(
Output::parse("glob:///dir/**/*").unwrap(),
Output::Glob(stub_glob_output("/dir/**/*"))
);
}
#[test]
#[should_panic(expected = "environment variable globs are not supported")]
fn errors_for_env_globs() {
Output::parse("$VAR_*").unwrap();
}
#[test]
#[should_panic(expected = "output protocol `unknown://` is not supported")]
fn errors_for_unknown_protocol() {
Output::parse("unknown://test").unwrap();
}
#[test]
#[should_panic(expected = "parent directory traversal (..) is not supported")]
fn errors_for_parent_traversal() {
Output::parse("../../file.txt").unwrap();
}
#[test]
#[should_panic(expected = "parent directory traversal (..) is not supported")]
fn errors_for_parent_traversal_inner() {
Output::parse("dir/../../file.txt").unwrap();
}
}
mod parse_object {
use super::*;
#[test]
fn files() {
let output: Output = serde_json::from_str(r#""file.txt""#).unwrap();
assert_eq!(output, Output::File(stub_file_output("file.txt")));
let output: Output = serde_json::from_str(r#"{ "file": "file.txt" }"#).unwrap();
assert_eq!(output, Output::File(stub_file_output("file.txt")));
let output: Output =
serde_json::from_str(r#"{ "file": "dir/file.txt", "optional": true }"#).unwrap();
assert_eq!(
output,
Output::File({
let mut inner = stub_file_output("dir/file.txt");
inner.optional = Some(true);
inner
})
);
}
#[test]
fn globs() {
let output: Output = serde_json::from_str(r#""file.*""#).unwrap();
assert_eq!(output, Output::Glob(stub_glob_output("file.*")));
let output: Output = serde_json::from_str(r#"{ "glob": "file.*" }"#).unwrap();
assert_eq!(output, Output::Glob(stub_glob_output("file.*")));
}
#[test]
#[should_panic] fn errors_for_parent_traversal() {
let _: Output = serde_json::from_str(r#"{ "glob": "../../file.*" }"#).unwrap();
}
#[test]
#[should_panic] fn errors_for_parent_traversal_inner() {
let _: Output = serde_json::from_str(r#"{ "glob": "dir/../../file.*" }"#).unwrap();
}
}
mod file {
use super::*;
#[test]
fn project_relative() {
let output = stub_file_output("project/file.txt");
assert_eq!(output.file, "project/file.txt");
assert_eq!(output.get_path(), "project/file.txt");
assert!(!output.is_workspace_relative());
let output = stub_file_output("./project/file.txt");
assert_eq!(output.file, "project/file.txt");
assert_eq!(output.get_path(), "project/file.txt");
assert!(!output.is_workspace_relative());
}
#[test]
fn workspace_relative() {
let output = stub_file_output("/root/file.txt");
assert_eq!(output.file, "/root/file.txt");
assert_eq!(output.get_path(), "root/file.txt");
assert!(output.is_workspace_relative());
}
#[test]
fn supports_optional_field() {
let output = stub_file_output("file.txt?optional");
assert!(output.optional.unwrap());
let output = stub_file_output("file.txt?optional=true");
assert!(output.optional.unwrap());
let output = stub_file_output("file.txt?optional=false");
assert!(!output.optional.unwrap());
}
#[test]
#[should_panic(expected = "globs are not supported")]
fn errors_for_glob() {
stub_file_output("file.*");
}
#[test]
#[should_panic(expected = "unsupported value for `optional`")]
fn errors_invalid_optional_field() {
stub_file_output("file.txt?optional=invalid");
}
#[test]
#[should_panic(expected = "unknown file field `unknown`")]
fn errors_unknown_field() {
stub_file_output("file.txt?unknown");
}
}
mod glob {
use super::*;
#[test]
fn project_relative() {
let output = stub_glob_output("project/file.*");
assert_eq!(output.glob, "project/file.*");
assert_eq!(output.get_path(), "project/file.*");
assert!(!output.is_workspace_relative());
assert!(!output.is_negated());
let output = stub_glob_output("./project/file.*");
assert_eq!(output.glob, "project/file.*");
assert_eq!(output.get_path(), "project/file.*");
assert!(!output.is_workspace_relative());
assert!(!output.is_negated());
}
#[test]
fn project_relative_negated() {
let output = stub_glob_output("!project/file.*");
assert_eq!(output.glob, "!project/file.*");
assert_eq!(output.get_path(), "!project/file.*");
assert!(!output.is_workspace_relative());
assert!(output.is_negated());
let output = stub_glob_output("!./project/file.*");
assert_eq!(output.glob, "!project/file.*");
assert_eq!(output.get_path(), "!project/file.*");
assert!(!output.is_workspace_relative());
assert!(output.is_negated());
let output = stub_glob_output("./!project/file.*");
assert_eq!(output.glob, "!project/file.*");
assert_eq!(output.get_path(), "!project/file.*");
assert!(!output.is_workspace_relative());
assert!(output.is_negated());
}
#[test]
fn workspace_relative() {
let output = stub_glob_output("/root/file.*");
assert_eq!(output.glob, "/root/file.*");
assert_eq!(output.get_path(), "root/file.*");
assert!(output.is_workspace_relative());
assert!(!output.is_negated());
}
#[test]
fn workspace_relative_negated() {
let output = stub_glob_output("!/root/file.*");
assert_eq!(output.glob, "!/root/file.*");
assert_eq!(output.get_path(), "!root/file.*");
assert!(output.is_workspace_relative());
assert!(output.is_negated());
let output = stub_glob_output("/!root/file.*");
assert_eq!(output.glob, "!/root/file.*");
assert_eq!(output.get_path(), "!root/file.*");
assert!(output.is_workspace_relative());
assert!(output.is_negated());
}
#[test]
#[should_panic(expected = "unknown glob field `cache`")]
fn errors_invalid_cache_field() {
stub_glob_output("glob://file.*?cache=invalid");
}
#[test]
#[should_panic(expected = "unknown glob field `unknown`")]
fn errors_unknown_field() {
stub_glob_output("glob://file.*?unknown");
}
}
}