Lightweight tagged data library.
at main 185 lines 5.1 kB view raw
1//! Tests for the crate's APIs. 2 3use crate::label::Label; 4use crate::parse::*; 5use crate::storage::Storage; 6use crate::tag::KeyValueSep; 7use crate::tag::PathSep; 8use crate::tag::Tag; 9use crate::tag::TagKind; 10use crate::TagManager; 11use anyhow::anyhow as err; 12use anyhow::Result; 13use string_interner::Symbol; 14 15// Helper function to test that a tag that's parsed and then resolved 16// back into a string results in the same string that was originally 17// put into the manager. 18fn test_roundtrip<L, S, T, P>(manager: &TagManager<L, S, T, P>, input: &str) -> Result<()> 19where 20 L: Label, 21 S: Symbol, 22 T: Tag<Label = L, Symbol = S>, 23 P: Parser<Tag = T> + Send + Sync, 24{ 25 let tag = manager.parse_tag(input)?; 26 let output = manager.resolve_tag(&tag)?; 27 assert_eq!(input, output); 28 Ok(()) 29} 30 31#[test] 32fn roundtrip_plain_tag() -> Result<()> { 33 let manager = TagManager::builder() 34 .parser(Plain::new()) 35 .storage(Storage::default()) 36 .build(); 37 38 test_roundtrip(&manager, "hello") 39} 40 41#[test] 42fn transform_tag() -> Result<()> { 43 let parser = Trim( 44 TrimBounds::Both, 45 ChangeCase(Case::Snake, KeyValue::new(KvPolicy::NoAmbiguousSep)), 46 ); 47 48 let manager = TagManager::builder() 49 .parser(parser) 50 .storage(Storage::default()) 51 .key_value_separator(KeyValueSep("/")) 52 .build(); 53 54 let tag = manager.parse_tag(" \t HELLO_WORLD/GOODBYE_WORLD ")?; 55 let interner = manager.storage().lock()?; 56 let (key, value) = tag.resolve_key_value(&interner)?; 57 58 assert_eq!(key, "hello_world"); 59 assert_eq!(value, "goodbye_world"); 60 61 Ok(()) 62} 63 64#[test] 65fn roundtrip_key_value_tag_unambiguous() -> Result<()> { 66 let manager = TagManager::builder() 67 .parser(KeyValue::new(KvPolicy::NoAmbiguousSep)) 68 .storage(Storage::default()) 69 .build(); 70 71 test_roundtrip(&manager, "hello:world") 72} 73 74#[test] 75fn key_part_key_value_tag_unambiguous() -> Result<()> { 76 let manager = TagManager::builder() 77 .parser(KeyValue::new(KvPolicy::NoAmbiguousSep)) 78 .storage(Storage::default()) 79 .build(); 80 81 let input = "hello:world"; 82 let tag = manager.parse_tag(input)?; 83 let lock = manager.storage().lock()?; 84 let (key, value) = tag.resolve_key_value(&lock)?; 85 assert_eq!(key, "hello"); 86 assert_eq!(value, "world"); 87 88 Ok(()) 89} 90 91#[test] 92fn roundtrip_key_value_tag_split_first() -> Result<()> { 93 let manager = TagManager::builder() 94 .parser(KeyValue::new(KvPolicy::SplitOnFirstSep)) 95 .storage(Storage::default()) 96 .build(); 97 98 test_roundtrip(&manager, "hello:world") 99} 100 101#[test] 102fn key_part_key_value_tag_split_first() -> Result<()> { 103 let manager = TagManager::builder() 104 .parser(KeyValue::new(KvPolicy::SplitOnFirstSep)) 105 .storage(Storage::default()) 106 .build(); 107 108 let input = "hello:world:today"; 109 let tag = manager.parse_tag(input)?; 110 let lock = manager.storage().lock()?; 111 let (key, value) = tag.resolve_key_value(&lock)?; 112 assert_eq!(key, "hello"); 113 assert_eq!(value, "world:today"); 114 Ok(()) 115} 116 117#[test] 118fn roundtrip_key_value_tag_split_last() -> Result<()> { 119 let manager = TagManager::builder() 120 .parser(KeyValue::new(KvPolicy::SplitOnLastSep)) 121 .storage(Storage::default()) 122 .build(); 123 124 test_roundtrip(&manager, "hello:world") 125} 126 127#[test] 128fn key_part_key_value_tag_split_last() -> Result<()> { 129 let manager = TagManager::builder() 130 .parser(KeyValue::new(KvPolicy::SplitOnLastSep)) 131 .storage(Storage::default()) 132 .build(); 133 134 let input = "hello:world:today"; 135 let tag = manager.parse_tag(input)?; 136 let lock = manager.storage().lock()?; 137 let (key, value) = tag.resolve_key_value(&lock)?; 138 assert_eq!(key, "hello:world"); 139 assert_eq!(value, "today"); 140 Ok(()) 141} 142 143#[test] 144fn roundtrip_multipart_tag() -> Result<()> { 145 let manager = TagManager::builder() 146 .parser(Multipart::new(MultipartPolicy::RequireMultipart)) 147 .storage(Storage::default()) 148 .path_separator(PathSep(":")) 149 .build(); 150 151 test_roundtrip(&manager, "hello:world:today:its:me") 152} 153 154#[test] 155fn complex_parser() -> Result<()> { 156 let manager = TagManager::builder() 157 .parser(Trim( 158 TrimBounds::Both, 159 ChangeCase( 160 Case::Snake, 161 Or( 162 Multipart::new(MultipartPolicy::RequireMultipart), 163 Or(KeyValue::new(KvPolicy::NoAmbiguousSep), Plain::new()), 164 ), 165 ), 166 )) 167 .storage(Storage::default()) 168 .build(); 169 170 let tags: Vec<_> = 171 manager.parse_tags_into_with_kind(["lotr/legolas/friends", "score:5", "rustlang"]); 172 173 let mut iter = tags.into_iter(); 174 let (t1, t2, t3) = ( 175 iter.next().ok_or(err!("nothing"))??, 176 iter.next().ok_or(err!("nothing"))??, 177 iter.next().ok_or(err!("nothing"))??, 178 ); 179 180 assert_eq!(t1.1, TagKind::Multipart); 181 assert_eq!(t2.1, TagKind::KeyValue); 182 assert_eq!(t3.1, TagKind::Plain); 183 184 Ok(()) 185}