Path: blob/main/src/vs/base/test/common/cancelPreviousCalls.test.ts
3296 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import assert from 'assert';6import { Disposable } from '../../common/lifecycle.js';7import { CancellationToken } from '../../common/cancellation.js';8import { ensureNoDisposablesAreLeakedInTestSuite } from './utils.js';9import { cancelPreviousCalls } from '../../common/decorators/cancelPreviousCalls.js';1011suite('cancelPreviousCalls decorator', () => {12const disposables = ensureNoDisposablesAreLeakedInTestSuite();1314class MockDisposable extends Disposable {15/**16* Arguments that the {@linkcode doSomethingAsync} method was called with.17*/18private readonly callArgs1: ([number, string, CancellationToken | undefined])[] = [];1920/**21* Arguments that the {@linkcode doSomethingElseAsync} method was called with.22*/23private readonly callArgs2: ([number, string, CancellationToken | undefined])[] = [];2425/**26* Returns the arguments that the {@linkcode doSomethingAsync} method was called with.27*/28public get callArguments1() {29return this.callArgs1;30}3132/**33* Returns the arguments that the {@linkcode doSomethingElseAsync} method was called with.34*/35public get callArguments2() {36return this.callArgs2;37}3839@cancelPreviousCalls40async doSomethingAsync(arg1: number, arg2: string, cancellationToken?: CancellationToken): Promise<void> {41this.callArgs1.push([arg1, arg2, cancellationToken]);4243await new Promise(resolve => setTimeout(resolve, 25));44}4546@cancelPreviousCalls47async doSomethingElseAsync(arg1: number, arg2: string, cancellationToken?: CancellationToken): Promise<void> {48this.callArgs2.push([arg1, arg2, cancellationToken]);4950await new Promise(resolve => setTimeout(resolve, 25));51}52}5354test('should call method with CancellationToken', async () => {55const instance = disposables.add(new MockDisposable());5657await instance.doSomethingAsync(1, 'foo');5859const callArguments = instance.callArguments1;60assert.strictEqual(61callArguments.length,621,63`The 'doSomethingAsync' method must be called just once.`,64);6566const args = callArguments[0];67assert(68args.length === 3,69`The 'doSomethingAsync' method must be called with '3' arguments, got '${args.length}'.`,70);7172const arg1 = args[0];73const arg2 = args[1];74const arg3 = args[2];7576assert.strictEqual(77arg1,781,79`The 'doSomethingAsync' method call must have the correct 1st argument.`,80);8182assert.strictEqual(83arg2,84'foo',85`The 'doSomethingAsync' method call must have the correct 2nd argument.`,86);8788assert(89CancellationToken.isCancellationToken(arg3),90`The last argument of the 'doSomethingAsync' method must be a 'CancellationToken', got '${arg3}'.`,91);9293assert(94arg3.isCancellationRequested === false,95`The 'CancellationToken' argument must not yet be cancelled.`,96);9798assert(99instance.callArguments2.length === 0,100`The 'doSomethingElseAsync' method must not be called.`,101);102});103104test('cancel token of the previous call when method is called again', async () => {105const instance = disposables.add(new MockDisposable());106107instance.doSomethingAsync(1, 'foo');108await new Promise(resolve => setTimeout(resolve, 10));109instance.doSomethingAsync(2, 'bar');110111const callArguments = instance.callArguments1;112assert.strictEqual(113callArguments.length,1142,115`The 'doSomethingAsync' method must be called twice.`,116);117118const call1Args = callArguments[0];119assert(120call1Args.length === 3,121`The first call of the 'doSomethingAsync' method must have '3' arguments, got '${call1Args.length}'.`,122);123124assert.strictEqual(125call1Args[0],1261,127`The first call of the 'doSomethingAsync' method must have the correct 1st argument.`,128);129130assert.strictEqual(131call1Args[1],132'foo',133`The first call of the 'doSomethingAsync' method must have the correct 2nd argument.`,134);135136assert(137CancellationToken.isCancellationToken(call1Args[2]),138`The first call of the 'doSomethingAsync' method must have the 'CancellationToken' as the 3rd argument.`,139);140141assert(142call1Args[2].isCancellationRequested === true,143`The 'CancellationToken' of the first call must be cancelled.`,144);145146const call2Args = callArguments[1];147assert(148call2Args.length === 3,149`The second call of the 'doSomethingAsync' method must have '3' arguments, got '${call1Args.length}'.`,150);151152assert.strictEqual(153call2Args[0],1542,155`The second call of the 'doSomethingAsync' method must have the correct 1st argument.`,156);157158assert.strictEqual(159call2Args[1],160'bar',161`The second call of the 'doSomethingAsync' method must have the correct 2nd argument.`,162);163164assert(165CancellationToken.isCancellationToken(call2Args[2]),166`The second call of the 'doSomethingAsync' method must have the 'CancellationToken' as the 3rd argument.`,167);168169assert(170call2Args[2].isCancellationRequested === false,171`The 'CancellationToken' of the second call must be cancelled.`,172);173174assert(175instance.callArguments2.length === 0,176`The 'doSomethingElseAsync' method must not be called.`,177);178});179180test('different method calls must not interfere with each other', async () => {181const instance = disposables.add(new MockDisposable());182183instance.doSomethingAsync(10, 'baz');184await new Promise(resolve => setTimeout(resolve, 10));185instance.doSomethingElseAsync(25, 'qux');186187assert.strictEqual(188instance.callArguments1.length,1891,190`The 'doSomethingAsync' method must be called once.`,191);192193const call1Args = instance.callArguments1[0];194assert(195call1Args.length === 3,196`The first call of the 'doSomethingAsync' method must have '3' arguments, got '${call1Args.length}'.`,197);198199assert.strictEqual(200call1Args[0],20110,202`The first call of the 'doSomethingAsync' method must have the correct 1st argument.`,203);204205assert.strictEqual(206call1Args[1],207'baz',208`The first call of the 'doSomethingAsync' method must have the correct 2nd argument.`,209);210211assert(212CancellationToken.isCancellationToken(call1Args[2]),213`The first call of the 'doSomethingAsync' method must have the 'CancellationToken' as the 3rd argument.`,214);215216assert(217call1Args[2].isCancellationRequested === false,218`The 'CancellationToken' of the first call must not be cancelled.`,219);220221assert.strictEqual(222instance.callArguments2.length,2231,224`The 'doSomethingElseAsync' method must be called once.`,225);226227const call2Args = instance.callArguments2[0];228assert(229call2Args.length === 3,230`The first call of the 'doSomethingElseAsync' method must have '3' arguments, got '${call1Args.length}'.`,231);232233assert.strictEqual(234call2Args[0],23525,236`The first call of the 'doSomethingElseAsync' method must have the correct 1st argument.`,237);238239assert.strictEqual(240call2Args[1],241'qux',242`The first call of the 'doSomethingElseAsync' method must have the correct 2nd argument.`,243);244245assert(246CancellationToken.isCancellationToken(call2Args[2]),247`The first call of the 'doSomethingElseAsync' method must have the 'CancellationToken' as the 3rd argument.`,248);249250assert(251call2Args[2].isCancellationRequested === false,252`The 'CancellationToken' of the second call must be cancelled.`,253);254255instance.doSomethingElseAsync(105, 'uxi');256257assert.strictEqual(258instance.callArguments1.length,2591,260`The 'doSomethingAsync' method must be called once.`,261);262263assert.strictEqual(264instance.callArguments2.length,2652,266`The 'doSomethingElseAsync' method must be called twice.`,267);268269assert(270call1Args[2].isCancellationRequested === false,271`The 'CancellationToken' of the first call must not be cancelled.`,272);273274const call3Args = instance.callArguments2[1];275assert(276CancellationToken.isCancellationToken(call3Args[2]),277`The last argument of the second call of the 'doSomethingElseAsync' method must be a 'CancellationToken'.`,278);279280assert(281call2Args[2].isCancellationRequested,282`The 'CancellationToken' of the first call must be cancelled.`,283);284285assert(286call3Args[2].isCancellationRequested === false,287`The 'CancellationToken' of the second call must not be cancelled.`,288);289290assert.strictEqual(291call3Args[0],292105,293`The second call of the 'doSomethingElseAsync' method must have the correct 1st argument.`,294);295296assert.strictEqual(297call3Args[1],298'uxi',299`The second call of the 'doSomethingElseAsync' method must have the correct 2nd argument.`,300);301});302});303304305