1// Copyright (C) 2024 The Android Open Source Project 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15import {SharedAsyncDisposable} from './shared_disposable'; 16 17describe('SharedDisposableAsync', () => { 18 it('allows access to the underlying disposable', async () => { 19 const order: string[] = []; 20 21 const disposable = { 22 [Symbol.asyncDispose]: async () => { 23 order.push('dispose'); 24 }, 25 }; 26 27 const shared = SharedAsyncDisposable.wrap(disposable); 28 29 expect(shared.get()).toBe(disposable); 30 }); 31 32 it('only disposes after refcount drops to 0', async () => { 33 const order: string[] = []; 34 35 const disposable = { 36 [Symbol.asyncDispose]: async () => { 37 order.push('dispose'); 38 }, 39 }; 40 41 order.push('create a'); 42 const a = SharedAsyncDisposable.wrap(disposable); 43 44 order.push('clone b'); 45 const b = a.clone(); 46 47 order.push('dispose a'); 48 await a[Symbol.asyncDispose](); 49 50 order.push('dispose b'); 51 await b[Symbol.asyncDispose](); 52 53 expect(order).toEqual([ 54 'create a', 55 'clone b', 56 'dispose a', 57 'dispose b', 58 'dispose', 59 ]); 60 }); 61 62 it('throws on double dispose', async () => { 63 const disposable = { 64 [Symbol.asyncDispose]: async () => {}, 65 }; 66 67 const shared = SharedAsyncDisposable.wrap(disposable); 68 await shared[Symbol.asyncDispose](); 69 70 // Second dispose should fail 71 await expect(shared[Symbol.asyncDispose]()).rejects.toThrow(); 72 }); 73 74 it('throws on clone after dispose', async () => { 75 const disposable = { 76 [Symbol.asyncDispose]: async () => {}, 77 }; 78 79 const shared = SharedAsyncDisposable.wrap(disposable); 80 await shared[Symbol.asyncDispose](); 81 82 // Clone after dispose should fail 83 expect(() => shared.clone()).toThrow(); 84 }); 85 86 it('reveals isDisposed status', async () => { 87 const disposable = { 88 [Symbol.asyncDispose]: async () => {}, 89 }; 90 91 const shared = SharedAsyncDisposable.wrap(disposable); 92 expect(shared.isDisposed).toBe(false); 93 94 await shared[Symbol.asyncDispose](); 95 expect(shared.isDisposed).toBe(true); 96 }); 97}); 98