From 5d9e90f6c45bb4e1a1bbe7d04f3afdcba8abb0be Mon Sep 17 00:00:00 2001 From: Khalil Estell Date: Fri, 20 Oct 2023 11:31:14 -0700 Subject: [PATCH] :boom::sparkles: libhal 3.0.0 Migrate from Boost.LEAF to C++ exceptions --- .github/workflows/3.0.0-alpha.1.yml | 12 ++ .github/workflows/ci.yml | 6 +- CMakeLists.txt | 2 - conanfile.py | 16 +-- include/libhal/accelerometer.hpp | 7 +- include/libhal/adc.hpp | 8 +- include/libhal/can.hpp | 19 ++-- include/libhal/dac.hpp | 9 +- include/libhal/distance_sensor.hpp | 7 +- include/libhal/error.hpp | 54 ++------- include/libhal/functional.hpp | 3 +- include/libhal/gyroscope.hpp | 7 +- include/libhal/i2c.hpp | 22 ++-- include/libhal/initializer.hpp | 61 +++++++++++ include/libhal/input_pin.hpp | 15 ++- include/libhal/interrupt_pin.hpp | 6 +- include/libhal/magnetometer.hpp | 7 +- include/libhal/motor.hpp | 8 +- include/libhal/output_pin.hpp | 21 ++-- include/libhal/pwm.hpp | 13 +-- include/libhal/rotation_sensor.hpp | 7 +- include/libhal/serial.hpp | 27 +++-- include/libhal/servo.hpp | 7 +- include/libhal/spi.hpp | 34 ++---- include/libhal/steady_clock.hpp | 3 +- include/libhal/temperature_sensor.hpp | 7 +- include/libhal/timeout.hpp | 73 +++++-------- include/libhal/timer.hpp | 25 ++--- include/libhal/units.hpp | 2 - test_package/main.cpp | 51 ++++----- tests/adc.test.cpp | 23 +--- tests/can.test.cpp | 39 +------ tests/conanfile.py | 45 -------- tests/dac.test.cpp | 23 +--- tests/error.test.cpp | 152 +++++++++++++++++++------- tests/g_force.test.cpp | 16 ++- tests/helpers.cpp | 10 +- tests/helpers.hpp | 11 +- tests/i2c.test.cpp | 46 ++------ tests/input_pin.test.cpp | 36 +----- tests/interrupt_pin.test.cpp | 23 +--- tests/lengths.test.cpp | 91 +++++++-------- tests/motor.test.cpp | 25 +---- tests/output_pin.test.cpp | 51 ++------- tests/pwm.test.cpp | 37 ++----- tests/serial.test.cpp | 68 +++--------- tests/servo.test.cpp | 42 +------ tests/spi.test.cpp | 44 ++------ tests/steady_clock.test.cpp | 9 +- tests/timeout.test.cpp | 15 +-- tests/timer.test.cpp | 53 ++------- 51 files changed, 538 insertions(+), 860 deletions(-) create mode 100644 .github/workflows/3.0.0-alpha.1.yml create mode 100644 include/libhal/initializer.hpp delete mode 100644 tests/conanfile.py diff --git a/.github/workflows/3.0.0-alpha.1.yml b/.github/workflows/3.0.0-alpha.1.yml new file mode 100644 index 000000000..565abf7c3 --- /dev/null +++ b/.github/workflows/3.0.0-alpha.1.yml @@ -0,0 +1,12 @@ +name: 🚀 Deploy exceptions v1 + +on: + workflow_dispatch: + +jobs: + deploy: + uses: libhal/ci/.github/workflows/deploy.yml@5.x.y + with: + version: exceptions + arch: "x86_64" + secrets: inherit diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 967d685d4..fcf9ee20b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,10 +3,6 @@ name: ✅ CI on: workflow_dispatch: pull_request: - release: - types: - - published - - deleted push: branches: - main @@ -15,5 +11,5 @@ on: jobs: ci: - uses: libhal/ci/.github/workflows/library.yml@4.x.y + uses: libhal/ci/.github/workflows/library_check.yml@5.x.y secrets: inherit diff --git a/CMakeLists.txt b/CMakeLists.txt index fe1be5fa6..a9087943c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,9 +47,7 @@ libhal_unit_test(SOURCES tests/main.test.cpp PACKAGES - boost-leaf tl-function-ref LINK_LIBRARIES - boost::leaf tl::function-ref) diff --git a/conanfile.py b/conanfile.py index 75e57b201..ab51656ba 100644 --- a/conanfile.py +++ b/conanfile.py @@ -26,9 +26,8 @@ class libhal_conan(ConanFile): name = "libhal" - version = "2.0.3" license = "Apache-2.0" - url = "https://github.com/conan-io/conan-center-index" + url = "https://github.com/libhal/libhal" homepage = "https://libhal.github.io/libhal" description = ("A collection of interfaces and abstractions for embedded " "peripherals and devices using modern C++") @@ -51,10 +50,6 @@ def _compilers_minimum_version(self): "apple-clang": "14.0.0" } - @property - def _bare_metal(self): - return self.settings.os == "baremetal" - def validate(self): if self.settings.get_safe("compiler.cppstd"): check_min_cppstd(self, self._min_cppstd) @@ -66,7 +61,6 @@ def build_requirements(self): def requirements(self): self.requires("tl-function-ref/1.0.0") - self.requires("boost-leaf/1.83.0") def layout(self): cmake_layout(self) @@ -90,13 +84,5 @@ def package_info(self): self.cpp_info.libdirs = [] self.cpp_info.resdirs = [] - if self._bare_metal: - self.cpp_info.defines = [ - "BOOST_LEAF_EMBEDDED", - # TODO(#694): Remove this or have it be configurable. Users - # should not be forced to operate without thread support - "BOOST_LEAF_NO_THREADS" - ] - def package_id(self): self.info.clear() diff --git a/include/libhal/accelerometer.hpp b/include/libhal/accelerometer.hpp index 96c60e3d7..d02a44cd5 100644 --- a/include/libhal/accelerometer.hpp +++ b/include/libhal/accelerometer.hpp @@ -14,7 +14,6 @@ #pragma once -#include "error.hpp" #include "units.hpp" namespace hal { @@ -53,9 +52,9 @@ class accelerometer /** * @brief Read the latest acceleration sensed by the device * - * @return result - acceleration data + * @return read_t - acceleration data */ - [[nodiscard]] result read() + [[nodiscard]] read_t read() { return driver_read(); } @@ -63,6 +62,6 @@ class accelerometer virtual ~accelerometer() = default; private: - virtual result driver_read() = 0; + virtual read_t driver_read() = 0; }; } // namespace hal diff --git a/include/libhal/adc.hpp b/include/libhal/adc.hpp index 954d995e1..76d946080 100644 --- a/include/libhal/adc.hpp +++ b/include/libhal/adc.hpp @@ -14,8 +14,6 @@ #pragma once -#include "error.hpp" - namespace hal { /** * @brief Analog to Digital Converter (ADC) hardware abstraction interface. @@ -50,9 +48,9 @@ class adc /** * @brief Sample the analog to digital converter and return the result * - * @return result - the sampled adc value + * @return read_t - the sampled adc value */ - [[nodiscard]] result read() + [[nodiscard]] read_t read() { return driver_read(); } @@ -60,6 +58,6 @@ class adc virtual ~adc() = default; private: - virtual result driver_read() = 0; + virtual read_t driver_read() = 0; }; } // namespace hal diff --git a/include/libhal/can.hpp b/include/libhal/can.hpp index d8c0410f8..431c55756 100644 --- a/include/libhal/can.hpp +++ b/include/libhal/can.hpp @@ -17,7 +17,6 @@ #include #include -#include "error.hpp" #include "functional.hpp" #include "units.hpp" @@ -149,10 +148,10 @@ class can * @brief Configure this can bus port to match the settings supplied * * @param p_settings - settings to apply to can driver - * @return status - success or failure + * @return void - success or failure * @throws std::errc::invalid_argument if the settings could not be achieved. */ - [[nodiscard]] status configure(const settings& p_settings) + void configure(const settings& p_settings) { return driver_configure(p_settings); } @@ -176,11 +175,11 @@ class can * If this occurs, this function must be called to re-enable bus * communication. * - * @return status - success or failure. In the case this function fails + * @return void - success or failure. In the case this function fails * repeatedly, it is advised to simply not use the bus anymore as something is * critical wrong and may not be recoverable. */ - [[nodiscard]] status bus_on() + void bus_on() { return driver_bus_on(); } @@ -189,13 +188,13 @@ class can * @brief Send a can message * * @param p_message - the message to be sent - * @return result - success or failure + * @return send_t - success or failure * @throws std::errc::network_down - if the can device is in the "bus-off" * state. This can happen if a critical fault in the bus has occurred. A call * to `bus_on()` will need to be issued to attempt to talk on the bus again. * See `bus_on()` for more details. */ - [[nodiscard]] result send(const message_t& p_message) + send_t send(const message_t& p_message) { return driver_send(p_message); } @@ -216,9 +215,9 @@ class can virtual ~can() = default; private: - virtual status driver_configure(const settings& p_settings) = 0; - virtual status driver_bus_on() = 0; - virtual result driver_send(const message_t& p_message) = 0; + virtual void driver_configure(const settings& p_settings) = 0; + virtual void driver_bus_on() = 0; + virtual send_t driver_send(const message_t& p_message) = 0; virtual void driver_on_receive(hal::callback p_handler) = 0; }; } // namespace hal diff --git a/include/libhal/dac.hpp b/include/libhal/dac.hpp index 49cb4e545..99a5c078e 100644 --- a/include/libhal/dac.hpp +++ b/include/libhal/dac.hpp @@ -14,10 +14,9 @@ #pragma once +#include #include -#include "error.hpp" - namespace hal { /** * @brief Digital to Analog Converter (DAC) hardware abstraction interface. @@ -58,9 +57,9 @@ class dac * * @param p_percentage - value from 0.0f to +1.0f representing the proportion * of the output voltage from the Vss to Vcc. - * @return result - success or failure + * @return write_t - success or failure */ - [[nodiscard]] result write(float p_percentage) + write_t write(float p_percentage) { auto clamped_percentage = std::clamp(p_percentage, 0.0f, 1.0f); return driver_write(clamped_percentage); @@ -69,6 +68,6 @@ class dac virtual ~dac() = default; private: - virtual result driver_write(float p_percentage) = 0; + virtual write_t driver_write(float p_percentage) = 0; }; } // namespace hal diff --git a/include/libhal/distance_sensor.hpp b/include/libhal/distance_sensor.hpp index 74675e4f2..fc5e1d47e 100644 --- a/include/libhal/distance_sensor.hpp +++ b/include/libhal/distance_sensor.hpp @@ -14,7 +14,6 @@ #pragma once -#include "error.hpp" #include "units.hpp" namespace hal { @@ -96,9 +95,9 @@ class distance_sensor /** * @brief Read the current distance measured by the device * - * @return result - distance data + * @return read_t - distance data */ - [[nodiscard]] result read() + [[nodiscard]] read_t read() { return driver_read(); } @@ -106,6 +105,6 @@ class distance_sensor virtual ~distance_sensor() = default; private: - virtual result driver_read() = 0; + virtual read_t driver_read() = 0; }; } // namespace hal diff --git a/include/libhal/error.hpp b/include/libhal/error.hpp index edede81c8..c77c9884e 100644 --- a/include/libhal/error.hpp +++ b/include/libhal/error.hpp @@ -15,66 +15,26 @@ #pragma once #include - -#include - -#define HAL_CHECK BOOST_LEAF_CHECK +#include namespace hal { -template -using match = boost::leaf::match; -template -using result = boost::leaf::result; -using status = result; using error_handler = void(void); inline error_handler* on_error_callback = nullptr; -/** - * @brief a readability function for returning successful results; - * - * For functions that return `status`, rather than returning `{}` to default - * initialize the status object as "success", use this function to make it more - * clear to the reader. - * - * EXAMPLE: - * - * hal::status some_function() { - * return hal::success(); - * } - * - * @return status - that is always successful - */ -inline status success() -{ - // Default initialize the status object using the brace initialization, which - // will set the status to the default "success" state. - status successful_status{}; - return successful_status; -} - -template -[[nodiscard]] constexpr auto attempt(TryBlock&& p_try_block, H&&... p_handlers) -{ - return boost::leaf::try_handle_some(p_try_block, p_handlers...); -} - -template -[[nodiscard]] constexpr auto attempt_all(TryBlock&& p_try_block, - H&&... p_handlers) +template +void safe_throw(thrown_t&& p_thrown_object) { - return boost::leaf::try_handle_all(p_try_block, p_handlers...); -} + static_assert( + std::is_trivially_destructible_v, + "safe_throw() only works with trivially destructible thrown types"); -template -[[nodiscard]] inline auto new_error(Item&&... p_item) -{ if (on_error_callback) { on_error_callback(); } - return boost::leaf::new_error(std::forward(p_item)...); + throw p_thrown_object; } [[noreturn]] inline void halt() diff --git a/include/libhal/functional.hpp b/include/libhal/functional.hpp index e0db4108a..e4c200c72 100644 --- a/include/libhal/functional.hpp +++ b/include/libhal/functional.hpp @@ -16,9 +16,10 @@ #include -#include "third_party/inplace_function.hpp" #include +#include "third_party/inplace_function.hpp" + namespace hal { /** * @brief Definition of a non-owning callable object diff --git a/include/libhal/gyroscope.hpp b/include/libhal/gyroscope.hpp index 770c23c4c..bc8e0d479 100644 --- a/include/libhal/gyroscope.hpp +++ b/include/libhal/gyroscope.hpp @@ -14,7 +14,6 @@ #pragma once -#include "error.hpp" #include "units.hpp" namespace hal { @@ -52,9 +51,9 @@ class gyroscope /** * @brief Read the latest angular velocity sensed by the device * - * @return result - angular velocity data + * @return read_t - angular velocity data */ - [[nodiscard]] result read() + [[nodiscard]] read_t read() { return driver_read(); } @@ -62,6 +61,6 @@ class gyroscope virtual ~gyroscope() = default; private: - virtual result driver_read() = 0; + virtual read_t driver_read() = 0; }; } // namespace hal diff --git a/include/libhal/i2c.hpp b/include/libhal/i2c.hpp index 297a40f70..2298842a2 100644 --- a/include/libhal/i2c.hpp +++ b/include/libhal/i2c.hpp @@ -16,7 +16,6 @@ #include -#include "error.hpp" #include "functional.hpp" #include "timeout.hpp" #include "units.hpp" @@ -60,10 +59,10 @@ class i2c * @brief Configure i2c to match the settings supplied * * @param p_settings - settings to apply to i2c driver - * @return status - success or failure - * @throws std::errc::invalid_argument if the settings could not be achieved. + * @throws std::errc::invalid_argument if the settings could not be + * achieved. */ - [[nodiscard]] status configure(const settings& p_settings) + void configure(const settings& p_settings) { return driver_configure(p_settings); } @@ -106,7 +105,7 @@ class i2c * @param p_timeout callable which notifies the i2c driver that it has run out * of time to perform the transaction and must stop and return control to the * caller. - * @return result - success or failure + * @return transaction_t - success or failure * @throws std::errc::io_error indicates that the i2c lines were put into an * invalid state during the transaction due to interference, misconfiguration * of the i2c peripheral or the addressed device or something else. @@ -117,11 +116,10 @@ class i2c * @throws std::errc::timed_out if the transaction exceeded its time allotment * indicated by p_timeout. */ - [[nodiscard]] result transaction( - hal::byte p_address, - std::span p_data_out, - std::span p_data_in, - hal::function_ref p_timeout) + transaction_t transaction(hal::byte p_address, + std::span p_data_out, + std::span p_data_in, + hal::function_ref p_timeout) { return driver_transaction(p_address, p_data_out, p_data_in, p_timeout); } @@ -129,8 +127,8 @@ class i2c virtual ~i2c() = default; private: - virtual status driver_configure(const settings& p_settings) = 0; - virtual result driver_transaction( + virtual void driver_configure(const settings& p_settings) = 0; + virtual transaction_t driver_transaction( hal::byte p_address, std::span p_data_out, std::span p_data_in, diff --git a/include/libhal/initializer.hpp b/include/libhal/initializer.hpp new file mode 100644 index 000000000..a93524336 --- /dev/null +++ b/include/libhal/initializer.hpp @@ -0,0 +1,61 @@ +#pragma once + +#include +#include + +namespace hal { + +template +struct selector_t +{ + static constexpr auto val = value; + + constexpr std::int64_t operator()() const + { + return value; + } +}; + +template +struct port_t : selector_t +{}; + +template +struct pin_t : selector_t +{}; + +template +struct bus_t : selector_t +{}; + +template +struct channel_t : selector_t +{}; + +template +struct buffer_t : selector_t +{}; + +template +concept port_param = std::is_same_v, T>; +template +concept pin_param = std::is_same_v, T>; +template +concept bus_param = std::is_same_v, T>; +template +concept channel_param = std::is_same_v, T>; +template +concept buffer_param = std::is_same_v, T>; + +template +inline constexpr port_t port{}; +template +inline constexpr pin_t pin{}; +template +inline constexpr bus_t bus{}; +template +inline constexpr channel_t channel{}; +template +inline constexpr buffer_t buffer{}; + +} // namespace hal diff --git a/include/libhal/input_pin.hpp b/include/libhal/input_pin.hpp index 7ecae6656..b7aab21fa 100644 --- a/include/libhal/input_pin.hpp +++ b/include/libhal/input_pin.hpp @@ -14,7 +14,6 @@ #pragma once -#include "error.hpp" #include "units.hpp" namespace hal { @@ -45,10 +44,10 @@ class input_pin * @brief Configure the input pin to match the settings supplied * * @param p_settings - settings to apply to input pin - * @return status - success or failure - * @throws std::errc::invalid_argument if the settings could not be achieved. + * @throws std::errc::invalid_argument if the settings could not be + * achieved. */ - [[nodiscard]] status configure(const settings& p_settings) + void configure(const settings& p_settings) { return driver_configure(p_settings); } @@ -56,10 +55,10 @@ class input_pin /** * @brief Read the state of the input pin * - * @return result - true indicates HIGH voltage level and false + * @return bool - true indicates HIGH voltage level and false * indicates LOW voltage level */ - [[nodiscard]] result level() + [[nodiscard]] level_t level() { return driver_level(); } @@ -67,7 +66,7 @@ class input_pin virtual ~input_pin() = default; private: - virtual status driver_configure(const settings& p_settings) = 0; - virtual result driver_level() = 0; + virtual void driver_configure(const settings& p_settings) = 0; + virtual level_t driver_level() = 0; }; } // namespace hal diff --git a/include/libhal/interrupt_pin.hpp b/include/libhal/interrupt_pin.hpp index 75ba5bb58..e2c258ec5 100644 --- a/include/libhal/interrupt_pin.hpp +++ b/include/libhal/interrupt_pin.hpp @@ -14,7 +14,6 @@ #pragma once -#include "error.hpp" #include "functional.hpp" #include "units.hpp" @@ -94,10 +93,9 @@ class interrupt_pin * @brief Configure the interrupt pin to match the settings supplied * * @param p_settings - settings to apply to interrupt pin - * @return status - success or failure * @throws std::errc::invalid_argument if the settings could not be achieved. */ - [[nodiscard]] status configure(const settings& p_settings) + void configure(const settings& p_settings) { return driver_configure(p_settings); } @@ -117,7 +115,7 @@ class interrupt_pin virtual ~interrupt_pin() = default; private: - virtual status driver_configure(const settings& p_settings) = 0; + virtual void driver_configure(const settings& p_settings) = 0; virtual void driver_on_trigger(hal::callback p_callback) = 0; }; } // namespace hal diff --git a/include/libhal/magnetometer.hpp b/include/libhal/magnetometer.hpp index 7c110c14f..cbbae233d 100644 --- a/include/libhal/magnetometer.hpp +++ b/include/libhal/magnetometer.hpp @@ -14,7 +14,6 @@ #pragma once -#include "error.hpp" #include "units.hpp" namespace hal { @@ -61,9 +60,9 @@ class magnetometer /** * @brief Read the latest magnetic field strength sensed by the device * - * @return result - magnetic field strength data + * @return read_t - magnetic field strength data */ - [[nodiscard]] result read() + [[nodiscard]] read_t read() { return driver_read(); } @@ -71,6 +70,6 @@ class magnetometer virtual ~magnetometer() = default; private: - virtual result driver_read() = 0; + virtual read_t driver_read() = 0; }; } // namespace hal diff --git a/include/libhal/motor.hpp b/include/libhal/motor.hpp index db13e80c0..6a2730edd 100644 --- a/include/libhal/motor.hpp +++ b/include/libhal/motor.hpp @@ -14,8 +14,6 @@ #pragma once -#include "error.hpp" - namespace hal { /** * @brief Hardware abstraction for an open loop rotational actuator @@ -68,9 +66,9 @@ class motor * * @param p_power - Percentage of power to apply to the motor from -1.0f to * +1.0f, -100% to 100%, respectively. - * @return result - success or failure + * @return power_t - success or failure */ - [[nodiscard]] result power(float p_power) + power_t power(float p_power) { auto clamped_power = std::clamp(p_power, -1.0f, +1.0f); return driver_power(clamped_power); @@ -79,6 +77,6 @@ class motor virtual ~motor() = default; private: - virtual result driver_power(float p_power) = 0; + virtual power_t driver_power(float p_power) = 0; }; } // namespace hal diff --git a/include/libhal/output_pin.hpp b/include/libhal/output_pin.hpp index 68de3cd47..5e9f3e0b4 100644 --- a/include/libhal/output_pin.hpp +++ b/include/libhal/output_pin.hpp @@ -14,7 +14,6 @@ #pragma once -#include "error.hpp" #include "units.hpp" namespace hal { @@ -63,10 +62,10 @@ class output_pin * @brief Configure the output pin to match the settings supplied * * @param p_settings - settings to apply to output pin - * @return status - success or failure - * @throws std::errc::invalid_argument if the settings could not be achieved. + * @throws std::errc::invalid_argument if the settings could not be + * achieved. */ - [[nodiscard]] status configure(const settings& p_settings) + void configure(const settings& p_settings) { return driver_configure(p_settings); } @@ -76,9 +75,9 @@ class output_pin * * @param p_high - if true then the pin state is set to HIGH voltage. If * false, the pin state is set to LOW voltage. - * @return result - success or failure + * @return set_level_t - success or failure */ - [[nodiscard]] result level(bool p_high) + set_level_t level(bool p_high) { return driver_level(p_high); } @@ -92,9 +91,9 @@ class output_pin * This pin may not equal the state set by `level(bool)` when the pin is * configured as open-drain. * - * @return result - return the current level state of the output pin + * @return level_t - return the current level state of the output pin */ - [[nodiscard]] result level() + [[nodiscard]] level_t level() { return driver_level(); } @@ -102,8 +101,8 @@ class output_pin virtual ~output_pin() = default; private: - virtual status driver_configure(const settings& p_settings) = 0; - virtual result driver_level(bool p_high) = 0; - virtual result driver_level() = 0; + virtual void driver_configure(const settings& p_settings) = 0; + virtual set_level_t driver_level(bool p_high) = 0; + virtual level_t driver_level() = 0; }; } // namespace hal diff --git a/include/libhal/pwm.hpp b/include/libhal/pwm.hpp index 06fb6636c..c815dae67 100644 --- a/include/libhal/pwm.hpp +++ b/include/libhal/pwm.hpp @@ -17,7 +17,6 @@ #include #include -#include "error.hpp" #include "units.hpp" namespace hal { @@ -83,11 +82,11 @@ class pwm * implementors to omit redundant clamping code, reducing code bloat. * * @param p_frequency - settings to apply to pwm driver - * @return result - success or failure + * @return frequency_t - success or failure * @throws std::errc::argument_out_of_domain - if the frequency is beyond what * the pwm generator is capable of achieving. */ - [[nodiscard]] result frequency(hertz p_frequency) + frequency_t frequency(hertz p_frequency) { auto clamped_frequency = std::clamp(p_frequency, 1.0_Hz, 1.0_GHz); return driver_frequency(clamped_frequency); @@ -112,9 +111,9 @@ class pwm * * @param p_duty_cycle - a value from 0.0f to +1.0f representing the duty * cycle percentage. - * @return result - success or failure + * @return duty_cycle_t - success or failure */ - [[nodiscard]] result duty_cycle(float p_duty_cycle) + duty_cycle_t duty_cycle(float p_duty_cycle) { auto clamped_duty_cycle = std::clamp(p_duty_cycle, 0.0f, 1.0f); return driver_duty_cycle(clamped_duty_cycle); @@ -123,7 +122,7 @@ class pwm virtual ~pwm() = default; private: - virtual result driver_frequency(hertz p_frequency) = 0; - virtual result driver_duty_cycle(float p_duty_cycle) = 0; + virtual frequency_t driver_frequency(hertz p_frequency) = 0; + virtual duty_cycle_t driver_duty_cycle(float p_duty_cycle) = 0; }; } // namespace hal diff --git a/include/libhal/rotation_sensor.hpp b/include/libhal/rotation_sensor.hpp index b62c4b061..d42d40fd8 100644 --- a/include/libhal/rotation_sensor.hpp +++ b/include/libhal/rotation_sensor.hpp @@ -14,7 +14,6 @@ #pragma once -#include "error.hpp" #include "units.hpp" namespace hal { @@ -94,9 +93,9 @@ class rotation_sensor /** * @brief Read the current angle measured by the device * - * @return result - rotation data + * @return read_t - rotation data */ - [[nodiscard]] result read() + [[nodiscard]] read_t read() { return driver_read(); } @@ -104,6 +103,6 @@ class rotation_sensor virtual ~rotation_sensor() = default; private: - virtual result driver_read() = 0; + virtual read_t driver_read() = 0; }; } // namespace hal diff --git a/include/libhal/serial.hpp b/include/libhal/serial.hpp index 23747dd98..0b80c8282 100644 --- a/include/libhal/serial.hpp +++ b/include/libhal/serial.hpp @@ -19,7 +19,6 @@ #include #include -#include "error.hpp" #include "units.hpp" namespace hal { @@ -182,10 +181,10 @@ class serial * fails, the state of the serial device has not changed. * * @param p_settings - settings to apply to serial driver - * @return status - success or failure - * @throws std::errc::invalid_argument if the settings could not be achieved + * @throws std::errc::invalid_argument if the settings could not be + * achieved */ - [[nodiscard]] status configure(const settings& p_settings) + void configure(const settings& p_settings) { return driver_configure(p_settings); } @@ -194,9 +193,9 @@ class serial * @brief Write data to the transmitter line of the serial port * * @param p_data - data to be transmitted over the serial port - * @return result - serial write response + * @return write_t - serial write response */ - [[nodiscard]] result write(std::span p_data) + write_t write(std::span p_data) { return driver_write(p_data); } @@ -225,11 +224,11 @@ class serial * parse it as needed. The choice of operation is application/driver specific. * * @param p_data - Buffer to read bytes in to - * @return result - serial read response data + * @return read_t - serial read response data * @throws std::errc::io_error - a frame error occurred at some point during * reception. */ - [[nodiscard]] result read(std::span p_data) + [[nodiscard]] read_t read(std::span p_data) { return driver_read(p_data); } @@ -243,9 +242,9 @@ class serial * - Use the fastest available option to perform these operations, meaning * that the contents of the internal working buffer will not be zeroed out. * - * @return result - success or failure + * @return flush_t - success or failure */ - [[nodiscard]] result flush() + flush_t flush() { return driver_flush(); } @@ -253,9 +252,9 @@ class serial virtual ~serial() = default; private: - virtual status driver_configure(const settings& p_settings) = 0; - virtual result driver_write(std::span p_data) = 0; - virtual result driver_read(std::span p_data) = 0; - virtual result driver_flush() = 0; + virtual void driver_configure(const settings& p_settings) = 0; + virtual write_t driver_write(std::span p_data) = 0; + virtual read_t driver_read(std::span p_data) = 0; + virtual flush_t driver_flush() = 0; }; } // namespace hal diff --git a/include/libhal/servo.hpp b/include/libhal/servo.hpp index 90b6f9c86..77dae628e 100644 --- a/include/libhal/servo.hpp +++ b/include/libhal/servo.hpp @@ -14,7 +14,6 @@ #pragma once -#include "error.hpp" #include "units.hpp" namespace hal { @@ -68,7 +67,7 @@ class servo * but is either intrinsic to the servo or a configuration of the servo. * * @param p_position - the position to move the servo shaft in degrees. - * @return result - success or failure + * @return position_t - success or failure * @throws std::errc::invalid_argument - when position exceeds the range of * the servo. When this error occurs, the guaranteed behavior is that the * servo keeps its last set position. @@ -77,7 +76,7 @@ class servo * this error occurs, the guaranteed behavior is that the servo keeps its last * set position. */ - [[nodiscard]] result position(hal::degrees p_position) + position_t position(hal::degrees p_position) { return driver_position(p_position); } @@ -85,6 +84,6 @@ class servo virtual ~servo() = default; private: - virtual result driver_position(hal::degrees p_position) = 0; + virtual position_t driver_position(hal::degrees p_position) = 0; }; } // namespace hal diff --git a/include/libhal/spi.hpp b/include/libhal/spi.hpp index a2429aac0..8a99ee579 100644 --- a/include/libhal/spi.hpp +++ b/include/libhal/spi.hpp @@ -18,7 +18,6 @@ #include #include -#include "error.hpp" #include "units.hpp" namespace hal { @@ -53,15 +52,6 @@ class spi bool data_valid_on_trailing_edge = false; }; - /** - * @brief Feedback from performing a transfer on the spi bus - * - * This structure is currently empty as no feedback has been determined for - * now. This structure may be expanded in the future. - */ - struct transfer_t - {}; - /// Default filler data placed on the bus in place of actual write data when /// the write buffer has been exhausted. static constexpr hal::byte default_filler = hal::byte{ 0xFF }; @@ -70,13 +60,14 @@ class spi * @brief Configure spi to match the settings supplied * * @param p_settings - settings to apply to spi - * @return status - success or failure - * @throws std::errc::invalid_argument if the settings could not be achieved. + * @throws std::errc::invalid_argument if the settings could not be + * achieved. */ - [[nodiscard]] status configure(const settings& p_settings) + void configure(const settings& p_settings) { return driver_configure(p_settings); } + /** * @brief Send and receive data between a selected device on the spi bus. * This function will block until the entire transfer is finished. @@ -92,12 +83,10 @@ class spi * dropped. * @param p_filler - filler data placed on the bus in place of actual write * data when p_data_out has been exhausted. - * @return result - success or failure */ - [[nodiscard]] result transfer( - std::span p_data_out, - std::span p_data_in, - hal::byte p_filler = default_filler) + void transfer(std::span p_data_out, + std::span p_data_in, + hal::byte p_filler = default_filler) { return driver_transfer(p_data_out, p_data_in, p_filler); } @@ -105,10 +94,9 @@ class spi virtual ~spi() = default; private: - virtual status driver_configure(const settings& p_settings) = 0; - virtual result driver_transfer( - std::span p_data_out, - std::span p_data_in, - hal::byte p_filler) = 0; + virtual void driver_configure(const settings& p_settings) = 0; + virtual void driver_transfer(std::span p_data_out, + std::span p_data_in, + hal::byte p_filler) = 0; }; } // namespace hal diff --git a/include/libhal/steady_clock.hpp b/include/libhal/steady_clock.hpp index 626b8dad9..ff698d063 100644 --- a/include/libhal/steady_clock.hpp +++ b/include/libhal/steady_clock.hpp @@ -16,7 +16,6 @@ #include -#include "error.hpp" #include "units.hpp" namespace hal { @@ -75,7 +74,7 @@ class steady_clock /** * @brief Get the operating frequency of the steady clock * - * @return result - operating frequency of the steady clock. + * @return frequency_t - operating frequency of the steady clock. * Guaranteed to be a positive value by the implementing driver. */ [[nodiscard]] frequency_t frequency() diff --git a/include/libhal/temperature_sensor.hpp b/include/libhal/temperature_sensor.hpp index 55baa53dd..646ebf550 100644 --- a/include/libhal/temperature_sensor.hpp +++ b/include/libhal/temperature_sensor.hpp @@ -14,7 +14,6 @@ #pragma once -#include "error.hpp" #include "units.hpp" namespace hal { @@ -42,9 +41,9 @@ class temperature_sensor /** * @brief Read the current temperature measured by the device * - * @return result - temperature data + * @return read_t - temperature data */ - [[nodiscard]] result read() + [[nodiscard]] read_t read() { return driver_read(); } @@ -52,6 +51,6 @@ class temperature_sensor virtual ~temperature_sensor() = default; private: - virtual result driver_read() = 0; + virtual read_t driver_read() = 0; }; } // namespace hal diff --git a/include/libhal/timeout.hpp b/include/libhal/timeout.hpp index ab29f599f..c9becda3a 100644 --- a/include/libhal/timeout.hpp +++ b/include/libhal/timeout.hpp @@ -20,7 +20,6 @@ */ #pragma once -#include "error.hpp" #include "functional.hpp" namespace hal { @@ -40,15 +39,16 @@ enum class work_state }; /** - * @brief Timeout is a callable object or function that signals to a procedure - * that the procedure has exceeded its time allotment and should return control - * to the calling function. + * @brief Signature of a function that throws std::errc::timed_out * - * @throws hal::timeout - when the timeout condition has been met. - * @returns status - sets error flag set when timeout - * condition has been met, otherwise returns success. + * A function that expires after a certain amount of time or after a certain + * amount of events, or after a specific event occurs. When called, this + * function checks if the expiration event has occurred and if so, throws the + * exception std::errc::timed_out. + * + * @throws std::errc::timed_out - to indicate that it has expired */ -using timeout_function = status(void); +using timeout_function = void(void); template concept timeout = std::convertible_to>; @@ -66,10 +66,9 @@ concept timeout = std::convertible_to>; * This function can be repeatedly tried until it has reached a terminal state * with the try_until() function. * - * @returns result - sets error flag set when an error occurs, - * otherwise returns work_state enum. + * @returns work_state - indicates what the state of the worker function is. */ -using work_function = result(); +using work_function = work_state(); template concept worker = std::convertible_to>; @@ -78,47 +77,35 @@ concept worker = std::convertible_to>; * @brief Delay the execution of the application or thread for a duration of * time. * - * @tparam Timeout - timeout type - * @param p_timeout - callable timeout object - * @return status - success or failure + * @param p_timeout - callable timeout object/function */ -[[nodiscard]] inline status delay(timeout auto p_timeout) +inline void delay(timeout auto p_timeout) { - bool waiting = true; - - // This lambda catches a `std::errc::timed_out` handle them by changing - // `waiting` from true to false in order to break the while loop below. - auto timeout_catcher = - [&waiting](hal::match p_errc) -> status { - (void)p_errc; - // Simply change the waiting bool - waiting = false; - // return successful - return {}; - }; - - HAL_CHECK(hal::attempt( - [&p_timeout]() -> status { - // Continuously call p_callback until it either returns - // `std::errc::timeout_out` - while (true) { - HAL_CHECK(p_timeout()); - } - // Unreachable! - return {}; - }, - timeout_catcher)); + try { + while (true) { + p_timeout(); + } + } catch (const std::errc& p_error) { + if (p_error != std::errc::timed_out) { + throw; + } + } - return {}; + while (true) { + // Does stuff ... + if (!p_timeout()) { + throw std::errc::timed_out; + } + } } /** * @brief Create a timeout that will never time out * - * @return auto - callable that will never return timeout + * @return auto - callable that will never timeout */ -[[nodiscard]] inline auto never_timeout() +inline auto never_timeout() { - return []() -> status { return {}; }; + return []() {}; } } // namespace hal diff --git a/include/libhal/timer.hpp b/include/libhal/timer.hpp index b2b12493b..e125c65d4 100644 --- a/include/libhal/timer.hpp +++ b/include/libhal/timer.hpp @@ -16,7 +16,6 @@ #include -#include "error.hpp" #include "functional.hpp" #include "units.hpp" @@ -90,9 +89,9 @@ class timer /** * @brief Determine if the timer is currently running * - * @return result - information about the timer + * @return is_running_t - information about the timer */ - [[nodiscard]] result is_running() + [[nodiscard]] is_running_t is_running() { return driver_is_running(); } @@ -107,9 +106,9 @@ class timer * schedule event expires, this function may not complete before the hardware * calls the callback. * - * @return result - success or failure + * @return cancel_t - success or failure */ - [[nodiscard]] result cancel() + cancel_t cancel() { return driver_cancel(); } @@ -130,13 +129,12 @@ class timer * * @param p_callback - callback function to be called when the timer expires * @param p_delay - the amount of time until the timer expires - * @return result - success or failure + * @return schedule_t - success or failure * @throws out_of_bounds_error - if p_interval is greater than what can be * cannot be achieved */ - [[nodiscard]] result schedule( - hal::callback p_callback, - hal::time_duration p_delay) + schedule_t schedule(hal::callback p_callback, + hal::time_duration p_delay) { return driver_schedule(p_callback, p_delay); } @@ -144,10 +142,9 @@ class timer virtual ~timer() = default; private: - virtual result driver_is_running() = 0; - virtual result driver_cancel() = 0; - virtual result driver_schedule( - hal::callback p_callback, - hal::time_duration p_delay) = 0; + virtual is_running_t driver_is_running() = 0; + virtual cancel_t driver_cancel() = 0; + virtual schedule_t driver_schedule(hal::callback p_callback, + hal::time_duration p_delay) = 0; }; } // namespace hal diff --git a/include/libhal/units.hpp b/include/libhal/units.hpp index e759cc49d..c0af73a24 100644 --- a/include/libhal/units.hpp +++ b/include/libhal/units.hpp @@ -17,8 +17,6 @@ #include #include -#include "error.hpp" - /** * @brief The foundation of libhal containing, interfaces, utilities and soft * drivers. diff --git a/test_package/main.cpp b/test_package/main.cpp index 793afac85..9459cba19 100644 --- a/test_package/main.cpp +++ b/test_package/main.cpp @@ -13,31 +13,33 @@ // limitations under the License. #include +#include +#include #include class test_pwm : public hal::pwm { private: - virtual hal::result driver_frequency(hal::hertz p_frequency) + hal::pwm::frequency_t driver_frequency(hal::hertz p_frequency) final { std::printf("frequency = %f Hz\n", p_frequency); - return frequency_t{}; + return {}; } - virtual hal::result driver_duty_cycle(float p_position) + hal::pwm::duty_cycle_t driver_duty_cycle(float p_position) final { - error_count_down--; - if (error_count_down == 0) { - return hal::new_error(std::errc::io_error); + m_error_count_down--; + if (m_error_count_down == 0) { + hal::safe_throw(std::errc::io_error); } std::printf("duty cycle = %f %%\n", p_position); - return duty_cycle_t{}; + return {}; } - int error_count_down = 2; + int m_error_count_down = 2; }; int main() @@ -47,26 +49,19 @@ int main() int status = 0; test_pwm pwm; - hal::attempt_all( - [&pwm]() -> hal::status { - HAL_CHECK(pwm.frequency(10.0_kHz)); - - HAL_CHECK(pwm.duty_cycle(0.25)); - HAL_CHECK(pwm.duty_cycle(0.50)); - HAL_CHECK(pwm.duty_cycle(-0.25)); - HAL_CHECK(pwm.duty_cycle(-1.0)); - - return hal::success(); - }, - [](std::errc p_errc) { - std::printf("Caught error successfully!\n"); - std::printf(" Error value: %s\n", - std::strerror(static_cast(p_errc))); - }, - [&status]() { - std::printf("Unknown error!\n"); - status = -1; - }); + try { + pwm.frequency(10.0_kHz); + pwm.duty_cycle(0.25); + pwm.duty_cycle(0.50); + pwm.duty_cycle(-0.25); + pwm.duty_cycle(-1.0); + } catch (std::errc p_errc) { + std::printf("Caught error successfully!\n"); + std::printf(" Error value: %d\n", static_cast(p_errc)); + } catch (...) { + std::printf("Unknown error!\n"); + status = -1; + } return status; } diff --git a/tests/adc.test.cpp b/tests/adc.test.cpp index 04462f985..22e84dc17 100644 --- a/tests/adc.test.cpp +++ b/tests/adc.test.cpp @@ -13,6 +13,7 @@ // limitations under the License. #include +#include #include @@ -24,16 +25,11 @@ class test_adc : public hal::adc { public: constexpr static float m_returned_position{ 0.5f }; - bool m_return_error_status{ false }; - ~test_adc() override = default; private: - result driver_read() override + read_t driver_read() override { - if (m_return_error_status) { - return hal::new_error(); - } return read_t{ .sample = m_returned_position }; } }; @@ -50,20 +46,7 @@ void adc_test() auto result = test.read(); // Verify - expect(bool{ result }); - expect(that % expected_value == result.value().sample); - }; - - "adc errors test"_test = []() { - // Setup - test_adc test; - test.m_return_error_status = true; - - // Exercise - auto result = test.read(); - - // Verify - expect(!bool{ result }); + expect(that % expected_value == result.sample); }; } } // namespace hal diff --git a/tests/can.test.cpp b/tests/can.test.cpp index 9d954fca8..09e728a93 100644 --- a/tests/can.test.cpp +++ b/tests/can.test.cpp @@ -13,6 +13,7 @@ // limitations under the License. #include +#include #include @@ -34,35 +35,23 @@ class test_can : public hal::can settings m_settings{}; message_t m_message{}; hal::callback m_handler = [](const message_t&) {}; - bool m_return_error_status{ false }; bool m_bus_on_called{ false }; ~test_can() override = default; private: - status driver_configure(const settings& p_settings) override + void driver_configure(const settings& p_settings) override { m_settings = p_settings; - if (m_return_error_status) { - return hal::new_error(); - } - return success(); }; - status driver_bus_on() override + void driver_bus_on() override { m_bus_on_called = true; - if (m_return_error_status) { - return hal::new_error(); - } - return success(); } - result driver_send(const message_t& p_message) override + send_t driver_send(const message_t& p_message) override { m_message = p_message; - if (m_return_error_status) { - return hal::new_error(); - } return send_t{}; }; @@ -82,31 +71,15 @@ void can_test() test_can test; // Exercise - auto result1 = test.configure(expected_settings); - auto result2 = test.send(expected_message); + test.configure(expected_settings); + test.send(expected_message); test.on_receive(expected_handler); test.m_handler(expected_message); // Verify - expect(bool{ result1 }); - expect(bool{ result2 }); expect(that % expected_settings.baud_rate == test.m_settings.baud_rate); expect(that % expected_message.id == test.m_message.id); expect(that % 1 == counter); }; - - "can errors test"_test = []() { - // Setup - test_can test; - test.m_return_error_status = true; - - // Exercise - auto result1 = test.configure(expected_settings); - auto result2 = test.send(expected_message); - - // Verify - expect(!bool{ result1 }); - expect(!bool{ result2 }); - }; }; } // namespace hal diff --git a/tests/conanfile.py b/tests/conanfile.py deleted file mode 100644 index 0fbf35737..000000000 --- a/tests/conanfile.py +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/python -# -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from conan import ConanFile -from conan.tools.build import cross_building -from conan.tools.cmake import CMake, cmake_layout -import os - - -class TestConan(ConanFile): - settings = "os", "arch", "compiler", "build_type" - generators = "CMakeToolchain", "CMakeDeps", "VirtualBuildEnv" - - def requirements(self): - self.requires(self.tested_reference_str) - self.test_requires("boost-ext-ut/1.1.9") - - def layout(self): - cmake_layout(self) - - def build(self): - cmake = CMake(self) - if self.settings.os == "Windows": - cmake.configure() - else: - cmake.configure(variables={"ENABLE_ASAN": True}) - cmake.build() - - def test(self): - if not cross_building(self): - bin_path = os.path.join(self.cpp.build.bindirs[0], "unit_test") - self.run(bin_path, env="conanrun") diff --git a/tests/dac.test.cpp b/tests/dac.test.cpp index 7350f9e34..d2540f0ee 100644 --- a/tests/dac.test.cpp +++ b/tests/dac.test.cpp @@ -13,6 +13,7 @@ // limitations under the License. #include +#include #include @@ -23,17 +24,12 @@ class test_dac : public hal::dac { public: float m_passed_value{}; - bool m_return_error_status{ false }; - ~test_dac() override = default; private: - result driver_write(float p_value) override + write_t driver_write(float p_value) override { m_passed_value = p_value; - if (m_return_error_status) { - return hal::new_error(); - } return write_t{}; } }; @@ -49,23 +45,10 @@ void dac_test() test_dac test; // Exercise - auto result = test.write(expected_value); + test.write(expected_value); // Verify - expect(bool{ result }); expect(that % expected_value == test.m_passed_value); }; - - "dac errors test"_test = []() { - // Setup - test_dac test; - test.m_return_error_status = true; - - // Exercise - auto result = test.write(expected_value); - - // Verify - expect(!bool{ result }); - }; }; } // namespace hal diff --git a/tests/error.test.cpp b/tests/error.test.cpp index 38177e629..24b69ee6c 100644 --- a/tests/error.test.cpp +++ b/tests/error.test.cpp @@ -12,66 +12,140 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include - +#include #include +#include +#include + #include namespace hal { -namespace { -int callback_call_count = 0; +struct uuid_t +{ + std::array uuid{}; +}; + +consteval uuid_t to_uuid([[maybe_unused]] const std::string_view p_str) +{ + return uuid_t{}; } + +struct error_metadata_t +{ + // 2 bits of info + // Maybe these should be different types of error_t rather than metadata + enum class classification : uint8_t + { + transient, + recoverable, + fatal, + }; + + enum class recovery_hint : uint8_t + { + retry, + reset_hardware, + change_configuration, + }; + + enum class source : uint8_t + { + function, + peripheral, + device, + soft, + application, + }; + + std::uint64_t raw{}; +}; + +struct message_id_t +{ + std::uint16_t raw{}; + std::array additional_data{}; +}; + +struct header_t +{ + std::array header{ 'L', 'I', 'B', 'H', 'A', 'L', 'E', 'X' }; +}; + +struct error_t +{ + header_t header{}; + uuid_t uuid{}; + void* driver_instance{}; + error_metadata_t metadata{}; + std::errc error_code{}; + std::optional message_id{}; + + static constexpr size_t uuid_size = sizeof(uuid); + static constexpr size_t metadata_size = sizeof(metadata); + static constexpr size_t error_code_size = sizeof(error_code); + static constexpr size_t message_id_size = sizeof(message_id); +}; + +[[maybe_unused]] constexpr size_t error_size = sizeof(error_t); + void error_test() { using namespace boost::ut; - on_error_callback = []() { callback_call_count++; }; - - "[success] hal::on_error calls callback"_test = []() { + "[success] hal::safe_throw"_test = []() { // Setup - auto current_call_count = callback_call_count; - expect(that % current_call_count == callback_call_count); + bool exception_thrown = false; - // Exercise - // Should call the `on_error_callback` defined in the tweaks file - (void)new_error(); - - // Verify - expect(that % current_call_count < callback_call_count); + try { + hal::safe_throw(5); + } catch (int) { + exception_thrown = true; + } + expect(exception_thrown); }; - "[success] hal::attempt calls handler"_test = []() { + "[success] hal::safe_throw"_test = []() { // Setup - static const int expected = 123456789; - int value_to_be_change = 0; - - // Exercise - // Should call the `on_error_callback` defined in the tweaks file - auto result = attempt([]() -> status { return new_error(expected); }, - [&value_to_be_change](int p_handler_value) -> status { - value_to_be_change = p_handler_value; - return {}; - }); - - // Verify - expect(that % value_to_be_change == expected); - expect(that % true == bool{ result }); + bool exception_thrown = false; + + struct pod_t + { + float value; + }; + + try { + hal::safe_throw(pod_t{ .value = 5.0f }); + } catch (pod_t) { + exception_thrown = true; + } + + expect(exception_thrown); }; - "[success] hal::attempt calls handler"_test = []() { +#define TEST_COMPILE_TIME_FAILURE 0 +#if TEST_COMPILE_TIME_FAILURE + "[success] hal::safe_throw(non-trivial-dtor)"_test = []() { // Setup - constexpr int expected = 123456789; - int value_to_be_change = 0; + bool exception_thrown = false; - // Exercise - // Should call the `on_error_callback` defined in the tweaks file + struct dtor_t + { + float value; + ~dtor_t() + { + value = 0; + } + }; - attempt_all([]() -> status { return new_error(); }, - [&value_to_be_change]() { value_to_be_change = expected; }); + try { + hal::safe_throw(dtor_t{ .value = 5.0f }); + } catch (dtor_t) { + exception_thrown = true; + } - // Verify - expect(that % value_to_be_change == expected); + expect(exception_thrown); }; +#endif }; } // namespace hal diff --git a/tests/g_force.test.cpp b/tests/g_force.test.cpp index b91e59857..a8a335d3e 100644 --- a/tests/g_force.test.cpp +++ b/tests/g_force.test.cpp @@ -14,6 +14,7 @@ #include "helpers.hpp" +#include #include #include @@ -46,10 +47,11 @@ void g_force_test() g_force g_force_difference = 1.0_g - 1.5_g; // Verify - expect(that % compare_floats(earth_g_force, g_force_quotient)); - expect(that % compare_floats(static_cast(3.0_g), g_force_product)); - expect(that % compare_floats(2.5_g, g_force_sum)); - expect(that % compare_floats(-0.5_g, g_force_difference)); + expect(that % + compare_floats({ .a = earth_g_force, .b = g_force_quotient })); + expect(that % compare_floats({ .a = 3.0_g, .b = g_force_product })); + expect(that % compare_floats({ .a = 2.5_g, .b = g_force_sum })); + expect(that % compare_floats({ .a = -0.5_g, .b = g_force_difference })); }; "g_force_type boundry test"_test = []() { @@ -62,8 +64,10 @@ void g_force_test() float float_min = std::numeric_limits::min(); // Verify - expect(that % compare_floats(float_max, static_cast(g_force_max))); - expect(that % compare_floats(float_min, static_cast(g_force_min))); + expect(that % compare_floats( + { .a = float_max, .b = static_cast(g_force_max) })); + expect(that % compare_floats( + { .a = float_min, .b = static_cast(g_force_min) })); }; } diff --git a/tests/helpers.cpp b/tests/helpers.cpp index 3de15cc1d..656658636 100644 --- a/tests/helpers.cpp +++ b/tests/helpers.cpp @@ -1,9 +1,9 @@ +#include + #include "helpers.hpp" -bool compare_floats(float p_first, // NOLINT - float p_second, // NOLINT - float p_error_margin) // NOLINT +bool compare_floats(compare_float_t p_compare) { - float difference = std::abs(p_first - p_second); - return difference < p_error_margin; + float difference = std::abs(p_compare.a - p_compare.b); + return difference < p_compare.margin; } \ No newline at end of file diff --git a/tests/helpers.hpp b/tests/helpers.hpp index a2fc64271..4b0ec31f7 100644 --- a/tests/helpers.hpp +++ b/tests/helpers.hpp @@ -16,6 +16,13 @@ #include +struct compare_float_t +{ + float a; + float b; + float margin = 0.0001f; +}; + /** * @brief Compares two single floating point values, with in a given error * margin. @@ -25,6 +32,4 @@ * @param p_error_margin How precise the error of an error should be checked. * @return true if the two floats are equal within a margin of error */ -bool compare_floats(float p_first, - float p_second, - float p_error_margin = 0.0001f); \ No newline at end of file +bool compare_floats(compare_float_t p_compare); \ No newline at end of file diff --git a/tests/i2c.test.cpp b/tests/i2c.test.cpp index ab15e881a..53641d3e7 100644 --- a/tests/i2c.test.cpp +++ b/tests/i2c.test.cpp @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include @@ -24,9 +25,7 @@ constexpr hal::i2c::settings expected_settings{ .clock_rate = 1.0_Hz }; constexpr hal::byte expected_address{ 100 }; constexpr std::array expected_data_out{ 'a', 'b' }; std::array expected_data_in{ '1', '2' }; -const hal::function_ref expected_timeout = []() { - return success(); -}; +const hal::function_ref expected_timeout = []() {}; class test_i2c : public hal::i2c { @@ -35,36 +34,28 @@ class test_i2c : public hal::i2c hal::byte m_address{}; std::span m_data_out{}; std::span m_data_in{}; - bool m_return_error_status{ false }; - std::function m_timeout = []() -> hal::status { - return hal::success(); - }; + std::function m_timeout = []() {}; ~test_i2c() override = default; private: - status driver_configure(const settings& p_settings) override + void driver_configure(const settings& p_settings) override { m_settings = p_settings; - if (m_return_error_status) { - return hal::new_error(); - } - return success(); + return; }; - result driver_transaction( + transaction_t driver_transaction( hal::byte p_address, std::span p_data_out, std::span p_data_in, hal::function_ref p_timeout) override { - HAL_CHECK(p_timeout()); + p_timeout(); m_address = p_address; m_data_out = p_data_out; m_data_in = p_data_in; m_timeout = p_timeout; - if (m_return_error_status) { - return hal::new_error(); - } + return transaction_t{}; }; }; @@ -78,32 +69,15 @@ void i2c_test() test_i2c test; // Exercise - auto result1 = test.configure(expected_settings); - auto result2 = test.transaction( + test.configure(expected_settings); + test.transaction( expected_address, expected_data_out, expected_data_in, expected_timeout); // Verify - expect(bool{ result1 }); - expect(bool{ result2 }); expect(that % expected_settings.clock_rate == test.m_settings.clock_rate); expect(that % expected_address == test.m_address); expect(that % expected_data_out.data() == test.m_data_out.data()); expect(that % expected_data_in.data() == test.m_data_in.data()); }; - - "i2c errors test"_test = []() { - // Setup - test_i2c test; - test.m_return_error_status = true; - - // Exercise - auto result1 = test.configure(expected_settings); - auto result2 = test.transaction( - expected_address, expected_data_out, expected_data_in, expected_timeout); - - // Verify - expect(!bool{ result1 }); - expect(!bool{ result2 }); - }; }; } // namespace hal diff --git a/tests/input_pin.test.cpp b/tests/input_pin.test.cpp index b739af18e..e8a2e2bd3 100644 --- a/tests/input_pin.test.cpp +++ b/tests/input_pin.test.cpp @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include @@ -25,24 +26,15 @@ class test_input_pin : public hal::input_pin { public: settings m_settings{}; - bool m_return_error_status{ false }; - ~test_input_pin() override = default; private: - status driver_configure(const settings& p_settings) override + void driver_configure(const settings& p_settings) override { m_settings = p_settings; - if (m_return_error_status) { - return hal::new_error(); - } - return success(); } - result driver_level() override + level_t driver_level() override { - if (m_return_error_status) { - return hal::new_error(); - } return level_t{ .state = true }; } }; @@ -56,28 +48,12 @@ void input_pin_test() test_input_pin test; // Exercise - auto result1 = test.configure(expected_settings); - auto result2 = test.level(); + test.configure(expected_settings); + auto level = test.level(); // Verify - expect(bool{ result1 }); - expect(bool{ result2 }); expect(expected_settings.resistor == test.m_settings.resistor); - expect(that % true == result2.value().state); - }; - - "input_pin errors test"_test = []() { - // Setup - test_input_pin test; - test.m_return_error_status = true; - - // Exercise - auto result1 = test.configure(expected_settings); - auto result2 = test.level(); - - // Verify - expect(!bool{ result1 }); - expect(!bool{ result2 }); + expect(that % true == level.state); }; }; } // namespace hal diff --git a/tests/interrupt_pin.test.cpp b/tests/interrupt_pin.test.cpp index 0a123359f..dbaebe6c6 100644 --- a/tests/interrupt_pin.test.cpp +++ b/tests/interrupt_pin.test.cpp @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include @@ -30,16 +31,11 @@ class test_interrupt_pin : public hal::interrupt_pin public: settings m_settings{}; std::function m_callback = [](bool) {}; - bool m_return_error_status{ false }; private: - status driver_configure(const settings& p_settings) override + void driver_configure(const settings& p_settings) override { m_settings = p_settings; - if (m_return_error_status) { - return hal::new_error(); - } - return success(); }; void driver_on_trigger(hal::callback p_callback) override { @@ -58,27 +54,14 @@ void interrupt_pin_test() auto expected_callback = [&counter](bool) { counter++; }; // Exercise - auto result = test.configure(expected_settings); + test.configure(expected_settings); test.on_trigger(expected_callback); test.m_callback(false); // Verify - expect(bool{ result }); expect(expected_settings.resistor == test.m_settings.resistor); expect(expected_settings.trigger == test.m_settings.trigger); expect(that % 1 == counter); }; - - "interrupt_pin errors test"_test = []() { - // Setup - test_interrupt_pin test; - test.m_return_error_status = true; - - // Exercise - auto result = test.configure(expected_settings); - - // Verify - expect(!bool{ result }); - }; }; } // namespace hal diff --git a/tests/lengths.test.cpp b/tests/lengths.test.cpp index 6004afd93..4d5e2a22c 100644 --- a/tests/lengths.test.cpp +++ b/tests/lengths.test.cpp @@ -33,16 +33,19 @@ void lengths_test() kilometer = 1.0_km, inch = 1.0_inch, yard = 1.0_yards, mile = 1.0_miles; - expect(that % compare_floats(micrometer, - static_cast(1.0f / std::micro::den))); - expect(that % compare_floats(millimeter, - static_cast(1.0f / std::milli::den))); - expect(that % compare_floats(meter, 1.0f)); - expect(that % compare_floats(kilometer, - static_cast(1.0f * std::kilo::num))); - expect(that % compare_floats(inch, meters_in_inches)); - expect(that % compare_floats(yard, meters_in_yards)); - expect(that % compare_floats(mile, meters_in_miles)); + expect(that % + compare_floats({ .a = micrometer, + .b = static_cast(1.0f / std::micro::den) })); + expect(that % + compare_floats({ .a = millimeter, + .b = static_cast(1.0f / std::milli::den) })); + expect(that % compare_floats({ .a = meter, .b = 1.0f })); + expect(that % + compare_floats({ .a = kilometer, + .b = static_cast(1.0f * std::kilo::num) })); + expect(that % compare_floats({ .a = inch, .b = meters_in_inches })); + expect(that % compare_floats({ .a = yard, .b = meters_in_yards })); + expect(that % compare_floats({ .a = mile, .b = meters_in_miles })); }; // ensuring that when you overwrite another UDL of type Lengths @@ -52,127 +55,127 @@ void lengths_test() kilometer = 1.0_km, inch = 1.0_inch, yard = 1.0_yards, mile = 1.0_miles; meter = micrometer; - expect(that % compare_floats(meter, micrometer)); + expect(that % compare_floats({ .a = meter, .b = micrometer })); meter = millimeter; - expect(that % compare_floats(meter, millimeter)); + expect(that % compare_floats({ .a = meter, .b = millimeter })); meter = kilometer; - expect(that % compare_floats(meter, kilometer)); + expect(that % compare_floats({ .a = meter, .b = kilometer })); meter = inch; - expect(that % compare_floats(meter, inch)); + expect(that % compare_floats({ .a = meter, .b = inch })); meter = yard; - expect(that % compare_floats(meter, yard)); + expect(that % compare_floats({ .a = meter, .b = yard })); meter = mile; - expect(that % compare_floats(meter, mile)); + expect(that % compare_floats({ .a = meter, .b = mile })); }; // ensures that all micrometer math operators work "Lengths_Type Micrometer_Calculation Test"_test = []() { meters micrometer_result = 1.0_um * 1000.0f; - expect(that % compare_floats(micrometer_result, 1.0_mm)); + expect(that % compare_floats({ .a = micrometer_result, .b = 1.0_mm })); micrometer_result /= 1000.0f; - expect(that % compare_floats(micrometer_result, 1.0_um)); + expect(that % compare_floats({ .a = micrometer_result, .b = 1.0_um })); micrometer_result = 1.0_um + 1.0_um; - expect(that % compare_floats(micrometer_result, 2.0_um)); + expect(that % compare_floats({ .a = micrometer_result, .b = 2.0_um })); micrometer_result -= 1.0_um; - expect(that % compare_floats(micrometer_result, 1.0_um)); + expect(that % compare_floats({ .a = micrometer_result, .b = 1.0_um })); }; // ensures that all millimeter math operators work "Lengths_Type Millimeter_Calculation Test"_test = []() { meters millimeter_result = 1.0_mm * 1000.0f; - expect(that % compare_floats(millimeter_result, 1.0_m)); + expect(that % compare_floats({ .a = millimeter_result, .b = 1.0_m })); millimeter_result /= 1000.0f; - expect(that % compare_floats(millimeter_result, 1.0_mm)); + expect(that % compare_floats({ .a = millimeter_result, .b = 1.0_mm })); millimeter_result = 1.0_mm + 1.0_mm; - expect(that % compare_floats(millimeter_result, 2.0_mm)); + expect(that % compare_floats({ .a = millimeter_result, .b = 2.0_mm })); millimeter_result -= 1.0_mm; - expect(that % compare_floats(millimeter_result, 1.0_mm)); + expect(that % compare_floats({ .a = millimeter_result, .b = 1.0_mm })); }; // ensures that all meter math operators work "Lengths_Type Meter_Calculation Test"_test = []() { meters meter_result = 1.0_m * 1000.0f; - expect(that % compare_floats(meter_result, 1.0_km)); + expect(that % compare_floats({ .a = meter_result, .b = 1.0_km })); meter_result /= 1000.0f; - expect(that % compare_floats(meter_result, 1.0_m)); + expect(that % compare_floats({ .a = meter_result, .b = 1.0_m })); meter_result = 1.0_m + 1.0_m; - expect(that % compare_floats(meter_result, 2.0_m)); + expect(that % compare_floats({ .a = meter_result, .b = 2.0_m })); meter_result -= 1.0_m; - expect(that % compare_floats(meter_result, 1.0_m)); + expect(that % compare_floats({ .a = meter_result, .b = 1.0_m })); }; // ensures that all kilometer math operators work "Lengths_Type Kilometer_Calculation Test"_test = []() { meters kilometer_result = 1.0_km * 1000.0f; - expect(that % compare_floats(kilometer_result, 1000.0_km)); + expect(that % compare_floats({ .a = kilometer_result, .b = 1000.0_km })); kilometer_result /= 1000.0f; - expect(that % compare_floats(kilometer_result, 1.0_km)); + expect(that % compare_floats({ .a = kilometer_result, .b = 1.0_km })); kilometer_result = 1.0_km + 1.0_km; - expect(that % compare_floats(kilometer_result, 2.0_km)); + expect(that % compare_floats({ .a = kilometer_result, .b = 2.0_km })); kilometer_result -= 1.0_km; - expect(that % compare_floats(kilometer_result, 1.0_km)); + expect(that % compare_floats({ .a = kilometer_result, .b = 1.0_km })); }; // ensures that all inch math operators work "Lengths_Type Inch_Calculation Test"_test = []() { meters inch_result = 1.0_inch * 1000.0f; - expect(that % compare_floats(inch_result, 1000.0_inch)); + expect(that % compare_floats({ .a = inch_result, .b = 1000.0_inch })); inch_result /= 1000.0f; - expect(that % compare_floats(inch_result, 1.0_inch)); + expect(that % compare_floats({ .a = inch_result, .b = 1.0_inch })); inch_result = 1.0_inch + 1.0_inch; - expect(that % compare_floats(inch_result, 2.0_inch)); + expect(that % compare_floats({ .a = inch_result, .b = 2.0_inch })); inch_result -= 1.0_inch; - expect(that % compare_floats(inch_result, 1.0_inch)); + expect(that % compare_floats({ .a = inch_result, .b = 1.0_inch })); }; // ensures that all yard math operators work "Lengths_Type Yards_Calculation Test"_test = []() { meters yard_result = 1.0_yards * 1000.0f; - expect(that % compare_floats(yard_result, 1000.0_yards)); + expect(that % compare_floats({ .a = yard_result, .b = 1000.0_yards })); yard_result /= 1000.0f; - expect(that % compare_floats(yard_result, 1.0_yards)); + expect(that % compare_floats({ .a = yard_result, .b = 1.0_yards })); yard_result = 1.0_yards + 1.0_yards; - expect(that % compare_floats(yard_result, 2.0_yards)); + expect(that % compare_floats({ .a = yard_result, .b = 2.0_yards })); yard_result -= 1.0_yards; - expect(that % compare_floats(yard_result, 1.0_yards)); + expect(that % compare_floats({ .a = yard_result, .b = 1.0_yards })); }; // ensures that all mile math operators work "Lengths_Type Miles_Calculation Test"_test = []() { meters mile_result = 1.0_miles * 1000.0f; - expect(that % compare_floats(mile_result, 1000.0_miles)); + expect(that % compare_floats({ .a = mile_result, .b = 1000.0_miles })); mile_result /= 1000.0f; - expect(that % compare_floats(mile_result, 1.0_miles)); + expect(that % compare_floats({ .a = mile_result, .b = 1.0_miles })); mile_result = 1.0_miles + 1.0_miles; - expect(that % compare_floats(mile_result, 2.0_miles)); + expect(that % compare_floats({ .a = mile_result, .b = 2.0_miles })); mile_result -= 1.0_miles; - expect(that % compare_floats(mile_result, 1.0_miles)); + expect(that % compare_floats({ .a = mile_result, .b = 1.0_miles })); }; } diff --git a/tests/motor.test.cpp b/tests/motor.test.cpp index a8da81510..f36067c71 100644 --- a/tests/motor.test.cpp +++ b/tests/motor.test.cpp @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include @@ -24,18 +25,13 @@ class test_motor : public hal::motor { public: float m_power{}; - bool m_return_error_status{ false }; - ~test_motor() override = default; private: - result driver_power(float power) override + power_t driver_power(float power) override { m_power = power; - if (m_return_error_status) { - return hal::new_error(); - } - return power_t{}; + return {}; }; }; } // namespace @@ -48,23 +44,10 @@ void motor_test() test_motor test; // Exercise - auto result = test.power(expected_value); + test.power(expected_value); // Verify - expect(bool{ result }); expect(that % expected_value == test.m_power); }; - - "motor errors test"_test = []() { - // Setup - test_motor test; - test.m_return_error_status = true; - - // Exercise - auto result = test.power(expected_value); - - // Verify - expect(!bool{ result }); - }; }; } // namespace hal \ No newline at end of file diff --git a/tests/output_pin.test.cpp b/tests/output_pin.test.cpp index a5e544442..2b265d87c 100644 --- a/tests/output_pin.test.cpp +++ b/tests/output_pin.test.cpp @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include @@ -27,34 +28,23 @@ class test_output_pin : public hal::output_pin public: settings m_settings{}; bool m_driver_level{}; - bool m_return_error_status{ false }; ~test_output_pin() override = default; private: - status driver_configure(const settings& p_settings) override + void driver_configure(const settings& p_settings) override { m_settings = p_settings; - if (m_return_error_status) { - return hal::new_error(); - } - return success(); - }; - result driver_level(bool p_high) override + } + set_level_t driver_level(bool p_high) override { m_driver_level = p_high; - if (m_return_error_status) { - return hal::new_error(); - } return set_level_t{}; - }; - result driver_level() override + } + level_t driver_level() override { - if (m_return_error_status) { - return hal::new_error(); - } return level_t{ .state = m_driver_level }; - }; + } }; } // namespace @@ -66,34 +56,15 @@ void output_pin_test() test_output_pin test; // Exercise - auto result1 = test.configure(expected_settings); - auto result2 = test.level(true); - auto result3 = test.level(); + test.configure(expected_settings); + test.level(true); + auto level = test.level(); // Verify - expect(bool{ result1 }); - expect(bool{ result2 }); - expect(bool{ result3 }); expect(expected_settings.open_drain == test.m_settings.open_drain); expect(expected_settings.resistor == test.m_settings.resistor); expect(that % true == test.m_driver_level); - expect(that % true == result3.value().state); - }; - - "output_pin errors test"_test = []() { - // Setup - test_output_pin test; - test.m_return_error_status = true; - - // Exercise - auto result1 = test.configure(expected_settings); - auto result2 = test.level(true); - auto result3 = test.level(); - - // Verify - expect(!bool{ result1 }); - expect(!bool{ result2 }); - expect(!bool{ result3 }); + expect(that % true == level.state); }; }; } // namespace hal diff --git a/tests/pwm.test.cpp b/tests/pwm.test.cpp index fd9888ed6..d75550d0f 100644 --- a/tests/pwm.test.cpp +++ b/tests/pwm.test.cpp @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include @@ -26,27 +27,19 @@ class test_pwm : public hal::pwm public: hertz m_frequency{}; float m_duty_cycle{}; - bool m_return_error_status{ false }; - ~test_pwm() override = default; private: - result driver_frequency(hertz p_frequency) override + frequency_t driver_frequency(hertz p_frequency) override { m_frequency = p_frequency; - if (m_return_error_status) { - return hal::new_error(); - } return frequency_t{}; - }; - result driver_duty_cycle(float p_duty_cycle) override + } + duty_cycle_t driver_duty_cycle(float p_duty_cycle) override { m_duty_cycle = p_duty_cycle; - if (m_return_error_status) { - return hal::new_error(); - } return duty_cycle_t{}; - }; + } }; } // namespace @@ -58,28 +51,12 @@ void pwm_test() test_pwm test; // Exercise - auto result1 = test.frequency(expected_frequency); - auto result2 = test.duty_cycle(expected_duty_cycle); + test.frequency(expected_frequency); + test.duty_cycle(expected_duty_cycle); // Verify - expect(bool{ result1 }); - expect(bool{ result2 }); expect(that % expected_frequency == test.m_frequency); expect(that % expected_duty_cycle == test.m_duty_cycle); }; - - "pwm errors test"_test = []() { - // Setup - test_pwm test; - test.m_return_error_status = true; - - // Exercise - auto result1 = test.frequency(expected_frequency); - auto result2 = test.duty_cycle(expected_duty_cycle); - - // Verify - expect(!bool{ result1 }); - expect(!bool{ result2 }); - }; }; } // namespace hal diff --git a/tests/serial.test.cpp b/tests/serial.test.cpp index ab842c2e8..a2d67b34e 100644 --- a/tests/serial.test.cpp +++ b/tests/serial.test.cpp @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include @@ -29,48 +30,33 @@ class test_serial : public hal::serial public: settings m_settings{}; bool m_flush_called{ false }; - bool m_return_error_status{ false }; - ~test_serial() override = default; private: - status driver_configure(const settings& p_settings) override + void driver_configure(const settings& p_settings) override { m_settings = p_settings; - if (m_return_error_status) { - return hal::new_error(); - } - return success(); - }; + } - result driver_write(std::span p_data) override + write_t driver_write(std::span p_data) override { - if (m_return_error_status) { - return hal::new_error(); - } return write_t{ p_data }; - }; + } - result driver_read(std::span p_data) override + read_t driver_read(std::span p_data) override { - if (m_return_error_status) { - return hal::new_error(); - } return read_t{ .data = p_data.subspan(0, 1), .available = 1, .capacity = 1, }; - }; + } - result driver_flush() override + flush_t driver_flush() override { m_flush_called = true; - if (m_return_error_status) { - return hal::new_error(); - } return flush_t{}; - }; + } }; } // namespace @@ -84,43 +70,19 @@ void serial_test() std::array expected_buffer{ '1', '2' }; // Exercise - auto result1 = test.configure(expected_settings); - auto result2 = test.write(expected_payload); - auto result3 = test.read(expected_buffer); - auto result4 = test.flush(); + test.configure(expected_settings); + auto write_info = test.write(expected_payload); + auto read_info = test.read(expected_buffer); + test.flush(); // Verify - expect(bool{ result1 }); - expect(bool{ result2 }); - expect(bool{ result3 }); - expect(bool{ result4 }); auto delta = expected_settings.baud_rate - test.m_settings.baud_rate; expect(that % 0.001f > std::abs(delta)); expect(expected_settings.stop == test.m_settings.stop); expect(expected_settings.parity == test.m_settings.parity); - expect(that % expected_payload.data() == result2.value().data.data()); - expect(that % expected_buffer.data() == result3.value().data.data()); + expect(that % expected_payload.data() == write_info.data.data()); + expect(that % expected_buffer.data() == read_info.data.data()); expect(true == test.m_flush_called); }; - - "serial errors test"_test = []() { - // Setup - test_serial test; - const std::array expected_payload{ 'a', 'b' }; - std::array expected_buffer{ '1', '2' }; - test.m_return_error_status = true; - - // Exercise - auto result1 = test.configure(expected_settings); - auto result2 = test.write(expected_payload); - auto result3 = test.read(expected_buffer); - auto result4 = test.flush(); - - // Verify - expect(!bool{ result1 }); - expect(!bool{ result2 }); - expect(!bool{ result3 }); - expect(!bool{ result4 }); - }; }; } // namespace hal diff --git a/tests/servo.test.cpp b/tests/servo.test.cpp index b6fdd64b8..10f551098 100644 --- a/tests/servo.test.cpp +++ b/tests/servo.test.cpp @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include @@ -19,32 +20,19 @@ namespace hal { namespace { constexpr auto expected_value = hal::degrees(45); -constexpr auto min_range = hal::degrees(-90); -constexpr auto max_range = hal::degrees(+90); class test_servo : public hal::servo { public: hal::degrees m_position = 0.0f; - ~test_servo() override = default; private: - result driver_position(hal::degrees p_position) override + position_t driver_position(hal::degrees p_position) override { - bool in_range = min_range < p_position && p_position < max_range; - if (!in_range) { - return hal::new_error(std::errc::invalid_argument, - hal::servo::range_error{ - .min = min_range, - .max = max_range, - }); - } - m_position = p_position; - - return position_t{}; - }; + return {}; + } }; } // namespace @@ -56,30 +44,10 @@ void servo_test() test_servo test; // Exercise - auto result = test.position(expected_value); + test.position(expected_value); // Verify - expect(bool{ result }); expect(that % expected_value == test.m_position); }; - - "servo errors test"_test = []() { - // Setup - test_servo test; - - // Exercise - hal::attempt_all( - [&test]() -> hal::status { - HAL_CHECK(test.position(max_range + 45.0f)); - return hal::new_error(); - }, - // Verify - [](std::errc p_error_code, hal::servo::range_error p_range_error) { - expect(std::errc::invalid_argument == p_error_code); - expect(that % min_range == p_range_error.min); - expect(that % max_range == p_range_error.max); - }, - []() { expect(false) << "None of the above errors were thrown!"; }); - }; }; } // namespace hal \ No newline at end of file diff --git a/tests/spi.test.cpp b/tests/spi.test.cpp index f4b51eb3e..010461640 100644 --- a/tests/spi.test.cpp +++ b/tests/spi.test.cpp @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include @@ -34,27 +35,19 @@ class test_spi : public hal::spi ~test_spi() override = default; private: - status driver_configure(const settings& p_settings) override + void driver_configure(const settings& p_settings) override { m_settings = p_settings; - if (m_return_error_status) { - return hal::new_error(); - } - return success(); - }; + } - result driver_transfer(std::span p_data_out, - std::span p_data_in, - hal::byte p_filler) override + void driver_transfer(std::span p_data_out, + std::span p_data_in, + hal::byte p_filler) override { m_data_out = p_data_out; m_data_in = p_data_in; m_filler = p_filler; - if (m_return_error_status) { - return hal::new_error(); - } - return transfer_t{}; - }; + } }; } // namespace @@ -69,32 +62,13 @@ void spi_test() const auto expected_filler = ' '; // Exercise - auto result1 = test.configure(expected_settings); - auto result2 = test.transfer(expected_out, expected_in, expected_filler); + test.configure(expected_settings); + test.transfer(expected_out, expected_in, expected_filler); // Verify - expect(bool{ result1 }); - expect(bool{ result2 }); expect(that % expected_out.data() == test.m_data_out.data()); expect(that % expected_in.data() == test.m_data_in.data()); expect(expected_filler == test.m_filler); }; - - "spi errors test"_test = []() { - // Setup - test_spi test; - const std::array expected_out{ 'a', 'b' }; - std::array expected_in{ '1', '2' }; - const auto expected_filler = ' '; - test.m_return_error_status = true; - - // Exercise - auto result1 = test.configure(expected_settings); - auto result2 = test.transfer(expected_out, expected_in, expected_filler); - - // Verify - expect(!bool{ result1 }); - expect(!bool{ result2 }); - }; }; } // namespace hal diff --git a/tests/steady_clock.test.cpp b/tests/steady_clock.test.cpp index 63e6e4c5a..35df7957b 100644 --- a/tests/steady_clock.test.cpp +++ b/tests/steady_clock.test.cpp @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include @@ -47,12 +48,12 @@ void steady_clock_test() test_steady_clock test; // Exercise - auto result1 = test.frequency(); - auto result2 = test.uptime(); + auto frequency = test.frequency(); + auto uptime = test.uptime(); // Verify - expect(that % test.m_frequency == result1.operating_frequency); - expect(that % test.m_uptime == result2.ticks); + expect(that % test.m_frequency == frequency.operating_frequency); + expect(that % test.m_uptime == uptime.ticks); }; }; } // namespace hal diff --git a/tests/timeout.test.cpp b/tests/timeout.test.cpp index 62903c054..c450b0892 100644 --- a/tests/timeout.test.cpp +++ b/tests/timeout.test.cpp @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include @@ -20,18 +21,19 @@ namespace hal { void timeout_test() { using namespace boost::ut; - +#if 0 "hal::delay(timeout)"_test = []() { // Setup constexpr int timeout_call_limit = 10; int counts = 0; - auto test_timeout_function = [&counts]() mutable -> status { + auto test_timeout_function = [&counts]() mutable -> bool { counts++; if (counts >= timeout_call_limit) { - return hal::new_error(std::errc::timed_out); + return true; } - return {}; + return false; }; + using timeout_type = decltype(test_timeout_function); // Exercise @@ -49,9 +51,7 @@ void timeout_test() "hal::delay(timeout) returns error"_test = []() { // Setup - auto test_timeout_function = []() mutable -> status { - return hal::new_error(); - }; + auto test_timeout_function = []() mutable -> status { hal::safe_throw(5); }; // Exercise auto result = hal::delay(test_timeout_function); @@ -59,5 +59,6 @@ void timeout_test() // Verify expect(!bool{ result }); }; +#endif }; } // namespace hal diff --git a/tests/timer.test.cpp b/tests/timer.test.cpp index aefef2b49..82ffdae61 100644 --- a/tests/timer.test.cpp +++ b/tests/timer.test.cpp @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include @@ -26,33 +27,25 @@ class test_timer : public hal::timer bool m_is_running{ false }; hal::callback m_callback = []() {}; hal::time_duration m_delay; - bool m_return_error_status{ false }; private: - result driver_is_running() override + is_running_t driver_is_running() override { - if (m_return_error_status) { - return hal::new_error(); - } return is_running_t{ .is_running = m_is_running }; }; - result driver_cancel() override + cancel_t driver_cancel() override { m_is_running = false; - if (m_return_error_status) { - return hal::new_error(); - } return cancel_t{}; }; - result driver_schedule(hal::callback p_callback, - hal::time_duration p_delay) override + + // NOLINTNEXTLINE + schedule_t driver_schedule(hal::callback p_callback, + hal::time_duration p_delay) override { m_is_running = true; m_callback = p_callback; m_delay = p_delay; - if (m_return_error_status) { - return hal::new_error(); - } return schedule_t{}; }; }; @@ -73,41 +66,19 @@ void timer_test() // Exercise + Verify auto result1 = test.is_running(); - expect(bool{ result1 }); - expect(that % false == result1.value().is_running); + expect(that % false == result1.is_running); - auto result2 = test.schedule(expected_callback, expected_delay); + test.schedule(expected_callback, expected_delay); result1 = test.is_running(); - expect(bool{ result1 }); - expect(bool{ result2 }); - expect(that % true == result1.value().is_running); + expect(that % true == result1.is_running); expect(expected_delay == test.m_delay); test.m_callback(); expect(that % true == callback_stored_successfully); - auto result3 = test.cancel(); + test.cancel(); result1 = test.is_running(); - expect(bool{ result1 }); - expect(bool{ result3 }); - expect(that % false == result1.value().is_running); - }; - "timer errors test"_test = []() { - // Setup - test_timer test; - const hal::function_ref expected_callback = []() {}; - const hal::time_duration expected_delay = {}; - test.m_return_error_status = true; - - // Exercise - auto result1 = test.is_running(); - auto result2 = test.schedule(expected_callback, expected_delay); - auto result3 = test.cancel(); - - // Verify - expect(!bool{ result1 }); - expect(!bool{ result2 }); - expect(!bool{ result3 }); + expect(that % false == result1.is_running); }; }; } // namespace hal