-
Notifications
You must be signed in to change notification settings - Fork 143
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: clarinet-sdk: vitest config and custom matchers (#1151)
* feat: vitest config and helpers for clarinet projects * feat: implement clarity value formatter * feat: improve and actually use cv formatter * chore: preparing for the release * feat: improve sdk tx handling for transfer stx and deploy contract * refactor: remove dead code * chore: upgrade dependencies * fix: parse json clarity args * refactor: self review * refactor: improve types * fix: remove pub function * chore: prep release * docs: typo Co-authored-by: Micaiah Reid <[email protected]> * docs: typo Co-authored-by: Micaiah Reid <[email protected]> * refactor: type * chore: upgrade dependencies * docs: update readme * chore: restore deleted deployment plans * docs: update sdk readme * fix: use the right packaged name * docs: update components/clarinet-sdk/README.md --------- Co-authored-by: Micaiah Reid <[email protected]>
- Loading branch information
1 parent
edf98aa
commit 0e4ec1e
Showing
26 changed files
with
3,559 additions
and
405 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,4 +14,4 @@ plan: | |
method: increment | ||
parameters: | ||
- u1 | ||
cost: 5960 | ||
cost: 5960 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,33 @@ | ||
# Clarinet SDK | ||
|
||
The Clarinet SDK can be used to interact with the simnet from Node.js. | ||
|
||
You can use this SDK to: | ||
- call public and read-only functions from smart contracts | ||
- get clarity maps or data-var values | ||
- deploy contracts | ||
- get contract ABI | ||
- write unit tests for Clarity smart contracts | ||
|
||
## Core | ||
|
||
``` | ||
npm install @hirosystems/clarinet-sdk | ||
``` | ||
|
||
### Usage | ||
|
||
```ts | ||
import { initVM } from "@hirosystems/clarinet-sdk"; | ||
import { Cl } from "@stacks/transactions"; | ||
import { initVM } from "obscurity-sdk"; | ||
|
||
async function main() { | ||
const vm = await initVM(); | ||
|
||
const accounts = vm.getAccounts(); | ||
const w1 = accounts.get("wallet_1"); | ||
if (!w1) return; | ||
const w1 = accounts.get("wallet_1")!; | ||
|
||
const call = vm.callPublicFn("counter", "increment", [Cl.uint(1)], w1); | ||
const call = vm.callPublicFn("counter", "add", [Cl.uint(1)], w1); | ||
console.log(call.result); // Cl.int(Cl.ok(true)) | ||
|
||
const counter = vm.getDataVar("counter", "counter"); | ||
|
@@ -24,20 +37,168 @@ async function main() { | |
main(); | ||
``` | ||
|
||
## Contributing | ||
By default, the SDK will look for a Clarinet.toml file in the current working directory. | ||
It's also possible to provide the path to the manifest like so: | ||
```ts | ||
const vm = await initVM("./path/to/Clarinet.toml"); | ||
``` | ||
|
||
## Tests | ||
|
||
> Note: A bit of boilerplate is needed to setup the testing environment. Soon it will be handled by the clarinet-cli. | ||
The SDK can be used to write unit-tests for Clarinet projects. | ||
Make sure you are in directory with a Clarinet.toml file and the associated Clarity smart contracts: | ||
|
||
```sh | ||
cd ./my-project | ||
ls # here you should see the Clarinet.toml file | ||
``` | ||
|
||
Clone the clarinet repo adn switch to the sdk component | ||
Let's initialize the Node.js project: | ||
```sh | ||
npm init -y # the -y option sets default properties | ||
npm install @hirosystems/clarinet-sdk @stacks/transactions vite vitest vitest-environment-clarinet | ||
``` | ||
|
||
Update the package.json file scripts to handle tests: | ||
```json | ||
"scripts": { | ||
"test": "vitest run", | ||
"test:coverage": "vitest run -- --coverage true" | ||
}, | ||
``` | ||
|
||
The `./.gitignore` file also needs to be updated, add the following lines at the end. It is especially important to ignore `node_modules`. | ||
``` | ||
logs | ||
*.log | ||
npm-debug.log* | ||
coverage | ||
*.info | ||
node_modules | ||
``` | ||
|
||
A config file is needed for Vitest to use the clarinet-environment. | ||
Create the file `vitest.config.js` with the following content: | ||
```js | ||
/// <reference types="vitest" /> | ||
|
||
import { defineConfig } from "vite"; | ||
import { vitestSetupFilePath, getClarinetVitestsArgv } from "@hirosystems/clarinet-sdk/vitest"; | ||
|
||
export default defineConfig({ | ||
test: { | ||
environment: "clarinet", | ||
singleThread: true, | ||
setupFiles: [vitestSetupFilePath], | ||
environmentOptions: { | ||
clarinet: getClarinetVitestsArgv(), | ||
}, | ||
}, | ||
}); | ||
``` | ||
|
||
The set up is ready, let's write the first test. Create a test file in the `unit-tests` directory: | ||
|
||
```sh | ||
mkdir unit-tests | ||
touch unit-tests/my-contract.test.js | ||
``` | ||
|
||
```js | ||
// unit-tests/my-contract.test.js | ||
import { describe, it, expect } from "vitest"; | ||
import { Cl } from "@stacks/transactions"; | ||
|
||
describe("test counter ONE", () => { | ||
const accounts = vm.getAccounts(); | ||
const w1 = accounts.get("wallet_1"); | ||
if (!w1) throw new Error("wallet_1 does not exist"); | ||
|
||
it("adds two numbers", () => { | ||
const callAdd = vm.callPublicFn("my-contract", "add", [Cl.uint(21), Cl.uint(21)], w1); | ||
expect(callAdd.result).toBeOk(Cl.uint(42)); | ||
}); | ||
}); | ||
|
||
``` | ||
|
||
### Notes: | ||
|
||
- This code assumes that you have a contract called `my-contract` with a method `add`. | ||
```clar | ||
;; contracts/my-contract.clar | ||
(define-public (add (n1 uint) (n2 uint)) | ||
(ok (+ n1 n2)) | ||
) | ||
``` | ||
|
||
- You may need to disable the deno extension if it's activated in `.vscode/settings.json`. | ||
|
||
|
||
### Type checking | ||
|
||
You can use TypeScript to write test by installing it and setting up the `tsconfig.json`. | ||
|
||
```sh | ||
npm install typescript | ||
touch tsconfig.json | ||
``` | ||
|
||
```json | ||
{ | ||
"compilerOptions": { | ||
"target": "ESNext", | ||
"useDefineForClassFields": true, | ||
"module": "ESNext", | ||
"lib": ["ESNext"], | ||
"skipLibCheck": true, | ||
|
||
"moduleResolution": "bundler", | ||
"allowImportingTsExtensions": true, | ||
"resolveJsonModule": true, | ||
"isolatedModules": true, | ||
"noEmit": true, | ||
|
||
"strict": true, | ||
"noImplicitAny": true, | ||
"noUnusedLocals": true, | ||
"noUnusedParameters": true, | ||
"noFallthroughCasesInSwitch": true | ||
}, | ||
"include": ["node_modules/@hirosystems/clarinet-sdk/vitest-helpers/src", "unit-tests"] | ||
} | ||
|
||
``` | ||
|
||
If you want to write your test in JavaScript but still have a certain level of type safety and autocompletion, VSCode can help you with that. You can create a basic `jsconfig.json` file: | ||
|
||
```json | ||
{ | ||
"compilerOptions": { | ||
"checkJs": true, | ||
"strict": true | ||
}, | ||
"include": ["node_modules/@hirosystems/clarinet-sdk/vitest-helpers/src", "unit-tests"] | ||
} | ||
``` | ||
|
||
## Contributing | ||
|
||
Clone the clarinet repo and go to the clarinet-sdk component directory: | ||
```sh | ||
git clone [email protected]:hirosystems/clarinet.git | ||
cd clarinet/components/clarinet-sdk | ||
``` | ||
|
||
Open the SDK workspace in VSCode: | ||
``` | ||
```sh | ||
code ./clarinet-sdk.code-workspace | ||
``` | ||
|
||
Compile the project (both WASM and JS): | ||
``` | ||
```sh | ||
npm install | ||
npm run build | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.