Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
7 changes: 6 additions & 1 deletion modules.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,10 @@
"tabs": [
"SoundMatrix"
]
},
"unittest": {
"tabs": [
"UnitTest"
]
}
}
}
128 changes: 128 additions & 0 deletions src/bundles/unittest/asserts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import { is_pair, head, tail, is_list, is_null, member, length } from './list';

/**
* Asserts the equality (===) of the two parameters.
* @param expected The expected value.
* @param received The given value.
* @returns
*/
export function assert_equals(expected: any, received: any) {
if (expected !== received) {
throw new Error(`Expected \`${expected}\`, got \`${received}\`!`);
}
}

/**
* Asserts the inequality (!==) of the two parameters.
* @param expected The expected value.
* @param received The given value.
* @returns
*/
export function assert_not_equals(expected: any, received: any) {
if (expected === received) {
throw new Error(`Expected not equal \`${expected}\`!`);
}
}

/**
* Asserts the inequality (!==) of the two parameters.
* @param expected The expected value.
* @param received The given value.
* @returns
*/
export function assert_approx_equals(expected: number, received: number) {
if (Math.abs(expected - received) > 0.001) {
throw new Error(`Expected \`${expected}\` to approx. \`${received}\`!`);
}
}

/**
* Asserts that `expected` > `received`.
* @param expected
* @param received
*/
export function assert_greater(expected: number, received: number) {
if (expected <= received) {
throw new Error(`Expected \`${expected}\` > \`${received}\`!`);
}
}

/**
* Asserts that `expected` >= `received`.
* @param expected
* @param received
*/
export function assert_greater_equals(expected: number, received: number) {
if (expected < received) {
throw new Error(`Expected \`${expected}\` >= \`${received}\`!`);
}
}

/**
* Asserts that `expected` < `received`.
* @param expected
* @param received
*/
export function assert_lesser(expected: number, received: number) {
if (expected >= received) {
throw new Error(`Expected \`${expected}\` < \`${received}\`!`);
}
}

/**
* Asserts that `expected` <= `received`.
* @param expected
* @param received
*/
export function assert_lesser_equals(expected: number, received: number) {
if (expected > received) {
throw new Error(`Expected \`${expected}\` <= \`${received}\`!`);
}
}

/**
* Asserts that `xs` contains `toContain`.
* @param xs The list to assert.
* @param toContain The element that `xs` is expected to contain.
*/
export function assert_contains(xs: any, toContain: any) {
const fail = () => {
throw new Error(`Expected \`${xs}\` to contain \`${toContain}\`.`);
};

if (is_null(xs)) {
fail();
} else if (is_list(xs)) {
if (is_null(member(toContain, xs))) {
fail();
}
} else if (is_pair(xs)) {
if (head(xs) === toContain || tail(xs) === toContain) {
return;
}

// check the head, if it fails, checks the tail, if that fails, fail.
try {
assert_contains(head(xs), toContain);
return;
} catch (_) {
try {
assert_contains(tail(xs), toContain);
return;
} catch (__) {
fail();
}
}
} else {
throw new Error(`First argument must be a list or a pair, got \`${xs}\`.`);
}
}

/**
* Asserts that the given list has length `len`.
* @param list The list to assert.
* @param len The expected length of the list.
*/
export function assert_length(list: any, len: number) {
assert_equals(length(list), len);
}
82 changes: 82 additions & 0 deletions src/bundles/unittest/functions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { TestContext, TestSuite, Test } from './types';

const handleErr = (err: any) => {
if (err.error && err.error.message) {
return (err.error as Error).message;
}
if (err.message) {
return (err as Error).message;
}
throw err;
};

export const context: TestContext = {
describe: (msg: string, suite: TestSuite) => {
const starttime = performance.now();
context.suiteResults = {
name: msg,
results: [],
total: 0,
passed: 0,
};

suite();

context.allResults.results.push(context.suiteResults);

const endtime = performance.now();
context.runtime += endtime - starttime;
return context.allResults;
},

it: (msg: string, test: Test) => {
const name = `${msg}`;
let error = '';
context.suiteResults.total += 1;

try {
test();
} catch (err: any) {
error = handleErr(err);
}

context.suiteResults.passed += 1;
context.suiteResults.results.push({
name,
error,
});
},

suiteResults: {
name: '',
results: [],
total: 0,
passed: 0,
},

allResults: {
results: [],
toReplString: () =>
`${context.allResults.results.length} suites completed in ${context.runtime} ms.`,
},

runtime: 0,
};

/**
* Defines a single test.
* @param str Description for this test.
* @param func Function containing tests.
*/
export function it(msg: string, func: Test) {
context.it(msg, func);
}

/**
* Describes a test suite.
* @param str Description for this test.
* @param func Function containing tests.
*/
export function describe(msg: string, func: TestSuite) {
return context.describe(msg, func);
}
41 changes: 41 additions & 0 deletions src/bundles/unittest/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { it, describe } from './functions';
import {
assert_equals,
assert_not_equals,
assert_contains,
assert_approx_equals,
assert_greater,
assert_greater_equals,
assert_length,
} from './asserts';
import { mock_fn } from './mocks';

/**
* Collection of unit-testing tools for Source.
* @author Jia Xiaodong
*/

/**
* Increment a number by a value of 1.
* @param x the number to be incremented
* @returns the incremented value of the number
*/
function sample_function(x: number) {
return x + 1;
}

// Un-comment the next line if your bundle requires the use of variables
// declared in cadet-frontend or js-slang.
export default () => ({
sample_function,
it,
describe,
assert_equals,
assert_not_equals,
assert_contains,
assert_greater,
assert_greater_equals,
assert_approx_equals,
assert_length,
mock_fn,
});
Loading