npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

assemblyscript-unittest-framework

v1.0.3

Published

assemblyscript unit test framework

Downloads

169

Readme

Assemblyscript Unittest Framework

A comprehensive AssemblyScript testing solution, offering developers a robust suite of features to ensure their code performs as expected:

  • Function Mocking
  • Coverage statistics
  • Expectations

Getting Started

Install Assemblyscript Unittest Framework using npm

npm install --save-dev assemblyscript-unittest-framework

Let's get started by writing a test for a simple function that add two numbers. Assume that there is already environment of assemblyscript.

First, create source/sum.ts:

export function add(a: i32, b: i32): i32 {
  return a + b;
}

Then, create a file named tests/sum.test.ts. This will contain our actual test:

import { test, expect, endTest } from "assemblyscript-unittest-framework/assembly";
import { add } from "../source/sum";

test("sum", () => {
  expect(add(1, 2)).equal(3);
  expect(add(1, 1)).equal(3);
});
endTest();  // Don't forget it!

Don't forget endTest() at the end of *.test.ts files

Create a config file in project root as-test.config.js:

for cjs:

module.exports = {
  include: ["source", "tests"],
};

for mjs:

export default {
  include: ["source", "tests"],
};

Add the following section to your package.json

{
  "scripts": {
    "test": "as-test"
  }
}

Finally, run npm run test and as-test will print this message:

transform source/sum.ts => build/source/sum.ts.cov
transform build/source/sum.ts.cov => build/source/sum.ts
transform tests/sum.test.ts => build/tests/sum.test.ts
(node:489815) ExperimentalWarning: WASI is an experimental feature. This feature could change at any time

test case: 1/2 (success/total)

Error Message:
        sum:
                tests/sum.test.ts:6:3 (6:3, 6:29)

You can also use npx as-test -h for more information to control detail configurations

Configuration

This is the template of as-test.config.js:

module.exports = {
  // test related code folder
  include: ["source", "tests"],
  exclude: [],

  /** optional: assemblyscript compile flag, default is --exportStart _start -O0 */
  flags: "",

  /**
   * optional: import functions
   * @param {ImportsArgument} runtime
   * @returns
   */
  imports(runtime) {
    return {
      env: {
        logInfo(ptr, len) {
          if (runtime.exports) {
            let arrbuf = runtime.exports.__getArrayBuffer(ptr);
            let str = Buffer.from(arrbuf).toString("utf8");
            console.log(str);
          }
        },
      },
      builtin: {
        getU8FromLinkedMemory(a) {
          return 1;
        },
      },
    };
  },

  /**  optional: template file path, default "coverage" */
  // temp: "coverage",

  /**  optional: report file path, default "coverage" */
  // output: "coverage",

  /** optional: test result output format, default "table" */
  // mode: ["html", "json", "table"],
};

Using Matchers

The simplest way to test a value is with exact equality.

test('two plus two is four', () => {
  expect(2 + 2).equal(4);
});

In this code, expect(2+2) returns an "Value" object. You typically won't do much with these objects except call matchers on them. In this code, .equal(4) is the matcher. When Jest runs, it tracks all the failing matchers so that it can print out nice error messages for you.

Equal

In the most condition, equal is similar as ==, you can use this matcher to compare i32 | i64 | u32 | u64 | f32 | f64 | string just like ==. What's more, it can also be used to compare some inner type, such as Array | Map | Set.

However, Class and Interface cannot be compared directly now.

notEqual is the opposite of equal

Numbers

Most ways of comparing numbers have matcher equivalents, like equal, greaterThan, greaterThanOrEqual, lessThan, lessThanOrEqual.

Specially, for float type, use closeTo instead of equal to avoid rounding error.

Nullable

isNull and notNull matcher can be used to a nullable object. Of cource, you can also use equal and notEqual to do same thing with explicit generic declartion expect<T | null>()

Using Mock Function

Because Assemblyscript's grammar is not as flexible as javascript, mock function have a lot of limitation and API design is not similar as jest (a javascript test framework).

However, There is a way to do some mock function.

Imagine that we are testing a function which includes a system-interface:

// source.ts
declare function sys_getTime(): i32;
export function getTime(): bool {
  let errno = sys_getTime();
  if (errno < 0) {
    // error handle
    return false;
  }
  // do something
  return true;
}

To test error handle part, we need to inject some code to sys_getTime and expect to return a errno.

// source.test.ts
test("getTime error handle", () => {
  const fn = mock(sys_getTime, () => {
    return -1;
  });
  expect(getTime()).equal(false); // success
  expect(fn.calls).equal(1);      // success
});
endTest();

mock API can temporary change the behavior of function, effective scope is each test. In this mock function, you can do every thing include expecting arguments, mock return values and so on.

Tips:

  • Because Assemblyscript is a strongly typed language, you should keep the function signature aligned.
  • AssemblyScript does not support closures. If a mock function needs to be called several times in one test, and you want it to return different values or match arguments to different values, using a global counter for this function is a good way to achieve this.

Example for MockFn

  1. expect arguments

    test("check argument", () => {
      const fn = mock(add, (a: i32, b: i32) => {
        expect(a).equal(1);
        return a + b;
      });
      expect(fn.calls).greaterThanOrEqual(1);
    });
  2. return difference value

    const ret = [1,2,3,4,5,6,7,8];  // global variant
    const calls = 0;                // global variant
    test("check argument", () => {
      const fn = mock(add, (a: i32, b: i32) => {
        return ret[calls++];
      });
      expect(fn.calls).greaterThanOrEqual(1);
    });
  3. re-call origin

    test("call origin", () => {
      mock(add, (a: i32, b: i32) => {
        unmock(add);
        const res = add(a,b);
        remock(add);
        return res;
      });
    });

Coverage Report

After testing, you can get a html / json / table format test coverage report include "Statements Coverage", "Branches Coverage", "Functions Coverage", "Lines Coverage"

Architecture

  • assembly/ written in Assemblyscript, provides user-accessible testing APIs such as test, inspect, mock, etc.
  • src/ written in Typescript, implements the test functionality.