git-checks-config 0.2.2

Configuration parsing for checks.
Documentation
// Copyright Kitware, Inc.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use erased_serde::Deserializer;
use serde_json::json;

use crate::BranchCheckConfig;
use crate::CommitCheckConfig;
use crate::TopicCheckConfig;

mod checks {
    use git_checks_core::impl_prelude::*;
    use serde_derive::Deserialize;

    use crate::BranchCheckConfig;
    use crate::CommitCheckConfig;
    use crate::IntoCheck;
    use crate::TopicCheckConfig;

    #[derive(Debug)]
    pub struct MyCheck {}

    impl Check for MyCheck {
        fn name(&self) -> &str {
            "test-mycheck-commit"
        }

        fn check(&self, _: &CheckGitContext, _: &Commit) -> Result<CheckResult, Box<dyn Error>> {
            panic!("the dummy commit should not be run")
        }
    }

    impl BranchCheck for MyCheck {
        fn name(&self) -> &str {
            "test-mycheck-branch"
        }

        fn check(&self, _: &CheckGitContext, _: &CommitId) -> Result<CheckResult, Box<dyn Error>> {
            panic!("the dummy commit should not be run")
        }
    }

    impl TopicCheck for MyCheck {
        fn name(&self) -> &str {
            "test-mycheck-topic"
        }

        fn check(&self, _: &CheckGitContext, _: &Topic) -> Result<CheckResult, Box<dyn Error>> {
            panic!("the dummy commit should not be run")
        }
    }

    #[derive(Deserialize, Debug)]
    pub struct MyCheckConfig {}

    impl IntoCheck for MyCheckConfig {
        type Check = MyCheck;

        fn into_check(self) -> Self::Check {
            MyCheck {}
        }
    }

    register_checks! {
        MyCheckConfig {
            "mycheck/commit" => CommitCheckConfig,
            "mycheck/branch" => BranchCheckConfig,
            "mycheck/topic" => TopicCheckConfig,
        },
    }

    #[test]
    fn test_mycheck_name_commit() {
        let check = MyCheck {};
        assert_eq!(Check::name(&check), "test-mycheck-commit");
    }

    #[test]
    fn test_mycheck_name_branch() {
        let check = MyCheck {};
        assert_eq!(BranchCheck::name(&check), "test-mycheck-branch");
    }

    #[test]
    fn test_mycheck_name_topic() {
        let check = MyCheck {};
        assert_eq!(TopicCheck::name(&check), "test-mycheck-topic");
    }
}

#[test]
fn test_commit_registry() {
    assert_eq!(inventory::iter::<CommitCheckConfig>.into_iter().count(), 1);
}

#[test]
fn test_branch_registry() {
    assert_eq!(inventory::iter::<BranchCheckConfig>.into_iter().count(), 1);
}

#[test]
fn test_topic_registry() {
    assert_eq!(inventory::iter::<TopicCheckConfig>.into_iter().count(), 1);
}

#[test]
fn test_commit_check_name() {
    let config = inventory::iter::<CommitCheckConfig>
        .into_iter()
        .next()
        .unwrap();

    assert_eq!(config.name(), "mycheck/commit");
}

#[test]
fn test_branch_check_name() {
    let config = inventory::iter::<BranchCheckConfig>
        .into_iter()
        .next()
        .unwrap();

    assert_eq!(config.name(), "mycheck/branch");
}

#[test]
fn test_topic_check_name() {
    let config = inventory::iter::<TopicCheckConfig>
        .into_iter()
        .next()
        .unwrap();

    assert_eq!(config.name(), "mycheck/topic");
}

#[test]
fn test_commit_deserialize() {
    let config = inventory::iter::<CommitCheckConfig>
        .into_iter()
        .next()
        .unwrap();
    let mut data = <dyn Deserializer>::erase(json!({}));
    let _ = config.create(&mut data).unwrap();
}

#[test]
fn test_branch_deserialize() {
    let config = inventory::iter::<BranchCheckConfig>
        .into_iter()
        .next()
        .unwrap();
    let mut data = <dyn Deserializer>::erase(json!({}));
    let _ = config.create(&mut data).unwrap();
}

#[test]
fn test_topic_deserialize() {
    let config = inventory::iter::<TopicCheckConfig>
        .into_iter()
        .next()
        .unwrap();
    let mut data = <dyn Deserializer>::erase(json!({}));
    let _ = config.create(&mut data).unwrap();
}

#[test]
fn test_commit_deserialize_error() {
    let config = inventory::iter::<CommitCheckConfig>
        .into_iter()
        .next()
        .unwrap();
    let mut data = <dyn Deserializer>::erase(json!(null));
    let err = config.create(&mut data).unwrap_err();

    let err_msg = err.to_string();
    assert!(
        [
            "invalid type: null, expected struct MyCheckConfig",
            "invalid type: unit value, expected struct MyCheckConfig",
        ]
        .iter()
        .any(|&m| m == err_msg),
        "unexpected error text: {}",
        err_msg,
    );
}

#[test]
fn test_branch_deserialize_error() {
    let config = inventory::iter::<BranchCheckConfig>
        .into_iter()
        .next()
        .unwrap();
    let mut data = <dyn Deserializer>::erase(json!(null));
    let err = config.create(&mut data).unwrap_err();

    let err_msg = err.to_string();
    assert!(
        [
            "invalid type: null, expected struct MyCheckConfig",
            "invalid type: unit value, expected struct MyCheckConfig",
        ]
        .iter()
        .any(|&m| m == err_msg),
        "unexpected error text: {}",
        err_msg,
    );
}

#[test]
fn test_topic_deserialize_error() {
    let config = inventory::iter::<TopicCheckConfig>
        .into_iter()
        .next()
        .unwrap();
    let mut data = <dyn Deserializer>::erase(json!(null));
    let err = config.create(&mut data).unwrap_err();

    let err_msg = err.to_string();
    assert!(
        [
            "invalid type: null, expected struct MyCheckConfig",
            "invalid type: unit value, expected struct MyCheckConfig",
        ]
        .iter()
        .any(|&m| m == err_msg),
        "unexpected error text: {}",
        err_msg,
    );
}