Skip to main content

canic_testkit/
lib.rs

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