api: add test-harness feature

If enabled, the Schema type implements Eq and PartialEq for
testing the api macro better.

Note that these implementations don't make all too much
since since they also compare `dyn Fn` types which do not
implement Eq. Since they're also `&'static` they can't
really be runtime closures, so this should be fine, we know
they'll always point to some regular function.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
Wolfgang Bumiller 2020-01-08 10:22:41 +01:00
parent 08e1cf3c2f
commit b0ef405186
4 changed files with 80 additions and 0 deletions

View File

@ -28,3 +28,4 @@ lazy_static = "1.4"
default = [ "router", "cli" ]
router = [ "hyper", "tokio" ]
cli = [ "router", "hyper", "tokio" ]
test-harness = []

View File

@ -67,3 +67,13 @@ macro_rules! const_regex {
$crate::const_regex! { $($rest)* }
};
}
#[cfg(feature = "test-harness")]
impl Eq for ConstRegexPattern {}
#[cfg(feature = "test-harness")]
impl PartialEq for ConstRegexPattern {
fn eq(&self, rhs: &Self) -> bool {
self.regex_string == rhs.regex_string
}
}

View File

@ -124,6 +124,29 @@ pub enum ApiHandler {
AsyncHttp(ApiAsyncHttpHandlerFn),
}
#[cfg(feature = "test-harness")]
impl Eq for ApiHandler {}
#[cfg(feature = "test-harness")]
impl PartialEq for ApiHandler {
fn eq(&self, rhs: &Self) -> bool {
unsafe {
match (self, rhs) {
(ApiHandler::Sync(l), ApiHandler::Sync(r)) => {
core::mem::transmute::<_, usize>(l) == core::mem::transmute::<_, usize>(r)
}
(ApiHandler::Async(l), ApiHandler::Async(r)) => {
core::mem::transmute::<_, usize>(l) == core::mem::transmute::<_, usize>(r)
}
(ApiHandler::AsyncHttp(l), ApiHandler::AsyncHttp(r)) => {
core::mem::transmute::<_, usize>(l) == core::mem::transmute::<_, usize>(r)
}
_ => false,
}
}
}
}
/// Lookup table to child `Router`s
///
/// Stores a sorted list of `(name, router)` tuples:
@ -361,6 +384,7 @@ fn dummy_handler_fn(
const DUMMY_HANDLER: ApiHandler = ApiHandler::Sync(&dummy_handler_fn);
/// This struct defines synchronous API call which returns the restulkt as json `Value`
#[cfg_attr(feature = "test-harness", derive(Eq, PartialEq))]
pub struct ApiMethod {
/// The protected flag indicates that the provides function should be forwarded
/// to the deaemon running in priviledged mode.

View File

@ -65,6 +65,7 @@ impl fmt::Display for ParameterError {
/// Data type to describe boolean values
#[derive(Debug)]
#[cfg_attr(feature = "test-harness", derive(Eq, PartialEq))]
pub struct BooleanSchema {
pub description: &'static str,
/// Optional default value.
@ -91,6 +92,7 @@ impl BooleanSchema {
/// Data type to describe integer values.
#[derive(Debug)]
#[cfg_attr(feature = "test-harness", derive(Eq, PartialEq))]
pub struct IntegerSchema {
pub description: &'static str,
/// Optional minimum.
@ -221,8 +223,30 @@ impl NumberSchema {
}
}
#[cfg(feature = "test-harness")]
impl Eq for NumberSchema {}
#[cfg(feature = "test-harness")]
impl PartialEq for NumberSchema {
fn eq(&self, rhs: &Self) -> bool {
fn f64_eq(l: Option<f64>, r: Option<f64>) -> bool {
match (l, r) {
(None, None) => true,
(Some(l), Some(r)) => (l - r).abs() < 0.0001,
_ => false,
}
}
self.description == rhs.description
&& f64_eq(self.minimum, rhs.minimum)
&& f64_eq(self.maximum, rhs.maximum)
&& f64_eq(self.default, rhs.default)
}
}
/// Data type to describe string values.
#[derive(Debug)]
#[cfg_attr(feature = "test-harness", derive(Eq, PartialEq))]
pub struct StringSchema {
pub description: &'static str,
/// Optional default value.
@ -319,6 +343,7 @@ impl StringSchema {
/// All array elements are of the same type, as defined in the `items`
/// schema.
#[derive(Debug)]
#[cfg_attr(feature = "test-harness", derive(Eq, PartialEq))]
pub struct ArraySchema {
pub description: &'static str,
/// Element type schema.
@ -386,6 +411,7 @@ pub type SchemaPropertyMap = &'static [(&'static str, bool, &'static Schema)];
/// Data type to describe objects (maps).
#[derive(Debug)]
#[cfg_attr(feature = "test-harness", derive(Eq, PartialEq))]
pub struct ObjectSchema {
pub description: &'static str,
/// If set, allow additional properties which are not defined in
@ -464,6 +490,7 @@ impl ObjectSchema {
/// ).schema();
/// ```
#[derive(Debug)]
#[cfg_attr(feature = "test-harness", derive(Eq, PartialEq))]
pub enum Schema {
Null,
Boolean(BooleanSchema),
@ -556,6 +583,24 @@ impl std::fmt::Debug for ApiStringFormat {
}
}
#[cfg(feature = "test-harness")]
impl Eq for ApiStringFormat {}
#[cfg(feature = "test-harness")]
impl PartialEq for ApiStringFormat {
fn eq(&self, rhs: &Self) -> bool {
match (self, rhs) {
(ApiStringFormat::Enum(l), ApiStringFormat::Enum(r)) => l == r,
(ApiStringFormat::Pattern(l), ApiStringFormat::Pattern(r)) => l == r,
(ApiStringFormat::PropertyString(l), ApiStringFormat::PropertyString(r)) => l == r,
(ApiStringFormat::VerifyFn(l), ApiStringFormat::VerifyFn(r)) => {
(l as *const fn(&str) -> _ as usize) == (r as *const fn(&str) -> _ as usize)
}
(_, _) => false,
}
}
}
/// Helper function to parse boolean values
///
/// - true: `1 | on | yes | true`