Moved query operand tests to lib lest.
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 1s
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 1s
This commit is contained in:
@@ -309,12 +309,10 @@ impl Calculation {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn operation(&self) -> &Operand {
|
||||
&self.operation
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn get_fields(&self, existing: Field) -> Vec<Field> {
|
||||
let mut output = Vec::new();
|
||||
for item in self.values.iter() {
|
||||
@@ -358,7 +356,6 @@ impl Calculation {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn validate_value<CV>(&self, value: CV) -> Result<(), MTTError>
|
||||
where
|
||||
CV: Into<CalcValue>,
|
||||
@@ -401,38 +398,36 @@ impl Calculation {
|
||||
}
|
||||
}
|
||||
Operand::Equal => {
|
||||
if self.values.len() >= 2 {
|
||||
result = self.values[0]
|
||||
.get(existing)
|
||||
.equal(&self.values[1].get(existing));
|
||||
if self.values.len() == 2 {
|
||||
result = Field::Boolean(
|
||||
self.values[0].get(existing) == self.values[1].get(existing),
|
||||
);
|
||||
}
|
||||
}
|
||||
Operand::GreaterThan => {
|
||||
if self.values.len() >= 2 {
|
||||
result = self.values[0]
|
||||
.get(existing)
|
||||
.greater(&self.values[1].get(existing));
|
||||
if self.values.len() == 2 {
|
||||
result =
|
||||
Field::Boolean(self.values[0].get(existing) > self.values[1].get(existing));
|
||||
}
|
||||
}
|
||||
Operand::GreaterThanEqual => {
|
||||
if self.values.len() >= 2 {
|
||||
result = self.values[0]
|
||||
.get(existing)
|
||||
.greater_equal(&self.values[1].get(existing));
|
||||
if self.values.len() == 2 {
|
||||
result = Field::Boolean(
|
||||
self.values[0].get(existing) >= self.values[1].get(existing),
|
||||
);
|
||||
}
|
||||
}
|
||||
Operand::LessThan => {
|
||||
if self.values.len() >= 2 {
|
||||
result = self.values[0]
|
||||
.get(existing)
|
||||
.lesser(&self.values[1].get(existing));
|
||||
if self.values.len() == 2 {
|
||||
result =
|
||||
Field::Boolean(self.values[0].get(existing) < self.values[1].get(existing));
|
||||
}
|
||||
}
|
||||
Operand::LessThanEqual => {
|
||||
if self.values.len() >= 2 {
|
||||
result = self.values[0]
|
||||
.get(existing)
|
||||
.lesser_equal(&self.values[1].get(existing));
|
||||
if self.values.len() == 2 {
|
||||
result = Field::Boolean(
|
||||
self.values[0].get(existing) <= self.values[1].get(existing),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1203,7 +1203,6 @@ mod document_files {
|
||||
_ => unreachable!("got {:?}: should have been an error", result.get_action()),
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
#[test]
|
||||
fn does_query_return_related_entries() {
|
||||
@@ -1313,6 +1312,7 @@ mod document_files {
|
||||
_ => unreachable!("got {:?}: should have been a reply", action),
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
#[test]
|
||||
fn query_should_work_with_multiple_fields() {
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
use chrono::prelude::*;
|
||||
use std::{
|
||||
cmp::Ordering,
|
||||
ops::{Add, AddAssign},
|
||||
time::Duration,
|
||||
};
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
||||
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq)]
|
||||
pub enum Field {
|
||||
Boolean(bool),
|
||||
DateTime(DateTime<Utc>),
|
||||
@@ -21,54 +22,6 @@ impl Field {
|
||||
pub fn get_type(&self) -> FieldType {
|
||||
self.into()
|
||||
}
|
||||
|
||||
pub fn equal(&self, other: &Field) -> Field {
|
||||
if self.get_type() == other.get_type() {
|
||||
{ self == other }.into()
|
||||
} else {
|
||||
Field::None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn not_equal(&self, other: &Field) -> Field {
|
||||
if self.get_type() == other.get_type() {
|
||||
{ self != other }.into()
|
||||
} else {
|
||||
Field::None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn greater(&self, other: &Self) -> Field {
|
||||
if self.get_type() == other.get_type() {
|
||||
{ self > other }.into()
|
||||
} else {
|
||||
Field::None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn greater_equal(&self, other: &Self) -> Field {
|
||||
if self.get_type() == other.get_type() {
|
||||
{ self >= other }.into()
|
||||
} else {
|
||||
Field::None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lesser(&self, other: &Self) -> Field {
|
||||
if self.get_type() == other.get_type() {
|
||||
{ self < other }.into()
|
||||
} else {
|
||||
Field::None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lesser_equal(&self, other: &Self) -> Field {
|
||||
if self.get_type() == other.get_type() {
|
||||
{ self <= other }.into()
|
||||
} else {
|
||||
Field::None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for Field {
|
||||
@@ -161,6 +114,21 @@ impl From<i32> for Field {
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for Field {
|
||||
fn partial_cmp(&self, other: &Field) -> Option<Ordering> {
|
||||
match (self, other) {
|
||||
(Self::Boolean(d1), Self::Boolean(d2)) => d1.partial_cmp(d2),
|
||||
(Self::DateTime(d1), Self::DateTime(d2)) => d1.partial_cmp(d2),
|
||||
(Self::Duration(d1), Self::Duration(d2)) => d1.partial_cmp(d2),
|
||||
(Self::Integer(d1), Self::Integer(d2)) => d1.partial_cmp(d2),
|
||||
(Self::Revision(d1), Self::Revision(d2)) => d1.partial_cmp(d2),
|
||||
(Self::StaticString(d1), Self::StaticString(d2)) => d1.partial_cmp(d2),
|
||||
(Self::Uuid(d1), Self::Uuid(d2)) => d1.partial_cmp(d2),
|
||||
(_, _) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod fields {
|
||||
use super::*;
|
||||
@@ -272,81 +240,33 @@ mod fields {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn does_field_equal_return_properly() {
|
||||
let mut values: Vec<Field> = Vec::new();
|
||||
let count = 2;
|
||||
while values.len() < count {
|
||||
let value: Field = Uuid::new_v4().into();
|
||||
if !values.contains(&value) {
|
||||
values.push(value);
|
||||
}
|
||||
}
|
||||
assert_eq!(values[0].equal(&values[0]), true.into());
|
||||
assert_eq!(values[0].equal(&values[1]), false.into());
|
||||
assert_eq!(values[0].equal(&"nope".into()), Field::None);
|
||||
fn do_comparason_functions_work() {
|
||||
let fields = [Field::Integer(0), Field::Integer(1), Field::Integer(2)];
|
||||
assert!(fields[1] == fields[1], "equal did not work");
|
||||
assert!(fields[1] < fields[2], "less than did not work");
|
||||
assert!(fields[1] <= fields[2], "less than equal to did not work");
|
||||
assert!(fields[1] <= fields[1], "less tahn equal 50 did not work");
|
||||
assert!(fields[1] > fields[0], "greater than did not work");
|
||||
assert!(fields[1] >= fields[0], "greater than equal to did not work");
|
||||
assert!(fields[1] >= fields[1], "greater than equal to did not work");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn does_field_not_equal_return_properly() {
|
||||
let mut values: Vec<Field> = Vec::new();
|
||||
let count = 2;
|
||||
while values.len() < count {
|
||||
let value: Field = Uuid::new_v4().into();
|
||||
if !values.contains(&value) {
|
||||
values.push(value);
|
||||
}
|
||||
}
|
||||
assert_eq!(values[0].not_equal(&values[0]), false.into());
|
||||
assert_eq!(values[0].not_equal(&values[1]), true.into());
|
||||
assert_eq!(values[0].not_equal(&"nope".into()), Field::None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_field_have_greater_value() {
|
||||
let value1: Field = 1.into();
|
||||
let value2: Field = 2.into();
|
||||
let value3: Field = 3.into();
|
||||
let mismatch: Field = "bad".into();
|
||||
assert_eq!(value2.greater(&value1), true.into());
|
||||
assert_eq!(value2.greater(&value2), false.into());
|
||||
assert_eq!(value2.greater(&value3), false.into());
|
||||
assert_eq!(value2.greater(&mismatch), Field::None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_field_have_greater_or_equal_value() {
|
||||
let value1: Field = 1.into();
|
||||
let value2: Field = 2.into();
|
||||
let value3: Field = 3.into();
|
||||
let mismatch: Field = "bad".into();
|
||||
assert_eq!(value2.greater_equal(&value1), true.into());
|
||||
assert_eq!(value2.greater_equal(&value2), true.into());
|
||||
assert_eq!(value2.greater_equal(&value3), false.into());
|
||||
assert_eq!(value2.greater_equal(&mismatch), Field::None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_field_have_lesser_value() {
|
||||
let value1: Field = 1.into();
|
||||
let value2: Field = 2.into();
|
||||
let value3: Field = 3.into();
|
||||
let mismatch: Field = "bad".into();
|
||||
assert_eq!(value2.lesser(&value1), false.into());
|
||||
assert_eq!(value2.lesser(&value2), false.into());
|
||||
assert_eq!(value2.lesser(&value3), true.into());
|
||||
assert_eq!(value2.lesser(&mismatch), Field::None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_field_have_lesser_or_equal_value() {
|
||||
let value1: Field = 1.into();
|
||||
let value2: Field = 2.into();
|
||||
let value3: Field = 3.into();
|
||||
let mismatch: Field = "bad".into();
|
||||
assert_eq!(value2.lesser_equal(&value1), false.into());
|
||||
assert_eq!(value2.lesser_equal(&value2), true.into());
|
||||
assert_eq!(value2.lesser_equal(&value3), true.into());
|
||||
assert_eq!(value2.lesser_equal(&mismatch), Field::None);
|
||||
fn does_mismatched_comparason_fields_return_false() {
|
||||
let fields = [Field::Integer(0), Field::Uuid(Uuid::nil())];
|
||||
assert!(!(fields[0] == fields[1]), "equal did not work");
|
||||
assert!(!(fields[0] < fields[1]), "less than did not work");
|
||||
assert!(!(fields[0] <= fields[1]), "less than equal to did not work");
|
||||
assert!(!(fields[0] <= fields[1]), "less tahn equal 50 did not work");
|
||||
assert!(!(fields[1] > fields[0]), "greater than did not work");
|
||||
assert!(
|
||||
!(fields[1] >= fields[0]),
|
||||
"greater than equal to did not work"
|
||||
);
|
||||
assert!(
|
||||
!(fields[1] >= fields[0]),
|
||||
"greater than equal to did not work"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
151
tests/query_test.rs
Normal file
151
tests/query_test.rs
Normal file
@@ -0,0 +1,151 @@
|
||||
mod support;
|
||||
|
||||
use morethantext::{CalcValue, Calculation, Field, FieldType, MoreThanText, Operand, Query};
|
||||
use std::collections::HashSet;
|
||||
use support::TestDocument;
|
||||
|
||||
const COUNT: usize = 5;
|
||||
|
||||
fn setup_range() -> (MoreThanText, TestDocument) {
|
||||
let mut mtt = MoreThanText::new();
|
||||
let test_doc = TestDocument::new(vec![FieldType::Integer]);
|
||||
mtt.create_document(test_doc.get_docdef()).unwrap();
|
||||
let mut data: Vec<Vec<i128>> = Vec::new();
|
||||
for i in 0..COUNT {
|
||||
let holder: i128 = i.try_into().unwrap();
|
||||
data.push(vec![holder]);
|
||||
}
|
||||
test_doc.populate_multiple(&mut mtt, data);
|
||||
(mtt, test_doc)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn does_empty_query_get_all_documents() {
|
||||
let (mut mtt, test_doc) = setup_range();
|
||||
let mut query = Query::new(test_doc.get_doc_name());
|
||||
let result = mtt.records(query).unwrap();
|
||||
assert_eq!(result.len(), 5, "got {:?}", result);
|
||||
let mut holder: HashSet<Field> = HashSet::new();
|
||||
for rec in result.iter() {
|
||||
holder.insert(rec.get(test_doc.get_field_name(0)).unwrap());
|
||||
}
|
||||
assert_eq!(holder.len(), COUNT, "got {:?}", holder);
|
||||
for i in 0..COUNT {
|
||||
let data: i128 = i.try_into().unwrap();
|
||||
holder.remove(&data.into());
|
||||
}
|
||||
assert_eq!(holder.len(), 0, "got {:?}", holder);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn does_query_pull_specific_information() {
|
||||
let (mut mtt, test_doc) = setup_range();
|
||||
let expected = 3;
|
||||
let mut calc = Calculation::new(Operand::Equal);
|
||||
calc.add_value(expected.clone()).unwrap();
|
||||
calc.add_value(CalcValue::Existing(FieldType::Integer))
|
||||
.unwrap();
|
||||
let mut query = Query::new(test_doc.get_doc_name());
|
||||
query.add(test_doc.get_field_name(0), calc);
|
||||
let result = mtt.records(query).unwrap();
|
||||
assert_eq!(result.len(), 1);
|
||||
let rec = result.iter().last().unwrap();
|
||||
assert_eq!(
|
||||
rec.get(test_doc.get_field_name(0)).unwrap(),
|
||||
expected.into()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn does_query_work_with_less_than() {
|
||||
let (mut mtt, test_doc) = setup_range();
|
||||
let expected = 2;
|
||||
let mut calc = Calculation::new(Operand::LessThan);
|
||||
calc.add_value(expected.clone()).unwrap();
|
||||
calc.add_value(CalcValue::Existing(FieldType::Integer))
|
||||
.unwrap();
|
||||
let mut query = Query::new(test_doc.get_doc_name());
|
||||
query.add(test_doc.get_field_name(0), calc);
|
||||
let result = mtt.records(query).unwrap();
|
||||
assert_eq!(result.len(), 2, "got {:?}", result);
|
||||
let mut holder: HashSet<Field> = HashSet::new();
|
||||
for rec in result.iter() {
|
||||
holder.insert(rec.get(test_doc.get_field_name(0)).unwrap());
|
||||
}
|
||||
assert_eq!(holder.len(), 2, "got {:?}", holder);
|
||||
for i in 3..COUNT {
|
||||
let data: i128 = i.try_into().unwrap();
|
||||
holder.remove(&data.into());
|
||||
}
|
||||
assert_eq!(holder.len(), 0, "got {:?}", holder);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn does_query_work_with_less_than_equal() {
|
||||
let (mut mtt, test_doc) = setup_range();
|
||||
let expected = 2;
|
||||
let mut calc = Calculation::new(Operand::LessThanEqual);
|
||||
calc.add_value(expected.clone()).unwrap();
|
||||
calc.add_value(CalcValue::Existing(FieldType::Integer))
|
||||
.unwrap();
|
||||
let mut query = Query::new(test_doc.get_doc_name());
|
||||
query.add(test_doc.get_field_name(0), calc);
|
||||
let result = mtt.records(query).unwrap();
|
||||
assert_eq!(result.len(), 3, "got {:?}", result);
|
||||
let mut holder: HashSet<Field> = HashSet::new();
|
||||
for rec in result.iter() {
|
||||
holder.insert(rec.get(test_doc.get_field_name(0)).unwrap());
|
||||
}
|
||||
assert_eq!(holder.len(), 3, "got {:?}", holder);
|
||||
for i in 2..COUNT {
|
||||
let data: i128 = i.try_into().unwrap();
|
||||
holder.remove(&data.into());
|
||||
}
|
||||
assert_eq!(holder.len(), 0, "got {:?}", holder);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn does_query_work_with_greater_than() {
|
||||
let (mut mtt, test_doc) = setup_range();
|
||||
let expected = 2;
|
||||
let mut calc = Calculation::new(Operand::GreaterThan);
|
||||
calc.add_value(expected.clone()).unwrap();
|
||||
calc.add_value(CalcValue::Existing(FieldType::Integer))
|
||||
.unwrap();
|
||||
let mut query = Query::new(test_doc.get_doc_name());
|
||||
query.add(test_doc.get_field_name(0), calc);
|
||||
let result = mtt.records(query).unwrap();
|
||||
assert_eq!(result.len(), 2, "got {:?}", result);
|
||||
let mut holder: HashSet<Field> = HashSet::new();
|
||||
for rec in result.iter() {
|
||||
holder.insert(rec.get(test_doc.get_field_name(0)).unwrap());
|
||||
}
|
||||
assert_eq!(holder.len(), 2, "got {:?}", holder);
|
||||
for i in 0..2 {
|
||||
holder.remove(&i.into());
|
||||
}
|
||||
assert_eq!(holder.len(), 0, "got {:?}", holder);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn does_query_work_with_greater_than_equal() {
|
||||
let (mut mtt, test_doc) = setup_range();
|
||||
let expected = 2;
|
||||
let mut calc = Calculation::new(Operand::GreaterThanEqual);
|
||||
calc.add_value(expected.clone()).unwrap();
|
||||
calc.add_value(CalcValue::Existing(FieldType::Integer))
|
||||
.unwrap();
|
||||
let mut query = Query::new(test_doc.get_doc_name());
|
||||
query.add(test_doc.get_field_name(0), calc);
|
||||
let result = mtt.records(query).unwrap();
|
||||
assert_eq!(result.len(), 3, "got {:?}", result);
|
||||
let mut holder: HashSet<Field> = HashSet::new();
|
||||
for rec in result.iter() {
|
||||
holder.insert(rec.get(test_doc.get_field_name(0)).unwrap());
|
||||
}
|
||||
assert_eq!(holder.len(), 3, "got {:?}", holder);
|
||||
for i in 0..3 {
|
||||
holder.remove(&i.into());
|
||||
}
|
||||
assert_eq!(holder.len(), 0, "got {:?}", holder);
|
||||
}
|
||||
@@ -41,12 +41,18 @@ impl TestDocument {
|
||||
self.field_names[position].clone()
|
||||
}
|
||||
|
||||
pub fn populate<F>(&self, mtt: &mut MoreThanText, data: Vec<F>) where F: Into<Field> + Clone {
|
||||
pub fn populate<F>(&self, mtt: &mut MoreThanText, data: Vec<F>)
|
||||
where
|
||||
F: Into<Field> + Clone,
|
||||
{
|
||||
let wrapper = vec![data];
|
||||
self.populate_multiple(mtt, wrapper);
|
||||
}
|
||||
|
||||
pub fn populate_multiple<F>(&self, mtt: &mut MoreThanText, data: Vec<Vec<F>>) where F: Into<Field> + Clone {
|
||||
pub fn populate_multiple<F>(&self, mtt: &mut MoreThanText, data: Vec<Vec<F>>)
|
||||
where
|
||||
F: Into<Field> + Clone,
|
||||
{
|
||||
for rec in data.iter() {
|
||||
let mut add = Addition::new(self.doc_name.clone());
|
||||
for i in 0..self.field_names.len() {
|
||||
|
||||
Reference in New Issue
Block a user