Documentation
/*
==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--

sub-strs

Copyright (C) 2019-2024  Anonymous

There are several releases over multiple years,
they are listed as ranges, such as: "2019-2024".

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

::--::--::--::--::--::--::--::--::--::--::--::--::--::--::--::--
*/

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_iter([EMPTY_STR]).is_none());
    assert!(GlobSet::merge([EMPTY_STR].into_iter().filter_map(|s: &str| GlobSet::from_iter(s.split(EMPTY_STR)))).is_none());

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