Skip to main content

copybook_governance_contracts/
lib.rs

1#![cfg_attr(not(test), deny(clippy::unwrap_used, clippy::expect_used))]
2// SPDX-License-Identifier: AGPL-3.0-or-later
3//! Contract façade for governance interoperability.
4//!
5//! This crate keeps the cross-cutting governance contract imports small and stable
6//! for downstream crates.
7
8/// Re-exported feature flag contract types.
9pub mod feature_flags {
10    pub use copybook_contracts::feature_flags::*;
11}
12
13/// Re-exported support matrix contract types.
14pub mod support_matrix {
15    pub use copybook_support_matrix::*;
16}
17
18pub use feature_flags::FeatureLifecycle;
19pub use feature_flags::{
20    Feature, FeatureCategory, FeatureFlags, FeatureFlagsBuilder, FeatureFlagsHandle,
21};
22pub use support_matrix::{
23    FeatureId, FeatureSupport, SupportStatus, all_features, find_feature, find_feature_by_id,
24};
25
26#[cfg(test)]
27#[allow(clippy::expect_used)]
28#[allow(clippy::unwrap_used)]
29mod tests {
30    use super::*;
31
32    #[test]
33    fn test_reexported_feature_flags_builder() {
34        let flags = FeatureFlags::builder()
35            .enable(Feature::Comp1)
36            .disable(Feature::LruCache)
37            .build();
38        assert!(flags.is_enabled(Feature::Comp1));
39        assert!(!flags.is_enabled(Feature::LruCache));
40    }
41
42    #[test]
43    fn test_reexported_feature_category() {
44        assert_eq!(Feature::Comp1.category(), FeatureCategory::Experimental);
45    }
46
47    #[test]
48    fn test_reexported_feature_lifecycle() {
49        // Ensure FeatureLifecycle is accessible through facade
50        let _ = FeatureLifecycle::Experimental;
51        let _ = FeatureLifecycle::Stable;
52        let _ = FeatureLifecycle::Deprecated;
53    }
54
55    #[test]
56    fn test_reexported_support_matrix_all_features() {
57        let features = all_features();
58        assert_eq!(features.len(), 7);
59    }
60
61    #[test]
62    fn test_reexported_find_feature_by_id() {
63        let f = find_feature_by_id(FeatureId::EditedPic);
64        assert!(f.is_some());
65        assert_eq!(f.unwrap().status, SupportStatus::Supported);
66    }
67
68    #[test]
69    fn test_reexported_find_feature_by_string() {
70        let f = find_feature("nested-odo");
71        assert!(f.is_some());
72        assert_eq!(f.unwrap().id, FeatureId::NestedOdo);
73    }
74
75    #[test]
76    fn test_feature_flags_default_has_expected_defaults() {
77        let flags = FeatureFlags::default();
78        assert!(flags.is_enabled(Feature::SignSeparate));
79        assert!(flags.is_enabled(Feature::Comp1));
80        assert!(flags.is_enabled(Feature::Comp2));
81        assert!(flags.is_enabled(Feature::LruCache));
82        assert!(!flags.is_enabled(Feature::AuditSystem));
83    }
84
85    #[test]
86    fn test_feature_flags_handle_via_facade() {
87        let handle = FeatureFlagsHandle::new();
88        handle.enable(Feature::Profiling);
89        assert!(handle.is_enabled(Feature::Profiling));
90        handle.toggle(Feature::Profiling);
91        assert!(!handle.is_enabled(Feature::Profiling));
92    }
93
94    #[test]
95    fn test_support_status_variants_accessible() {
96        let _ = SupportStatus::Supported;
97        let _ = SupportStatus::Partial;
98        let _ = SupportStatus::Planned;
99        let _ = SupportStatus::NotPlanned;
100    }
101
102    #[test]
103    fn test_find_feature_unknown_returns_none() {
104        assert!(find_feature("nonexistent").is_none());
105    }
106
107    #[test]
108    fn test_cross_module_feature_id_equality() {
109        let from_matrix = find_feature_by_id(FeatureId::Level88Conditions).unwrap();
110        let from_string = find_feature("level-88").unwrap();
111        assert_eq!(from_matrix.id, from_string.id);
112    }
113
114    #[test]
115    fn test_feature_flags_enable_disable_category_via_facade() {
116        let flags = FeatureFlags::builder()
117            .enable_category(FeatureCategory::Testing)
118            .build();
119        assert!(flags.is_enabled(Feature::MutationTesting));
120        assert!(flags.is_enabled(Feature::FuzzingIntegration));
121    }
122}