Skip to content

Commit

Permalink
feat(test): add schedulerIsEmpty assert helper
Browse files Browse the repository at this point in the history
  • Loading branch information
fkleuver committed Oct 24, 2019
1 parent 850657d commit b20318e
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 4 deletions.
113 changes: 112 additions & 1 deletion packages/testing/src/assert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {
IIndexable,
} from '@aurelia/kernel';
import {
CompositionRoot, CustomElement, CustomAttribute,
CompositionRoot, CustomElement, CustomAttribute, IScheduler, ITaskQueue, TaskQueue, TaskQueuePriority, ITask,
} from '@aurelia/runtime';
import {
isDeepEqual,
Expand Down Expand Up @@ -704,6 +704,116 @@ function isValueEqual(inputElementOrSelector: string | Node, expected: unknown,
}
}

const isSchedulerEmpty = (function () {
function priorityToString(priority: TaskQueuePriority) {
switch (priority) {
case TaskQueuePriority.microTask:
return 'microTask';
case TaskQueuePriority.render:
return 'render';
case TaskQueuePriority.macroTask:
return 'macroTask';
case TaskQueuePriority.postRender:
return 'postRender';
case TaskQueuePriority.idle:
return 'idle';
default:
return 'unknown';
}
}

function round(num: number) {
return ((num * 10 + .5) | 0) / 10;
}

function reportTask(task: any) {
const id = task.id;
const created = round(task.createdTime);
const queue = round(task.queueTime);
const preempt = task.preempt;
const reusable = task.reusable;
const persistent = task.persistent;
const status = task._status;

return ` task id=${id} createdTime=${created} queueTime=${queue} preempt=${preempt} reusable=${reusable} persistent=${persistent} status=${status}`;
}

function toArray(task: any) {
const arr = [task];
while (task = task.next) {
arr.push(task);
}
return arr;
}

function reportTaskQueue(taskQueue: any) {
const processing = taskQueue.processingSize;
const pending = taskQueue.pendingSize;
const delayed = taskQueue.delayedSize;
const flushReq = taskQueue.flushRequested;
const prio = taskQueue.priority;

let info = `${priorityToString(prio)}TaskQueue has processing=${processing} pending=${pending} delayed=${delayed} flushRequested=${flushReq}\n\n`;
if (processing > 0) {
info += ` Tasks in processing:\n${toArray(taskQueue.processingHead).map(reportTask).join('')}`;
}
if (pending > 0) {
info += ` Tasks in pending:\n${toArray(taskQueue.pendingHead).map(reportTask).join('')}`;
}
if (delayed > 0) {
info += ` Tasks in delayed:\n${toArray(taskQueue.delayedHead).map(reportTask).join('')}`;
}

return info;
}

return function $isSchedulerEmpty() {
// Please don't do this anywhere else. We need to get rid of this / improve this at some point, not make it worse.
// Also for this to work, a HTMLTestContext needs to have been created somewhere, so we can't just call this e.g. in kernel and certain runtime tests that don't use
// the full test context.
const scheduler = (DOM as any)['scheduler'] as IScheduler;

const microTaskQueue = scheduler.getMicroTaskQueue() as any;
const renderTaskQueue = scheduler.getRenderTaskQueue() as any;
const macroTaskQueue = scheduler.getMacroTaskQueue() as any;
const postRenderTaskQueue = scheduler.getPostRenderTaskQueue() as any;
const idleTaskQueue = scheduler.getIdleTaskQueue() as any;

let isEmpty = true;
let message = '';
if (!microTaskQueue.isEmpty) {
message += `\n${reportTaskQueue(microTaskQueue)}\n\n`;
isEmpty = false;
}
if (!renderTaskQueue.isEmpty) {
message += `\n${reportTaskQueue(renderTaskQueue)}\n\n`;
isEmpty = false;
}
if (!macroTaskQueue.isEmpty) {
message += `\n${reportTaskQueue(macroTaskQueue)}\n\n`;
isEmpty = false;
}
if (!postRenderTaskQueue.isEmpty) {
message += `\n${reportTaskQueue(postRenderTaskQueue)}\n\n`;
isEmpty = false;
}
if (!idleTaskQueue.isEmpty) {
message += `\n${reportTaskQueue(idleTaskQueue)}\n\n`;
isEmpty = false;
}

if (!isEmpty) {
innerFail({
actual: void 0,
expected: void 0,
message,
operator: '' as any,
stackStartFn: $isSchedulerEmpty
});
}
};
})();

const assert = Object_freeze({
throws,
doesNotThrow,
Expand Down Expand Up @@ -733,6 +843,7 @@ const assert = Object_freeze({
match,
notMatch,
visibleTextEqual,
isSchedulerEmpty,
isCustomElementType,
isCustomAttributeType,
strict: {
Expand Down
12 changes: 9 additions & 3 deletions packages/testing/src/inspect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ export class AssertionError extends Error {
public code: string;
public actual: any;
public expected: any;
public operator: keyof IOperatorText;
public operator!: keyof IOperatorText;
public generatedMessage: boolean;

public constructor(options: IAssertionErrorOpts) {
Expand All @@ -314,7 +314,7 @@ export class AssertionError extends Error {
const limit = Error.stackTraceLimit;
Error.stackTraceLimit = 0;

const prefix = message == null ? '' : `${message} - `;
let prefix = message == null ? '' : `${message} - `;

if (operator === 'deepStrictEqual' || operator === 'strictEqual') {
super(`${prefix}${createErrDiff(actual, expected, operator)}`);
Expand All @@ -323,7 +323,8 @@ export class AssertionError extends Error {
|| operator === 'notStrictEqual'
) {
let base = operatorText[operator];
const res = inspectValue(actual).split('\n');
// eslint-disable-next-line prefer-const
let res = inspectValue(actual).split('\n');
if (
operator === 'notStrictEqual'
&& isObject(actual)
Expand Down Expand Up @@ -366,6 +367,11 @@ export class AssertionError extends Error {
other = ` ${operator} ${other}`;
}
}
if (!operator) {
other = '';
res = '';
prefix = prefix.slice(0, -3);
}
super(`${prefix}${res}${other}`);
}

Expand Down

0 comments on commit b20318e

Please sign in to comment.