diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/.clang-tidy | 16 | ||||
-rw-r--r-- | tests/TestClient.hpp | 26 | ||||
-rw-r--r-- | tests/connect_disconnect_node_patch.ttl | 6 | ||||
-rw-r--r-- | tests/ingen_bench.cpp | 89 | ||||
-rw-r--r-- | tests/ingen_test.cpp | 165 | ||||
-rw-r--r-- | tests/lint/meson.build | 24 | ||||
-rw-r--r-- | tests/meson.build | 100 | ||||
-rw-r--r-- | tests/test_utils.hpp | 35 | ||||
-rw-r--r-- | tests/tst_FilePath.cpp | 108 |
9 files changed, 330 insertions, 239 deletions
diff --git a/tests/.clang-tidy b/tests/.clang-tidy new file mode 100644 index 00000000..6c26f23c --- /dev/null +++ b/tests/.clang-tidy @@ -0,0 +1,16 @@ +Checks: > + -*-no-malloc, + -*-vararg, + -android-cloexec-fopen, + -cert-err33-c, + -concurrency-mt-unsafe, + -cppcoreguidelines-avoid-non-const-global-variables, + -cppcoreguidelines-owning-memory, + -cppcoreguidelines-pro-bounds-pointer-arithmetic, + -cppcoreguidelines-pro-type-reinterpret-cast, + -cppcoreguidelines-pro-type-union-access, + -fuchsia-statically-constructed-objects, + -google-readability-todo, + -llvm-header-guard, + -readability-function-cognitive-complexity, +InheritParentConfig: true diff --git a/tests/TestClient.hpp b/tests/TestClient.hpp index e76e4aa5..72265b14 100644 --- a/tests/TestClient.hpp +++ b/tests/TestClient.hpp @@ -17,23 +17,29 @@ #ifndef INGEN_TESTCLIENT_HPP #define INGEN_TESTCLIENT_HPP -#include "ingen/Interface.hpp" -#include "ingen/Log.hpp" +#include <ingen/Interface.hpp> +#include <ingen/Log.hpp> +#include <ingen/Message.hpp> +#include <ingen/Status.hpp> +#include <ingen/URI.hpp> -#include <boost/variant/get.hpp> +#include <variant> -using namespace ingen; +#include <cstdlib> -class TestClient : public ingen::Interface +namespace ingen { + +class TestClient : public Interface { public: - explicit TestClient(Log& log) : _log(log) {} - ~TestClient() {} + explicit TestClient(Log& log) noexcept : _log(log) {} + + ~TestClient() override = default; URI uri() const override { return URI("ingen:testClient"); } void message(const Message& msg) override { - if (const Response* const response = boost::get<Response>(&msg)) { + if (const Response* const response = std::get_if<Response>(&msg)) { if (response->status != Status::SUCCESS) { _log.error("error on message %1%: %2% (%3%)\n", response->id, @@ -41,7 +47,7 @@ public: response->subject); exit(EXIT_FAILURE); } - } else if (const Error* const error = boost::get<Error>(&msg)) { + } else if (const Error* const error = std::get_if<Error>(&msg)) { _log.error("error: %1%\n", error->message); exit(EXIT_FAILURE); } @@ -51,4 +57,6 @@ private: Log& _log; }; +} // namespace ingen + #endif // INGEN_TESTCLIENT_HPP diff --git a/tests/connect_disconnect_node_patch.ttl b/tests/connect_disconnect_node_patch.ttl index 77ada2ad..373b5cbf 100644 --- a/tests/connect_disconnect_node_patch.ttl +++ b/tests/connect_disconnect_node_patch.ttl @@ -13,10 +13,10 @@ <msg1> a patch:Put ; - patch:subject <ingen:/main/sampler> ; + patch:subject <ingen:/main/metro> ; patch:body [ a ingen:Block ; - lv2:prototype <http://lv2plug.in/plugins/eg-sampler> + lv2:prototype <http://lv2plug.in/plugins/eg-metro> ] . <msg2> @@ -85,7 +85,7 @@ patch:body [ a ingen:Arc ; ingen:tail <ingen:/main/control> ; - ingen:head <ingen:/main/sampler/control> + ingen:head <ingen:/main/metro/control> ] . <msg10> diff --git a/tests/ingen_bench.cpp b/tests/ingen_bench.cpp index 99abee97..ee890401 100644 --- a/tests/ingen_bench.cpp +++ b/tests/ingen_bench.cpp @@ -14,62 +14,61 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/Atom.hpp" -#include "ingen/Clock.hpp" -#include "ingen/Configuration.hpp" -#include "ingen/EngineBase.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Parser.hpp" -#include "ingen/World.hpp" -#include "ingen/runtime_paths.hpp" -#include "ingen/types.hpp" +#include <ingen/Atom.hpp> +#include <ingen/Clock.hpp> +#include <ingen/Configuration.hpp> +#include <ingen/EngineBase.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Parser.hpp> +#include <ingen/World.hpp> +#include <ingen/runtime_paths.hpp> #include <chrono> #include <cstdint> #include <cstdio> #include <cstdlib> +#include <exception> #include <iostream> #include <memory> #include <string> -using namespace std; -using namespace ingen; +namespace ingen::bench { +namespace { -unique_ptr<World> world; +std::unique_ptr<ingen::World> world; -static void +void ingen_try(bool cond, const char* msg) { if (!cond) { - cerr << "ingen: Error: " << msg << endl; + std::cerr << "ingen: Error: " << msg << "\n"; world.reset(); exit(EXIT_FAILURE); } } -static std::string +std::string real_path(const char* path) { char* const c_real_path = realpath(path, nullptr); - const std::string result(c_real_path ? c_real_path : ""); + std::string result(c_real_path ? c_real_path : ""); free(c_real_path); return result; } int -main(int argc, char** argv) +run(int argc, char** argv) { - set_bundle_path_from_code((void*)&ingen_try); - // Create world try { - world = unique_ptr<World>{new World(nullptr, nullptr, nullptr)}; + world = std::make_unique<ingen::World>(nullptr, nullptr, nullptr); + world->conf().add( "output", "output", 'O', "File to write benchmark output", ingen::Configuration::SESSION, world->forge().String, Atom()); world->load_configuration(argc, argv); } catch (std::exception& e) { - cout << "ingen: " << e.what() << endl; + std::cout << "ingen: " << e.what() << "\n"; return EXIT_FAILURE; } @@ -77,17 +76,19 @@ main(int argc, char** argv) const Atom& load = world->conf().option("load"); const Atom& out = world->conf().option("output"); if (!load.is_valid() || !out.is_valid()) { - cerr << "Usage: ingen_bench --load START_GRAPH --output OUT_FILE" << endl; + std::cerr << "Usage: ingen_bench --load START_GRAPH --output OUT_FILE\n"; return EXIT_FAILURE; } // Get start graph and output file options - const std::string start_graph = real_path((const char*)load.get_body()); - const std::string out_file = (const char*)out.get_body(); + const std::string start_graph = + real_path(static_cast<const char*>(load.get_body())); + + const std::string out_file = static_cast<const char*>(out.get_body()); if (start_graph.empty()) { - cerr << "error: initial graph '" - << ((const char*)load.get_body()) - << "' does not exist" << endl; + std::cerr << "error: initial graph '" + << static_cast<const char*>(load.get_body()) + << "' does not exist\n"; return EXIT_FAILURE; } @@ -96,24 +97,26 @@ main(int argc, char** argv) "Unable to load server module"); // Initialise engine - ingen_try(bool(world->engine()), + ingen_try(!!world->engine(), "Unable to create engine"); world->engine()->init(48000.0, 4096, 4096); world->engine()->activate(); // Load graph if (!world->parser()->parse_file(*world, *world->interface(), start_graph)) { - cerr << "error: failed to load initial graph " << start_graph << endl; + std::cerr << "error: failed to load initial graph " << start_graph + << "\n"; + return EXIT_FAILURE; } world->engine()->flush_events(std::chrono::milliseconds(20)); // Run benchmark // TODO: Set up real-time scheduling for this and worker threads - ingen::Clock clock; - const uint32_t n_test_frames = 1 << 20; - const uint32_t block_length = 4096; - const uint64_t t_start = clock.now_microseconds(); + const ingen::Clock clock; + const uint32_t n_test_frames = 1 << 20; + const uint32_t block_length = 4096; + const uint64_t t_start = clock.now_microseconds(); for (uint32_t i = 0; i < n_test_frames; i += block_length) { world->engine()->advance(block_length); world->engine()->run(block_length); @@ -122,14 +125,14 @@ main(int argc, char** argv) const uint64_t t_end = clock.now_microseconds(); // Write log output - std::unique_ptr<FILE, decltype(&fclose)> log{fopen(out_file.c_str(), "a"), - &fclose}; + const std::unique_ptr<FILE, int (*)(FILE*)> log{fopen(out_file.c_str(), "a"), + &fclose}; if (ftell(log.get()) == 0) { fprintf(log.get(), "# n_threads\trun_time\treal_time\n"); } - fprintf(log.get(), "%u\t%f\t%f\n", + fprintf(log.get(), "%d\t%f\t%f\n", world->conf().option("threads").get<int32_t>(), - (t_end - t_start) / 1000000.0, + static_cast<double>(t_end - t_start) / 1000000.0, (n_test_frames / 48000.0)); // Shut down @@ -137,3 +140,15 @@ main(int argc, char** argv) return EXIT_SUCCESS; } + +} // namespace +} // namespace ingen::bench + +int +main(int argc, char** argv) +{ + ingen::set_bundle_path_from_code( + reinterpret_cast<void (*)()>(&ingen::bench::ingen_try)); + + return ingen::bench::run(argc, argv); +} diff --git a/tests/ingen_test.cpp b/tests/ingen_test.cpp index 476fab64..215d20a1 100644 --- a/tests/ingen_test.cpp +++ b/tests/ingen_test.cpp @@ -15,73 +15,74 @@ */ #include "TestClient.hpp" -#include "ingen_config.h" - -#include "ingen/Atom.hpp" -#include "ingen/AtomForge.hpp" -#include "ingen/AtomReader.hpp" -#include "ingen/AtomWriter.hpp" -#include "ingen/Configuration.hpp" -#include "ingen/EngineBase.hpp" -#include "ingen/FilePath.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Parser.hpp" -#include "ingen/Properties.hpp" -#include "ingen/Serialiser.hpp" -#include "ingen/Store.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIMap.hpp" -#include "ingen/World.hpp" -#include "ingen/filesystem.hpp" -#include "ingen/fmt.hpp" -#include "ingen/runtime_paths.hpp" -#include "ingen/types.hpp" -#include "raul/Path.hpp" -#include "serd/serd.h" -#include "sord/sordmm.hpp" -#include "sratom/sratom.h" + +#include <ingen/Atom.hpp> +#include <ingen/AtomForge.hpp> +#include <ingen/AtomReader.hpp> +#include <ingen/Configuration.hpp> +#include <ingen/EngineBase.hpp> +#include <ingen/FilePath.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Parser.hpp> +#include <ingen/Serialiser.hpp> +#include <ingen/Store.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIMap.hpp> +#include <ingen/World.hpp> +#include <ingen/fmt.hpp> +#include <ingen/memory.hpp> +#include <ingen/runtime_paths.hpp> +#include <raul/Path.hpp> +#include <serd/serd.h> +#include <sord/sordmm.hpp> +#include <sratom/sratom.h> #include <chrono> #include <cstdint> #include <cstdlib> +#include <exception> +#include <filesystem> #include <iostream> +#include <map> +#include <memory> #include <string> #include <utility> -using namespace std; -using namespace ingen; +// #define DUMP_EVENTS 1 + +namespace ingen::test { +namespace { -unique_ptr<World> world; +std::unique_ptr<World> world; -static void +void ingen_try(bool cond, const char* msg) { if (!cond) { - cerr << "ingen: Error: " << msg << endl; + std::cerr << "ingen: Error: " << msg << "\n"; world.reset(); exit(EXIT_FAILURE); } } -static FilePath +FilePath real_file_path(const char* path) { - UPtr<char, FreeDeleter<char>> real_path{realpath(path, nullptr)}; + const std::unique_ptr<char, FreeDeleter<char>> real_path{realpath(path, nullptr), + FreeDeleter<char>{}}; return FilePath{real_path.get()}; } int -main(int argc, char** argv) +run(int argc, char** argv) { - set_bundle_path_from_code((void*)&ingen_try); - // Create world try { - world = unique_ptr<World>{new World(nullptr, nullptr, nullptr)}; + world = std::make_unique<World>(nullptr, nullptr, nullptr); world->load_configuration(argc, argv); - } catch (std::exception& e) { - cout << "ingen: " << e.what() << endl; + } catch (const std::exception& e) { + std::cerr << "ingen: " << e.what() << "\n"; return EXIT_FAILURE; } @@ -89,19 +90,23 @@ main(int argc, char** argv) const Atom& load = world->conf().option("load"); const Atom& execute = world->conf().option("execute"); if (!load.is_valid() || !execute.is_valid()) { - cerr << "Usage: ingen_test --load START_GRAPH --execute COMMANDS_FILE" << endl; + std::cerr + << "Usage: ingen_test --load START_GRAPH --execute COMMANDS_FILE\n"; + return EXIT_FAILURE; } // Get start graph and commands file options - const FilePath load_path = real_file_path((const char*)load.get_body()); - const FilePath run_path = real_file_path((const char*)execute.get_body()); + const FilePath load_path = real_file_path(static_cast<const char*>(load.get_body())); + const FilePath run_path = real_file_path(static_cast<const char*>(execute.get_body())); if (load_path.empty()) { - cerr << "error: initial graph '" << load_path << "' does not exist" << endl; + std::cerr << "error: initial graph '" << load_path << "' does not exist\n"; return EXIT_FAILURE; - } else if (run_path.empty()) { - cerr << "error: command file '" << run_path << "' does not exist" << endl; + } + + if (run_path.empty()) { + std::cerr << "error: command file '" << run_path << "' does not exist\n"; return EXIT_FAILURE; } @@ -110,21 +115,21 @@ main(int argc, char** argv) "Unable to load server module"); // Initialise engine - ingen_try(bool(world->engine()), + ingen_try(!!world->engine(), "Unable to create engine"); world->engine()->init(48000.0, 4096, 4096); world->engine()->activate(); // Load graph if (!world->parser()->parse_file(*world, *world->interface(), load_path)) { - cerr << "error: failed to load initial graph " << load_path << endl; + std::cerr << "error: failed to load initial graph " << load_path << "\n"; return EXIT_FAILURE; } world->engine()->flush_events(std::chrono::milliseconds(20)); // Read commands - AtomForge forge(world->uri_map().urid_map_feature()->urid_map); + AtomForge forge(world->uri_map().urid_map()); sratom_set_object_mode(&forge.sratom(), SRATOM_OBJECT_MODE_BLANK_SUBJECT); @@ -132,29 +137,35 @@ main(int argc, char** argv) AtomReader atom_reader(world->uri_map(), world->uris(), world->log(), - *world->interface().get()); + *world->interface()); // AtomWriter to serialise responses from the engine - SPtr<Interface> client(new TestClient(world->log())); + const std::shared_ptr<Interface> client{new TestClient(world->log())}; world->interface()->set_respondee(client); world->engine()->register_client(client); SerdURI cmds_base; SerdNode cmds_file_uri = serd_node_new_file_uri( - (const uint8_t*)run_path.c_str(), + reinterpret_cast<const uint8_t*>(run_path.c_str()), nullptr, &cmds_base, true); - Sord::Model* cmds = new Sord::Model(*world->rdf_world(), - (const char*)cmds_file_uri.buf); + + auto* cmds = + new Sord::Model(*world->rdf_world(), + reinterpret_cast<const char*>(cmds_file_uri.buf)); + SerdEnv* env = serd_env_new(&cmds_file_uri); cmds->load_file(env, SERD_TURTLE, run_path); - Sord::Node nil; - int n_events = 0; + const Sord::Node nil; + int n_events = 0; for (;; ++n_events) { - std::string subject_str = fmt("msg%1%", n_events); - Sord::URI subject(*world->rdf_world(), subject_str, - (const char*)cmds_file_uri.buf); - Sord::Iter iter = cmds->find(subject, nil, nil); + const std::string subject_str = fmt("msg%1%", n_events); + + Sord::URI subject(*world->rdf_world(), + subject_str, + reinterpret_cast<const char*>(cmds_file_uri.buf)); + + auto iter = cmds->find(subject, nil, nil); if (iter.end()) { break; } @@ -162,9 +173,9 @@ main(int argc, char** argv) forge.clear(); forge.read(*world->rdf_world(), cmds->c_obj(), subject.c_obj()); -#if 0 +#ifdef DUMP_EVENTS const LV2_Atom* atom = forge.atom(); - cerr << "READ " << atom->size << " BYTES" << endl; + cerr << "READ " << atom->size << " BYTES\n"; cerr << sratom_to_turtle( sratom, &world->uri_map().urid_unmap_feature()->urid_unmap, @@ -173,6 +184,7 @@ main(int argc, char** argv) #endif if (!atom_reader.write(forge.atom(), n_events + 1)) { + delete cmds; return EXIT_FAILURE; } @@ -182,34 +194,34 @@ main(int argc, char** argv) delete cmds; // Save resulting graph - auto r = world->store()->find(Raul::Path("/")); + auto r = world->store()->find(raul::Path("/")); const std::string base = run_path.stem(); const std::string out_name = base.substr(0, base.find('.')) + ".out.ingen"; - const FilePath out_path = filesystem::current_path() / out_name; + const FilePath out_path = std::filesystem::current_path() / out_name; world->serialiser()->write_bundle(r->second, URI(out_path)); - // Undo every event (should result in a graph identical to the original) + // Undo every event (makes the graph identical to the original) for (int i = 0; i < n_events; ++i) { world->interface()->undo(); world->engine()->flush_events(std::chrono::milliseconds(20)); } // Save completely undone graph - r = world->store()->find(Raul::Path("/")); + r = world->store()->find(raul::Path("/")); const std::string undo_name = base.substr(0, base.find('.')) + ".undo.ingen"; - const FilePath undo_path = filesystem::current_path() / undo_name; + const FilePath undo_path = std::filesystem::current_path() / undo_name; world->serialiser()->write_bundle(r->second, URI(undo_path)); - // Redo every event (should result in a graph identical to the pre-undo output) + // Redo every event (makes the graph identical to the pre-undo output) for (int i = 0; i < n_events; ++i) { world->interface()->redo(); world->engine()->flush_events(std::chrono::milliseconds(20)); } // Save completely redone graph - r = world->store()->find(Raul::Path("/")); + r = world->store()->find(raul::Path("/")); const std::string redo_name = base.substr(0, base.find('.')) + ".redo.ingen"; - const FilePath redo_path = filesystem::current_path() / redo_name; + const FilePath redo_path = std::filesystem::current_path() / redo_name; world->serialiser()->write_bundle(r->second, URI(redo_path)); serd_env_free(env); @@ -220,3 +232,20 @@ main(int argc, char** argv) return EXIT_SUCCESS; } + +} // namespace +} // namespace ingen::test + +int +main(int argc, char** argv) +{ + try { + ingen::set_bundle_path_from_code( + reinterpret_cast<void (*)()>(&ingen::test::ingen_try)); + + return ingen::test::run(argc, argv); + } catch (const std::exception& e) { + std::cerr << "ingen: " << e.what() << "\n"; + return EXIT_FAILURE; + } +} diff --git a/tests/lint/meson.build b/tests/lint/meson.build new file mode 100644 index 00000000..c641cbaa --- /dev/null +++ b/tests/lint/meson.build @@ -0,0 +1,24 @@ +# Copyright 2019-2024 David Robillard <d@drobilla.net> +# SPDX-License-Identifier: 0BSD OR GPL-3.0-or-later + +if not meson.is_subproject() + # Check code with cppcheck + cppcheck = find_program('cppcheck', required: false) + if cppcheck.found() + compdb_path = join_paths(ingen_build_root, 'compile_commands.json') + suppress_path = join_paths(ingen_src_root, '.suppress.cppcheck') + test( + 'cppcheck', + cppcheck, + args: [ + '--cppcheck-build-dir=' + meson.current_build_dir(), + '--enable=warning,style,performance,portability', + '--error-exitcode=1', + '--project=' + compdb_path, + '--suppressions-list=' + suppress_path, + '-q', + ], + suite: 'code', + ) + endif +endif diff --git a/tests/meson.build b/tests/meson.build new file mode 100644 index 00000000..1637230b --- /dev/null +++ b/tests/meson.build @@ -0,0 +1,100 @@ +# Copyright 2019-2022 David Robillard <d@drobilla.net> +# SPDX-License-Identifier: 0BSD OR GPL-3.0-or-later + +##################### +# Integration Tests # +##################### + +ingen_test = executable( + 'ingen_test', + files('ingen_test.cpp'), + cpp_args: cpp_suppressions + platform_defines, + dependencies: [ingen_dep], +) + +ingen_bench = executable( + 'ingen_bench', + files('ingen_bench.cpp'), + cpp_args: cpp_suppressions + platform_defines, + dependencies: [ingen_dep], +) + +empty_manifest = files('empty.ingen/manifest.ttl') +empty_main = files('empty.ingen/main.ttl') + +integration_tests = [ + 'connect_disconnect_node_node', + 'connect_disconnect_node_patch', + 'connect_disconnect_patch_patch', + 'copy_node', + 'create_delete_node', + 'create_delete_patch', + 'create_delete_poly_patch', + 'create_delete_port', + 'disconnect_all_node', + 'disconnect_all_port', + 'duplicate_node', + 'enable_graph', + 'get_engine', + 'get_node', + 'get_patch', + 'get_plugin', + 'get_plugins', + 'get_port', + 'load_graph', + 'move_node', + 'move_port', + 'move_root_port', + 'poly', + 'put_audio_in', + 'save_graph', + 'set_graph_poly', + 'set_patch_port_value', +] + +test_env = environment( + { + 'INGEN_MODULE_PATH': ':'.join( + [ + ingen_build_root / 'src', + ingen_build_root / 'src' / 'client', + ingen_build_root / 'src' / 'gui', + ingen_build_root / 'src' / 'server', + ], + ), + 'LV2_PATH': ':'.join( + [ + lv2_dep.get_variable( + default_value: lv2dir, + internal: 'lv2dir', + pkgconfig: 'lv2dir', + ), + lv2_dep.get_variable( + default_value: lv2dir, + internal: 'plugindir', + pkgconfig: 'plugindir', + ), + ], + ), + }, +) + +foreach test : integration_tests + test( + test, + ingen_test, + env: test_env, + args: [ + ['--load', empty_manifest], + ['--execute', files(test + '.ttl')], + ], + ) +endforeach + +######## +# Lint # +######## + +if get_option('lint') + subdir('lint') +endif diff --git a/tests/test_utils.hpp b/tests/test_utils.hpp index 48e3a588..4c358739 100644 --- a/tests/test_utils.hpp +++ b/tests/test_utils.hpp @@ -14,25 +14,32 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/fmt.hpp" +#include <ingen/fmt.hpp> #include <iostream> +#include <string> #define EXPECT_TRUE(value) \ - if (!(value)) { \ - std::cerr << fmt("error: %1%:%2%: !%3%\n", \ - __FILE__, __LINE__, (#value)); \ - } + do { \ + if (!(value)) { \ + std::cerr << fmt("error: %1%:%2%: !%3%\n", \ + __FILE__, __LINE__, (#value)); \ + } \ + } while (0) #define EXPECT_FALSE(value) \ - if ((value)) { \ - std::cerr << (fmt("error: %1%:%2%: !%3%\n", \ - __FILE__, __LINE__, (#value))); \ - } + do { \ + if ((value)) { \ + std::cerr << (fmt("error: %1%:%2%: !%3%\n", \ + __FILE__, __LINE__, (#value))); \ + } \ + } while (0) #define EXPECT_EQ(value, expected) \ - if (!((value) == (expected))) { \ - std::cerr << fmt("error: %1%:%2%: %3% != %4%\n", \ - __FILE__, __LINE__, (#value), (#expected)); \ - std::cerr << "note: actual value: " << value << std::endl; \ - } + do { \ + if (!((value) == (expected))) { \ + std::cerr << fmt("error: %1%:%2%: %3% != %4%\n", \ + __FILE__, __LINE__, (#value), (#expected)); \ + std::cerr << "note: actual value: " << (value) << std::endl; \ + } \ + } while (0) diff --git a/tests/tst_FilePath.cpp b/tests/tst_FilePath.cpp deleted file mode 100644 index 768371fe..00000000 --- a/tests/tst_FilePath.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/* - This file is part of Ingen. - Copyright 2018 David Robillard <http://drobilla.net/> - - Ingen 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 any later version. - - Ingen 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 details. - - You should have received a copy of the GNU Affero General Public License - along with Ingen. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include "test_utils.hpp" - -#include "ingen/FilePath.hpp" -#include "ingen/fmt.hpp" - -#include <boost/utility/string_view.hpp> - -#include <string> - -using ingen::FilePath; -using ingen::fmt; - -int -main(int, char**) -{ - EXPECT_EQ(FilePath("/").parent_path(), FilePath("/")); - - EXPECT_TRUE(FilePath("/abs").is_absolute()) - EXPECT_FALSE(FilePath("/abs").is_relative()) - EXPECT_EQ(FilePath("/abs").root_name(), FilePath()); - EXPECT_EQ(FilePath("/abs").root_directory(), FilePath("/")); - EXPECT_EQ(FilePath("/abs").root_path(), FilePath("/")); - EXPECT_EQ(FilePath("/abs").relative_path(), FilePath("abs")); - EXPECT_EQ(FilePath("/abs").parent_path(), FilePath("/")); - EXPECT_EQ(FilePath("/abs").filename(), FilePath("abs")); - EXPECT_EQ(FilePath("/abs").stem(), FilePath("abs")); - EXPECT_EQ(FilePath("/abs").extension(), FilePath()); - - EXPECT_FALSE(FilePath("rel").is_absolute()) - EXPECT_TRUE(FilePath("rel").is_relative()) - EXPECT_EQ(FilePath("rel").root_name(), FilePath()); - EXPECT_EQ(FilePath("rel").root_directory(), FilePath()); - EXPECT_EQ(FilePath("rel").root_path(), FilePath()); - EXPECT_EQ(FilePath("rel").relative_path(), FilePath()); - EXPECT_EQ(FilePath("rel").parent_path(), FilePath()); - EXPECT_EQ(FilePath("rel").filename(), "rel"); - EXPECT_EQ(FilePath("rel").stem(), "rel"); - EXPECT_EQ(FilePath("rel").extension(), FilePath()); - - EXPECT_FALSE(FilePath("file.txt").is_absolute()) - EXPECT_TRUE(FilePath("file.txt").is_relative()) - EXPECT_EQ(FilePath("file.txt").filename(), "file.txt"); - EXPECT_EQ(FilePath("file.txt").stem(), "file"); - EXPECT_EQ(FilePath("file.txt").extension(), ".txt"); - - EXPECT_TRUE(FilePath("/abs/file.txt").is_absolute()) - EXPECT_FALSE(FilePath("/abs/file.txt").is_relative()) - EXPECT_EQ(FilePath("/abs/file.txt").filename(), "file.txt"); - EXPECT_EQ(FilePath("/abs/file.txt").stem(), "file"); - EXPECT_EQ(FilePath("/abs/file.txt").extension(), ".txt"); - - EXPECT_FALSE(FilePath("rel/file.txt").is_absolute()) - EXPECT_TRUE(FilePath("rel/file.txt").is_relative()) - EXPECT_EQ(FilePath("rel/file.txt").filename(), "file.txt"); - EXPECT_EQ(FilePath("rel/file.txt").stem(), "file"); - EXPECT_EQ(FilePath("rel/file.txt").extension(), ".txt"); - - FilePath path("/x"); - EXPECT_EQ(path, "/x"); - path = std::string("/a"); - EXPECT_EQ(path, "/a"); - - path /= FilePath("b"); - EXPECT_EQ(path, "/a/b"); - - path += FilePath("ar"); - EXPECT_EQ(path, "/a/bar"); - - path += std::string("/c"); - EXPECT_EQ(path, "/a/bar/c"); - - path += "a"; - EXPECT_EQ(path, "/a/bar/ca"); - - path += 'r'; - EXPECT_EQ(path, "/a/bar/car"); - - path += boost::string_view("/d"); - EXPECT_EQ(path, "/a/bar/car/d"); - - const FilePath apple("apple"); - const FilePath zebra("zebra"); - EXPECT_TRUE(apple == apple); - EXPECT_TRUE(apple != zebra); - EXPECT_TRUE(apple < zebra); - EXPECT_TRUE(apple <= zebra); - EXPECT_TRUE(apple <= apple); - EXPECT_TRUE(zebra > apple); - EXPECT_TRUE(zebra >= apple); - EXPECT_TRUE(zebra >= zebra); - return 0; -} |