Repository: typeorm/typeorm
File: src/metadata/EntityListenerMetadata.ts (TypeScript)

Code before:

    /**
     * Executes listener method of the given entity.
     */
    execute(entity: ObjectLiteral) {
        // Check if the Embedded Metadata does not exist
        if (!this.embeddedMetadata) {
            // Get the Entity's Method
            const entityMethod = entity[this.propertyName]

            // Check if the Entity Method does not exist
            if (!entityMethod)
                throw new Error(
                    `Entity listener method "${this.propertyName}" does not exist in entity "${entity.constructor.name}".`,
                )

            // Check if the Entity Method is not a function
            if (typeof entityMethod !== "function")
                throw new Error(
                    `Entity listener method "${this.propertyName}" in entity "${
                        entity.constructor.name
                    }" must be a function but got "${typeof entityMethod}".`,
                )

            // Return the Entity Method
            return entityMethod()
        }

        // Call the Embedded Method
        this.callEntityEmbeddedMethod(
            entity,
            this.embeddedMetadata.propertyPath.split("."),
        )
    }

    // ---------------------------------------------------------------------
    // Protected Methods
    // ---------------------------------------------------------------------

    /**
     * Calls embedded entity listener method no matter how nested it is.
     */
    protected callEntityEmbeddedMethod(
        entity: ObjectLiteral,
        propertyPaths: string[],
    ): void {
        const propertyPath = propertyPaths.shift()
        if (!propertyPath || !entity[propertyPath]) return

        if (propertyPaths.length === 0) {
            if (Array.isArray(entity[propertyPath])) {

Review comment (bug):
The method is unbound, that's why the tests are failing. If you extract if from the object, it will loose the reference to the object.

Code after:

    /**
     * Executes listener method of the given entity.
     */
    execute(entity: ObjectLiteral) {
        // Check if the Embedded Metadata does not exist
        if (!this.embeddedMetadata) {
            // Get the Entity's Method
            const entityMethod = entity[this.propertyName]

            // Check if the Entity Method does not exist
            if (!entityMethod)
                throw new Error(
                    `Entity listener method "${this.propertyName}" does not exist in entity "${entity.constructor.name}".`,
                )

            // Check if the Entity Method is not a function
            if (typeof entityMethod !== "function")
                throw new Error(
                    `Entity listener method "${this.propertyName}" in entity "${
                        entity.constructor.name
                    }" must be a function but got "${typeof entityMethod}".`,
                )

            // Call and return the Entity Method
            return entityMethod.call(entity)
        }

        // Call the Embedded Method
        this.callEntityEmbeddedMethod(
            entity,
            this.embeddedMetadata.propertyPath.split("."),
        )
    }

    // ---------------------------------------------------------------------
    // Protected Methods
    // ---------------------------------------------------------------------

    /**
     * Calls embedded entity listener method no matter how nested it is.
     */
    protected callEntityEmbeddedMethod(
        entity: ObjectLiteral,
        propertyPaths: string[],
    ): void {
        const propertyPath = propertyPaths.shift()
        if (!propertyPath || !entity[propertyPath]) return

        if (propertyPaths.length === 0) {
            if (Array.isArray(entity[propertyPath])) {