From c40205b37e5f95d3d4a49166aafea70e1ee5e641 Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Tue, 19 Jan 2021 20:37:19 -0500 Subject: [PATCH] test: Move DirsAndFileName functionality tests with the definition --- object_store/src/path.rs | 177 -------------------------------- object_store/src/path/parsed.rs | 165 +++++++++++++++++++++++++++++ 2 files changed, 165 insertions(+), 177 deletions(-) diff --git a/object_store/src/path.rs b/object_store/src/path.rs index 4ba3b9dfc0..a00f23f9c8 100644 --- a/object_store/src/path.rs +++ b/object_store/src/path.rs @@ -237,180 +237,3 @@ impl PartialEq for PathRepresentation { /// The delimiter to separate object namespaces, creating a directory structure. pub const DELIMITER: &str = "/"; - -#[cfg(test)] -mod tests { - use super::*; - - // Invariants to maintain/document/test: - // - // - always ends in DELIMITER if it's a directory. If it's the end object, it - // should have some sort of file extension like .parquet, .json, or .segment - // - does not contain unencoded DELIMITER - // - for file paths: does not escape root dir - // - for object storage: looks like directories - // - Paths that come from object stores directly don't need to be - // parsed/validated - // - Within a process, the same backing store will always be used - // - - #[test] - fn prefix_matches() { - let mut haystack = Path::default(); - haystack.push_all_dirs(&["foo/bar", "baz%2Ftest", "something"]); - - // self starts with self - assert!( - haystack.prefix_matches(&haystack), - "{:?} should have started with {:?}", - haystack, - haystack - ); - - // a longer prefix doesn't match - let mut needle = haystack.clone(); - needle.push_dir("longer now"); - assert!( - !haystack.prefix_matches(&needle), - "{:?} shouldn't have started with {:?}", - haystack, - needle - ); - - // one dir prefix matches - let mut needle = Path::default(); - needle.push_dir("foo/bar"); - assert!( - haystack.prefix_matches(&needle), - "{:?} should have started with {:?}", - haystack, - needle - ); - - // two dir prefix matches - needle.push_dir("baz%2Ftest"); - assert!( - haystack.prefix_matches(&needle), - "{:?} should have started with {:?}", - haystack, - needle - ); - - // partial dir prefix matches - let mut needle = Path::default(); - needle.push_dir("f"); - assert!( - haystack.prefix_matches(&needle), - "{:?} should have started with {:?}", - haystack, - needle - ); - - // one dir and one partial dir matches - let mut needle = Path::default(); - needle.push_all_dirs(&["foo/bar", "baz"]); - assert!( - haystack.prefix_matches(&needle), - "{:?} should have started with {:?}", - haystack, - needle - ); - } - - #[test] - fn prefix_matches_with_file_name() { - let mut haystack = Path::default(); - haystack.push_all_dirs(&["foo/bar", "baz%2Ftest", "something"]); - - let mut needle = haystack.clone(); - - // All directories match and file name is a prefix - haystack.set_file_name("foo.segment"); - needle.set_file_name("foo"); - - assert!( - haystack.prefix_matches(&needle), - "{:?} should have started with {:?}", - haystack, - needle - ); - - // All directories match but file name is not a prefix - needle.set_file_name("e"); - - assert!( - !haystack.prefix_matches(&needle), - "{:?} should not have started with {:?}", - haystack, - needle - ); - - // Not all directories match; file name is a prefix of the next directory; this - // matches - let mut needle = Path::default(); - needle.push_all_dirs(&["foo/bar", "baz%2Ftest"]); - needle.set_file_name("s"); - - assert!( - haystack.prefix_matches(&needle), - "{:?} should have started with {:?}", - haystack, - needle - ); - - // Not all directories match; file name is NOT a prefix of the next directory; - // no match - needle.set_file_name("p"); - - assert!( - !haystack.prefix_matches(&needle), - "{:?} should not have started with {:?}", - haystack, - needle - ); - } - - #[test] - fn parts_after_prefix_behavior() { - let mut existing_path = DirsAndFileName::default(); - existing_path.push_all_dirs(&["apple", "bear", "cow", "dog"]); - existing_path.file_name = Some("egg.json".into()); - - // Prefix with one directory - let mut prefix = DirsAndFileName::default(); - prefix.push_dir("apple"); - let expected_parts: Vec = vec!["bear", "cow", "dog", "egg.json"] - .into_iter() - .map(Into::into) - .collect(); - let parts = existing_path.parts_after_prefix(&prefix).unwrap(); - assert_eq!(parts, expected_parts); - - // Prefix with two directories - let mut prefix = DirsAndFileName::default(); - prefix.push_all_dirs(&["apple", "bear"]); - let expected_parts: Vec = vec!["cow", "dog", "egg.json"] - .into_iter() - .map(Into::into) - .collect(); - let parts = existing_path.parts_after_prefix(&prefix).unwrap(); - assert_eq!(parts, expected_parts); - - // Not a prefix - let mut prefix = DirsAndFileName::default(); - prefix.push_dir("cow"); - assert!(existing_path.parts_after_prefix(&prefix).is_none()); - - // Prefix with a partial directory - let mut prefix = DirsAndFileName::default(); - prefix.push_dir("ap"); - assert!(existing_path.parts_after_prefix(&prefix).is_none()); - - // Prefix matches but there aren't any parts after it - let mut existing_path = DirsAndFileName::default(); - existing_path.push_all_dirs(&["apple", "bear", "cow", "dog"]); - let prefix = existing_path.clone(); - let parts = existing_path.parts_after_prefix(&prefix).unwrap(); - assert!(parts.is_empty()); - } -} diff --git a/object_store/src/path/parsed.rs b/object_store/src/path/parsed.rs index 3ed062acc6..cd13217e95 100644 --- a/object_store/src/path/parsed.rs +++ b/object_store/src/path/parsed.rs @@ -147,3 +147,168 @@ impl From for DirsAndFileName { other.inner.into() } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn prefix_matches() { + let mut haystack = DirsAndFileName::default(); + haystack.push_all_dirs(&["foo/bar", "baz%2Ftest", "something"]); + + // self starts with self + assert!( + haystack.prefix_matches(&haystack), + "{:?} should have started with {:?}", + haystack, + haystack + ); + + // a longer prefix doesn't match + let mut needle = haystack.clone(); + needle.push_dir("longer now"); + assert!( + !haystack.prefix_matches(&needle), + "{:?} shouldn't have started with {:?}", + haystack, + needle + ); + + // one dir prefix matches + let mut needle = DirsAndFileName::default(); + needle.push_dir("foo/bar"); + assert!( + haystack.prefix_matches(&needle), + "{:?} should have started with {:?}", + haystack, + needle + ); + + // two dir prefix matches + needle.push_dir("baz%2Ftest"); + assert!( + haystack.prefix_matches(&needle), + "{:?} should have started with {:?}", + haystack, + needle + ); + + // partial dir prefix matches + let mut needle = DirsAndFileName::default(); + needle.push_dir("f"); + assert!( + haystack.prefix_matches(&needle), + "{:?} should have started with {:?}", + haystack, + needle + ); + + // one dir and one partial dir matches + let mut needle = DirsAndFileName::default(); + needle.push_all_dirs(&["foo/bar", "baz"]); + assert!( + haystack.prefix_matches(&needle), + "{:?} should have started with {:?}", + haystack, + needle + ); + } + + #[test] + fn prefix_matches_with_file_name() { + let mut haystack = DirsAndFileName::default(); + haystack.push_all_dirs(&["foo/bar", "baz%2Ftest", "something"]); + + let mut needle = haystack.clone(); + + // All directories match and file name is a prefix + haystack.set_file_name("foo.segment"); + needle.set_file_name("foo"); + + assert!( + haystack.prefix_matches(&needle), + "{:?} should have started with {:?}", + haystack, + needle + ); + + // All directories match but file name is not a prefix + needle.set_file_name("e"); + + assert!( + !haystack.prefix_matches(&needle), + "{:?} should not have started with {:?}", + haystack, + needle + ); + + // Not all directories match; file name is a prefix of the next directory; this + // matches + let mut needle = DirsAndFileName::default(); + needle.push_all_dirs(&["foo/bar", "baz%2Ftest"]); + needle.set_file_name("s"); + + assert!( + haystack.prefix_matches(&needle), + "{:?} should have started with {:?}", + haystack, + needle + ); + + // Not all directories match; file name is NOT a prefix of the next directory; + // no match + needle.set_file_name("p"); + + assert!( + !haystack.prefix_matches(&needle), + "{:?} should not have started with {:?}", + haystack, + needle + ); + } + + #[test] + fn parts_after_prefix_behavior() { + let mut existing_path = DirsAndFileName::default(); + existing_path.push_all_dirs(&["apple", "bear", "cow", "dog"]); + existing_path.file_name = Some("egg.json".into()); + + // Prefix with one directory + let mut prefix = DirsAndFileName::default(); + prefix.push_dir("apple"); + let expected_parts: Vec = vec!["bear", "cow", "dog", "egg.json"] + .into_iter() + .map(Into::into) + .collect(); + let parts = existing_path.parts_after_prefix(&prefix).unwrap(); + assert_eq!(parts, expected_parts); + + // Prefix with two directories + let mut prefix = DirsAndFileName::default(); + prefix.push_all_dirs(&["apple", "bear"]); + let expected_parts: Vec = vec!["cow", "dog", "egg.json"] + .into_iter() + .map(Into::into) + .collect(); + let parts = existing_path.parts_after_prefix(&prefix).unwrap(); + assert_eq!(parts, expected_parts); + + // Not a prefix + let mut prefix = DirsAndFileName::default(); + prefix.push_dir("cow"); + assert!(existing_path.parts_after_prefix(&prefix).is_none()); + + // Prefix with a partial directory + let mut prefix = DirsAndFileName::default(); + prefix.push_dir("ap"); + assert!(existing_path.parts_after_prefix(&prefix).is_none()); + + // Prefix matches but there aren't any parts after it + let mut existing_path = DirsAndFileName::default(); + existing_path.push_all_dirs(&["apple", "bear", "cow", "dog"]); + let prefix = existing_path.clone(); + let parts = existing_path.parts_after_prefix(&prefix).unwrap(); + assert!(parts.is_empty()); + } +}