Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/pic js #11

Merged
merged 9 commits into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 };
}
Loading