diff options
author | David Robillard <d@drobilla.net> | 2018-06-16 10:26:47 -0400 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2019-01-05 17:12:38 +0100 |
commit | 0f943c203ae9653efabb8168b82d2e56898c5fac (patch) | |
tree | ce32ff3f75525edfe02d08395350a44e0a93be75 /tests | |
parent | 6650e22960f4dcd7d66dc560aae0347dc3272e1d (diff) | |
download | serd-0f943c203ae9653efabb8168b82d2e56898c5fac.tar.gz serd-0f943c203ae9653efabb8168b82d2e56898c5fac.tar.bz2 serd-0f943c203ae9653efabb8168b82d2e56898c5fac.zip |
WIP: Add C++ bindings
Diffstat (limited to 'tests')
-rw-r--r-- | tests/serd_cxx_test.cpp | 381 |
1 files changed, 381 insertions, 0 deletions
diff --git a/tests/serd_cxx_test.cpp b/tests/serd_cxx_test.cpp new file mode 100644 index 00000000..2196df56 --- /dev/null +++ b/tests/serd_cxx_test.cpp @@ -0,0 +1,381 @@ +/* + Copyright 2018 David Robillard <http://drobilla.net> + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#undef NDEBUG + +#include "serd/serd.hpp" + +#include <cassert> +#include <iostream> +#include <sstream> +#include <type_traits> +#include <utility> +#include <vector> + +template <typename T> +static int +test_move_only(T&& obj) +{ + static_assert(!std::is_copy_constructible<T>::value, ""); + static_assert(!std::is_copy_assignable<T>::value, ""); + + const auto* const ptr = obj.c_obj(); + + // Move construct + T moved{std::move(obj)}; + assert(moved.c_obj() == ptr); + assert(!obj.c_obj()); + + // Move assign + obj = std::move(moved); + assert(obj.c_obj() == ptr); + assert(!moved.c_obj()); + + return 0; +} + +template <typename T> +static int +test_copy_move(const T& obj) +{ + T copy{obj}; + assert(copy == obj); + + T moved{std::move(copy)}; + assert(moved == obj); + assert(copy != obj); + + T copy_assigned{obj}; + copy_assigned = obj; + assert(copy_assigned == obj); + + T move_assigned{obj}; + move_assigned = std::move(copy_assigned); + assert(move_assigned == obj); + assert(copy_assigned != obj); + + return 0; +} + +static int +test_operators() +{ + int st = 0; + + serd::World world; + + serd::Model model(world, serd::ModelFlag::index_SPO); + model.insert(serd::make_uri("http://example.org/s"), + serd::make_uri("http://example.org/p"), + serd::make_uri("http://example.org/o")); + + serd::Sink sink; + serd::Env env; + + std::ostringstream stream; + serd::ByteSink byte_sink{stream}; + + st |= test_copy_move( + serd::Optional<serd::Node>{serd::make_string("hello")}); + st |= test_move_only(serd::World{}); + st |= test_move_only(*model.begin()); + st |= test_copy_move(serd::Env{}); + st |= test_move_only(serd::Reader{world, serd::Syntax::Turtle, sink, 4096}); + st |= test_move_only(serd::ByteSink{stream}); + st |= test_copy_move(model.begin()); + st |= test_copy_move(model.all()); + // Sink + st |= test_copy_move(model); + // st |= test_move_only(serd::Inserter{model, env}); + // st |= test_move_only(serd::Sink{}); + + st |= test_copy_move(serd::Env{}); + + return st; +} + +static int +test_optional() +{ + test_copy_move(serd::Optional<serd::Node>(serd::make_string("node"))); + + const serd::Node node = serd::make_string("node"); + const serd::Node other = serd::make_string("other"); + + // Truthiness + assert(!serd::Optional<serd::Node>()); + assert(!serd::Optional<serd::Node>(nullptr)); + assert(serd::Optional<serd::Node>(node)); + + // Comparison and general sanity + serd::Optional<serd::Node> optional{node}; + assert(optional); + assert(optional == node); + assert(optional != other); + assert(*optional == node); + assert(optional->str() == "node"); + assert(optional.ptr() != node.c_obj()); // non-const, must be a copy + + // Reset + optional.reset(); + assert(!optional); + assert(!optional.ptr()); + + // Copying and moving + serd::Node nonconst = serd::make_string("nonconst"); + const SerdNode* c_node = nonconst.c_obj(); + + optional = nonconst; + serd::Optional<serd::Node> copied{optional}; + assert(copied == nonconst); + assert(copied.ptr() != c_node); + + optional = std::move(nonconst); + serd::Optional<serd::Node> moved{std::move(optional)}; + assert(moved.ptr() == c_node); + assert(!optional); + + serd::Optional<serd::Node> copy_assigned; + copy_assigned = optional; + assert(copy_assigned == optional); + assert(copy_assigned.ptr() != c_node); + + serd::Optional<serd::Node> move_assigned; + move_assigned = std::move(moved); + assert(move_assigned.ptr() == c_node); + assert(!optional); + + return 0; +} + +static int +test_node(const serd::Node& node) +{ + test_copy_move(node); + + if (node.datatype()) { + return test_node(*node.datatype()); + } else if (node.language()) { + return test_node(*node.language()); + } + return 0; +} + +static int +test_nodes() +{ + using namespace serd; + + const auto type = make_uri("http://example.org/Type"); + const auto base = make_uri("http://example.org/"); + const auto root = make_uri("http://example.org/"); + + assert(!test_node(make_string("hello"))); + assert(!test_node(make_plain_literal("hello", "en"))); + assert(!test_node(make_typed_literal("hello", type))); + assert(!test_node(make_blank("blank"))); + assert(!test_node(make_curie("eg:curie"))); + assert(!test_node(make_uri("http://example.org/thing"))); + assert(!test_node(make_resolved_uri("thing", base))); + assert(!test_node(make_file_uri("/foo/bar", "host"))); + assert(!test_node(make_file_uri("/foo/bar"))); + assert(!test_node(make_file_uri("/foo/bar", "host"))); + assert(!test_node(make_file_uri("/foo/bar"))); + assert(!test_node(make_relative_uri("http://example.org/a", base))); + assert(!test_node(make_relative_uri("http://example.org/a", base, root))); + assert(!test_node(make_decimal(1.2, 7))); + assert(!test_node(make_decimal(3.4, 7, type))); + assert(!test_node(make_integer(56))); + assert(!test_node(make_integer(78, type))); + assert(!test_node(make_blob("blob", 4, true))); + assert(!test_node(make_blob("blob", 4, true, type))); + + return 0; +} + +static int +test_reader() +{ + struct Sink : public serd::Sink + { + serd::Status statement(serd::StatementFlags, + const serd::Statement& statement) override + { + ++n_statements; + stream << statement.subject() << " " << statement.predicate() << " " + << statement.object() << std::endl; + return serd::Status::success; + } + + size_t n_statements{}; + std::stringstream stream{}; + }; + + Sink sink; + serd::World world; + serd::Reader reader(world, serd::Syntax::Turtle, sink, 4096); + + reader.start_string("@prefix eg: <http://example.org> ." + "eg:s eg:p eg:o1 , eg:o2 ."); + reader.read_document(); + + assert(sink.n_statements == 2); + assert(sink.stream.str() == "eg:s eg:p eg:o1\neg:s eg:p eg:o2\n"); + + return 0; +} + +static int +test_writer() +{ + serd::World world; + serd::Env env; + std::ostringstream stream; + serd::ByteSink sink(stream); + serd::Writer writer(world, serd::Syntax::Turtle, {}, env, stream); + + writer.base(serd::make_uri("http://drobilla.net/base/")); + writer.set_root_uri(serd::make_uri("http://drobilla.net/")); + writer.prefix(serd::make_string("eg"), + serd::make_uri("http://example.org/")); + writer.write({}, + serd::make_uri("http://drobilla.net/base/s"), + serd::make_uri("http://example.org/p"), + serd::make_uri("http://drobilla.net/o")); + + writer.finish(); + + assert(stream.str() == "@base <http://drobilla.net/base/> .\n" + "@prefix eg: <http://example.org/> .\n" + "\n" + "<s>\n" + "\teg:p <../o> .\n"); + + return 0; +} + +static int +test_env() +{ + serd::Env env; + + const auto base = serd::make_uri("http://drobilla.net/"); + env.set_base_uri(base); + assert(env.base_uri() == base); + + env.set_prefix(serd::make_string("eg"), + serd::make_uri("http://example.org/")); + + assert(env.qualify(serd::make_uri("http://example.org/foo")) == + serd::make_curie("eg:foo")); + + assert(env.expand(serd::make_uri("foo")) == + serd::make_uri("http://drobilla.net/foo")); + + serd::Env copied{env}; + assert(copied.qualify(serd::make_uri("http://example.org/foo")) == + serd::make_curie("eg:foo")); + + assert(copied.expand(serd::make_uri("foo")) == + serd::make_uri("http://drobilla.net/foo")); + + serd::Env assigned; + assigned = env; + auto curie = env.qualify(serd::make_uri("http://example.org/foo")); + + assert(assigned.qualify(serd::make_uri("http://example.org/foo")) == + serd::make_curie("eg:foo")); + + assert(assigned.expand(serd::make_uri("foo")) == + serd::make_uri("http://drobilla.net/foo")); + + return 0; +} + +static int +test_model() +{ + serd::World world; + serd::Model model(world, + serd::ModelFlag::index_SPO | serd::ModelFlag::index_OPS); + + assert(model.empty()); + + const auto s = serd::make_uri("http://example.org/s"); + const auto p = serd::make_uri("http://example.org/p"); + const auto o1 = serd::make_uri("http://example.org/o1"); + const auto o2 = serd::make_uri("http://example.org/o2"); + + model.insert(s, p, o1); + model.insert(s, p, o2); + + assert(!model.empty()); + assert(model.size() == 2); + assert(model.ask(s, p, o1)); + assert(model.ask(s, p, o1)); + assert(!model.ask(s, p, s)); + + size_t total_count = 0; + for (const auto& statement : model) { + assert(statement.subject() == s); + assert(statement.predicate() == p); + assert(statement.object() == o1 || statement.object() == o2); + ++total_count; + } + assert(total_count == 2); + + size_t o1_count = 0; + for (const auto& statement : model.range({}, {}, o1)) { + assert(statement.subject() == s); + assert(statement.predicate() == p); + assert(statement.object() == o1); + ++o1_count; + } + assert(o1_count == 1); + + size_t o2_count = 0; + for (const auto& statement : model.range({}, {}, o2)) { + assert(statement.subject() == s); + assert(statement.predicate() == p); + assert(statement.object() == o2); + ++o2_count; + } + assert(o2_count == 1); + + serd::Model copy(model); + assert(copy == model); + + copy.insert(s, p, s); + assert(copy != model); + + return 0; +} + +int +main() +{ + int st = 0; + + st |= test_operators(); + st |= test_optional(); + st |= test_nodes(); + st |= test_env(); + st |= test_reader(); + st |= test_writer(); + st |= test_model(); + + return st; +} |