// License: see LICENSE file at root directory of `master` branch

use sub_strs::{Glob, GlobSet};

const EMPTY_STR: &str = concat!();

#[test]
fn test_glob() {
    let g: Glob = "some*".into();
    for s in &["some", "something", "someone"] {
        assert!(g.matches(s));
    }
    for s in &["it's something", "it's some"] {
        assert!(g.matches(s) == false);
    }

    let g: Glob = String::from("*some*").into();
    for s in &["it's something", "it's some", "some", "someone"] {
        assert!(g.matches(s));
    }
    for s in &["it's som", "it's som", "som", "omeone"] {
        assert!(g.matches(s) == false);
    }

    let g: Glob = "*so?e*".into();
    for s in &["it's something", "it's some", "some", "someone"] {
        assert!(g.matches(s));
    }
    for s in &["it's som", "it's som", "som", "omeone"] {
        assert!(g.matches(s) == false);
    }

    let s = String::from("*so**?*e*");
    let g = Glob::from(&s);
    for s in &["it's something", "it's some", "some", "someone"] {
        assert!(g.matches(s));
    }
    for s in &["it's som", "it's som", "som", "omeone"] {
        assert!(g.matches(s) == false);
    }

    let g: Glob = "???*".into();
    for s in &["acb", "ABC+", "xyz{}[]", "río"] {
        assert!(g.matches(s));
    }
    for s in &["ac", "A+", "xy"] {
        assert!(g.matches(s) == false);
    }

    let g: Glob = "*".to_string().into();
    for s in &[EMPTY_STR, "123?*"] {
        assert!(g.matches(s));
    }

    let g = Glob::from("*.*");
    for s in &["a.md", "b.rs", "c.png", "d.", ".", ".jpg"] {
        assert!(g.matches(s));
    }
    for s in &["", "b", "c"] {
        assert!(g.matches(s) == false);
    }

    let g = Glob::from("*end");
    for s in &["123-end", "abc-end"] {
        assert!(g.matches(s));
    }
    for s in &["123-ending", "abc-ending"] {
        assert!(g.matches(s) == false);
    }

    let g = Glob::from("*e");
    for s in &["ae-ae", "AE-ae"] {
        assert!(g.matches(s));
    }
    for s in &["ae-ae--", "AE-ae--"] {
        assert!(g.matches(s) == false);
    }

    let g = Glob::from("*a*bc*a*");
    for s in &["abcabc", "--a--bcabc", "--abc--a-bc--"] {
        assert!(g.matches(s));
    }
    for s in &["a-b-c-a-b-c"] {
        assert!(g.matches(s) == false);
    }

    let g = Glob::from("*a*bc*a*bc*");
    for s in &["abcabc", "--a--bcabc", "--abc--a-bc--"] {
        assert!(g.matches(s));
    }
    for s in &["a-b-c-a-b-c"] {
        assert!(g.matches(s) == false);
    }

    let g = Glob::from("abc");
    for s in &["abc"] {
        assert!(g.matches(s));
    }
    for s in &["abcdef", "0123abc"] {
        assert!(g.matches(s) == false);
    }

    let g = Glob::from("*abc");
    for s in &["abc", "---abc"] {
        assert!(g.matches(s));
    }
    for s in &["abc---"] {
        assert!(g.matches(s) == false);
    }

    let g = Glob::from("abc*");
    for s in &["abc", "abc---"] {
        assert!(g.matches(s));
    }
    for s in &["---abc"] {
        assert!(g.matches(s) == false);
    }

    let g = Glob::from(EMPTY_STR);
    assert!(g.matches(EMPTY_STR));
    for s in &["  \t\n", "b", "c"] {
        assert!(g.matches(s) == false);
    }
}

#[test]
fn test_glob_set() {
    const ALL: &str = concat!('*');

    assert!(GlobSet::from(vec![EMPTY_STR.into()].into_iter()).is_none());
    assert!(GlobSet::merge(vec![EMPTY_STR].into_iter().filter_map(|s: &str| GlobSet::from(s.split(EMPTY_STR).map(|s| s.into())))).is_none());

    assert!(GlobSet::from(vec![ALL.into(), EMPTY_STR.into()].into_iter()).is_some());
    assert!(
        GlobSet::merge(vec![ALL, EMPTY_STR].into_iter().filter_map(|s: &str| GlobSet::from(s.split(EMPTY_STR).map(|s| s.into())))).is_some()
    );
}
