# ** 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 # 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 "Property values and datatypes" begin @testset "Entity properties" begin int_prop = CaosDB.Entity.create_property_entity(name="IntProp", datatype="INTEGER") double_prop = CaosDB.Entity.create_property_entity(name="DoubleProp", datatype="DOUBLE") bool_prop = CaosDB.Entity.create_property_entity(name="BoolProp", datatype="BOOLEAN") string_prop = CaosDB.Entity.create_property_entity(name="StringProp", datatype="TEXT") CaosDB.Entity.set_value(int_prop, 123) CaosDB.Entity.set_value(double_prop, 10.246) CaosDB.Entity.set_value(bool_prop, true) CaosDB.Entity.set_value(string_prop, "Hello World") @test CaosDB.Entity.get_value(int_prop) == 123 @test CaosDB.Entity.get_value(double_prop) == 10.246 @test CaosDB.Entity.get_value(bool_prop) === true @test CaosDB.Entity.get_value(string_prop) == "Hello World" @test isa(CaosDB.Entity.get_value(int_prop), Integer) @test isa(CaosDB.Entity.get_value(double_prop), Number) @test isa(CaosDB.Entity.get_value(bool_prop), Bool) @test isa(CaosDB.Entity.get_value(string_prop), String) @test CaosDB.Entity.get_datatype(int_prop) == ("INTEGER", false, false) @test CaosDB.Entity.get_datatype(double_prop) == ("DOUBLE", false, false) @test CaosDB.Entity.get_datatype(bool_prop) == ("BOOLEAN", false, false) @test CaosDB.Entity.get_datatype(string_prop) == ("TEXT", false, false) """ Test lists """ int_list_prop = CaosDB.Entity.create_property_entity(name="IntProp", datatype="INTEGER", is_list=true) double_list_prop = CaosDB.Entity.create_property_entity(name="DoubleProp", datatype="DOUBLE", is_list=true) bool_list_prop = CaosDB.Entity.create_property_entity(name="BoolProp", datatype="BOOLEAN", is_list=true) string_list_prop = CaosDB.Entity.create_property_entity(name="StringProp", datatype="TEXT", is_list=true) CaosDB.Entity.set_value(int_list_prop, [123, 456]) CaosDB.Entity.set_value(double_list_prop, [10.246, 3.14]) CaosDB.Entity.set_value(bool_list_prop, [true, false]) CaosDB.Entity.set_value(string_list_prop, ["Hello", "World"]) @test CaosDB.Entity.get_value(int_list_prop) == [123, 456] @test CaosDB.Entity.get_value(double_list_prop) == [10.246, 3.14] @test CaosDB.Entity.get_value(bool_list_prop) === [true, false] @test CaosDB.Entity.get_value(string_list_prop) == ["Hello", "World"] @test isa(CaosDB.Entity.get_value(int_list_prop), Vector{Cint}) @test isa(CaosDB.Entity.get_value(double_list_prop), Vector{Cdouble}) @test isa(CaosDB.Entity.get_value(bool_list_prop), Vector{Bool}) @test isa(CaosDB.Entity.get_value(string_list_prop), Vector{String}) @test CaosDB.Entity.get_datatype(int_list_prop) == ("INTEGER", false, true) @test CaosDB.Entity.get_datatype(double_list_prop) == ("DOUBLE", false, true) @test CaosDB.Entity.get_datatype(bool_list_prop) == ("BOOLEAN", false, true) @test CaosDB.Entity.get_datatype(string_list_prop) == ("TEXT", false, true) end @testset "Property properties" begin int_prop = CaosDB.Entity.create_property(name="IntProp", datatype="INTEGER") double_prop = CaosDB.Entity.create_property(name="DoubleProp", datatype="DOUBLE") bool_prop = CaosDB.Entity.create_property(name="BoolProp", datatype="BOOLEAN") string_prop = CaosDB.Entity.create_property(name="StringProp", datatype="TEXT") CaosDB.Entity.set_value(int_prop, 123) CaosDB.Entity.set_value(double_prop, 10.246) CaosDB.Entity.set_value(bool_prop, true) CaosDB.Entity.set_value(string_prop, "Hello World") @test CaosDB.Entity.get_value(int_prop) == 123 @test CaosDB.Entity.get_value(double_prop) == 10.246 @test CaosDB.Entity.get_value(bool_prop) === true @test CaosDB.Entity.get_value(string_prop) == "Hello World" @test isa(CaosDB.Entity.get_value(int_prop), Integer) @test isa(CaosDB.Entity.get_value(double_prop), Number) @test isa(CaosDB.Entity.get_value(bool_prop), Bool) @test isa(CaosDB.Entity.get_value(string_prop), String) @test CaosDB.Entity.get_datatype(int_prop) == ("INTEGER", false, false) @test CaosDB.Entity.get_datatype(double_prop) == ("DOUBLE", false, false) @test CaosDB.Entity.get_datatype(bool_prop) == ("BOOLEAN", false, false) @test CaosDB.Entity.get_datatype(string_prop) == ("TEXT", false, false) """ Test lists """ int_list_prop = CaosDB.Entity.create_property(name="IntProp", datatype="INTEGER", is_list=true) double_list_prop = CaosDB.Entity.create_property(name="DoubleProp", datatype="DOUBLE", is_list=true) bool_list_prop = CaosDB.Entity.create_property(name="BoolProp", datatype="BOOLEAN", is_list=true) string_list_prop = CaosDB.Entity.create_property(name="StringProp", datatype="TEXT", is_list=true) CaosDB.Entity.set_value(int_list_prop, [123, 456]) CaosDB.Entity.set_value(double_list_prop, [10.246, 3.14]) CaosDB.Entity.set_value(bool_list_prop, [true, false]) CaosDB.Entity.set_value(string_list_prop, ["Hello", "World"]) @test CaosDB.Entity.get_value(int_list_prop) == [123, 456] @test CaosDB.Entity.get_value(double_list_prop) == [10.246, 3.14] @test CaosDB.Entity.get_value(bool_list_prop) === [true, false] @test CaosDB.Entity.get_value(string_list_prop) == ["Hello", "World"] @test isa(CaosDB.Entity.get_value(int_list_prop), Vector{Cint}) @test isa(CaosDB.Entity.get_value(double_list_prop), Vector{Cdouble}) @test isa(CaosDB.Entity.get_value(bool_list_prop), Vector{Bool}) @test isa(CaosDB.Entity.get_value(string_list_prop), Vector{String}) @test CaosDB.Entity.get_datatype(int_list_prop) == ("INTEGER", false, true) @test CaosDB.Entity.get_datatype(double_list_prop) == ("DOUBLE", false, true) @test CaosDB.Entity.get_datatype(bool_list_prop) == ("BOOLEAN", false, true) @test CaosDB.Entity.get_datatype(string_list_prop) == ("TEXT", false, true) end end end