it('should pass the input to factories', async () => {
            await fc.assert(
                fc.asyncProperty(valuesArbitrary, valueArbitrary, valuesArbitrary, async (errors, value, args) => {
                    const failing = errors.map((error) => jest.fn().mockRejectedValue(error))
                    const successful = jest.fn().mockResolvedValue(value)
                    const factory = firstFactory(...failing, successful)

                    expect(await factory(...args)).toBe(value)

                    // Make sure all the tasks got called with the correct arguments
                    for (const factory of failing) {
                        expect(factory).toHaveBeenCalledTimes(1)
                        expect(factory).toHaveBeenCalledWith(...args)
                    }

                    expect(successful).toHaveBeenCalledTimes(1)
                    expect(successful).toHaveBeenCalledWith(...args)
                })
            )
        })


unknown

it('should resolve with the return value of a synchronous task', async () => {
            await fc.assert(
                fc.asyncProperty(valueArbitrary, async (value) => {
                    const task = jest.fn().mockReturnValue(value)
                    const handleError = jest.fn()

                    await expect(mapError(task, handleError)).resolves.toBe(value)
                    expect(handleError).not.toHaveBeenCalled()
                })
            )
        })


it('should resolve with the resolution value of an asynchronous task', async () => {
            await fc.assert(
                fc.asyncProperty(valueArbitrary, async (value) => {
                    const task = jest.fn().mockResolvedValue(value)
                    const handleError = jest.fn()

                    await expect(mapError(task, handleError)).resolves.toBe(value)
                    expect(handleError).not.toHaveBeenCalled()
                })
            )
        })


it('should reject and call the toError callback if a synchronous task throws', async () => {
            await fc.assert(
                fc.asyncProperty(valueArbitrary, valueArbitrary, async (error, mappedError) => {
                    const task = jest.fn().mockImplementation(() => {
                        throw error
                    })
                    const handleError = jest.fn().mockReturnValue(mappedError)

                    await expect(mapError(task, handleError)).rejects.toBe(mappedError)
                    expect(handleError).toHaveBeenCalledOnce()
                    expect(handleError).toHaveBeenCalledExactlyOnceWith(error)
                })
            )
        })


it('should reject and call the toError callback if an asynchronous task rejects', async () => {
            await fc.assert(
                fc.asyncProperty(valueArbitrary, valueArbitrary, async (error, mappedError) => {
                    const task = jest.fn().mockRejectedValue(error)
                    const handleError = jest.fn().mockReturnValue(mappedError)

                    await expect(mapError(task, handleError)).rejects.toBe(mappedError)
                    expect(handleError).toHaveBeenCalledOnce()
                    expect(handleError).toHaveBeenCalledExactlyOnceWith(error)
                })
            )
        })


it('should resolve with the return value of a synchronous task', async () => {
            await fc.assert(
                fc.asyncProperty(valueArbitrary, async (value) => {
                    const task = jest.fn().mockReturnValue(value)
                    const handleError = jest.fn()

                    await expect(tapError(task, handleError)).resolves.toBe(value)
                    expect(handleError).not.toHaveBeenCalled()
                })
            )
        })


it('should resolve with the resolution value of an asynchronous task', async () => {
            await fc.assert(
                fc.asyncProperty(valueArbitrary, async (value) => {
                    const task = jest.fn().mockResolvedValue(value)
                    const handleError = jest.fn()

                    await expect(tapError(task, handleError)).resolves.toBe(value)
                    expect(handleError).not.toHaveBeenCalled()
                })
            )
        })


it('should reject and call the onError callback if a synchronous task throws', async () => {
            await fc.assert(
                fc.asyncProperty(valueArbitrary, async (error) => {
                    const task = jest.fn().mockImplementation(() => {
                        throw error
                    })
                    const handleError = jest.fn()

                    await expect(tapError(task, handleError)).rejects.toBe(error)
                    expect(handleError).toHaveBeenCalledOnce()
                    expect(handleError).toHaveBeenCalledExactlyOnceWith(error)
                })
            )
        })


it('should reject and call the onError callback if an asynchronous task rejects', async () => {
            await fc.assert(
                fc.asyncProperty(valueArbitrary, async (error) => {
                    const task = jest.fn().mockRejectedValue(error)
                    const handleError = jest.fn()

                    await expect(tapError(task, handleError)).rejects.toBe(error)
                    expect(handleError).toHaveBeenCalledOnce()
                    expect(handleError).toHaveBeenCalledExactlyOnceWith(error)
                })
            )
        })


it('should reject with the original error if the onError callback throws', async () => {
            await fc.assert(
                fc.asyncProperty(valueArbitrary, valueArbitrary, async (error, anotherError) => {
                    const task = jest.fn().mockRejectedValue(error)
                    const handleError = jest.fn().mockImplementation(() => {
                        throw anotherError
                    })

                    await expect(tapError(task, handleError)).rejects.toBe(error)
                    expect(handleError).toHaveBeenCalledOnce()
                    expect(handleError).toHaveBeenCalledExactlyOnceWith(error)
                })
            )
        })


it('should reject with the original error if the onError callback rejects', async () => {
            await fc.assert(
                fc.asyncProperty(valueArbitrary, valueArbitrary, async (error, anotherError) => {
                    const task = jest.fn().mockRejectedValue(error)
                    const handleError = jest.fn().mockRejectedValue(anotherError)

                    await expect(tapError(task, handleError)).rejects.toBe(error)
                    expect(handleError).toHaveBeenCalledOnce()
                    expect(handleError).toHaveBeenCalledExactlyOnceWith(error)
                })
            )
        })


it('should throw', () => {
                fc.assert(
                    fc.property(numAttemptsArbitrary, (numAttempts) => {
                        expect(() => createSimpleRetryStrategy(numAttempts)).toThrow()
                    })
                )
            })


it('should return a function that returns true until numAttempts is reached', () => {
                    fc.assert(
                        fc.property(numAttemptsArbitrary, (numAttempts) => {
                            const strategy = createSimpleRetryStrategy(numAttempts)

                            // The first N attempts should return true since we want to retry them
                            for (let attempt = 1; attempt <= numAttempts; attempt++) {
                                expect(strategy(attempt, 'error', [], [])).toBeTruthy()
                            }

                            // The N+1th attempt should return false
                            expect(strategy(numAttempts + 1, 'error', [], [])).toBeFalsy()
                        })
                    )
                })


it('should return false if the amount of attempts has been reached, the wrapped strategy value otherwise', () => {
                    fc.assert(
                        fc.property(numAttemptsArbitrary, (numAttempts) => {
                            // We'll create a simple wrapped strategy
                            const wrappedStrategy = (attempt: number) => [attempt]
                            const strategy = createSimpleRetryStrategy(numAttempts, wrappedStrategy)

                            // The first N attempts should return the return value of the wrapped strategy
                            for (let attempt = 1; attempt <= numAttempts; attempt++) {
                                expect(strategy(attempt, 'error', [0], [0])).toEqual(wrappedStrategy(attempt))
                            }

                            // The N+1th attempt should return false
                            expect(strategy(numAttempts + 1, 'error', [0], [0])).toBeFalsy()
                        })
                    )
                })


it('should have addition, update and deletion working correctly', () => {
                fc.assert(
                    fc.property(keyArbitrary, valueArbitrary, valueArbitrary, (key, value1, value2) => {
                        const map = new TestMap()

                        // Sanity check first
                        expect(map.has(key)).toBeFalsy()

                        // Set a value first
                        map.set(key, value1)

                        // Check whether the insertion worked
                        expect(map.has(key)).toBeTruthy()
                        expect(map.size).toBe(1)
                        expect(map.get(key)).toBe(value1)
                        expect(Array.from(map.keys())).toEqual([key])
                        expect(Array.from(map.values())).toEqual([value1])
                        expect(Array.from(map.entries())).toEqual([[key, value1]])

                        // Now overwrite the value
                        map.set(key, value2)

                        // Check whether the insertion worked
                        expect(map.has(key)).toBeTruthy()
                        expect(map.size).toBe(1)
                        expect(map.get(key)).toBe(value2)
                        expect(Array.from(map.keys())).toEqual([key])
                        expect(Array.from(map.values())).toEqual([value2])
                        expect(Array.from(map.entries())).toEqual([[key, value2]])

                        // Now delete the value
                        map.delete(key)

                        // And check that the deletion worked
                        expect(map.has(key)).toBeFalsy()
                        expect(map.size).toBe(0)
                        expect(map.get(key)).toBeUndefined()
                        expect(Array.from(map.keys())).toEqual([])
                        expect(Array.from(map.values())).toEqual([])
                        expect(Array.from(map.entries())).toEqual([])
                    })
                )
            })


it('should instantiate from entries', () => {
                fc.assert(
                    fc.property(fc.array(fc.tuple(keyArbitrary, valueArbitrary)), (entries) => {
                        const map = new TestMap(entries)

                        // This looks like the simplest way of deduplicating the entries
                        //
                        // For the test below we want to make sure that we check that the map
                        // contains the last value belonging to a key - entries can contain
                        // duplicate keys so we need this helper data structure to store the last value set for a key
                        const valuesByHash = Object.fromEntries(entries.map(([key, value]) => [hash(key), value]))

                        for (const [key] of entries) {
                            const hashedKey = hash(key)
                            expect(hashedKey in valuesByHash).toBeTruthy()

                            const value = valuesByHash[hashedKey]

                            expect(map.has(key)).toBeTruthy()
                            expect(map.get(key)).toBe(value)
                        }
                    })
                )
            })


it('should clear correctly', () => {
                fc.assert(
                    fc.property(fc.array(fc.tuple(keyArbitrary, valueArbitrary)), (entries) => {
                        const map = new TestMap(entries)

                        map.clear()

                        expect(map.size).toBe(0)
                        expect(Array.from(map.keys())).toEqual([])
                        expect(Array.from(map.values())).toEqual([])
                        expect(Array.from(map.entries())).toEqual([])
                    })
                )
            })


it('should call forEach correctly', () => {
                fc.assert(
                    fc.property(fc.array(fc.tuple(keyArbitrary, valueArbitrary)), (entries) => {
                        const map = new TestMap(entries)
                        const callback = jest.fn()

                        map.forEach(callback)

                        // We'll get the entries from the map since the original entries
                        // might contain duplicates
                        const mapEntries = Array.from(map.entries())
                        expect(callback).toHaveBeenCalledTimes(mapEntries.length)

                        for (const [key, value] of mapEntries) {
                            expect(callback).toHaveBeenCalledWith(value, key, map)
                        }
                    })
                )
            })


it('should use orElse if a key is not defined', () => {
                fc.assert(
                    fc.property(keyArbitrary, valueArbitrary, valueArbitrary, (key, value, orElseValue) => {
                        const map = new TestMap()
                        const orElse = jest.fn().mockReturnValue(orElseValue)

                        // Sanity check first
                        expect(map.has(key)).toBeFalsy()

                        // If the key has not been set, the map should use orElse
                        expect(map.getOrElse(key, orElse)).toBe(orElseValue)

                        // Set a value first
                        map.set(key, value)

                        // And check that orElse is not being used
                        expect(map.getOrElse(key, orElse)).toBe(value)

                        // Now delete the value
                        map.delete(key)

                        // And check that orElse is being used again
                        expect(map.getOrElse(key, orElse)).toBe(orElseValue)
                    })
                )
            })


it('should normalize a nullish value to empty bytes', () => {
                fc.assert(
                    fc.property(evmEndpointArbitrary, nullishArbitrary, (eid, address) => {
                        const normalized = normalizePeer(address, eid)
                        const denormalized = denormalizePeer(normalized, eid)

                        expect(normalized).toEqual(new Uint8Array(32))
                        expect(isZero(normalized)).toBe(true)
                        expect(isZero(denormalized)).toBe(true)
                    })
                )
            })


it('should normalize a peer correctly', () => {
                fc.assert(
                    fc.property(evmEndpointArbitrary, evmAddressArbitrary, (eid, address) => {
                        const normalized = normalizePeer(address, eid)
                        const denormalized = denormalizePeer(normalized, eid)

                        expect(denormalized).toBe(address)
                    })
                )
            })


it('should normalize a nullish value to empty bytes', () => {
                fc.assert(
                    fc.property(aptosEndpointArbitrary, nullishArbitrary, (eid, address) => {
                        const normalized = normalizePeer(address, eid)
                        const denormalized = denormalizePeer(normalized, eid)

                        expect(normalized).toEqual(new Uint8Array(32))
                        expect(isZero(normalized)).toBe(true)
                        expect(isZero(denormalized)).toBe(true)
                    })
                )
            })


it('should normalize a peer correctly', () => {
                fc.assert(
                    fc.property(aptosEndpointArbitrary, aptosAddressArbitrary, (eid, address) => {
                        const normalized = normalizePeer(address, eid)
                        const denormalized = denormalizePeer(normalized, eid)

                        expect(denormalized).toBe(address)
                    })
                )
            })


it('should normalize a nullish value to empty bytes', () => {
                fc.assert(
                    fc.property(solanaEndpointArbitrary, nullishArbitrary, (eid, address) => {
                        const normalized = normalizePeer(address, eid)
                        const denormalized = denormalizePeer(normalized, eid)

                        expect(normalized).toEqual(new Uint8Array(32))
                        expect(isZero(normalized)).toBe(true)
                        expect(isZero(denormalized)).toBe(true)
                    })
                )
            })


it('should normalize a peer correctly', () => {
                fc.assert(
                    fc.property(solanaEndpointArbitrary, solanaAddressArbitrary, (eid, address) => {
                        const normalized = normalizePeer(address, eid)
                        const denormalized = denormalizePeer(normalized, eid)

                        expect(denormalized).toBe(address)
                    })
                )
            })


it('should return true for identical values', () => {
            fc.assert(
                fc.property(fc.anything(), (value) => {
                    expect(isDeepEqual(value, value)).toBeTruthy()
                })
            )
        })


it('should return true for arrays containing the same values', () => {
            fc.assert(
                fc.property(arrayArbitrary, (array) => {
                    expect(isDeepEqual(array, [...array])).toBeTruthy()
                    expect(isDeepEqual([...array], array)).toBeTruthy()
                })
            )
        })


it('should return false for arrays containing different values', () => {
            fc.assert(
                fc.property(arrayArbitrary, arrayArbitrary, (arrayA, arrayB) => {
                    // We'll do a very simplified precondition - we'll only run tests when the first elements are different
                    fc.pre(!isDeepEqual(arrayA[0], arrayB[0]))

                    expect(isDeepEqual(arrayA, arrayB)).toBeFalsy()
                    expect(isDeepEqual(arrayB, arrayA)).toBeFalsy()
                })
            )
        })


it('should return false for arrays containing more values', () => {
            fc.assert(
                fc.property(arrayArbitrary, fc.anything(), (array, extraValue) => {
                    expect(isDeepEqual(array, [...array, extraValue])).toBeFalsy()
                    expect(isDeepEqual([...array, extraValue], array)).toBeFalsy()
                })
            )
        })


it('should return true for sets containing the same values', () => {
            fc.assert(
                fc.property(arrayArbitrary, (array) => {
                    const setA = new Set(array)
                    const setB = new Set(array)

                    expect(isDeepEqual(setA, setB)).toBeTruthy()
                    expect(isDeepEqual(setB, setA)).toBeTruthy()
                })
            )
        })


it('should return true for maps containing the same values', () => {
            fc.assert(
                fc.property(entriesArbitrary, (entries) => {
                    const mapA = new Map(entries)
                    const mapB = new Map(entries)

                    expect(isDeepEqual(mapA, mapB)).toBeTruthy()
                    expect(isDeepEqual(mapB, mapA)).toBeTruthy()
                })
            )
        })


it('should return true for objects containing the same values', () => {
            fc.assert(
                fc.property(
                    fc.record({
                        value: fc.anything(),
                    }),
                    (object) => {
                        expect(isDeepEqual(object, { ...object })).toBeTruthy()
                        expect(isDeepEqual({ ...object }, object)).toBeTruthy()
                    }
                )
            )
        })


it('should return false for objects containing different values', () => {
            fc.assert(
                fc.property(
                    fc.record({
                        value: fc.anything(),
                    }),
                    fc.anything(),
                    (object, value) => {
                        fc.pre(!isDeepEqual(object.value, value))

                        expect(isDeepEqual(object, { value })).toBeFalsy()
                        expect(isDeepEqual({ value }, object)).toBeFalsy()
                    }
                )
            )
        })


it('should serialize an internal message', () => {
            fc.assert(
                fc.property(fc.bigInt({ min: 0n, max: 1000n }), fc.boolean(), cellArbitrary, (value, bounce, body) => {
                    const messageRelaxed = internal({
                        value,
                        to: wallet.address,
                        bounce,
                        body,
                    })

                    const serialized = serializeMessageRelaxed(messageRelaxed)
                    const deserialized = deserializeMessageRelaxed(serialized)

                    // FIXME Jest comparison operators don't work well with message objects
                    // so a workaround expectation is used
                    //
                    // See https://github.com/ton-core/ton-core/blob/e0ed819973daf0484dfbacd0c30a0dcfe4714f8d/src/types/MessageRelaxed.spec.ts
                    expect(Cell.fromBase64(serialized).equals(messageRelaxedToCell(messageRelaxed))).toBeTruthy()

                    const reserialized = serializeMessageRelaxed(deserialized)
                    expect(reserialized).toEqual(serialized)
                })
            )
        })


it('should serialize an external message', () => {
            fc.assert(
                fc.property(cellArbitrary, (body) => {
                    const message = external({
                        to: wallet.address,
                        body,
                    })

                    const serialized = serializeMessage(message)
                    const deserialized = deserializeMessage(serialized)

                    // FIXME Jest comparison operators don't work well with message objects
                    // so a workaround expectation is used
                    //
                    // See https://github.com/ton-core/ton-core/blob/e0ed819973daf0484dfbacd0c30a0dcfe4714f8d/src/types/MessageRelaxed.spec.ts
                    expect(Cell.fromBase64(serialized).equals(messageToCell(message))).toBeTruthy()

                    const reserialized = serializeMessage(deserialized)
                    expect(reserialized).toEqual(serialized)
                })
            )
        })


it('should serialize an external message', () => {
            fc.assert(
                fc.property(cellArbitrary, (body) => {
                    const message = external({
                        to: wallet.address,
                        body,
                    })

                    const serialized = serializeMessage(message)
                    const deserialized = deserialize(serialized)

                    // FIXME Jest comparison operators don't work well with message objects
                    // so a workaround expectation is used
                    //
                    // See https://github.com/ton-core/ton-core/blob/e0ed819973daf0484dfbacd0c30a0dcfe4714f8d/src/types/MessageRelaxed.spec.ts
                    expect(Cell.fromBase64(serialized).equals(messageToCell(message))).toBeTruthy()

                    const reserialized = serializeMessage(deserialized as Message)
                    expect(reserialized).toEqual(serialized)
                })
            )
        })


it('should serialize an internal message', () => {
            fc.assert(
                fc.property(fc.bigInt({ min: 0n, max: 1000n }), fc.boolean(), cellArbitrary, (value, bounce, body) => {
                    const messageRelaxed = internal({
                        value,
                        to: wallet.address,
                        bounce,
                        body,
                    })

                    const serialized = serializeMessageRelaxed(messageRelaxed)
                    const deserialized = deserialize(serialized)

                    // FIXME Jest comparison operators don't work well with message objects
                    // so a workaround expectation is used
                    //
                    // See https://github.com/ton-core/ton-core/blob/e0ed819973daf0484dfbacd0c30a0dcfe4714f8d/src/types/MessageRelaxed.spec.ts
                    expect(Cell.fromBase64(serialized).equals(messageRelaxedToCell(messageRelaxed))).toBeTruthy()

                    const reserialized = serializeMessage(deserialized as Message)
                    expect(reserialized).toEqual(serialized)
                })
            )
        })


it('should throw if passed an invalid message', () => {
            fc.assert(
                fc.property(fc.base64String(), (serialized) => {
                    expect(() => deserialize(serialized)).toThrow(/Failed to deserialize data./)
                })
            )
        })


it('should sign a transaction', async () => {
                await fc.assert(
                    fc.asyncProperty(
                        endpointArbitrary,
                        solanaAddressArbitrary,
                        keypairArbitrary,
                        keypairArbitrary,
                        async (eid, address, sender, recipient) => {
                            const transfer = SystemProgram.transfer({
                                fromPubkey: sender.publicKey,
                                toPubkey: recipient.publicKey,
                                lamports: 49,
                            })

                            const connection = new Connection('http://soyllama.com')
                            const omniSigner = new OmniSignerSolana(eid, connection, sender)

                            const transaction = new Transaction().add(transfer)
                            transaction.recentBlockhash = 'EETubP5AKHgjPAhzPAFcb8BAY1hMH639CWCFTqi3hq1k'
                            transaction.feePayer = sender.publicKey

                            const omniTransaction: OmniTransaction = {
                                point: { eid, address },
                                data: serializeTransactionMessage(transaction),
                            }

                            const signature = await omniSigner.sign(omniTransaction)
                            const serializedTransaction = (transaction.sign(sender), transaction.serialize())

                            expect(deserializeTransactionBuffer(signature)).toEqual(serializedTransaction)
                        }
                    )
                )
            })


it('should sign and send a transaction', async () => {
                await fc.assert(
                    fc.asyncProperty(
                        endpointArbitrary,
                        solanaAddressArbitrary,
                        keypairArbitrary,
                        keypairArbitrary,
                        fc.string(),
                        async (eid, address, sender, recipient, transactionHash) => {
                            sendAndConfirmTransactionMock.mockResolvedValue(transactionHash)

                            const transfer = SystemProgram.transfer({
                                fromPubkey: sender.publicKey,
                                toPubkey: recipient.publicKey,
                                lamports: 49,
                            })

                            const connection = new Connection('http://soyllama.com')
                            const omniSigner = new OmniSignerSolana(eid, connection, sender)

                            const transaction = new Transaction().add(transfer)
                            transaction.recentBlockhash = 'EETubP5AKHgjPAhzPAFcb8BAY1hMH639CWCFTqi3hq1k'
                            transaction.feePayer = sender.publicKey

                            const omniTransaction: OmniTransaction = {
                                point: { eid, address },
                                data: serializeTransactionMessage(transaction),
                            }

                            const response = await omniSigner.signAndSend(omniTransaction)
                            expect(response).toEqual({
                                transactionHash,
                                wait: expect.any(Function),
                            })

                            expect(await response.wait()).toEqual({ transactionHash })
                        }
                    )
                )
            })


it('should throw an error', async () => {
                await fc.assert(
                    fc.asyncProperty(
                        endpointArbitrary,
                        solanaAddressArbitrary,
                        keypairArbitrary,
                        keypairArbitrary,
                        async (eid, address, sender, recipient) => {
                            const transfer = SystemProgram.transfer({
                                fromPubkey: sender.publicKey,
                                toPubkey: recipient.publicKey,
                                lamports: 49,
                            })

                            const connection = new Connection('http://soyllama.com')
                            const multiSigAddress = PublicKey.default
                            const wallet = Keypair.generate()
                            const omniSigner: OmniSigner = new OmniSignerSolanaSquads(
                                eid,
                                connection,
                                multiSigAddress,
                                wallet
                            )

                            const transaction = new Transaction().add(transfer)
                            transaction.recentBlockhash = 'EETubP5AKHgjPAhzPAFcb8BAY1hMH639CWCFTqi3hq1k'
                            transaction.feePayer = sender.publicKey

                            const omniTransaction: OmniTransaction = {
                                point: { eid, address },
                                data: serializeTransactionMessage(transaction),
                            }

                            await expect(omniSigner.sign(omniTransaction)).rejects.toThrow(
                                'OmniSignerSolanaSquads does not support the sign() method. Please use signAndSend().'
                            )
                        }
                    )
                )
            })


it('should work', async () => {
            await fc.assert(
                fc.asyncProperty(keypairArbitrary, keypairArbitrary, async (sender, recipient) => {
                    const transfer = SystemProgram.transfer({
                        fromPubkey: sender.publicKey,
                        toPubkey: recipient.publicKey,
                        lamports: 49,
                    })

                    const transaction = new Transaction().add(transfer)

                    // Transaction in Solana require a recent block hash to be set in order for them to be serialized
                    transaction.recentBlockhash = 'EETubP5AKHgjPAhzPAFcb8BAY1hMH639CWCFTqi3hq1k'

                    // Transactions in Solana require a fee payer to be set in order for them to be serialized
                    transaction.feePayer = sender.publicKey

                    // First we serialize the transaction
                    const serializedTransaction = serializeTransactionMessage(transaction)
                    // Then we deserialize it
                    const deserializedTransaction = deserializeTransactionMessage(serializedTransaction)
                    // And check that the fields match the original transaction
                    //
                    // The reason why we don't compare the transactions directly is that the signers will not match
                    // after deserialization (the signers get stripped out of the original transaction)
                    expect(deserializedTransaction.instructions).toEqual(transaction.instructions)
                    expect(deserializedTransaction.recentBlockhash).toEqual(transaction.recentBlockhash)
                    expect(deserializedTransaction.feePayer).toEqual(transaction.feePayer)

                    // Now we serialize the deserialized transaction again and check that it fully matches the serialized transaction
                    const reserializedTransaction = serializeTransactionMessage(deserializedTransaction)
                    expect(reserializedTransaction).toEqual(serializedTransaction)
                })
            )
        })


it('should add a feePayer and the latest block hash to the transaction', async () => {
            await fc.assert(
                fc.asyncProperty(
                    endpointArbitrary,
                    solanaAddressArbitrary,
                    keypairArbitrary,
                    keypairArbitrary,
                    solanaBlockhashArbitrary,
                    async (eid, address, sender, recipient, blockhash) => {
                        class TestOmniSDK extends OmniSDK {
                            test() {
                                const transfer = SystemProgram.transfer({
                                    fromPubkey: sender.publicKey,
                                    toPubkey: recipient.publicKey,
                                    lamports: 49,
                                })
                                const transaction = new Transaction().add(transfer)

                                return this.createTransaction(transaction)
                            }
                        }

                        const connection = new Connection('http://soyllama.com')
                        jest.spyOn(connection, 'getLatestBlockhash').mockResolvedValue({
                            blockhash,
                            lastValidBlockHeight: NaN,
                        })

                        const sdk = new TestOmniSDK(connection, { eid, address }, sender.publicKey)
                        const omniTransaction = await sdk.test()

                        expect(omniTransaction).toEqual({
                            data: expect.any(String),
                            point: { eid, address },
                        })
                    }
                )
            )
        })


it('should reject if urlFactory throws', async () => {
            await fc.assert(
                fc.asyncProperty(errorArbitrary, endpointArbitrary, async (error, eid) => {
                    const urlFactory = jest.fn().mockImplementation(() => {
                        throw error
                    })
                    const providerFactory = createConnectionFactory(urlFactory)

                    await expect(providerFactory(eid)).rejects.toBe(error)
                })
            )
        })


it('should reject if urlFactory rejects', async () => {
            await fc.assert(
                fc.asyncProperty(errorArbitrary, endpointArbitrary, async (error, eid) => {
                    const urlFactory = jest.fn().mockRejectedValue(error)
                    const providerFactory = createConnectionFactory(urlFactory)

                    await expect(providerFactory(eid)).rejects.toBe(error)
                })
            )
        })


it('should resolve with Connection if urlFactory returns a URL', async () => {
            await fc.assert(
                fc.asyncProperty(urlArbitrary, endpointArbitrary, async (url, eid) => {
                    const urlFactory = jest.fn().mockReturnValue(url)
                    const connectionFactory = createConnectionFactory(urlFactory)
                    const connection = await connectionFactory(eid)

                    expect(connection).toBeInstanceOf(Connection)
                    expect(connection.rpcEndpoint).toBe(url)
                })
            )
        })


it('should resolve with JsonRpcProvider if urlFactory resolves with a URL', async () => {
            await fc.assert(
                fc.asyncProperty(urlArbitrary, endpointArbitrary, async (url, eid) => {
                    const urlFactory = jest.fn().mockResolvedValue(url)
                    const connectionFactory = createConnectionFactory(urlFactory)
                    const connection = await connectionFactory(eid)

                    expect(connection).toBeInstanceOf(Connection)
                    expect(connection.rpcEndpoint).toBe(url)
                })
            )
        })


it('should throw an error for other endpoints', () => {
            fc.assert(
                fc.property(endpointArbitrary, (eid) => {
                    fc.pre(eid !== EndpointId.SOLANA_V2_MAINNET)
                    fc.pre(eid !== EndpointId.SOLANA_V2_TESTNET)
                    fc.pre(eid !== EndpointId.SOLANA_MAINNET)
                    fc.pre(eid !== EndpointId.SOLANA_TESTNET)

                    expect(() => defaultRpcUrlFactory(eid)).toThrow(
                        `Could not find a default Solana RPC URL for eid ${eid} (${formatEid(eid)})`
                    )
                })
            )
        })


it('should parse a BN instance', () => {
            fc.assert(
                fc.property(bnArbitrary, (bn) => {
                    expect(BNBigIntSchema.parse(bn)).toBe(BigInt(bn.toString()))
                })
            )
        })


it('should not parse anything else', () => {
            fc.assert(
                fc.property(fc.anything(), (value) => {
                    expect(() => BNBigIntSchema.parse(value)).toThrow(/Input not instance of BN/)
                })
            )
        })


it('should parse a PublicKey instance', () => {
            fc.assert(
                fc.property(
                    keypairArbitrary.map((keypair) => keypair.publicKey),
                    (publicKey) => {
                        expect(PublicKeySchema.parse(publicKey)).toBe(publicKey)
                    }
                )
            )
        })


it('should not parse anything else', () => {
            fc.assert(
                fc.property(fc.anything(), (value) => {
                    expect(() => PublicKeySchema.parse(value)).toThrow(/Input not instance of PublicKey/)
                })
            )
        })


it('should return undefined if the account has not been initialized', async () => {
            getAccountInfoMock.mockResolvedValue(null)

            await fc.assert(
                fc.asyncProperty(solanaEndpointArbitrary, keypairArbitrary, async (eid, keypair) => {
                    fc.pre(eid !== EndpointId.SOLANA_V2_SANDBOX)

                    const address = keypair.publicKey.toBase58()

                    const connection = await connectionFactory(oftConfig.eid)
                    const getAccountInfo = createGetAccountInfo(connection)

                    expect(await getAccountInfo(address)).toBeUndefined()
                })
            )
        })


it('should serialize correctly with a message', () => {
            fc.assert(
                fc.property(messageArbitrary, (message) => {
                    fc.pre(message !== '')

                    expect(String(new UnknownError(message))).toBe(`UnknownError: ${message}`)
                })
            )
        })


it('should serialize correctly when message is not passed', () => {
            fc.assert(
                fc.property(reasonArbitrary, (reason) => {
                    expect(String(new PanicError(reason))).toBe(
                        `PanicError: Contract panicked (assert() has been called). Error code ${reason}`
                    )
                })
            )
        })


it('should serialize correctly when message is empty', () => {
            fc.assert(
                fc.property(reasonArbitrary, (reason) => {
                    expect(String(new PanicError(reason, ''))).toBe(`PanicError. Error code ${reason}`)
                })
            )
        })


it('should serialize correctly with a message', () => {
            fc.assert(
                fc.property(reasonArbitrary, messageArbitrary, (reason, message) => {
                    fc.pre(message !== '')

                    expect(String(new PanicError(reason, message))).toBe(`PanicError: ${message}. Error code ${reason}`)
                })
            )
        })


it('should serialize correctly when message is not passed', () => {
            fc.assert(
                fc.property(reasonArbitrary, (reason) => {
                    expect(String(new RevertError(reason))).toBe(
                        `RevertError: Contract reverted. Error reason '${reason}'`
                    )
                })
            )
        })


it('should serialize correctly when message is empty', () => {
            fc.assert(
                fc.property(reasonArbitrary, (reason) => {
                    expect(String(new RevertError(reason, ''))).toBe(`RevertError. Error reason '${reason}'`)
                })
            )
        })


it('should serialize correctly with a message', () => {
            fc.assert(
                fc.property(reasonArbitrary, messageArbitrary, (reason, message) => {
                    fc.pre(message !== '')

                    expect(String(new RevertError(reason, message))).toBe(
                        `RevertError: ${message}. Error reason '${reason}'`
                    )
                })
            )
        })


it('should serialize correctly when args are empty', () => {
            fc.assert(
                fc.property(reasonArbitrary, (reason) => {
                    expect(String(new CustomError(reason, []))).toBe(
                        `CustomError: Contract reverted with custom error. Error ${reason}()`
                    )
                })
            )
        })


it('should serialize correctly when message is not passed', () => {
            fc.assert(
                fc.property(reasonArbitrary, argsArbitrary, (reason, args) => {
                    const formattedArgs = args.map((arg) => printJson(arg, false))

                    expect(String(new CustomError(reason, args))).toBe(
                        `CustomError: Contract reverted with custom error. Error ${reason}(${formattedArgs})`
                    )
                })
            )
        })


it('should serialize correctly when message is empty', () => {
            fc.assert(
                fc.property(reasonArbitrary, argsArbitrary, (reason, args) => {
                    const formattedArgs = args.map((arg) => printJson(arg, false))

                    expect(String(new CustomError(reason, args, ''))).toBe(
                        `CustomError. Error ${reason}(${formattedArgs})`
                    )
                })
            )
        })


it('should serialize correctly with a message', () => {
            fc.assert(
                fc.property(reasonArbitrary, argsArbitrary, messageArbitrary, (reason, args, message) => {
                    fc.pre(message !== '')

                    const formattedArgs = args.map((arg) => printJson(arg, false))

                    expect(String(new CustomError(reason, args, message))).toBe(
                        `CustomError: ${message}. Error ${reason}(${formattedArgs})`
                    )
                })
            )
        })


it('should parse BigNumberish', () => {
            fc.assert(
                fc.property(bigNumberishArbitrary, (bigNumberish) => {
                    expect(BigNumberishSchema.parse(bigNumberish)).toBe(bigNumberish)
                })
            )
        })


it('should parse BigNumberish into a bigint', () => {
            fc.assert(
                fc.property(bigNumberishArbitrary, (bigNumberish) => {
                    const parsed = BigNumberishBigIntSchema.parse(bigNumberish)

                    expect(typeof parsed).toBe('bigint')
                    expect(BigNumber.from(parsed)).toEqual(BigNumber.from(bigNumberish))
                })
            )
        })


it('should parse BigNumberish into a number if within bounds', () => {
            fc.assert(
                fc.property(bigNumberishArbitrary, (bigNumberish) => {
                    fc.pre(BigNumber.from(bigNumberish).abs().lte(BigInt(Number.MAX_SAFE_INTEGER)))

                    const parsed = BigNumberishNumberSchema.parse(bigNumberish)

                    expect(typeof parsed).toBe('number')
                    expect(BigNumber.from(parsed)).toEqual(BigNumber.from(bigNumberish))
                })
            )
        })


it('should throw an error if there is an overflow', () => {
            fc.assert(
                fc.property(bigNumberishArbitrary, (bigNumberish) => {
                    fc.pre(BigNumber.from(bigNumberish).abs().gt(BigInt(Number.MAX_SAFE_INTEGER)))

                    expect(() => BigNumberishNumberSchema.parse(bigNumberish)).toThrow('overflow')
                })
            )
        })


it('should reject if the eid of the transaction does not match the eid of the signer', async () => {
                await fc.assert(
                    fc.asyncProperty(endpointArbitrary, transactionArbitrary, async (eid, transaction) => {
                        fc.pre(eid !== transaction.point.eid)

                        const signer = {} as Signer
                        const omniSigner = new OmniSignerEVM(eid, signer)

                        await expect(() => omniSigner.sign(transaction)).rejects.toThrow(/Could not use signer/)
                    })
                )
            })


it('should sign the transaction using the signer if the eids match', async () => {
                await fc.assert(
                    fc.asyncProperty(
                        transactionArbitrary,
                        signedTransactionArbitrary,
                        async (transaction, signedTransaction) => {
                            const signTransaction = jest.fn().mockResolvedValue(signedTransaction)
                            const signer = { signTransaction } as unknown as Signer
                            const omniSigner = new OmniSignerEVM(transaction.point.eid, signer)

                            expect(await omniSigner.sign(transaction)).toBe(signedTransaction)
                            expect(signTransaction).toHaveBeenCalledWith({
                                to: transaction.point.address,
                                data: transaction.data,
                                value: transaction.value,
                            })
                        }
                    )
                )
            })


it('should reject if the eid of the transaction does not match the eid of the signer', async () => {
                await fc.assert(
                    fc.asyncProperty(endpointArbitrary, transactionArbitrary, async (eid, transaction) => {
                        fc.pre(eid !== transaction.point.eid)

                        const signer = {} as Signer
                        const omniSigner = new OmniSignerEVM(eid, signer)

                        await expect(() => omniSigner.signAndSend(transaction)).rejects.toThrow(/Could not use signer/)
                    })
                )
            })


it('should send the transaction using the signer if the eids match', async () => {
                await fc.assert(
                    fc.asyncProperty(transactionArbitrary, transactionHashArbitrary, async (transaction, hash) => {
                        const sendTransaction = jest.fn().mockResolvedValue({ hash })
                        const signer = { sendTransaction } as unknown as Signer
                        const omniSigner = new OmniSignerEVM(transaction.point.eid, signer)

                        expect(await omniSigner.signAndSend(transaction)).toEqual({ transactionHash: hash })
                        expect(sendTransaction).toHaveBeenCalledWith({
                            to: transaction.point.address,
                            data: transaction.data,
                            value: transaction.value,
                        })
                    })
                )
            })


it('should not be supported', async () => {
                await fc.assert(
                    fc.asyncProperty(
                        evmAddressArbitrary,
                        endpointArbitrary,
                        transactionArbitrary,
                        async (safeAddress, eid, transaction) => {
                            const signer = {} as Signer

                            const apiKit = {
                                getNextNonce: jest.fn(),
                            } as unknown as SafeApiKit

                            const safe = {
                                createTransaction: jest.fn().mockResolvedValue({ data: 'transaction' }),
                                getAddress: jest.fn().mockResolvedValue(safeAddress),
                                signTransaction: jest.fn().mockResolvedValue({ data: { data: '0xsigned' } }),
                            } as unknown as Safe

                            const omniSigner = new GnosisOmniSignerEVM(eid, signer, '', {}, undefined, apiKit, safe)

                            await expect(omniSigner.sign(transaction)).rejects.toThrow(
                                /Signing transactions with safe is currently not supported, use signAndSend instead/
                            )
                        }
                    )
                )
            })


it('should reject if the eid of the transaction does not match the eid of the signer', async () => {
                await fc.assert(
                    fc.asyncProperty(
                        evmAddressArbitrary,
                        endpointArbitrary,
                        transactionArbitrary,
                        async (safeAddress, eid, transaction) => {
                            fc.pre(eid !== transaction.point.eid)

                            const signer = {} as Signer
                            const safe = {
                                createTransaction: jest.fn().mockResolvedValue({ data: 'transaction' }),
                                getAddress: jest.fn().mockResolvedValue(safeAddress),
                                signTransactionHash: jest.fn().mockResolvedValue({ data: 'signature' }),
                            } as unknown as Safe
                            const omniSigner = new GnosisOmniSignerEVM(eid, signer, '', {}, undefined, undefined, safe)

                            await expect(() => omniSigner.signAndSend(transaction)).rejects.toThrow(
                                /Could not use signer/
                            )
                        }
                    )
                )
            })


it('should send the transaction using the signer if the eids match', async () => {
                await fc.assert(
                    fc.asyncProperty(
                        evmAddressArbitrary,
                        transactionArbitrary,
                        transactionHashArbitrary,
                        async (safeAddress, transaction, transactionHash) => {
                            const signer = { getAddress: jest.fn(), sendTransaction: jest.fn() } as unknown as Signer
                            const apiKit = {
                                proposeTransaction: jest.fn(),
                                getNextNonce: jest.fn(),
                            } as unknown as SafeApiKit
                            const safe = {
                                createTransaction: jest.fn().mockResolvedValue({ data: 'transaction' }),
                                getTransactionHash: jest.fn().mockResolvedValue(transactionHash),
                                getAddress: jest.fn().mockResolvedValue(safeAddress),
                                signTransactionHash: jest.fn().mockResolvedValue({ data: 'signature' }),
                            } as unknown as Safe

                            const omniSigner = new GnosisOmniSignerEVM(
                                transaction.point.eid,
                                signer,
                                '',
                                {
                                    safeAddress,
                                },
                                undefined,
                                apiKit,
                                safe
                            )

                            const result = await omniSigner.signAndSend(transaction)
                            expect(result.transactionHash).toEqual(transactionHash)

                            expect(await result.wait()).toEqual({ transactionHash })

                            expect(apiKit.getNextNonce).toHaveBeenCalledWith(safeAddress)
                            expect(apiKit.proposeTransaction).toHaveBeenCalledWith({
                                safeAddress,
                                safeTransactionData: 'transaction',
                                safeTxHash: transactionHash,
                                senderAddress: undefined,
                                senderSignature: 'signature',
                            })
                        }
                    )
                )
            })


it('should reject with no transactions', async () => {
                await fc.assert(
                    fc.asyncProperty(evmAddressArbitrary, endpointArbitrary, async (safeAddress, eid) => {
                        const signer = {} as Signer
                        const safe = {} as unknown as Safe
                        const omniSigner = new GnosisOmniSignerEVM(eid, signer, '', {}, undefined, undefined, safe)

                        await expect(() => omniSigner.signAndSendBatch([])).rejects.toThrow(
                            /signAndSendBatch received 0 transactions/
                        )
                    })
                )
            })


it('should reject if at least one of the transaction eids do not match the signer eid', async () => {
                await fc.assert(
                    fc.asyncProperty(
                        evmAddressArbitrary,
                        endpointArbitrary,
                        fc.array(transactionArbitrary, { minLength: 1 }),
                        async (safeAddress, eid, transactions) => {
                            fc.pre(transactions.some((transaction) => eid !== transaction.point.eid))

                            const signer = {} as Signer
                            const safe = {
                                createTransaction: jest.fn().mockResolvedValue({ data: 'transaction' }),
                                getAddress: jest.fn().mockResolvedValue(safeAddress),
                                signTransactionHash: jest.fn().mockResolvedValue({ data: 'signature' }),
                            } as unknown as Safe
                            const omniSigner = new GnosisOmniSignerEVM(eid, signer, '', {}, undefined, undefined, safe)

                            await expect(() => omniSigner.signAndSendBatch(transactions)).rejects.toThrow(
                                /Could not use signer/
                            )
                        }
                    )
                )
            })


it('should send the transaction using the signer if the eids match', async () => {
                await fc.assert(
                    fc.asyncProperty(
                        evmAddressArbitrary,
                        endpointArbitrary,
                        fc.array(transactionArbitrary, { minLength: 1 }),
                        transactionHashArbitrary,
                        async (safeAddress, eid, transactions, transactionHash) => {
                            const nonce = 17
                            const signer = { getAddress: jest.fn(), sendTransaction: jest.fn() } as unknown as Signer
                            const apiKit = {
                                proposeTransaction: jest.fn(),
                                getNextNonce: jest.fn().mockResolvedValue(nonce),
                            } as unknown as SafeApiKit
                            const safe = {
                                createTransaction: jest.fn().mockResolvedValue({ data: 'transaction' }),
                                getTransactionHash: jest.fn().mockResolvedValue(transactionHash),
                                getAddress: jest.fn().mockResolvedValue(safeAddress),
                                signTransactionHash: jest.fn().mockResolvedValue({ data: 'signature' }),
                            } as unknown as Safe

                            const omniSigner = new GnosisOmniSignerEVM(
                                eid,
                                signer,
                                '',
                                {
                                    safeAddress,
                                },
                                undefined,
                                apiKit,
                                safe
                            )

                            const transactionsWithMatchingEids = transactions.map((t) => ({
                                ...t,
                                point: { ...t.point, eid },
                            }))

                            const result = await omniSigner.signAndSendBatch(transactionsWithMatchingEids)
                            expect(result.transactionHash).toEqual(transactionHash)

                            expect(await result.wait()).toEqual({ transactionHash })

                            expect(safe.createTransaction).toHaveBeenCalledWith({
                                safeTransactionData: transactions.map((t) => ({
                                    to: t.point.address,
                                    data: t.data,
                                    value: String(t.value ?? 0),
                                    operation: OperationType.Call,
                                })),
                                options: { nonce },
                            })

                            expect(apiKit.getNextNonce).toHaveBeenCalledWith(safeAddress)
                            expect(apiKit.proposeTransaction).toHaveBeenCalledWith({
                                safeAddress,
                                safeTransactionData: 'transaction',
                                safeTxHash: transactionHash,
                                senderAddress: undefined,
                                senderSignature: 'signature',
                            })
                        }
                    )
                )
            })


it('should reject if urlFactory throws', async () => {
            await fc.assert(
                fc.asyncProperty(errorArbitrary, endpointArbitrary, async (error, eid) => {
                    const urlFactory = jest.fn().mockImplementation(() => {
                        throw error
                    })
                    const providerFactory = createProviderFactory(urlFactory)

                    await expect(providerFactory(eid)).rejects.toBe(error)
                })
            )
        })


it('should reject if urlFactory rejects', async () => {
            await fc.assert(
                fc.asyncProperty(errorArbitrary, endpointArbitrary, async (error, eid) => {
                    const urlFactory = jest.fn().mockRejectedValue(error)
                    const providerFactory = createProviderFactory(urlFactory)

                    await expect(providerFactory(eid)).rejects.toBe(error)
                })
            )
        })


it('should resolve with JsonRpcProvider if urlFactory returns a URL', async () => {
            await fc.assert(
                fc.asyncProperty(urlArbitrary, endpointArbitrary, async (url, eid) => {
                    const urlFactory = jest.fn().mockReturnValue(url)
                    const providerFactory = createProviderFactory(urlFactory)
                    const provider = await providerFactory(eid)

                    expect(provider).toBeInstanceOf(JsonRpcProvider)
                    expect(provider.connection.url).toBe(url)
                })
            )
        })


it('should resolve with JsonRpcProvider if urlFactory resolves with a URL', async () => {
            await fc.assert(
                fc.asyncProperty(urlArbitrary, endpointArbitrary, async (url, eid) => {
                    const urlFactory = jest.fn().mockResolvedValue(url)
                    const providerFactory = createProviderFactory(urlFactory)
                    const provider = await providerFactory(eid)

                    expect(provider).toBeInstanceOf(JsonRpcProvider)
                    expect(provider.connection.url).toBe(url)
                })
            )
        })


it('should create an OmniPoint with the address of the contract', () => {
            fc.assert(
                fc.property(evmAddressArbitrary, endpointArbitrary, (address, eid) => {
                    const contract = new Contract(address, [])
                    const omniContract: OmniContract = { eid, contract }

                    expect(omniContractToPoint(omniContract)).toEqual({ eid, address })
                })
            )
        })


it('should return address with non-zero address', () => {
            fc.assert(
                fc.property(evmAddressArbitrary, (address) => {
                    fc.pre(address !== AddressZero)

                    expect(makeZeroAddress(address)).toBe(address)
                })
            )
        })


it('should return the same address, just checksumed', () => {
            fc.assert(
                fc.property(evmAddressArbitrary, (address) => {
                    expect(addChecksum(address)).toEqualCaseInsensitive(address)
                })
            )
        })


it('should return a valid EVM address', () => {
            fc.assert(
                fc.property(evmAddressArbitrary, (address) => {
                    expect(isAddress(addChecksum(address))).toBe(true)
                })
            )
        })


it('should return undefined if called with undefined definition', async () => {
            await fc.assert(
                fc.asyncProperty(endpointArbitrary, async (eid) => {
                    await expect(createSignerAddressOrIndexFactory()(eid)).resolves.toBeUndefined()
                })
            )
        })


it('should return address if called with address definition', async () => {
            await fc.assert(
                fc.asyncProperty(evmAddressArbitrary, endpointArbitrary, async (address, eid) => {
                    await expect(createSignerAddressOrIndexFactory({ type: 'address', address })(eid)).resolves.toBe(
                        address
                    )
                })
            )
        })


it('should return index if called with index definition', async () => {
            await fc.assert(
                fc.asyncProperty(fc.integer(), endpointArbitrary, async (index, eid) => {
                    await expect(createSignerAddressOrIndexFactory({ type: 'index', index })(eid)).resolves.toBe(index)
                })
            )
        })


it('should reject if called with a missing named definition', async () => {
            const mockGetNamedAccounts = jest.fn().mockResolvedValue({ wombat: '0xwombat' })
            const mockHre = {
                getNamedAccounts: mockGetNamedAccounts,
            }
            const hreFactory = jest.fn().mockResolvedValue(mockHre)

            await fc.assert(
                fc.asyncProperty(endpointArbitrary, async (eid) => {
                    await expect(
                        createSignerAddressOrIndexFactory({ type: 'named', name: 'no-wombat' }, hreFactory)(eid)
                    ).rejects.toThrow(`Missing named account 'no-wombat' for eid ${formatEid(eid)}`)
                })
            )
        })


it('should resolve with an address if called with a defined named definition', async () => {
            const mockGetNamedAccounts = jest.fn().mockResolvedValue({ wombat: '0xwombat' })
            const mockHre = {
                getNamedAccounts: mockGetNamedAccounts,
            }
            const hreFactory = jest.fn().mockResolvedValue(mockHre)

            await fc.assert(
                fc.asyncProperty(endpointArbitrary, async (eid) => {
                    await expect(
                        createSignerAddressOrIndexFactory({ type: 'named', name: 'wombat' }, hreFactory)(eid)
                    ).resolves.toBe('0xwombat')
                })
            )
        })


it('should not override user values if provided', () => {
            fc.assert(
                fc.property(
                    fc.integer(),
                    fc.string(),
                    mnemonicArbitrary,
                    fc.boolean(),
                    (port, directory, mnemonic, overwriteAccounts) => {
                        expect(
                            resolveSimulationConfig(
                                { port, directory, overwriteAccounts, anvil: { mnemonic } },
                                hre.config
                            )
                        ).toEqual({
                            port,
                            directory: resolve(hre.config.paths.root, directory),
                            overwriteAccounts,
                            anvil: {
                                host: '0.0.0.0',
                                port: 8545,
                                mnemonic,
                            },
                        })
                    }
                )
            )
        })


it('should work with anvil options', async () => {
            await fc.assert(
                fc.asyncProperty(anvilOptionsArbitrary, async (anvilOptions) => {
                    const spec = serializeDockerComposeSpec({
                        version: '3.9',
                        services: {
                            anvil: createEvmNodeServiceSpec(anvilOptions),
                        },
                    })

                    await writeFile(SPEC_FILE_PATH, spec)

                    const result = validateSpec()

                    expect(result.stderr.toString('utf8')).toBe('')
                    expect(result.status).toBe(0)
                }),
                { numRuns: 20 }
            )
        })


it('should work with anvil services', async () => {
            await fc.assert(
                fc.asyncProperty(portArbitrary, servicesArbitrary, async (port, services) => {
                    const spec = serializeDockerComposeSpec({
                        version: '3.9',
                        services: {
                            ...services,
                            rpc: createEvmNodeProxyServiceSpec(port, services),
                        },
                    })

                    await writeFile(SPEC_FILE_PATH, spec)

                    const result = validateSpec()

                    expect(result.stderr.toString('utf8')).toBe('')
                    expect(result.status).toBe(0)
                }),
                { numRuns: 20 }
            )
        })


it('should reject if providerFactory rejects', async () => {
            await fc.assert(
                fc.asyncProperty(pointArbitrary, async (point) => {
                    const error = new Error()
                    const contractFactory = jest.fn().mockResolvedValue(new Contract(makeZeroAddress(undefined), []))
                    const providerFactory = jest.fn().mockRejectedValue(error)
                    const connectedContractFactory = createConnectedContractFactory(contractFactory, providerFactory)

                    await expect(connectedContractFactory(point)).rejects.toBe(error)
                })
            )
        })

Summary: The function should reject if the `providerFactory` throws an error when creating a connected contract.


it('should parse all valid endpoint labels', () => {
            fc.assert(
                fc.property(endpointArbitrary, (eid) => {
                    expect(types.eid.parse('eid', EndpointId[eid]!)).toEqual(eid)
                })
            )
        })

Summary: Parsing a valid endpoint label results in successfully matching its corresponding `eid`.


it('should not parse invalid strings', () => {
            fc.assert(
                fc.property(fc.string(), (eid) => {
                    // We filter out the values that by any slim chance could be valid endpoint IDs
                    fc.pre(EndpointId[eid] == null)
                    fc.pre(EndpointId[parseInt(eid)] == null)

                    expect(() => types.eid.parse('eid', eid)).toThrow()
                })
            )
        })

Summary: Parsing invalid strings with `types.eid.parse` should throw an error when the strings are not valid endpoint IDs.


it('should not parse invalid numbers', () => {
            fc.assert(
                fc.property(fc.integer(), (eid) => {
                    fc.pre(EndpointId[eid] == null)

                    expect(() => types.eid.parse('eid', String(eid))).toThrow()
                })
            )
        })

Summary: The test checks that attempting to parse invalid numbers using `types.eid.parse` results in an exception.


it('should not run tsc', async () => {
            await fc.assert(
                fc.asyncProperty(fc.oneof(fc.string(), fc.constantFrom(undefined)), async (env) => {
                    fc.pre(env !== 'production')

                    const plugin = createDeclarationBuild({ enabled: undefined })

                    await plugin.buildEnd.call(pluginContext)

                    expect(spawnSyncMock).not.toHaveBeenCalled()
                })
            )
        })

Summary: `tsc` should not be run when the environment is not 'production' during the build process.


Summary: Generated 128-bit unsigned integers should be within the range [0, 2^128 - 1].


Summary: Generated 128-bit signed integers should fall within the range \([-2^{127}, 2^{127} - 1]\).


it('Can generate a random symptom given only a name', () => {
		fc.assert(
			fc.property(fc.string(), (name: string) => {
				const symptom = randomSymptom(name);
				return symptom.name === name;
			})
		);
	})

Summary: Generating a random symptom with a specified name results in a symptom with that exact name.


it('Calculates the mean without breaking', () => {
		fc.assert(
			fc.property(
				fc.float64Array(),
				list => typeof mean((list as unknown) as number[]) === 'number'
			)
		);
	})

Summary: The `mean` function should return a numeric result when applied to an array of 64-bit floating-point numbers.


it('Creates a normal variable', () => {
		fc.assert(
			fc.property(
				fc.float(),
				fc.float({ next: false, min: 0.01 }),
				(a, b) => {
					const rv = createNormal('testNormal', a, b);
					return (
						rv._.dist === 'normal' && rv.mean === a && rv.sd === b
					);
				}
			)
		);
	})

Summary: `createNormal` function creates a normal distribution variable with the specified mean and standard deviation.


it('Creates a weibull variable', () => {
		fc.assert(
			fc.property(
				fc.float({ next: false, min: 0.01 }),
				fc.float({ next: false, min: 0.01 }),
				fc.float({ next: false, min: 0.01 }),
				(a, b, c) => {
					const rv = createWeibull('testWeibull', a, b, c);
					return (
						rv._.dist === 'weibull' &&
						rv.threshold === a &&
						rv.shape === b &&
						rv.scale === c
					);
				}
			)
		);
	})

Summary: Creating a Weibull variable ensures the distribution type is 'weibull' and checks that threshold, shape, and scale parameters are accurately set.


it("should do nothing when dependency does not exist", () => {
      fc.assert(
        fc.property(arbDomainName, (packumentName) => {
          let manifest = emptyProjectManifest;

          manifest = removeDependency(manifest, packumentName);

          expect(manifest.dependencies).toEqual({});
        })
      );
    })

Summary: Removing a non-existent dependency from a manifest leaves the dependencies unchanged.


it("should not add testables which already exist", () => {
      fc.assert(
        fc.property(arbDomainName, (packumentName) => {
          let manifest = emptyProjectManifest;

          manifest = addTestable(manifest, packumentName);
          manifest = addTestable(manifest, packumentName);

          expect(manifest.testables).toEqual([packumentName]);
        })
      );
    })

Summary: Adding the same `packumentName` twice to a project manifest should result in it appearing only once in the `testables` array.


it('should have no effect for undefined "scopedRegistries"', () => {
      fc.assert(
        fc.property(arbDomainName, (scope) => {
          const original: UnityProjectManifest = { dependencies: {} };

          const actual = removeScopeFromAllScopedRegistries(original, scope);

          expect(actual).toEqual(original);
        })
      );
    })

Summary: Removing a scope from an undefined "scopedRegistries" in a Unity project manifest should have no effect on the manifest.


it("should be ok for file", () => {
      fc.assert(
        fc.property(arbDomainName, (packumentName) => {
          const input = `file:/path/to/${{ packumentName }}`;
          expect(isZod(input, PackageUrl)).toBeTruthy();
        })
      );
    })

Summary: `isZod` should return true for file URL strings containing a domain name.


it("should be ok for just name", () => {
      fc.assert(
        fc.property(arbDomainName, (packumentName) => {
          expect(isPackageSpec(packumentName)).toBeTruthy();
        })
      );
    })

Summary: `isPackageSpec` should return true for valid domain names.


it("should be ok for name with semantic version", () => {
      fc.assert(
        fc.property(arbDomainName, (packumentName) => {
          const input = `${packumentName}@1.2.3`;
          expect(isPackageSpec(input)).toBeTruthy();
        })
      );
    })

Summary: A package name with a semantic version appended should be recognized as a valid package specification by `isPackageSpec`.


it("should be ok for name with file version", () => {
      fc.assert(
        fc.property(arbDomainName, (packumentName) => {
          const input = `${packumentName}@file:/path/to/${packumentName}`;
          expect(isPackageSpec(input)).toBeTruthy();
        })
      );
    })

Summary: `isPackageSpec` should return true for names formatted with file version syntax.


it("should be ok for name with http version", () => {
      fc.assert(
        fc.property(arbDomainName, (packumentName) => {
          const input = `${packumentName}@http://my.server/${packumentName}`;
          expect(isPackageSpec(input)).toBeTruthy();
        })
      );
    })

Summary: `isPackageSpec` returns true for package names combined with HTTP URLs.


it("should be ok for name with git version", () => {
      fc.assert(
        fc.property(arbDomainName, (packumentName) => {
          const input = `${packumentName}@git@github:user/${packumentName}`;
          expect(isPackageSpec(input)).toBeTruthy();
        })
      );
    })

Summary: `isPackageSpec` returns true for names with a Git version format.


it("should remove from scoped registries", () => {
      fc.assert(
        fc.property(arbNonEmptyManifest, (manifest) => {
          const packageName = recordKeys(manifest.dependencies)[0]!;

          const [updated] = tryRemoveProjectDependency(
            manifest,
            packageName
          ).unwrap();

          const anyScopedRegistryHasScope =
            updated.scopedRegistries?.some((it) =>
              it.scopes.includes(packageName)
            ) ?? false;
          expect(anyScopedRegistryHasScope).toBeFalsy();
        })
      );
    })

Summary: Removing a project dependency from a manifest should result in no scoped registries containing the dependency's scope.


it("should remove scoped registries property if empty", () => {
      fc.assert(
        fc.property(arbManifestWithDependencyCount(1), (manifest) => {
          const packageName = recordKeys(manifest.dependencies)[0]!;

          const [updated] = tryRemoveProjectDependency(
            manifest,
            packageName
          ).unwrap();

          expect(updated.scopedRegistries).not.toBeDefined();
        })
      );
    })

Summary: Removing a project dependency from a manifest should result in the `scopedRegistries` property being undefined if it becomes empty.


it("should have correct change for added dependency", () => {
      fc.assert(
        fc.property(
          arbManifest,
          arbDomainName,
          abrDependencyVersion,
          (manifest, packageName, version) => {
            // Make sure manifest does not have dependency
            manifest = removeDependency(manifest, packageName);

            const [, change] = addProjectDependency(
              manifest,
              packageName,
              version
            );

            expect(change).toEqual<AddResult>({ type: "added", version });
          }
        )
      );
    })

Summary: Adding a dependency to a manifest where it was previously removed should result in a change of type "added" with the correct version.


it('succeeds', async () => {
      await fc.assert(fc.asyncProperty(fc.integer(), async (i) => {
        const actual = await PromiseUtils.succeed(i);
        assert.equal(actual, i);
      }));
    })

Summary: `PromiseUtils.succeed` should return a promise that resolves to the input integer value.


it('succeeds with right on success', async () => {
      await fc.assert(fc.asyncProperty(fc.integer(), async (i) => {
        await assert.becomes(PromiseUtils.tryPromise(PromiseUtils.succeed(i)), E.right(i));
      }));
    })

Summary: `PromiseUtils.tryPromise` with `PromiseUtils.succeed` results in a promise that resolves to `E.right` with the input integer.


it('succeeds with left on failure', async () => {
    await fc.assert(fc.asyncProperty(fc.integer(), async (i) => {
      await assert.becomes(PromiseUtils.tryPromise(PromiseUtils.fail(i)), E.left(i));
    }));
  })

Summary: `PromiseUtils.tryPromise` returns `E.left(i)` when the promise fails with the value `i`.


it('returns empty array when all elements are none', () => {
      fc.assert(fc.property(fc.array(fc.integer()), (xs) => {
        assert.deepEqual(
          OptionUtils.somes(xs.map(() => O.none)),
          []
        );
      }));
    })

Summary: `OptionUtils.somes` returns an empty array when all elements in the input array are `none`.


it('returns the same number of elements', () => {
      fc.assert(fc.property(fc.array(fc.integer()), (xs) => {
        assert.equal(ArrayUtils.sort(xs).length, xs.length);
      }));
    })

Summary: `ArrayUtils.sort` maintains the same number of elements as the input array.


it('parses a correct 3-point version', async () => {
      await fc.assert(fc.asyncProperty(smallNat, smallNat, smallNat, async (major, minor, patch) => {
        const input = `${major}.${minor}.${patch}`;
        const expected = { major, minor, patch, preRelease: undefined, buildMetaData: undefined };
        await assert.becomes(Version.parseVersion(input), expected);
      }));
    })

Summary: Parses a 3-point version string into its major, minor, patch components, and verifies the absence of preRelease and buildMetaData.


it('fails on 2-point versions', async () => {
      await fc.assert(fc.asyncProperty(smallNat, smallNat, async (major, minor) => {
        const input = `${major}.${minor}`;
        await assert.isRejected(Version.parseVersion(input), 'Could not parse version string');
      }));
    })

Summary: The parsing of 2-point version strings (e.g., "major.minor") should be rejected by `Version.parseVersion`.


it('parses 2-point version', async () => {
      await fc.assert(fc.asyncProperty(smallNat, smallNat, async (major, minor) => {
        await assert.becomes(Version.parseMajorMinorVersion(`${major}.${minor}`), { major, minor });
      }));
    })

Summary: `Version.parseMajorMinorVersion` should return an object with `major` and `minor` properties that match input major and minor version numbers provided as a string.


it('round-trips for version with prerelease', async () => {
      await fc.assert(fc.asyncProperty(smallNat, smallNat, smallNat, smallNatString,
        async (major, minor, patch, preRelease) => {
          const input = `${major}.${minor}.${patch}-${preRelease}`;
          const version = await Version.parseVersion(input);
          const actual = Version.versionToString(version);
          assert.deepEqual(actual, input);
        }
      ));
    })

Summary: Parsing and converting a version string with a prerelease component should maintain the original version string after a round-trip conversion through `Version.parseVersion` and `Version.versionToString`.


it('compares major versions', () => {
      fc.assert(fc.property(fc.integer({ min: 0, max: 1000 }), fc.integer(), fc.integer(), fc.integer(), fc.integer(), fc.hexaString(), fc.hexaString(),
        (major, minor1, minor2, patch1, patch2, preRelease1, preRelease2) => {
          assert.equal(Version.compareVersions(
            { major, minor: minor1, patch: patch1, preRelease: preRelease1 },
            { major: major + 1, minor: minor2, patch: patch2, preRelease: preRelease2 }
          ), Comparison.LT);

          assert.equal(Version.compareVersions(
            { major: major + 1, minor: minor2, patch: patch2, preRelease: preRelease2 },
            { major, minor: minor1, patch: patch1, preRelease: preRelease1 }
          ), Comparison.GT);
        }));
    })

Summary: The `Version.compareVersions` function compares major version numbers, ensuring a lower major version results in `LT`, and a higher major version results in `GT`.


it('succeeds for advance command with major.minor arg', async () => {
      await fc.assert(fc.asyncProperty(fc.nat(100), fc.nat(100), async (major, minor) => {
        await assert.becomes(
          parseArgs([ 'advance', `${major}.${minor}` ]),
          O.some(BeehiveArgs.advanceArgs(false, process.cwd(), O.none, O.none, `release/${major}.${minor}`))
        );
        await assert.becomes(
          parseArgs([ 'advance', `${major}.${minor}`, '--dry-run' ]),
          O.some(BeehiveArgs.advanceArgs(true, process.cwd(), O.none, O.none, `release/${major}.${minor}`))
        );
      }));
    })

Summary: Parsing the 'advance' command with a `major.minor` argument should return the correct command object, with an optional dry-run flag.


it("Returns the same as the uncurried function", () => {
    fc.assert(
      fc.property(fc.string(), fc.integer(), fc.boolean(), (a, b, c) =>
        expect(curry(f)(a)(b)(c)).toEqual(f(a, b, c)),
      ),
    );
  })

Summary: The curried version of function `f` should return the same result as the uncurried version with the same arguments.


it("Returns its input", () => {
    fc.assert(fc.property(fc.anything(), x => expect(id(x)).toEqual(x)));
  })

Summary: The function `id` consistently returns its input unchanged, regardless of the input type.


it('allow to edit for valid input', async () =>
        await fc.assert(
          fc.asyncProperty(MAC(), async testValue => {
            input!.value = testValue.toUpperCase();
            await element.requestUpdate();
            expect(input!.checkValidity()).to.be.true;
          })
        ))


it('does not allow to edit for invalid input', async () =>
        await fc.assert(
          fc.asyncProperty(invertedRegex(regExp.MAC), async testValue => {
            input!.value = testValue;
            await element.requestUpdate();
            expect(input!.checkValidity()).to.be.false;
          })
        ))


it('allow to edit for valid input', async () =>
        await fc.assert(
          fc.asyncProperty(
            hexaString({ minLength: 4, maxLength: 4 }),
            async testValue => {
              input!.value = testValue.toUpperCase();
              await element.requestUpdate();
              expect(input!.checkValidity()).to.be.true;
            }
          )
        ))


it('does not allow to edit for invalid input', async () =>
        await fc.assert(
          fc.asyncProperty(hexaString({ minLength: 5 }), async testValue => {
            input!.value = testValue.toUpperCase();
            await element.requestUpdate();
            expect(input!.checkValidity()).to.be.false;
          })
        ))


it('does not allow to edit characters < 4', async () =>
        await fc.assert(
          fc.asyncProperty(
            hexaString({ minLength: 0, maxLength: 3 }),
            async testValue => {
              input!.value = testValue.toUpperCase();
              await element.requestUpdate();
              expect(input!.checkValidity()).to.be.false;
            }
          )
        ))


it('allow to edit for valid input', async () =>
        await fc.assert(
          fc.asyncProperty(
            hexaString({ minLength: 3, maxLength: 3 }),
            async testValue => {
              input!.value = testValue.toUpperCase();
              await element.requestUpdate();
              expect(input!.checkValidity()).to.be.true;
            }
          )
        ))


it('does not allow to edit for invalid input', async () =>
        await fc.assert(
          fc.asyncProperty(hexaString({ minLength: 4 }), async testValue => {
            input!.value = testValue.toUpperCase();
            await element.requestUpdate();
            expect(input!.checkValidity()).to.be.false;
          })
        ))


it('does not allow to edit characters < 3', async () =>
        await fc.assert(
          fc.asyncProperty(
            hexaString({ minLength: 0, maxLength: 2 }),
            async testValue => {
              input!.value = testValue.toUpperCase();
              await element.requestUpdate();
              expect(input!.checkValidity()).to.be.false;
            }
          )
        ))


it('allow to edit for valid input', async () =>
        await fc.assert(
          fc.asyncProperty(
            integer({ min: 0, max: 7 }).map(num => `${num}`),
            async testValue => {
              input!.value = testValue;
              await element.requestUpdate();
              expect(input!.checkValidity()).to.be.true;
            }
          )
        ))


it('does not allow to edit for invalid input', async () =>
        await fc.assert(
          fc.asyncProperty(
            integer({ min: 8 }).map(num => `${num}`),
            async testValue => {
              input!.value = testValue;
              await element.requestUpdate();
              expect(input!.checkValidity()).to.be.false;
            }
          )
        ))


it('edits name attribute only for valid inputs', async () => {
        await fc.assert(
          fc.asyncProperty(regexString(regExp.tAsciName, 1, 32), async name => {
            inputs[0].value = name;
            await (<WizardTextField>inputs[0]).requestUpdate();
            expect(inputs[0].checkValidity()).to.be.true;
          })
        );
      })


it('rejects name attribute starting with decimals', async () => {
        await fc.assert(
          fc.asyncProperty(regexString(regExp.decimal, 1, 1), async name => {
            inputs[0].value = name;
            await (<WizardTextField>inputs[0]).requestUpdate();
            expect(inputs[0].checkValidity()).to.be.false;
          })
        );
      })


it('edits smpRate attribute only for valid inputs', async () => {
        await fc.assert(
          fc.asyncProperty(
            integer({ min: 0 }).map(num => `${num}`),
            async smpRate => {
              inputs[4].value = smpRate;
              await (<WizardTextField>inputs[4]).requestUpdate();
              expect(inputs[4].checkValidity()).to.be.true;
            }
          )
        );
      })


it('rejects smpRate attribute in case input is not unsigned int', async () => {
        await fc.assert(
          fc.asyncProperty(
            regexString(inverseRegExp.uint, 1),
            async smpRate => {
              inputs[4].value = smpRate;
              await (<WizardTextField>inputs[4]).requestUpdate();
              expect(inputs[4].checkValidity()).to.be.false;
            }
          )
        );
      })


it('edits nofASDU attribute only for valid inputs', async () => {
        const input = <WizardTextField>inputs[5];
        input.nullSwitch?.click();
        await input.requestUpdate();

        await fc.assert(
          fc.asyncProperty(
            integer({ min: 0 }).map(num => `${num}`),
            async nofASDU => {
              input.value = nofASDU;
              await input.requestUpdate();
              expect(input.checkValidity()).to.be.true;
            }
          )
        );
      })


it('rejects nofASDU attribute in case input is not unsigned int', async () => {
        const input = <WizardTextField>inputs[5];
        input.nullSwitch?.click();
        await input.requestUpdate();

        await fc.assert(
          fc.asyncProperty(
            regexString(inverseRegExp.uint, 1),
            async nofASDU => {
              input.value = nofASDU;
              await input.requestUpdate();
              expect(input.checkValidity()).to.be.false;
            }
          )
        );
      })


it('edits bufTime attribute only for valid inputs', async () => {
        await fc.assert(
          fc.asyncProperty(
            integer({ min: 0 }).map(num => `${num}`),
            async bufTime => {
              inputs[6].value = bufTime;
              await (<WizardTextField>inputs[6]).requestUpdate();
              expect(inputs[6].checkValidity()).to.be.true;
            }
          )
        );
      })


it('rejects bufTime attribute starting with not being a unsigned int', async () => {
        await fc.assert(
          fc.asyncProperty(
            regexString(inverseRegExp.uint, 1),
            async bufTime => {
              inputs[6].value = bufTime;
              await (<WizardTextField>inputs[6]).requestUpdate();
              expect(inputs[6].checkValidity()).to.be.false;
            }
          )
        );
      })


it('edits intgPd attribute only for valid inputs', async () => {
        const input = <WizardTextField>inputs[7];
        input.nullSwitch?.click();
        await input.requestUpdate();

        await fc.assert(
          fc.asyncProperty(
            integer({ min: 0 }).map(num => `${num}`),
            async intgPd => {
              input.value = intgPd;
              await input.requestUpdate();
              expect(input.checkValidity()).to.be.true;
            }
          )
        );
      })


it('rejects intgPd attribute starting with not being a unsigned int', async () => {
        const input = <WizardTextField>inputs[7];
        input.nullSwitch?.click();
        await input.requestUpdate();

        await fc.assert(
          fc.asyncProperty(regexString(inverseRegExp.uint, 1), async intgPd => {
            input.value = intgPd;
            await input.requestUpdate();
            expect(input.checkValidity()).to.be.false;
          })
        );
      })


it('edits prefix attribute only for valid inputs', async () => {
        await fc.assert(
          fc.asyncProperty(regexString(regExp.tAsciName, 1, 11), async name => {
            inputs[2].value = name;
            await (<WizardTextField>inputs[2]).requestUpdate();
            expect(inputs[2].checkValidity()).to.be.true;
          })
        );
      })


it('rejects name attribute starting with decimals', async () => {
        await fc.assert(
          fc.asyncProperty(regexString(regExp.decimal, 1, 1), async name => {
            inputs[2].value = name;
            await (<WizardTextField>inputs[2]).requestUpdate();
            expect(inputs[2].checkValidity()).to.be.false;
          })
        );
      })


it('edits name attribute only for valid inputs', async () => {
      await fc.assert(
        fc.asyncProperty(regexString(regExp.tAsciName, 1, 32), async name => {
          nameTextField.value = name;
          await nameTextField.requestUpdate();
          expect(nameTextField.checkValidity()).to.be.true;
        })
      );
    })


it('rejects name attribute starting with decimals', async () => {
      await fc.assert(
        fc.asyncProperty(regexString(regExp.decimal, 1, 1), async name => {
          nameTextField.value = name;
          await nameTextField.requestUpdate();
          expect(nameTextField.checkValidity()).to.be.false;
        })
      );
    })


it('allow to edit for valid input', async () =>
          await fc.assert(
            fc.asyncProperty(ipV4(), async testValue => {
              input!.value = testValue;
              await element.requestUpdate();
              expect(input!.checkValidity()).to.be.true;
            })
          ))


it('does not allow to edit for invalid input', async () =>
          await fc.assert(
            fc.asyncProperty(invertedRegex(regExp.IPv4), async testValue => {
              input!.value = testValue;
              await element.requestUpdate();
              expect(input!.checkValidity()).to.be.false;
            })
          ))


it('allow to edit for valid input', async () =>
          await fc.assert(
            fc.asyncProperty(regexString(regExp.OSI, 1, 8), async testValue => {
              input!.value = testValue;
              await element.requestUpdate();
              expect(input!.checkValidity()).to.be.true;
            })
          ))


it('does not allow to edit for invalid input', async () =>
          await fc.assert(
            fc.asyncProperty(invertedRegex(regExp.OSI), async testValue => {
              input!.value = testValue;
              await element.requestUpdate();
              expect(input!.checkValidity()).to.be.false;
            })
          ))


it('allow to edit for valid input', async () =>
          await fc.assert(
            fc.asyncProperty(
              regexString(regExp.OSI, 1, 16),
              async testValue => {
                input!.value = testValue;
                await element.requestUpdate();
                expect(input!.checkValidity()).to.be.true;
              }
            )
          ))


it('allow to edit for valid input', async () =>
          await fc.assert(
            fc.asyncProperty(regexString(regExp.OSIAPi, 1), async testValue => {
              input!.value = testValue;
              await element.requestUpdate();
              expect(input!.checkValidity()).to.be.true;
            })
          ))


it('does not allow to edit for invalid input', async () =>
          await fc.assert(
            fc.asyncProperty(invertedRegex(regExp.OSIAPi), async testValue => {
              input!.value = testValue;
              await element.requestUpdate();
              expect(input!.checkValidity()).to.be.false;
            })
          ))


it('allow to edit for valid input', async () =>
          await fc.assert(
            fc.asyncProperty(
              regexString(regExp.OSIid, 1, 5),
              async testValue => {
                input!.value = testValue;
                await element.requestUpdate();
                expect(input!.checkValidity()).to.be.true;
              }
            )
          ))


it('does not allow to edit for invalid input', async () =>
          await fc.assert(
            fc.asyncProperty(invertedRegex(regExp.OSIid), async testValue => {
              input!.value = testValue;
              await element.requestUpdate();
              expect(input!.checkValidity()).to.be.false;
            })
          ))


it('allow to edit for valid input', async () =>
          await fc.assert(
            fc.asyncProperty(
              regexString(regExp.OSI, 1, 40),
              async testValue => {
                input!.value = testValue;
                await element.requestUpdate();
                expect(input!.checkValidity()).to.be.true;
              }
            )
          ))


it('allow to edit for valid input', async () =>
          await fc.assert(
            fc.asyncProperty(regexString(regExp.OSI, 3, 3), async testValue => {
              input!.value = testValue;
              await element.requestUpdate();
              expect(input!.checkValidity()).to.be.true;
            })
          ))


it('allow to edit for valid input', async () =>
          await fc.assert(
            fc.asyncProperty(regexString(/^[0-7]$/), async testValue => {
              input!.value = testValue;
              await element.requestUpdate();
              expect(input!.checkValidity()).to.be.true;
            })
          ))


it('does not allow to edit for invalid input', async () =>
          await fc.assert(
            fc.asyncProperty(invertedRegex(/^[0-7]$/), async testValue => {
              input!.value = testValue;
              await element.requestUpdate();
              expect(input!.checkValidity()).to.be.false;
            })
          ))


it('allow to edit for valid input', async () =>
          await fc.assert(
            fc.asyncProperty(
              nat({ max: 65535 }).map(num => `${num}`),
              async testValue => {
                input!.value = testValue;
                await element.requestUpdate();
                expect(input!.checkValidity()).to.be.true;
              }
            )
          ))


it('does not allow to edit for invalid input', async () =>
          await fc.assert(
            fc.asyncProperty(invertedRegex(/^[0-9]*$/), async testValue => {
              input!.value = testValue;
              await element.requestUpdate();
              expect(input!.checkValidity()).to.be.false;
            })
          ))


it('allow to edit for valid input', async () =>
          await fc.assert(
            fc.asyncProperty(regexString(/^\S*$/, 1), async testValue => {
              input!.value = testValue;
              await element.requestUpdate();
              expect(input!.checkValidity()).to.be.true;
            })
          ))


it('allow to edit for valid input', async () =>
          await fc.assert(
            fc.asyncProperty(
              integer({ min: 1025, max: 65535 }).map(num => `${num}`),
              async testValue => {
                input!.value = testValue;
                await element.requestUpdate();
                expect(input!.checkValidity()).to.be.true;
              }
            )
          ))