test search by using examples in doc.
This commit is contained in:
		@ -10,26 +10,26 @@ pub struct Query {
 | 
			
		||||
 | 
			
		||||
impl Query {
 | 
			
		||||
    pub fn search(&self, input: &mut Iterator<Item = &Texture>) -> Vec<Texture> {
 | 
			
		||||
        let mut results: Vec<(u64, &Texture)> = Vec::new();
 | 
			
		||||
        let mut results: Vec<(i64, &Texture)> = Vec::new();
 | 
			
		||||
 | 
			
		||||
        // We use pseudo decimal fixed point numbers here.
 | 
			
		||||
        // 1.000_000 = 1_000_000;
 | 
			
		||||
 | 
			
		||||
        // This is done, since algorithms like quicksort can fail on floats.
 | 
			
		||||
        let required_score = self.required_score() * 1_000_000u64;
 | 
			
		||||
        let required_score = self.required_score() * 1_000_000i64;
 | 
			
		||||
 | 
			
		||||
        for texture in input {
 | 
			
		||||
            let mut score = 0u64;
 | 
			
		||||
        'texture_loop: for texture in input {
 | 
			
		||||
            let mut score = 0i64;
 | 
			
		||||
 | 
			
		||||
            for (pos, filter) in self.filters.iter().enumerate() {
 | 
			
		||||
                match filter.score(texture) {
 | 
			
		||||
                    Score::RequiredMatch(true) => (),
 | 
			
		||||
                    Score::RequiredMatch(false) => {
 | 
			
		||||
                        // skip this texture
 | 
			
		||||
                        continue;
 | 
			
		||||
                        continue 'texture_loop;
 | 
			
		||||
                    }
 | 
			
		||||
                    Score::Match(true) => {
 | 
			
		||||
                        score += 1_000_000u64 * (1 + (0.1 / f64::sqrt(pos as f64 + 1.0)) as u64);
 | 
			
		||||
                        score += 1_000_000i64 + ((100_000.0 / f64::sqrt(pos as f64 + 1.0)) as i64);
 | 
			
		||||
                    }
 | 
			
		||||
                    Score::Match(false) => (),
 | 
			
		||||
                }
 | 
			
		||||
@ -40,7 +40,7 @@ impl Query {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        results.sort_by_key(|(score, _)| *score);
 | 
			
		||||
        results.sort_by_key(|(score, _)| score * -1);
 | 
			
		||||
 | 
			
		||||
        results
 | 
			
		||||
            .iter()
 | 
			
		||||
@ -48,8 +48,8 @@ impl Query {
 | 
			
		||||
            .collect::<Vec<Texture>>()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn required_score(&self) -> u64 {
 | 
			
		||||
        let non_special = self.filters.iter().filter(|f| !f.is_special()).count() as u64;
 | 
			
		||||
    fn required_score(&self) -> i64 {
 | 
			
		||||
        let non_special = self.filters.iter().filter(|f| !f.is_special()).count() as i64;
 | 
			
		||||
 | 
			
		||||
        // ceil(non_special / 2)
 | 
			
		||||
        (non_special + 1) / 2
 | 
			
		||||
@ -66,3 +66,100 @@ impl Query {
 | 
			
		||||
        Ok(result)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
/// These tests check against the example section in the search design document.
 | 
			
		||||
mod test {
 | 
			
		||||
    use super::*;
 | 
			
		||||
    use std::str::FromStr;
 | 
			
		||||
 | 
			
		||||
    /// just a shorthand
 | 
			
		||||
    fn tex(id: i32, name: &str, tags: &str, added_on: &str, resolution: u64) -> Texture {
 | 
			
		||||
        Texture {
 | 
			
		||||
            id: format!("{}", id), // Id should actaly be a uuid, but for testing this is fine.
 | 
			
		||||
            name: name.to_string(),
 | 
			
		||||
            tags: tags.split(",").map(|s| s.trim().to_string()).collect(),
 | 
			
		||||
            added_on: Date::from_str(added_on).unwrap(),
 | 
			
		||||
            resolution: (resolution, resolution),
 | 
			
		||||
            format: TextureFormat::JPEG,
 | 
			
		||||
            texture_hash: Sha256::from_data(b"Some Hash"),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // data of example section of search document.
 | 
			
		||||
    fn test_data() -> Vec<Texture> {
 | 
			
		||||
        vec![
 | 
			
		||||
            tex(
 | 
			
		||||
                1,
 | 
			
		||||
                "wood_185841",
 | 
			
		||||
                "Holz, Dunkel, Rot, Edel",
 | 
			
		||||
                "2019-05-15",
 | 
			
		||||
                4 * 1024,
 | 
			
		||||
            ),
 | 
			
		||||
            tex(2, "wood_84846", "Holz, Hell", "2019-05-13", 2 * 1024),
 | 
			
		||||
            tex(3, "silk_large", "Stoff, Rot, Edel", "2018-01-01", 8 * 1024),
 | 
			
		||||
            tex(4, "cotton_xxx", "Stoff, Rot, Rau", "2018-02-01", 2048),
 | 
			
		||||
            tex(5, "green_frabric", "Grün, Stoff", "2018-03-01", 1024),
 | 
			
		||||
            tex(6, "tin54_45", "Metall, Hell", "2018-03-01", 4 * 1024),
 | 
			
		||||
            tex(7, "copper4_1k", "Rot, Metall", "2016-03-01", 1024),
 | 
			
		||||
            tex(
 | 
			
		||||
                8,
 | 
			
		||||
                "rusty_metall",
 | 
			
		||||
                "Rot, Metall, Rost, Dunkel",
 | 
			
		||||
                "2015-03-01",
 | 
			
		||||
                8 * 1024,
 | 
			
		||||
            ),
 | 
			
		||||
        ]
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn assert_query(query: &str, expected: Vec<u8>) {
 | 
			
		||||
        let q = Query::parse(
 | 
			
		||||
            &query
 | 
			
		||||
                .split_whitespace()
 | 
			
		||||
                .map(|s| s.to_string())
 | 
			
		||||
                .collect::<Vec<String>>(),
 | 
			
		||||
        )
 | 
			
		||||
        .unwrap();
 | 
			
		||||
 | 
			
		||||
        let data = test_data();
 | 
			
		||||
 | 
			
		||||
        let result = q.search(&mut data.iter());
 | 
			
		||||
 | 
			
		||||
        let only_ids = result
 | 
			
		||||
            .into_iter()
 | 
			
		||||
            .map(|tex| tex.id.parse::<u8>().unwrap())
 | 
			
		||||
            .collect::<Vec<u8>>();
 | 
			
		||||
 | 
			
		||||
        assert_eq!(only_ids, expected)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_examples_from_doc_1() {
 | 
			
		||||
        assert_query("Holz Dunkel", vec![1, 2, 8]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_examples_from_doc_2() {
 | 
			
		||||
        assert_query("n:wood_", vec![1, 2]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_examples_from_doc_3() {
 | 
			
		||||
        assert_query("before:2019-05-31 after:2019-04-30", vec![1, 2]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_examples_from_doc_4() {
 | 
			
		||||
        assert_query("Stoff Rot Edel", vec![3, 4, 1]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_examples_from_doc_5() {
 | 
			
		||||
        assert_query("Stoff Rot !Edel", vec![4, 3, 5, 7, 8]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_examples_from_doc_6() {
 | 
			
		||||
        assert_query("Metall Dunkel res:4k", vec![8, 6, 1]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user