#!/usr/bin/env qore

%requires Util

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

%new-style
%require-types
%enable-all-warnings

%exec-class RemoveTreeTest

public class RemoveTreeTest inherits QUnit::Test {

    constructor() : Test ("RemoveTreeTest", "1.0") {
        addTestCase("remove_tree test", \test_remove_tree());
        addTestCase("remove_tree exception test", \test_remove_tree_exception());
        set_return_value(main());
    }

    test_remove_tree() {
        # create a temporary directory and check it's created and writable
        string tmp_path = make_tmp_dir();
        assertTrue(is_dir(tmp_path));
        assertTrue(is_writable(tmp_path));
        # check that it's possible to remove it empty
        remove_tree(tmp_path);
        assertFalse(is_dir(tmp_path));

        # create another temporary directory and add some contents
        tmp_path = make_tmp_dir();
        assertTrue(is_dir(tmp_path));
        assertTrue(is_writable(tmp_path));
        hash<TmpFileHash> f = make_tmp_file(NOTHING, NOTHING, tmp_path);
        f.file.close();
        assertTrue(is_file(f.path));
        assertTrue(is_writable(f.path));
        string d = make_tmp_dir(NOTHING, NOTHING, tmp_path);
        assertTrue(is_dir(d));
        assertTrue(is_writable(d));
        f = make_tmp_file(NOTHING, NOTHING, d);
        f.file.close();
        assertTrue(is_file(f.path));
        assertTrue(is_writable(f.path));

        # check that it's possible to remove it
        remove_tree(tmp_path);
        assertFalse(is_dir(tmp_path));
    }

    test_remove_tree_exception() {
        # create a temporary directory and check it's created and writable
        string tmp_path = make_tmp_dir();
        on_exit {
            remove_tree(tmp_path);
        }
        assertTrue(is_dir(tmp_path));
        assertTrue(is_writable(tmp_path));

        # invent a path to a directory/file which should not exist (the tmp dir is empty)
        string path = join_paths(tmp_path, "non-existent");

        # this call should throw an exception
        assertThrows("DIR-READ-FAILURE", \remove_tree(), (path));

        # now let's create a file (not a directory)...
        hash<TmpFileHash> file_path = make_tmp_file();
        file_path.file.close();
        assertTrue(is_file(file_path.path));
        assertTrue(is_writable(file_path.path));
        # ...and try and remove it with remove_tree which only removes directories
        assertThrows("DIR-READ-FAILURE", \remove_tree(), (file_path.path));
        assertTrue(is_file(file_path.path));
    }
}