// The engine API sketch must compile and its value types must behave. Engine / // DownloadHandle bodies land in stage 8; this only exercises the data shapes DAEMON // builds against. #include "vdm/engine.hpp" #include "vdm/task/download.hpp" #include #include "vtest.hpp" using namespace vdm; using namespace vdm::task; VT_TEST(api_download_spec_defaults) { DownloadSpec s; s.url = "https://example.com/big.iso"; s.save_path = "/home/u/Downloads/big.iso"; VT_CHECK(s.mirrors.empty()); VT_CHECK(!s.segments.has_value()); VT_CHECK(!s.buffer_bytes.has_value()); VT_CHECK(!s.checksum.has_value()); VT_CHECK(!s.probe_hint.has_value()); VT_CHECK(s.allow_resume); VT_CHECK(s.proxy.kind == net::ProxyKind::none); VT_CHECK(s.auth.scheme == net::AuthScheme::none); } VT_TEST(api_state_helpers) { VT_CHECK(is_terminal(EngineState::complete)); VT_CHECK(is_terminal(EngineState::failed)); VT_CHECK(is_terminal(EngineState::cancelled)); VT_CHECK(!is_terminal(EngineState::paused)); VT_CHECK(!is_terminal(EngineState::downloading)); } VT_TEST(api_callbacks_are_all_optional) { DownloadCallbacks cb; // every std::function default-constructs empty VT_CHECK(!cb.on_progress); VT_CHECK(!cb.on_state); VT_CHECK(!cb.on_auth_required); VT_CHECK(!cb.on_decision_needed); VT_CHECK(!cb.on_finished); cb.on_state = [](EngineState, EngineState, const std::optional &) {}; cb.on_finished = [](Result) {}; VT_CHECK(cb.on_state && cb.on_finished); } VT_TEST(api_value_types_roundtrip) { Progress p; p.downloaded = 1234; p.total = 5000; p.effective_segments = 4; SegmentProgress sp; sp.index = 0; sp.end = 1249; sp.completed = 1234; p.segments.push_back(sp); VT_CHECK_EQ(p.segments.size(), 1u); VT_CHECK_EQ(p.segments[0].end, 1249u); DownloadOutcome o; o.final_path = "/x"; o.bytes = 5000; VT_CHECK_EQ(o.bytes, 5000u); AuthChallenge a; a.host = "h"; a.scheme = AuthChallenge::Scheme::digest; VT_CHECK(a.scheme == AuthChallenge::Scheme::digest); DecisionRequest d; d.kind = DecisionRequest::Kind::server_file_changed; d.detail = "changed"; VT_CHECK(d.kind == DecisionRequest::Kind::server_file_changed); } VT_TEST(api_handle_and_engine_are_move_only_shaped) { static_assert(!std::is_copy_constructible_v, "Engine is non-copyable"); static_assert(std::is_copy_constructible_v, "handle is a shared handle"); DownloadHandle h; // default handle is invalid until Engine::start() fills it VT_CHECK(!h.valid()); }