@@ -8,7 +8,7 @@ import { Uri } from 'vscode';
88import { Resource } from '../../../client/common/types' ;
99import { clearCache } from '../../../client/common/utils/cacheUtils' ;
1010import {
11- cacheResourceSpecificInterpreterData , makeDebounceDecorator
11+ cacheResourceSpecificInterpreterData , makeDebounceAsyncDecorator , makeDebounceDecorator
1212} from '../../../client/common/utils/decorators' ;
1313import { sleep } from '../../core' ;
1414
@@ -151,11 +151,33 @@ suite('Common Utils - Decorators', () => {
151151 expect ( one . calls ) . to . deep . equal ( [ 'run' ] ) ;
152152 expect ( one . timestamps ) . to . have . lengthOf ( one . calls . length ) ;
153153 } ) ;
154+ test ( 'Debounce: one async call & no wait' , async ( ) => {
155+ const wait = 100 ;
156+ // tslint:disable-next-line:max-classes-per-file
157+ class One extends Base {
158+ @makeDebounceAsyncDecorator ( wait )
159+ public async run ( ) : Promise < void > {
160+ this . _addCall ( 'run' ) ;
161+ }
162+ }
163+ const one = new One ( ) ;
164+
165+ const start = Date . now ( ) ;
166+ let errored = false ;
167+ one . run ( ) . catch ( ( ) => errored = true ) ;
168+ await waitForCalls ( one . timestamps , 1 ) ;
169+ const delay = one . timestamps [ 0 ] - start ;
170+
171+ expect ( delay ) . to . be . at . least ( wait ) ;
172+ expect ( one . calls ) . to . deep . equal ( [ 'run' ] ) ;
173+ expect ( one . timestamps ) . to . have . lengthOf ( one . calls . length ) ;
174+ expect ( errored ) . to . be . equal ( false , 'Exception raised when there shouldn\'t have been any' ) ;
175+ } ) ;
154176 test ( 'Debounce: one async call' , async ( ) => {
155177 const wait = 100 ;
156178 // tslint:disable-next-line:max-classes-per-file
157179 class One extends Base {
158- @makeDebounceDecorator ( wait )
180+ @makeDebounceAsyncDecorator ( wait )
159181 public async run ( ) : Promise < void > {
160182 this . _addCall ( 'run' ) ;
161183 }
@@ -171,6 +193,99 @@ suite('Common Utils - Decorators', () => {
171193 expect ( one . calls ) . to . deep . equal ( [ 'run' ] ) ;
172194 expect ( one . timestamps ) . to . have . lengthOf ( one . calls . length ) ;
173195 } ) ;
196+ test ( 'Debounce: one async call and ensure exceptions are re-thrown' , async ( ) => {
197+ const wait = 100 ;
198+ // tslint:disable-next-line:max-classes-per-file
199+ class One extends Base {
200+ @makeDebounceAsyncDecorator ( wait )
201+ public async run ( ) : Promise < void > {
202+ this . _addCall ( 'run' ) ;
203+ throw new Error ( 'Kaboom' ) ;
204+ }
205+ }
206+ const one = new One ( ) ;
207+
208+ const start = Date . now ( ) ;
209+ let capturedEx : Error | undefined ;
210+ await one . run ( ) . catch ( ex => capturedEx = ex ) ;
211+ await waitForCalls ( one . timestamps , 1 ) ;
212+ const delay = one . timestamps [ 0 ] - start ;
213+
214+ expect ( delay ) . to . be . at . least ( wait ) ;
215+ expect ( one . calls ) . to . deep . equal ( [ 'run' ] ) ;
216+ expect ( one . timestamps ) . to . have . lengthOf ( one . calls . length ) ;
217+ expect ( capturedEx ) . to . not . be . equal ( undefined , 'Exception not re-thrown' ) ;
218+ } ) ;
219+ test ( 'Debounce: multiple async calls' , async ( ) => {
220+ const wait = 100 ;
221+ // tslint:disable-next-line:max-classes-per-file
222+ class One extends Base {
223+ @makeDebounceAsyncDecorator ( wait )
224+ public async run ( ) : Promise < void > {
225+ this . _addCall ( 'run' ) ;
226+ }
227+ }
228+ const one = new One ( ) ;
229+
230+ const start = Date . now ( ) ;
231+ let errored = false ;
232+ one . run ( ) . catch ( ( ) => errored = true ) ;
233+ one . run ( ) . catch ( ( ) => errored = true ) ;
234+ one . run ( ) . catch ( ( ) => errored = true ) ;
235+ one . run ( ) . catch ( ( ) => errored = true ) ;
236+ await waitForCalls ( one . timestamps , 1 ) ;
237+ const delay = one . timestamps [ 0 ] - start ;
238+
239+ expect ( delay ) . to . be . at . least ( wait ) ;
240+ expect ( one . calls ) . to . deep . equal ( [ 'run' ] ) ;
241+ expect ( one . timestamps ) . to . have . lengthOf ( one . calls . length ) ;
242+ expect ( errored ) . to . be . equal ( false , 'Exception raised when there shouldn\'t have been any' ) ;
243+ } ) ;
244+ test ( 'Debounce: multiple async calls when awaiting on all' , async ( ) => {
245+ const wait = 100 ;
246+ // tslint:disable-next-line:max-classes-per-file
247+ class One extends Base {
248+ @makeDebounceAsyncDecorator ( wait )
249+ public async run ( ) : Promise < void > {
250+ this . _addCall ( 'run' ) ;
251+ }
252+ }
253+ const one = new One ( ) ;
254+
255+ const start = Date . now ( ) ;
256+ await Promise . all ( [ one . run ( ) , one . run ( ) , one . run ( ) , one . run ( ) ] ) ;
257+ await waitForCalls ( one . timestamps , 1 ) ;
258+ const delay = one . timestamps [ 0 ] - start ;
259+
260+ expect ( delay ) . to . be . at . least ( wait ) ;
261+ expect ( one . calls ) . to . deep . equal ( [ 'run' ] ) ;
262+ expect ( one . timestamps ) . to . have . lengthOf ( one . calls . length ) ;
263+ } ) ;
264+ test ( 'Debounce: multiple async calls & wait on some' , async ( ) => {
265+ const wait = 100 ;
266+ // tslint:disable-next-line:max-classes-per-file
267+ class One extends Base {
268+ @makeDebounceAsyncDecorator ( wait )
269+ public async run ( ) : Promise < void > {
270+ this . _addCall ( 'run' ) ;
271+ }
272+ }
273+ const one = new One ( ) ;
274+
275+ const start = Date . now ( ) ;
276+ let errored = false ;
277+ one . run ( ) . catch ( ( ) => errored = true ) ;
278+ await one . run ( ) ;
279+ one . run ( ) . catch ( ( ) => errored = true ) ;
280+ one . run ( ) . catch ( ( ) => errored = true ) ;
281+ await waitForCalls ( one . timestamps , 2 ) ;
282+ const delay = one . timestamps [ 1 ] - start ;
283+
284+ expect ( delay ) . to . be . at . least ( wait ) ;
285+ expect ( one . calls ) . to . deep . equal ( [ 'run' , 'run' ] ) ;
286+ expect ( one . timestamps ) . to . have . lengthOf ( one . calls . length ) ;
287+ expect ( errored ) . to . be . equal ( false , 'Exception raised when there shouldn\'t have been any' ) ;
288+ } ) ;
174289 test ( 'Debounce: multiple calls grouped' , async ( ) => {
175290 const wait = 100 ;
176291 // tslint:disable-next-line:max-classes-per-file
0 commit comments