Skip to main content

ic_testkit/pic/
standalone.rs

1use candid::Principal;
2use pocket_ic::PocketIc;
3
4use super::{CanisterInstallExt, InstallSpec, PocketIcInstance, StandaloneCanisterInstallError};
5
6/// One caller-built PocketIC instance/server owner and one installed canister.
7///
8/// This fixture retains the instance and its optional managed server together.
9/// It does not impose process-wide synchronization or hide PocketIC methods.
10pub struct StandaloneCanisterFixture {
11    instance: PocketIcInstance<PocketIc>,
12    canister_id: Principal,
13}
14
15impl StandaloneCanisterFixture {
16    /// Install one canister into a caller-configured PocketIC instance.
17    ///
18    /// # Panics
19    ///
20    /// Panics with the contextual install error when installation fails.
21    #[must_use]
22    pub fn install(instance: PocketIcInstance<PocketIc>, spec: InstallSpec) -> Self {
23        Self::try_install(instance, spec)
24            .unwrap_or_else(|err| panic!("failed to install standalone canister fixture: {err}"))
25    }
26
27    /// Fallible counterpart to [`install`](Self::install).
28    ///
29    /// On failure, the error retains both the caller's instance/server ownership record and
30    /// the structured install failure.
31    pub fn try_install(
32        instance: PocketIcInstance<PocketIc>,
33        spec: InstallSpec,
34    ) -> Result<Self, StandaloneCanisterInstallError> {
35        let canister_id = match instance.instance.try_create_and_install(spec) {
36            Ok(canister_id) => canister_id,
37            Err(error) => return Err(StandaloneCanisterInstallError::new(instance, error)),
38        };
39
40        Ok(Self {
41            instance,
42            canister_id,
43        })
44    }
45
46    /// Borrow the PocketIC instance that owns this standalone fixture.
47    #[must_use]
48    pub const fn pocket_ic(&self) -> &PocketIc {
49        &self.instance.instance
50    }
51
52    /// Read the installed canister id for this standalone fixture.
53    #[must_use]
54    pub const fn canister_id(&self) -> Principal {
55        self.canister_id
56    }
57
58    /// Consume the fixture and return the instance/server ownership record and canister id.
59    pub fn into_parts(self) -> (PocketIcInstance<PocketIc>, Principal) {
60        (self.instance, self.canister_id)
61    }
62}