mod support; use chrono::Utc; use morethantext::{ action::{Addition, DocDef, Field, FieldType, Query}, Calculation, ErrorID, IndexType, MTTError, MoreThanText, Name, Operand, }; use std::{collections::HashSet, time::Duration}; use support::{random_name, TestDocument}; use uuid::Uuid; #[test] fn can_new_documents_be_added() { let count = 5; let mut mtt = MoreThanText::new(); let doc_name = random_name(); let field_name = random_name(); let mut data: HashSet = HashSet::new(); for i in 0..count { data.insert(i.into()); } let mut docdef = DocDef::new(doc_name.clone()); docdef.add_field(field_name.clone(), FieldType::Integer); mtt.create_document(docdef); for item in data.iter() { let mut add = Addition::new(doc_name.clone()); add.add_field(field_name.clone(), item.clone()); mtt.records(add).unwrap(); } let qry = Query::new(doc_name.clone()); let recs = mtt.records(qry).unwrap(); assert_eq!(recs.len(), data.len()); for rec in recs.iter() { let result = rec.get(&field_name).unwrap(); assert!( data.contains(&result), "did not find {:?} in {:?}", result, data ); data.remove(&result); } assert_eq!(data.len(), 0, "{:?} did not appear in query", data); } #[test] fn does_it_error_on_a_bad_document_name() { let mut mtt = MoreThanText::new(); let doc_name = Name::english("empty"); let mut expected = MTTError::new(ErrorID::NameNotFound(doc_name.clone().into())); expected.add_parent(ErrorID::Document(doc_name.clone().into())); let add = Addition::new(doc_name.clone()); let result = mtt.records(add).unwrap_err(); assert_eq!(result.to_string(), expected.to_string()); } #[test] fn does_it_error_on_bad_field_name() { let mut mtt = MoreThanText::new(); let doc_name = Name::english("holder"); let field_name = Name::english("missing"); let docdef = DocDef::new(doc_name.clone()); mtt.create_document(docdef); let mut add = Addition::new(doc_name.clone()); add.add_field(field_name.clone(), "something"); let mut expected = MTTError::new(ErrorID::NameNotFound(field_name.clone().into())); expected.add_parent(ErrorID::Field(field_name.clone().into())); expected.add_parent(ErrorID::Document(doc_name.clone().into())); let result = mtt.records(add).unwrap_err(); assert_eq!(result.to_string(), expected.to_string()); } #[test] fn does_it_error_on_bad_field_type() { let mut mtt = MoreThanText::new(); let test_doc = TestDocument::new(vec![FieldType::Uuid]); mtt.create_document(test_doc.get_docdef()); let mut add = Addition::new(test_doc.get_doc_name().clone()); add.add_field(test_doc.get_field_name(0), "something"); let mut expected = MTTError::new(ErrorID::FieldTypeExpected(FieldType::Uuid)); expected.add_parent(ErrorID::Field(test_doc.get_field_name(0).into())); expected.add_parent(ErrorID::Document(test_doc.get_doc_name().clone().into())); let result = mtt.records(add).unwrap_err(); assert_eq!(result.to_string(), expected.to_string()); } #[test] #[ignore = "requires session to store language preference"] fn does_it_error_on_missing_fields() { let mut mtt = MoreThanText::new(); let test_doc = TestDocument::new(vec![FieldType::Integer, FieldType::Integer]); mtt.create_document(test_doc.get_docdef()); let mut add = Addition::new(test_doc.get_doc_name().clone()); add.add_field(test_doc.get_field_name(0), 1); let mut expected = MTTError::new(ErrorID::FieldInvalidNone); expected.add_parent(ErrorID::Field(test_doc.get_field_name(0).into())); expected.add_parent(ErrorID::Document(test_doc.get_doc_name().clone().into())); let result = mtt.records(add).unwrap_err(); assert_eq!(result.to_string(), expected.to_string()); } #[test] fn can_default_values_be_used() { let mut mtt = MoreThanText::new(); let ftype = FieldType::StaticString; let test_doc = TestDocument::new(vec![ftype.clone()]); let mut docdef = test_doc.get_docdef(); docdef.set_default(&test_doc.get_field_name(0), ftype.clone()); mtt.create_document(docdef); let add = Addition::new(test_doc.get_doc_name().clone()); let results = mtt.records(add).unwrap(); let rec = results.iter().last().unwrap(); assert_eq!(rec.get(test_doc.get_field_name(0)).unwrap(), "".into()); } #[test] fn can_default_values_be_set() { let mut mtt = MoreThanText::new(); let ftype = FieldType::StaticString; let fdefault = Uuid::new_v4().to_string(); let test_doc = TestDocument::new(vec![ftype.clone()]); let mut docdef = test_doc.get_docdef(); docdef.set_default(&test_doc.get_field_name(0), fdefault.clone()); mtt.create_document(docdef); let add = Addition::new(test_doc.get_doc_name().clone()); let results = mtt.records(add).unwrap(); let rec = results.iter().last().unwrap(); assert_eq!( rec.get(test_doc.get_field_name(0)).unwrap(), fdefault.into() ); } #[test] fn can_default_values_be_overwritten() { let mut mtt = MoreThanText::new(); let ftype = FieldType::StaticString; let fdefault = Uuid::new_v4().to_string(); let used = "something"; let test_doc = TestDocument::new(vec![ftype.clone()]); let mut docdef = test_doc.get_docdef(); docdef.set_default(&test_doc.get_field_name(0), fdefault.clone()); mtt.create_document(docdef); let mut add = Addition::new(test_doc.get_doc_name().clone()); add.add_field(test_doc.get_field_name(0), used); let results = mtt.records(add).unwrap(); let rec = results.iter().last().unwrap(); assert_eq!(rec.get(test_doc.get_field_name(0)).unwrap(), used.into()); } #[test] fn can_default_values_be_calculated() { let duration = Duration::from_secs(300); let mut mtt = MoreThanText::new(); let test_doc = TestDocument::new(vec![FieldType::DateTime]); let mut docdef = test_doc.get_docdef(); let mut calc = Calculation::new(Operand::Add); calc.add_value(FieldType::DateTime); calc.add_value(duration.clone()); docdef.set_default(&test_doc.get_field_name(0), calc); mtt.create_document(docdef).unwrap(); let add = Addition::new(test_doc.get_doc_name()); let start = Utc::now() + duration; let results = mtt.records(add).unwrap(); let end = Utc::now() + duration; let rec = results.iter().last().unwrap(); let field = rec.get(&test_doc.get_field_name(0)).unwrap(); assert!(field > start.into()); assert!(field < end.into()); } #[test] fn are_unique_indexes_maintained_with_additions() { let data = 1; let mut mtt = MoreThanText::new(); let test_doc = TestDocument::new(vec![FieldType::Integer]); let mut docdef = test_doc.get_docdef(); docdef.add_index(&test_doc.get_field_name(0), IndexType::Unique); mtt.create_document(docdef); let mut add = Addition::new(test_doc.get_doc_name()); add.add_field(test_doc.get_field_name(0), data.clone()); mtt.records(add.clone()).unwrap(); let mut err = MTTError::new(ErrorID::IndexEntryAlreadyExists(data.into())); err.add_parent(ErrorID::Field(test_doc.get_field_name(0).into())); err.add_parent(ErrorID::Document(test_doc.get_doc_name().into())); let result = mtt.records(add).unwrap_err(); assert_eq!(result.to_string(), err.to_string()); }