#!/usr/bin/env qore
# -*- mode: qore; indent-tabs-mode: nil -*-

%new-style
%enable-all-warnings
%require-types
%strict-args
%no-child-restrictions
%allow-weak-references

%requires ../../../../qlib/QUnit.qm

%disable-warning invalid-operation
%disable-warning unreferenced-variable

%exec-class ForEachTest

class ForEachTest inherits QUnit::Test {
    constructor() : QUnit::Test("ForEachTest", "1.0", \ARGV) {
        addTestCase("weak reference tests", \weakReferenceTests());
        addTestCase("basic operator tests", \basicTests());
        set_return_value(main());
    }

    weakReferenceTests() {
        # issue 3202: the foreach statement doesn't work with weak references
        Mutex m();
        hash<auto> h.a := m;
        foreach Mutex m0 in (h.iterator()) {
            assertTrue(True);
        }
    }

    basicTests() {
        {
            list l = ();
            foreach int i in (NOTHING)
                l += i;
            foreach int i in (map $1, (select NOTHING, True))
                l += i;
            foreach int i in (select (map $1, NOTHING), True)
                l += i;
            assertEq((), l);
        }

        {
            list l = ();
            foreach int i in (select (map $1, (1, 2)), True)
                l += i;
            assertEq((1, 2), l);
        }

        {
            list l = ();
            foreach int i in (1, 2)
                l += i;
            assertEq((1, 2), l);
        }

        {
            list l = ();
            foreach int i in ((1, 2).iterator())
                l += i;
            assertEq((1, 2), l);
        }

        {
            list l = ();
            foreach int i in ((1, 2).iterator())
                l += $#;
            assertEq((0, 1), l);
        }

        {
            list l = ();
            foreach string str in (keys NOTHING)
                l += str;
            foreach string str in (keys 1)
                l += str;
            assertEq((), l);
        }

        {
            list l = ();
            foreach string str in (keys ("a": 1))
                l += str;
            assertEq(("a",), l);
        }

        {
            hash h = ("a": 1);
            list l = ();
            foreach string str in (keys h)
                l += str;
            assertEq(("a",), l);
        }

        {
            list l = ();
            foreach string str in (map $1, (keys NOTHING))
                l += str;
            foreach string str in (map $1, (keys 1))
                l += str;
            assertEq((), l);
        }

        {
            list l = ();
            foreach string str in (map $1, (keys ("a": 1)))
                l += str;
            assertEq(("a",), l);
        }

        {
            hash h = ("a": 1);
            list l = ();
            foreach string str in (map $1, (keys h))
                l += str;
            assertEq(("a",), l);
        }
    }
}
