#[test]
fn test_ignore_binding() {
    fn returns_unit(n) {
        let _ = 100;
    }

    let out = returns_unit(1) is Tuple;
    assert_eq!(out, true);
}

#[test]
fn test_name_binding() {
    fn returns_unit(n) {
        let a = 100;
    }

    let out = returns_unit(1) is Tuple;
    assert_eq!(out, true);
}

#[test]
fn test_match_binding() {
    fn returns_unit(n) {
        let [..] = [1, 2, 3];
    }

    let out = returns_unit(1) is Tuple;
    assert_eq!(out, true);
}

#[test]
fn test_patterns() {
    let out = match 1 {
        _ => 10,
    };
    assert_eq!(out, 10);

    let out = match 10 {
        n => 10,
    };
    assert_eq!(out, 10);

    let out = match 'a' {
        'a' => 'b',
        n => n,
    };
    assert_eq!(out, 'b');

    let out = match 10 {
        n => n,
    };
    assert_eq!(out, 10);

    let out = match 10 {
        10 => 5,
        n => n,
    };
    assert_eq!(out, 5);

    let out = match "hello world" {
        "hello world" => "hello john",
        n => n,
    };
    assert_eq!(out, "hello john");

    let out = match (true, false) {
        (true, false) => "aaaa",
        _ => "no",
    };
    assert_eq!(out, "aaaa");

    let out = match (1 == 1, 1 == 2) {
        (true, false) => "aaaa",
        _ => "no",
    };
    assert_eq!(out, "aaaa");
}

#[test]
fn test_vec_patterns() {
    let out = match [] {
        [..] => true,
    };
    assert_eq!(out, true);

    let out = match [] {
        [..] => true,
        _ => false,
    };
    assert_eq!(out, true);

    let out = match [1, 2] {
        [a, b] => a + 1 == b,
    };
    assert_eq!(out, true);

    let out = match [] {
        [a, b] => a + 1 == b,
    };
    assert_eq!(out, ());

    let out = match [1, 2] {
        [a, b] => a + 1 == b,
        _ => false,
    };
    assert_eq!(out, true);

    let out = match [1, 2] {
        [a, b, ..] => a + 1 == b,
        _ => false,
    };
    assert_eq!(out, true);

    let out = match [1, 2] {
        [1, ..] => true,
        _ => false,
    };
    assert_eq!(out, true);

    let out = match [1, 2] {
        [] => true,
        _ => false,
    };
    assert_eq!(out, false);

    let out = match [1, 2] {
        [1, 2] => true,
        _ => false,
    };
    assert_eq!(out, true);

    let out = match [1, 2] {
        [1] => true,
        _ => false,
    };
    assert_eq!(out, false);

    let out = match [1, [2, 3]] {
        [1, [2, ..]] => true,
        _ => false,
    };
    assert_eq!(out, true);

    let out = match [1, []] {
        [1, [2, ..]] => true,
        _ => false,
    };
    assert_eq!(out, false);

    let out = match [1, [2, 3]] {
        [1, [2, 3]] => true,
        _ => false,
    };
    assert_eq!(out, true);

    let out = match [1, [2, 4]] {
        [1, [2, 3]] => true,
        _ => false,
    };
    assert_eq!(out, false);
}

#[test]
fn test_object_patterns() {
    let out = match #{} {
        #{ .. } => true,
    };
    assert_eq!(out, true);

    let out = match #{ foo: true } {
        #{ foo } => foo,
        _ => false,
    };
    assert_eq!(out, true);

    let out = match #{} {
        #{ .. } => true,
        _ => false,
    };
    assert_eq!(out, true);

    let out = match #{ "foo": 10, "bar": 0 } {
        #{ "foo": v, .. } => v == 10,
        _ => false,
    };
    assert_eq!(out, true);

    let out = match #{ "foo": 10, "bar": 0 } {
        #{ "foo": v } => v == 10,
        _ => false,
    };
    assert_eq!(out, false);

    let out = match #{ "foo": 10, "bar": #{ "baz": [1, 2] } } {
        #{ "foo": v } => v == 10,
        _ => false,
    };
    assert_eq!(out, false);

    let out = match #{ "foo": 10, "bar": #{ "baz": [1, 2] } } {
        #{ "foo": v, .. } => v == 10,
        _ => false,
    };
    assert_eq!(out, true);
}
