Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 12a991ea authored by Simon Chan's avatar Simon Chan
Browse files

chore(struct): fix tests

parent 4d003b7b
Loading
Loading
Loading
Loading
+10 −11
Original line number Diff line number Diff line
@@ -5,8 +5,8 @@ import { StructValue } from "./struct-value.js";
describe('StructValue', () => {
    describe('.constructor', () => {
        it('should create `fieldValues` and `value`', () => {
            const foo = new StructValue();
            const bar = new StructValue();
            const foo = new StructValue({});
            const bar = new StructValue({});

            expect(foo).toHaveProperty('fieldValues', {});
            expect(foo).toHaveProperty('value', {});
@@ -19,14 +19,14 @@ describe('StructValue', () => {

    describe('#set', () => {
        it('should save the `StructFieldValue`', () => {
            const object = new StructValue();
            const object = new StructValue({});

            const foo = 'foo';
            const fooValue = {} as any;
            const fooValue = { get() { return 42; } } as any;
            object.set(foo, fooValue);

            const bar = 'bar';
            const barValue = {} as any;
            const barValue = { get() { return 'foo'; } } as any;
            object.set(bar, barValue);

            expect(object.fieldValues[foo]).toBe(fooValue);
@@ -34,7 +34,7 @@ describe('StructValue', () => {
        });

        it('should define a property for `key`', () => {
            const object = new StructValue();
            const object = new StructValue({});

            const foo = 'foo';
            const fooGetter = jest.fn(() => 42);
@@ -50,21 +50,20 @@ describe('StructValue', () => {

            expect(object.value).toHaveProperty(foo, 42);
            expect(fooGetter).toBeCalledTimes(1);
            expect(barGetter).toBeCalledTimes(0);
            expect(barGetter).toBeCalledTimes(1);

            object.value[foo] = 100;
            expect(fooSetter).toBeCalledTimes(1);
            expect(fooSetter).lastCalledWith(100);
            expect(fooSetter).toBeCalledTimes(0);
            expect(barSetter).toBeCalledTimes(0);
        });
    });

    describe('#get', () => {
        it('should return previously set `StructFieldValue`', () => {
            const object = new StructValue();
            const object = new StructValue({});

            const foo = 'foo';
            const fooValue = {} as any;
            const fooValue = { get() { return 'foo'; } } as any;
            object.set(foo, fooValue);

            expect(object.get(foo)).toBe(fooValue);
+2 −2
Original line number Diff line number Diff line
@@ -291,7 +291,7 @@ describe('Struct', () => {
                const stream = new MockDeserializationStream();
                const result = await struct.deserialize(stream);

                expect(Object.entries(Object.getOwnPropertyDescriptors(result))).toEqual([
                expect(Object.entries(Object.getOwnPropertyDescriptors(Object.getPrototypeOf(result)))).toEqual([
                    ['foo', { configurable: true, enumerable: true, writable: true, value: 42 }],
                    ['bar', { configurable: true, enumerable: true, writable: true, value: true }],
                ]);
@@ -308,7 +308,7 @@ describe('Struct', () => {
                const stream = new MockDeserializationStream();
                const result = await struct.deserialize(stream);

                expect(Object.entries(Object.getOwnPropertyDescriptors(result))).toEqual([
                expect(Object.entries(Object.getOwnPropertyDescriptors(Object.getPrototypeOf(result)))).toEqual([
                    ['foo', { configurable: true, enumerable: true, get: expect.any(Function) }],
                    ['bar', { configurable: true, enumerable: true, get: expect.any(Function), set: expect.any(Function) }],
                ]);
+81 −154
Original line number Diff line number Diff line
import { describe, expect, it, jest, test } from "@jest/globals";
import { describe, expect, it, jest } from "@jest/globals";

import { SyncPromise } from "./sync-promise.js";

describe('SyncPromise', () => {
    describe('constructor', () => {
        it('should call executor', () => {
            const executor = jest.fn((resolve) => {
                setTimeout(() => {
                    resolve(42);
                }, 10);
            });
            new SyncPromise(executor);
            expect(executor).toHaveBeenCalledTimes(1);
        });
function delay(timeout: number) {
    return new Promise(resolve => setTimeout(resolve, timeout));
}

        it('should asynchronously resolve', async () => {
            const promise = new SyncPromise((resolve) => {
                setTimeout(() => {
                    resolve(42);
                }, 10);
            });
            await expect(promise).resolves.toBe(42);
            await expect(promise.then()).resolves.toBe(42);
            await expect(promise.valueOrPromise()).resolves.toBe(42);
        });

        it('should asynchronously reject', async () => {
            const promise = new SyncPromise((_, reject) => {
                setTimeout(() => {
                    reject(new Error('error'));
                }, 10);
            });
            await expect(promise).rejects.toThrow('error');
            await expect(promise.then()).rejects.toThrow('error');
            await expect(promise.valueOrPromise()).rejects.toThrow('error');
describe('SyncPromise', () => {
    describe('.resolve', () => {
        it('should resolve with undefiend', () => {
            const promise = SyncPromise.resolve();
            expect(promise.valueOrPromise()).toBe(undefined);
        });

        it('should synchronously resolve with value', async () => {
            const promise = new SyncPromise((resolve) => {
                resolve(42);
            });
            await expect(promise).resolves.toBe(42);
            await expect(promise.then()).resolves.toBe(42);
        it('should resolve with a value', () => {
            const promise = SyncPromise.resolve(42);
            expect(promise.valueOrPromise()).toBe(42);
        });

        it('should synchronously resolve with promise', async () => {
            const promise = new SyncPromise((resolve) => {
                resolve(
                    new Promise(
                        resolve =>
                            setTimeout(
                                () => resolve(42),
                                10
                            )
                    )
                );
            });
            await expect(promise).resolves.toBe(42);
            await expect(promise.then()).resolves.toBe(42);
        it('should resolve with a promise', async () => {
            const promise = SyncPromise.resolve(Promise.resolve(42));
            await expect(promise.valueOrPromise()).resolves.toBe(42);
        });

        it('should synchronously resolve with resolved SyncPromise', async () => {
            const promise = new SyncPromise((resolve) => {
                resolve(
                    new SyncPromise(
                        resolve =>
                            resolve(42),
                    )
                );
        it('should resolve with a pending SyncPromise', async () => {
            const promise = SyncPromise.resolve(SyncPromise.resolve(Promise.resolve(42)));
            await expect(promise.valueOrPromise()).resolves.toBe(42);
        });
            await expect(promise).resolves.toBe(42);
            await expect(promise.then()).resolves.toBe(42);

        it('should resolve with a resolved SyncPromise', () => {
            const promise = SyncPromise.resolve(SyncPromise.resolve(42));
            expect(promise.valueOrPromise()).toBe(42);
        });

        it('should synchronously resolve with rejected SyncPromise', async () => {
            const promise = new SyncPromise((resolve) => {
                resolve(
                    new SyncPromise(
                        (_, reject) =>
                            reject(new Error('error'))
                    )
                );
            });
            await expect(promise).rejects.toThrowError('error');
            await expect(promise.then()).rejects.toThrowError('error');
        it('should resolve with a rejected SyncPromise', () => {
            const promise = SyncPromise.resolve(SyncPromise.reject(new Error('error')));
            expect(() => promise.valueOrPromise()).toThrowError('error');
        });

        it('should synchronously resolve with unsettled SyncPromise', async () => {
            const promise = new SyncPromise((resolve) => {
                resolve(
                    new SyncPromise(
                        resolve =>
                            setTimeout(
                                () => resolve(42),
                                10
                            )
                    )
                );
            });
            await expect(promise).resolves.toBe(42);
            await expect(promise.then()).resolves.toBe(42);
            await expect(promise.valueOrPromise()).resolves.toBe(42);
    });

        it('should synchronously reject with error', async () => {
            const promise = new SyncPromise((_, reject) => {
                reject(new Error('error'));
    describe('.reject', () => {
        it('should reject with the reason', () => {
            const promise = SyncPromise.reject(new Error('error'));
            expect(() => promise.valueOrPromise()).toThrowError('error');
        });
            await expect(promise).rejects.toThrow('error');
            await expect(promise.then()).rejects.toThrow('error');
            expect(() => promise.valueOrPromise()).toThrow('error');
    });

        it('should catch synchronous error', async () => {
            const promise = new SyncPromise(() => {
                throw new Error('error');
    describe('.try', () => {
        it('should call executor', () => {
            const executor = jest.fn(() => {
                return 42;
            });
            await expect(promise).rejects.toThrow('error');
            await expect(promise.then()).rejects.toThrow('error');
            expect(() => promise.valueOrPromise()).toThrow('error');
            SyncPromise.try(executor);
            expect(executor).toHaveBeenCalledTimes(1);
        });

        describe('should ignore multiple result', () => {
            test('multiple resolves', async () => {
                const promise = new SyncPromise((resolve) => {
                    resolve(42);
                    resolve(43);
                });
                await expect(promise).resolves.toBe(42);
        it('should resolve with a value', () => {
            const promise = SyncPromise.try(() => 42);
            expect(promise.valueOrPromise()).toBe(42);
        });

            test('multiple rejects', async () => {
                const promise = new SyncPromise((_, reject) => {
                    reject(new Error('error'));
                    reject(new Error('error2'));
                });
                await expect(promise).rejects.toThrow('error');
        it('should resolve with a promise', async () => {
            const promise = SyncPromise.try(() => Promise.resolve(42));
            await expect(promise.valueOrPromise()).resolves.toBe(42);
        });

            test('mixed', async () => {
                const promise = new SyncPromise((resolve, reject) => {
                    resolve(42);
                    reject(new Error('error2'));
                });
                await expect(promise).resolves.toBe(42);
        it('should resolve with a pending SyncPromise', async () => {
            const promise = SyncPromise.try(() => SyncPromise.resolve(Promise.resolve(42)));
            await expect(promise.valueOrPromise()).resolves.toBe(42);
        });

            test('mixed with throw', async () => {
                const promise = new SyncPromise((resolve) => {
                    resolve(42);
                    throw new Error('error2');
        it('should resolve with a resolved SyncPromise', () => {
            const promise = SyncPromise.try(() => SyncPromise.resolve(42));
            expect(promise.valueOrPromise()).toBe(42);
        });
                await expect(promise).resolves.toBe(42);

        it('should resolve with a rejected SyncPromise', () => {
            const promise = SyncPromise.try(() => SyncPromise.reject(new Error('error')));
            expect(() => promise.valueOrPromise()).toThrowError('error');
        });

        it('should reject with the error thrown', () => {
            const promise = SyncPromise.try(() => { throw new Error('error'); });
            expect(() => promise.valueOrPromise()).toThrowError('error');
        });
    });

    describe('#then', () => {
        it('chain a sync value', async () => {
            let promise = new SyncPromise(resolve => resolve(42));
            promise = promise.then(() => 'foo');
            await expect(promise).resolves.toBe('foo');
            await expect(promise.then()).resolves.toBe('foo');
            expect(promise.valueOrPromise()).toBe('foo');
        });

        it('chain a async value', async () => {
            let promise = new SyncPromise(resolve => resolve(42));
            promise = promise.then(
                () =>
                    new Promise(
                        (resolve) =>
                            setTimeout(
                                () => resolve('foo'),
                                10
                            )
                    )
            );
            await expect(promise).resolves.toBe('foo');
            await expect(promise.then()).resolves.toBe('foo');
            expect(promise.valueOrPromise()).resolves.toBe('foo');
        it('chain a pending SyncPromise with value', async () => {
            const promise = SyncPromise.resolve(Promise.resolve(42));
            const handler = jest.fn(() => 'foo');
            const result = promise.then(handler);

            await delay(0);

            expect(handler).toBeCalledTimes(1);
            expect(handler).toBeCalledWith(42);

            await expect(result.valueOrPromise()).resolves.toBe('foo');
        });

        it('chian a pending SyncPromise with a promise', async () => {
            const promise = SyncPromise.resolve(Promise.resolve(42));
            const handler = jest.fn(() => Promise.resolve('foo'));
            const result = promise.then(handler);

            await delay(0);

            expect(handler).toBeCalledTimes(1);
            expect(handler).toBeCalledWith(42);

            await expect(result.valueOrPromise()).resolves.toBe('foo');
        });
    });
});
+8 −0
Original line number Diff line number Diff line
@@ -26,6 +26,14 @@ export const SyncPromise: SyncPromiseStatic = {
            value !== null &&
            typeof (value as PromiseLike<T>).then === 'function'
        ) {
            if (
                value instanceof PendingSyncPromise ||
                value instanceof ResolvedSyncPromise ||
                value instanceof RejectedSyncPromise
            ) {
                return value;
            }

            return new PendingSyncPromise(value as PromiseLike<T>);
        } else {
            return new ResolvedSyncPromise(value as T);
+5 −5
Original line number Diff line number Diff line
@@ -69,7 +69,7 @@ describe('Types', () => {
                const context = new MockDeserializationStream();
                const array = new Uint8Array(size);
                context.array = array;
                const struct = new StructValue();
                const struct = new StructValue({});

                const fieldValue = await definition.deserialize(StructDefaultOptions, context, struct);
                expect(context.read).toBeCalledTimes(1);
@@ -86,7 +86,7 @@ describe('Types', () => {
                const context = new MockDeserializationStream();
                const buffer = new Uint8Array(size);
                context.array = buffer;
                const struct = new StructValue();
                const struct = new StructValue({});

                const fieldValue = await definition.deserialize(StructDefaultOptions, context, struct);
                expect(context.read).toBeCalledTimes(0);
@@ -108,7 +108,7 @@ describe('Types', () => {
                    const context = new MockDeserializationStream();
                    const array = new Uint8Array(size);
                    context.array = array;
                    const struct = new StructValue();
                    const struct = new StructValue({});

                    const fieldValue = await definition.deserialize(StructDefaultOptions, context, struct);

@@ -128,7 +128,7 @@ describe('Types', () => {
                    const sourceArray = new Uint8Array(Array.from({ length: size }, (_, i) => i));
                    const array = sourceArray;
                    context.array = array;
                    const struct = new StructValue();
                    const struct = new StructValue({});

                    const fieldValue = await definition.deserialize(StructDefaultOptions, context, struct);

@@ -147,7 +147,7 @@ describe('Types', () => {
                    const sourceArray = new Uint8Array(Array.from({ length: size }, (_, i) => i));
                    const array = sourceArray;
                    context.array = array;
                    const struct = new StructValue();
                    const struct = new StructValue({});

                    const fieldValue = await definition.deserialize(StructDefaultOptions, context, struct);

Loading