Skip to content

Commit

Permalink
Merge pull request #11 from letmejustputthishere/feature/pic-js
Browse files Browse the repository at this point in the history
Feature/pic js
  • Loading branch information
letmejustputthishere authored Feb 7, 2024
2 parents 1285b7d + e4912ea commit 2933793
Show file tree
Hide file tree
Showing 9 changed files with 180 additions and 40 deletions.
40 changes: 17 additions & 23 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -1,38 +1,32 @@
name: Tests
name: tests

on:
# push:
# branches: [ "main" ]
workflow_dispatch:
pull_request:

concurrency:
group: ${{ github.head_ref || github.run_id }}
cancel-in-progress: true
types: [synchronize, opened, reopened, ready_for_review, unlabeled]

jobs:
build:
test:
runs-on: ubuntu-22.04

strategy:
matrix:
node-version: [18]

steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3

- uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- name: Clear npm cache
run: npm cache clean --force
node-version: 18

- name: Install dfx
uses: dfinity/setup-dfx@main

- name: Install mops
uses: ZenVoich/setup-mops@v1
- name: Start dfx
run: |
dfx cache install
dfx start --background
- run: npm run setup
- run: npm test

- name: generate declarations
run: dfx generate backend

- name: install dependencies
run: npm i

- name: run tests
run: npm run test
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
> Due to current limitations, this template does not work in a Browser Editor when using gitpod or codespaces. Please use VS Code for desktop instead.
> <img width="633" alt="Screenshot 2024-01-29 at 12 44 57" src="https://github.com/letmejustputthishere/vite-sveltekit-motoko/assets/32162112/2f2c025d-354b-47ca-9303-56bce180f6e7">

[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/letmejustputthishere/vite-sveltekit-motoko)

[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/letmejustputthishere/vite-sveltekit-motoko?quickstart=1)
Expand All @@ -18,7 +17,7 @@ For an example of a real-world dapp built using this starter project, check out
## 📦 Create a New Project

> [!IMPORTANT]
> Make sure that [Node.js](https://nodejs.org/en/) `>= 18`, [mops](https://docs.mops.one/quick-start) `>=0.39.2` and [`dfx`](https://internetcomputer.org/docs/current/developer-docs/build/install-upgrade-remove) `>= 0.16` are installed on your system.
> Make sure that [Node.js](https://nodejs.org/en/) `>= 18`, [mops](https://docs.mops.one/quick-start) `>=0.39.2` and [`dfx`](https://internetcomputer.org/docs/current/developer-docs/build/install-upgrade-remove) `>= 0.16.1` are installed on your system.
Run the following commands in a new, empty project directory:

Expand All @@ -45,6 +44,11 @@ When ready, run `dfx deploy --network ic` to deploy your application to the Inte
- [mo-dev](https://github.com/dfinity/motoko-dev-server#readme): a live reload development server for Motoko
- [eslint](https://eslint.org/): a static code analysis tool used in software development for identifying problematic patterns or code that doesn't adhere to certain style guidelines in JavaScript and TypeScript
- [Internet Identity](https://github.com/dfinity/internet-identity/tree/main): a decentralized identity provider for the Internet Computer
- [pic.js](https://github.com/hadronous/pic-js): an Internet Computer Protocol canister testing library for TypeScript and JavaScript

## 🧪 Testing

You can run `npm run test` to run unit tests using [`mops test`](https://docs.mops.one/cli/mops-test) and end-to-end tests using [`pic.js`](https://hadronous.github.io/pic-js/).

## 📚 Documentation

Expand All @@ -55,10 +59,11 @@ When ready, run `dfx deploy --network ic` to deploy your application to the Inte
- [Motoko developer docs](https://internetcomputer.org/docs/current/developer-docs/build/cdks/motoko-dfinity/motoko/)
- [Mops usage instructions](https://j4mwm-bqaaa-aaaam-qajbq-cai.ic0.app/#/docs/install)
- [Internet Identity docs](https://internetcomputer.org/docs/current/developer-docs/integrations/internet-identity/overview)
- [pic-js](https://hadronous.github.io/pic-js/)

## 💡 Tips and Tricks

- Customize your project's code style by editing the `.prettierrc` file and then running `npm run format`.
- Reduce the latency of update calls by passing the `--emulator` flag to `dfx start`.
- Install a Motoko package by running `npx ic-mops add <package-name>`. Here is a [list of available packages](https://mops.one/).
- Install a Motoko package by running `mops add <package-name>`. Here is a [list of available packages](https://mops.one/).
- Split your frontend and backend console output by running `npm run frontend` and `npm run backend` in separate terminals.
4 changes: 2 additions & 2 deletions backend/main.mo
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
actor class Main() {
actor class Main(initArgs : { phrase : Text }) {
public query func greet(name : Text) : async Text {
return "Hello, " # name # "!";
return initArgs.phrase # ", " # name # "!";
};

public query ({ caller }) func whoAmI() : async Principal {
Expand Down
2 changes: 1 addition & 1 deletion backend/tests/main.greet.test.mo
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Main } "../main";

let main = await Main();
let main = await Main({ phrase = "Hello" });

assert (await main.greet("Moritz")) == "Hello, Moritz!";
26 changes: 26 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@
"version": "0.0.1",
"private": true,
"scripts": {
"setup": "npm i && npm run init-ii && dfx generate backend && dfx generate internet_identity && dfx deploy backend && dfx deps deploy",
"setup": "npm i && npm run init-ii && dfx generate backend && dfx generate internet_identity && dfx deploy backend --argument '(record {phrase = \"Hello\"})' && dfx deps deploy",
"init-ii": "dfx deps pull && dfx deps init internet_identity --argument '(null)'",
"start": "run-p frontend backend",
"frontend": "vite --host",
"backend": "mo-dev --generate --deploy -y",
"build": "vite build",
"test": "run-s test:backend test:frontend",
"test:frontend": "vitest run",
"test:backend": "mops test",
"pretest": "dfx generate backend",
"test": "run-s test:e2e test:unit",
"test:e2e": "vitest run",
"test:unit": "mops test",
"format": "prettier --write .",
"sources": "mops sources",
"postinstall": "mops install",
Expand All @@ -26,6 +27,7 @@
"@dfinity/auth-client": "^0.21.4",
"@dfinity/candid": "^0.21.4",
"@dfinity/principal": "^0.21.4",
"@hadronous/pic": "^0.3.0-b0",
"@sveltejs/adapter-auto": "^3.0.0",
"@sveltejs/adapter-static": "^3.0.1",
"@sveltejs/kit": "^2.0.0",
Expand Down
83 changes: 83 additions & 0 deletions tests/canister.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { describe, it, expect, afterEach, beforeEach } from 'vitest';

import { AnonymousIdentity } from '@dfinity/agent';
import { PocketIc, createIdentity, type Actor } from '@hadronous/pic';
import type { _SERVICE } from '../src/declarations/backend/backend.did';
import { deployCanister } from './setup';

describe('canister tests', () => {
let pic: PocketIc;
let actor: Actor<_SERVICE>;

const alice = createIdentity('superSecretAlicePassword');
const bob = createIdentity('superSecretBobPassword');

afterEach(async () => {
await pic.tearDown();
});

describe('when calling greet on the canister deployed with the default init args', () => {
beforeEach(async () => {
({ pic, actor } = await deployCanister({
deployer: alice.getPrincipal()
}));
});

it('the argument should be prefixed with `Hello, `', async () => {
await expect(actor.greet('Moritz')).resolves.toEqual('Hello, Moritz!');
});

it('the argument should be prefixed with `Hello, `, even for very long names', async () => {
const veryLongName = 'a'.repeat(1000);
await expect(actor.greet(veryLongName)).resolves.toEqual('Hello, ' + veryLongName + '!');
});

it('a call to whoami with the anonymous principal should return the anonymous principal', async () => {
actor.setIdentity(new AnonymousIdentity());
await expect(actor.whoAmI()).resolves.toEqual(new AnonymousIdentity().getPrincipal());
});

it('a call to whoami with the alice principal should return the alice principal', async () => {
actor.setIdentity(alice);
await expect(actor.whoAmI()).resolves.toEqual(alice.getPrincipal());
});

it('a call to whoami with the bob principal should return the bob principal', async () => {
actor.setIdentity(bob);
await expect(actor.whoAmI()).resolves.toEqual(bob.getPrincipal());
});
});

describe('when calling greet on the canister deployed with `bonjour` as an init arg', () => {
beforeEach(async () => {
({ pic, actor } = await deployCanister({
initArgs: { phrase: 'bonjour' },
deployer: alice.getPrincipal()
}));
});

it('the argument should be prefixed with `bonjour, `', async () => {
await expect(actor.greet('Moritz')).resolves.toEqual('bonjour, Moritz!');
});

it('the argument should be prefixed with `Hello, `, even for very long names', async () => {
const veryLongName = 'a'.repeat(1000);
await expect(actor.greet(veryLongName)).resolves.toEqual('bonjour, ' + veryLongName + '!');
});

it('a call to whoami with the anonymous principal should return the anonymous principal', async () => {
actor.setIdentity(new AnonymousIdentity());
await expect(actor.whoAmI()).resolves.toEqual(new AnonymousIdentity().getPrincipal());
});

it('a call to whoami with the alice principal should return the alice principal', async () => {
actor.setIdentity(alice);
await expect(actor.whoAmI()).resolves.toEqual(alice.getPrincipal());
});

it('a call to whoami with the bob principal should return the bob principal', async () => {
actor.setIdentity(bob);
await expect(actor.whoAmI()).resolves.toEqual(bob.getPrincipal());
});
});
});
7 changes: 0 additions & 7 deletions tests/index.test.ts

This file was deleted.

37 changes: 37 additions & 0 deletions tests/setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { IDL } from '@dfinity/candid';
import { idlFactory, init } from '../src/declarations/backend/backend.did.js';
import type { _SERVICE } from '../src/declarations/backend/backend.did';
import { resolve } from 'node:path';
import { PocketIc } from '@hadronous/pic';
import { Principal } from '@dfinity/principal';

type InitArgs = {
phrase: string;
};
const defaultInitArgs: InitArgs = {
phrase: 'Hello'
};
const WASM_PATH = resolve(__dirname, '..', '.dfx', 'local', 'canisters', 'backend', 'backend.wasm');

interface DeployOptions {
initArgs?: InitArgs;
deployer?: Principal;
}

export async function deployCanister({
initArgs = defaultInitArgs,
deployer = Principal.anonymous()
}: DeployOptions) {
const encodedInitArgs = IDL.encode(init({ IDL }), [initArgs]);
const pic = await PocketIc.create();
const fixture = await pic.setupCanister<_SERVICE>(
idlFactory,
WASM_PATH,
undefined,
encodedInitArgs,
deployer
);
const actor = fixture.actor;
const canisterId = fixture.canisterId;
return { pic, actor, canisterId };
}

0 comments on commit 2933793

Please sign in to comment.