canic_testkit/
lib.rs

1//! Test utilities and fixtures for exercising Canic canisters.
2//!
3//! This crate is intended for host-side test environments (for example via
4//! PocketIC) and provides small helpers for generating stable dummy principals
5//! and accounts.
6
7pub mod pic;
8
9use canic::cdk::types::{Account, Principal};
10
11///
12/// Deterministic dummy-value generator for tests.
13///
14/// Produces stable principals/accounts derived from a numeric seed, which makes
15/// tests reproducible without hardcoding raw byte arrays.
16///
17
18pub struct Fake;
19
20impl Fake {
21    ///
22    /// Deterministically derive an [`Account`] from `seed`.
23    ///
24    #[must_use]
25    pub fn account(seed: u32) -> Account {
26        let mut sub = [0u8; 32];
27        let bytes = seed.to_be_bytes();
28        sub[..4].copy_from_slice(&bytes);
29
30        Account {
31            owner: Self::principal(seed),
32            subaccount: Some(sub),
33        }
34    }
35
36    ///
37    /// Deterministically derive a [`Principal`] from `seed`.
38    ///
39    #[must_use]
40    pub fn principal(seed: u32) -> Principal {
41        let mut buf = [0u8; 29];
42        buf[..4].copy_from_slice(&seed.to_be_bytes());
43
44        Principal::from_slice(&buf)
45    }
46}
47
48///
49/// TESTS
50///
51
52#[cfg(test)]
53mod tests {
54    use super::*;
55
56    #[test]
57    fn fake_account_is_deterministic_and_unique() {
58        let a1 = Fake::account(42);
59        let a2 = Fake::account(42);
60        let b = Fake::account(99);
61
62        // Deterministic: same seed => same account
63        assert_eq!(a1, a2, "Fake::account should be deterministic");
64
65        // Unique: different seeds => different account
66        assert_ne!(a1, b, "Fake::account should vary by seed");
67    }
68
69    #[test]
70    fn fake_principal_is_deterministic_and_unique() {
71        let p1 = Fake::principal(7);
72        let p2 = Fake::principal(7);
73        let q = Fake::principal(8);
74
75        assert_eq!(p1, p2, "Fake::principal should be deterministic");
76        assert_ne!(p1, q, "Fake::principal should differ for different seeds");
77
78        let bytes = p1.as_slice();
79        assert_eq!(bytes.len(), 29, "Principal must be 29 bytes");
80    }
81}