use rslnp::Parser;
use token_lists::Token::{self, List};

fn test_parse(args: &str, expected: Vec<Token>) {
    let result: Vec<Token> = Parser::scopes()
        .parse(args.chars())
        .ok()
        .unwrap()
        .parse_rest(&())
        .unwrap();
    assert_eq!(result, expected)
}

// Automatic lists

#[test]
fn no_content() {
    test_parse("", Vec::new());
}

#[test]
fn single_element() {
    test_parse("a", vec!["a".into()]);
}

#[test]
fn single_line_list() {
    test_parse("a b c", vec![vec!["a", "b", "c"].into()]);
}

#[test]
fn whitespaces() {
    test_parse("     ", Vec::new());
}

#[test]
fn multiple_lines() {
    test_parse("a\nb\nc\n", vec!["a".into(), "b".into(), "c".into()]);
}

#[test]
fn newlines() {
    test_parse("\n\n\n\n\n", Vec::new());
}

// Brackets

#[test]
fn empty_bracket_list() {
    test_parse("()", vec![List(Vec::new())]);
}

#[test]
fn single_element_bracket_list() {
    test_parse("(a)", vec![vec!["a"].into()]);
}

#[test]
fn filled_bracket_list() {
    test_parse("(a b c)", vec![vec!["a", "b", "c"].into()]);
}

#[test]
fn multiple_bracket_lists() {
    test_parse(
        "() (a b c) (x)",
        vec![vec![vec![], vec!["a", "b", "c"], vec!["x"]].into()],
    );
}

// Separators

#[test]
fn empty_separator_list() {
    test_parse(";", vec![List(Vec::new())]);
}

#[test]
fn multiple_empty_separator_lists() {
    test_parse(
        ";;;",
        vec![List(Vec::new()), List(Vec::new()), List(Vec::new())],
    );
}

#[test]
fn single_element_separator_list() {
    test_parse("a;", vec![vec!["a"].into()]);
}

#[test]
fn filled_separator_list() {
    test_parse("a b c;", vec![vec!["a", "b", "c"].into()]);
}

#[test]
fn multiple_separator_lists() {
    test_parse(
        "; a b c; x;",
        vec![
            List(Vec::new()),
            vec!["a", "b", "c"].into(),
            vec!["x"].into(),
        ],
    );
}

// Strings

#[test]
fn string() {
    test_parse("\"hello\"", vec![vec!["string", "hello"].into()]);
}

#[test]
fn string_escape() {
    test_parse(
        "\"hello\\nworld\"",
        vec![vec!["string", "hello\nworld"].into()],
    );
}

#[test]
fn multiline_string() {
    test_parse(
        "\"\"\"\"A\n    B\n    C\n",
        vec![vec!["string", "A\nB\nC"].into()],
    );
}

// Symbol Characters

#[test]
fn separating_symbol_characters() {
    test_parse("a, b, c", vec![vec!["a", ",", "b", ",", "c"].into()]);
}

#[test]
fn multiple_symbol_characters() {
    test_parse(",,,,,", vec![vec![",", ",", ",", ",", ","].into()]);
}
