Skip to content
Snippets Groups Projects
runtests.jl 7.44 KiB
Newer Older
# ** header v3.0
# This file is a part of the CaosDB Project.
#
# Copyright (C) 2021 Indiscale GmbH <info@indiscale.com>
# Copyright (C) 2021 Florian Spreckelsen <f.spreckelsen@indiscale.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero 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
# Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public
# License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
# ** end header
#
florian's avatar
florian committed
using Test
using CaosDB

@testset "CaosDBUnitTests" begin
    @testset "TestUtility" begin
        if haskey(ENV, "SHELL")
            shell_var = ENV["SHELL"]
        else
            shell_var = "default"
        end
        @test CaosDB.Utility.get_env_fallback("SHELL", "default") == shell_var
    end

    @testset "TestExceptions" begin
        # In case of success, nothing is done
        @test CaosDB.Exceptions.evaluate_return_code(Cint(0)) == nothing

        # CaosDBExceptions are thrown for return codes > 0
        @test_throws CaosDB.Exceptions.CaosDBException CaosDB.Exceptions.evaluate_return_code(
            Cint(14),
        )
        @test_throws CaosDB.Exceptions.GenericCaosDBException CaosDB.Exceptions.evaluate_return_code(
            Cint(14),
        )
        try
            CaosDB.Exceptions.evaluate_return_code(Cint(14))
            # fail if this doesn't throw an error
            @test false
        catch e
            @test isa(e, CaosDB.Exceptions.GenericCaosDBException)
            @test e.code == 14
        end

        # Return codes < 0 correspond to unfinished transactions and
        # we expect messages to be returned.
        @test CaosDB.Exceptions.evaluate_return_code(Cint(-1)) == nothing
        @test_logs (
            :info,
            CaosDB.Exceptions.CaosDBMessage(
                "The transaction is currently being executed.",
                Cint(-1),
            ),
        ) CaosDB.Exceptions.evaluate_return_code(Cint(-1))

        # Check whether client errors can be built correctly and
        # return the correct code (Change it if this ever changes in
        # libcaosdb)
        client_err = CaosDB.Exceptions.ClientException("Client error")
        @test client_err.msg == "Client error"
        @test client_err.code == 9999
    end

    @testset "TestTransaction" begin
        # transactions can be generated from the default connection,
        # from a connection name, or from a connection object
        @test CaosDB.Transaction.create_transaction() != nothing
        @test CaosDB.Transaction.create_transaction("default") != nothing
        conn = CaosDB.Connection.get_connection()
        @test CaosDB.Transaction.create_transaction(conn) != nothing

        # Retrieval works by a single id, by a list of ids, or by querying
        trans1 = CaosDB.Transaction.create_transaction()
        @test CaosDB.Transaction.add_retrieve_by_id(trans1, "some_id") == nothing
        trans2 = CaosDB.Transaction.create_transaction()
        @test CaosDB.Transaction.add_retrieve_by_id(trans2, ["id1", "id2", "id3"]) ==
              nothing
        trans3 = CaosDB.Transaction.create_transaction()
        @test CaosDB.Transaction.add_query(trans3, "FIND ENTITY WITH id=123") == nothing

    end

    @testset "TestEntity" begin
        ent_with_name = CaosDB.Entity.create_entity("TestEnt")
        @test CaosDB.Entity.get_name(ent_with_name) == "TestEnt"

        rt_with_name = CaosDB.Entity.create_recordtype("TestRT")
        @test CaosDB.Entity.get_name(rt_with_name) == "TestRT"
        @test CaosDB.Entity.get_role(rt_with_name) == "RECORD_TYPE"

        prop_with_name_and_unit =
            CaosDB.Entity.create_property_entity(name = "TestProp", unit = "m")
        @test CaosDB.Entity.get_name(prop_with_name_and_unit) == "TestProp"
        @test CaosDB.Entity.get_role(prop_with_name_and_unit) == "PROPERTY"
        @test CaosDB.Entity.get_unit(prop_with_name_and_unit) == "m"

        rec_with_parent_and_props = CaosDB.Entity.create_record("TestRec")
        # cannot set an ID
        @test_throws CaosDB.Exceptions.ClientException CaosDB.Entity.set_id(
            rec_with_parent_and_props,
            "some_id",
        )
        # cannot set the datatype of a record
        @test_throws CaosDB.Exceptions.ClientException CaosDB.Entity.set_datatype(
            rec_with_parent_and_props,
            "INTEGER",
        )

        par1 = CaosDB.Entity.create_parent(name = "Parent1")
        par2 = CaosDB.Entity.create_parent(name = "Parent2", id = "id_of_parent_2")
        CaosDB.Entity.append_parents(rec_with_parent_and_props, [par1, par2])
        @test length(CaosDB.Entity.get_parents(rec_with_parent_and_props)) == 2
        # Getting has to work with all Integers that can be cast to Cint
        @test CaosDB.Entity.get_name(
            CaosDB.Entity.get_parent(rec_with_parent_and_props, Cint(1)),
        ) == "Parent1"
        @test CaosDB.Entity.get_name(
            CaosDB.Entity.get_parent(rec_with_parent_and_props, 2),
        ) == "Parent2"
        @test_throws DomainError CaosDB.Entity.get_parent(rec_with_parent_and_props, 3)
        @test CaosDB.Entity.get_id(
            CaosDB.Entity.get_parent(rec_with_parent_and_props, Cint(2)),
        ) == "id_of_parent_2"
        CaosDB.Entity.remove_parent(rec_with_parent_and_props, Cint(1))
        @test length(CaosDB.Entity.get_parents(rec_with_parent_and_props)) == 1
        @test CaosDB.Entity.get_name(
            CaosDB.Entity.get_parent(rec_with_parent_and_props, Cint(1)),
        ) == "Parent2"

        prop1 = CaosDB.Entity.create_property(name = "Property1", value = "2")
        prop2 = CaosDB.Entity.create_property(id = "id_of_property_2")
        CaosDB.Entity.set_datatype(prop2, "TEXT")
        prop3 = CaosDB.Entity.create_property(name = "Property3")
        CaosDB.Entity.append_properties(rec_with_parent_and_props, [prop1, prop2, prop3])
        @test length(CaosDB.Entity.get_properties(rec_with_parent_and_props)) == 3
        # properties can be accessed as a list

        # TODO(henrik, daniel)
        # @test CaosDB.Entity.get_value(
        #     CaosDB.Entity.get_properties(rec_with_parent_and_props)[1],
        # ) == "2"
        type, is_ref, is_list = CaosDB.Entity.get_datatype(
            CaosDB.Entity.get_properties(rec_with_parent_and_props)[2],
        )
        @test type == "TEXT"
        @test is_ref == false
        @test is_list == false
        @test CaosDB.Entity.get_id(
            CaosDB.Entity.get_properties(rec_with_parent_and_props)[2],
        ) == "id_of_property_2"
        CaosDB.Entity.remove_property(rec_with_parent_and_props, Cint(2))
        @test length(CaosDB.Entity.get_properties(rec_with_parent_and_props)) == 2
        @test CaosDB.Entity.get_name(
            CaosDB.Entity.get_properties(rec_with_parent_and_props)[2],
        ) == "Property3"
    end

    @testset "Datatype and values" begin
        # TODO(hernik, daniel) tests for some kinds of datatypes and
        # values. We probably don't need all since the actual
        # functions are already being tested in the C++ client but at
        # least some strings, numbers, and lists thereof should be
        # tested here, too