Skip to content

Commit

Permalink
test wip
Browse files Browse the repository at this point in the history
  • Loading branch information
FineArchs committed Oct 22, 2024
1 parent 4c8764e commit 746e9f5
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 35 deletions.
15 changes: 13 additions & 2 deletions src/interpreter/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,23 @@ export class Interpreter {
}
};

if (this.opts.irqRate < 0) throw new AiScriptHostsideError('IRQ rate must not be negative value');
if (!((this.opts.irqRate ?? 300) >= 0)) {
throw new AiScriptHostsideError(`Invalid IRQ rate (${this.opts.irqRate}): must be non-negative number`);
}
this.irqRate = this.opts.irqRate ?? 300;

const sleep = (time: number) => (
(): Promise<void> => new Promise(resolve => setTimeout(resolve, time))
);

if (typeof this.opts.irqSleep === 'function') {
this.irqSleep = this.opts.irqSleep;
} else if (this.opts.irqSleep === undefined) {
this.irqSleep = sleep(5);
} else if (this.opts.irqSleep >= 0) {
this.irqSleep = sleep(this.opts.irqSleep);
} else {
this.irqSleep = (): Promise<void> => new Promise(resolve => setTimeout(resolve, (this.opts.irqSleep ?? 5) as number));
throw new AiScriptHostsideError('irqSleep must be a function or a positive number.');
}
}

Expand Down
117 changes: 84 additions & 33 deletions test/interpreter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as assert from 'assert';
import { describe, expect, test } from 'vitest';
import { describe, expect, test, vi, beforeEach, afterEach } from 'vitest';
import { Parser, Interpreter, values, errors, utils, Ast } from '../src';

let { FN_NATIVE } = values;
Expand Down Expand Up @@ -116,40 +116,91 @@ describe('error location', () => {
});

describe('IRQ', () => {
async function countSleeps(irqRate: number): Promise<number> {
let count = 0;
const interpreter = new Interpreter({}, {
irqRate,
// It's safe only when no massive loop occurs
irqSleep: async () => count++,
describe('irqSleep is function', () => {
async function countSleeps(irqRate: number): Promise<number> {
let count = 0;
const interpreter = new Interpreter({}, {
irqRate,
// It's safe only when no massive loop occurs
irqSleep: async () => count++,
});
await interpreter.exec(Parser.parse(`
'Ai-chan kawaii'
'Ai-chan kawaii'
'Ai-chan kawaii'
'Ai-chan kawaii'
'Ai-chan kawaii'
'Ai-chan kawaii'
'Ai-chan kawaii'
'Ai-chan kawaii'
'Ai-chan kawaii'
'Ai-chan kawaii'`));
return count;
}

test.concurrent.each([
[0, 0],
[1, 10],
[2, 5],
[10, 1],
[Infinity, 0],
])('rate = %d', async (rate, count) => {
return expect(countSleeps(rate)).resolves.toEqual(count);
});

test.concurrent.each(
[-1, NaN],
)('rate = %d', async (rate, count) => {
return expect(countSleeps(rate)).rejects.toThrow(AiScriptHostsideError);
});
await interpreter.exec(Parser.parse(`
'Ai-chan kawaii'
'Ai-chan kawaii'
'Ai-chan kawaii'
'Ai-chan kawaii'
'Ai-chan kawaii'
'Ai-chan kawaii'
'Ai-chan kawaii'
'Ai-chan kawaii'
'Ai-chan kawaii'
'Ai-chan kawaii'`));
return count;
}

test.concurrent.each([
[0, 0],
[1, 10],
[2, 5],
[10, 1],
[Infinity, 0],
])('rate = %d', async (rate, count) => {
return expect(countSleeps(rate)).resolves.toEqual(count);
});

test.concurrent.each([
[-1, NaN],
])('rate = %d', async (rate, count) => {
return expect(countSleeps(rate)).rejects.toThrow(AiScriptHostsideError);
describe('irqSleep is number', () => {
// This function does IRQ 10 times so takes 10 * irqSleep milliseconds in sum when executed.
async function countSleeps(irqSleep: number): Promise<void> {
const interpreter = new Interpreter({}, {
irqRate: 1,
irqSleep,
});
await interpreter.exec(Parser.parse(`
'Ai-chan kawaii'
'Ai-chan kawaii'
'Ai-chan kawaii'
'Ai-chan kawaii'
'Ai-chan kawaii'
'Ai-chan kawaii'
'Ai-chan kawaii'
'Ai-chan kawaii'
'Ai-chan kawaii'
'Ai-chan kawaii'`));
}

beforeEach(() => {
vi.useFakeTimers();
})

afterEach(() => {
vi.restoreAllMocks();
})

test.concurrent('It ends', async () => {
const countSleepsSpy = vi.fn(countSleeps);
const promise = countSleepsSpy(100);
vi.advanceTimersByTime(1000);
return expect(countSleepsSpy).toHaveResolved();

Check failure on line 190 in test/interpreter.ts

View workflow job for this annotation

GitHub Actions / test (20.x)

test/interpreter.ts > IRQ > irqSleep is number > It ends

AssertionError: expected "countSleeps" to be successfully resolved at least once ❯ test/interpreter.ts:190:34
});

test.concurrent('It takes time', () => {
const countSleepsSpy = vi.fn(countSleeps);
const promise = countSleepsSpy(100);
vi.advanceTimersByTime(900);
return expect(countSleepsSpy).not.toHaveResolved();
});

test.concurrent.each(
[-1, NaN]
)('Invalid number: %d', (time) => {
return expect(countSleeps(time)).rejects.toThrow(AiScriptHostsideError);
});
});
});

0 comments on commit 746e9f5

Please sign in to comment.