Skip to content

Commit

Permalink
JSDocs, naming and types housekeeping
Browse files Browse the repository at this point in the history
  • Loading branch information
BowTiedRadone committed Jan 27, 2025
1 parent 9a9ff16 commit e19d170
Show file tree
Hide file tree
Showing 7 changed files with 203 additions and 161 deletions.
91 changes: 41 additions & 50 deletions citizen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,24 @@ import { initSimnet, Simnet } from "@hirosystems/clarinet-sdk";
import { EpochString } from "@hirosystems/clarinet-sdk-wasm";
import {
Batch,
ContractDeploymentProperties,
ContractsByEpoch,
SimnetPlan,
Transaction,
} from "./citizen.types";

/**
* Prepares the simnet environment and assures the target contract is treated
* as a first-class citizen, by combining it with its tests. This function
* handles:
* Prepares the simnet instance and assures the target contract's corresponding
* test contract is treated as a first-class citizen, relying on their
* concatenation. This function handles:
* - Contract sorting by epoch based on the deployment plan.
* - Combining the target contract with its tests and deploying all contracts
* to the simnet.
*
* @param manifestDir - The relative path to the manifest directory.
* @param sutContractName - The target contract name.
* @param manifestDir The relative path to the manifest directory.
* @param sutContractName The target contract name.
* @returns The initialized simnet instance with all contracts deployed, with
* the target contract treated as a first-class citizen.
* the test contract treated as a first-class citizen of the target contract.
*/
export const issueFirstClassCitizenship = async (
manifestDir: string,
Expand All @@ -46,8 +47,9 @@ export const issueFirstClassCitizenship = async (
await simnet.initEmptySession();

// Combine the target contract with its tests into a single contract. The
// resulting contract will replace the target contract in the simnet. This
// map stores the contract name and its corresponding source code.
// resulting contract will replace the target contract in the simnet.

/** The contract names mapped to the concatenated source code. */
const rendezvousSources = new Map(
[sutContractName]
.map((contractName) =>
Expand Down Expand Up @@ -75,7 +77,7 @@ export const issueFirstClassCitizenship = async (

/**
* Groups contracts by epoch from the simnet plan.
* @param simnetPlan - The simnet plan.
* @param simnetPlan The simnet plan.
* @returns A record of contracts grouped by epoch. The record key is the epoch
* string, and the value is an array of contracts. Each contract is represented
* as a record with the contract name as the key and a record containing the
Expand Down Expand Up @@ -110,33 +112,24 @@ export const groupContractsByEpochFromSimnetPlan = (
};

/**
* Deploy the contracts to the simnet in the correct order.
* Deploys the contracts to the simnet in the correct order.
* @param simnet The simnet instance.
* @param contractsByEpoch - The record of contracts by epoch.
* @param getContractSourceFn - The function to retrieve the contract source.
* @param contractsByEpoch The record of contracts by epoch.
* @param getContractSourceFn The function to retrieve the contract source.
*/
const deployContracts = async (
simnet: Simnet,
contractsByEpoch: Record<
EpochString,
Record<string, { path: string; clarity_version: 1 | 2 | 3 }>[]
>,
contractsByEpoch: ContractsByEpoch,
getContractSourceFn: (
name: string,
props: {
path: string;
clarity_version: 1 | 2 | 3;
}
props: ContractDeploymentProperties
) => string
): Promise<void> => {
for (const [epoch, contracts] of Object.entries(contractsByEpoch)) {
// Move to the next epoch and deploy the contracts in the correct order.
simnet.setEpoch(epoch as EpochString);
for (const contract of contracts.flatMap(Object.entries)) {
const [name, props]: [
string,
{ path: string; clarity_version: 1 | 2 | 3 }
] = contract;
const [name, props]: [string, ContractDeploymentProperties] = contract;

const source = getContractSourceFn(name, props);

Expand All @@ -158,27 +151,25 @@ const deployContracts = async (
};

/**
* Conditionally retrieve the contract source based on whether the contract is
* Conditionally retrieves the contract source based on whether the contract is
* a SUT contract or not.
* @param sutContractNames - The list of SUT contract names.
* @param rendezvousMap - The rendezvous map.
* @param contractName - The contract name.
* @param contractProps - The contract properties.
* @param manifestDir - The relative path to the manifest directory.
* @returns The contract source.
* @param targetContractNames The list of target contract names.
* @param rendezvousSourcesMap The contract names mapped to the concatenated
* source code.
* @param contractName The contract name.
* @param contractProps The contract deployment properties.
* @param manifestDir The relative path to the manifest directory.
* @returns The contract source code.
*/
export const getContractSource = (
sutContractNames: string[],
rendezvousMap: Map<string, string>,
targetContractNames: string[],
rendezvousSourcesMap: Map<string, string>,
contractName: string,
contractProps: {
path: string;
clarity_version: 1 | 2 | 3;
},
contractProps: ContractDeploymentProperties,
manifestDir: string
): string => {
if (sutContractNames.includes(contractName)) {
const contractSource = rendezvousMap.get(contractName);
if (targetContractNames.includes(contractName)) {
const contractSource = rendezvousSourcesMap.get(contractName);
if (!contractSource) {
throw new Error(`Contract source not found for ${contractName}`);
}
Expand All @@ -191,11 +182,11 @@ export const getContractSource = (
};

/**
* Build the Rendezvous data.
* Builds the Rendezvous data.
* @param simnetPlan The parsed simnet plan.
* @param contractName The contract name.
* @param manifestDir The relative path to the manifest directory.
* @returns The Rendezvous data representing an object. The returned object
* @returns The Rendezvous data representing a record. The returned record
* contains the Rendezvous source code and the Rendezvous contract name.
*/
export const buildRendezvousData = (
Expand Down Expand Up @@ -233,7 +224,7 @@ export const buildRendezvousData = (
};

/**
* Get the contract source code from the simnet plan.
* Retrieves the contract source code using the simnet plan.
* @param simnetPlan The parsed simnet plan.
* @param manifestDir The relative path to the manifest directory.
* @param sutContractName The target contract name.
Expand Down Expand Up @@ -266,7 +257,7 @@ const getSimnetPlanContractSource = (
};

/**
* Get the test contract source code.
* Retrieves the test contract source code.
* @param simnetPlan The parsed simnet plan.
* @param sutContractName The target contract name.
* @param manifestDir The relative path to the manifest directory.
Expand Down Expand Up @@ -312,15 +303,15 @@ export const getTestContractSource = (
};

/**
* Schedule a Rendezvous between the System Under Test (`SUT`) and the
* invariants.
* @param sutContractSource The SUT contract source code.
* @param invariants The invariants contract source code.
* Schedules a Rendezvous between the System Under Test (`SUT`) and the test
* contract.
* @param targetContractSource The target contract source code.
* @param tests The corresponding test contract source code.
* @returns The Rendezvous source code.
*/
export function scheduleRendezvous(
sutContractSource: string,
invariants: string
targetContractSource: string,
tests: string
): string {
/**
* The `context` map tracks how many times each function has been called.
Expand All @@ -334,5 +325,5 @@ export function scheduleRendezvous(
(define-public (update-context (function-name (string-ascii 100)) (called uint))
(ok (map-set context function-name {called: called})))`;

return `${sutContractSource}\n\n${context}\n\n${invariants}`;
return `${targetContractSource}\n\n${context}\n\n${tests}`;
}
7 changes: 6 additions & 1 deletion citizen.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,10 @@ export type SimnetPlan = {

export type ContractsByEpoch = Record<
EpochString,
Record<string, { path: string; clarity_version: 1 | 2 | 3 }>[]
Record<string, ContractDeploymentProperties>[]
>;

export type ContractDeploymentProperties = {
path: string;
clarity_version: 1 | 2 | 3;
};
42 changes: 17 additions & 25 deletions heatstroke.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,24 @@
/**
* Heatstrokes Reporter
*
* This reporter integrates with `fast-check` to provide detailed and formatted
* outputs for failed property-based tests. It captures key information such as
* the contract, functions, arguments, outputs, and the specific invariant that
* failed, enabling quick identification of issues.
*/

/**
* Reports the details of a failed property-based test run.
*
* This function provides a detailed report when a fuzzing test fails including
* the contract, functions, arguments, outputs, and the specific invariant that
* failed.
*
* @param runDetails - The details of the test run provided by fast-check.
* @property runDetails.failed - Indicates if the property test failed.
* @property runDetails.counterexample - The input that caused the failure.
* @property runDetails.numRuns - The number of test cases that were run.
* @property runDetails.seed - The seed used to generate the test cases.
* @property runDetails.path - The path to reproduce the failing test.
* @property runDetails.error - The error thrown during the test.
*/

import { green } from "ansicolor";
import { EventEmitter } from "events";
import { getContractNameFromContractId } from "./shared";

/**
* Heatstrokes Reporter
*
* Provides a detailed report when a test run test ends. In case of failure,
* includes the contract, functions, arguments, outputs, and the specific
* invariant or property test that failed.
* @param runDetails The details of the test run provided by fast-check.
* @property `runDetails.failed`: Indicates if the test run failed.
* @property `runDetails.counterexample`: The input that caused the failure.
* @property `runDetails.numRuns`: The number of test cases that were run.
* @property `runDetails.seed`: The replay seed for reproducing the failure.
* @property `runDetails.path`: The replay path for reproducing the failure.
* @property `runDetails.error`: The error thrown during the test.
* @param radio The event emitter to log messages.
* @param type The type of test that failed: invariant or property.
* @returns void
*/
export function reporter(
//@ts-ignore
runDetails,
Expand Down
Loading

0 comments on commit e19d170

Please sign in to comment.