• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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