{"version":3,"file":"bespunky-angular-zen-core-testing.mjs","sources":["../../../../libs/angular-zen/core/testing/src/mocks/element.mock.ts","../../../../libs/angular-zen/core/testing/src/mocks/script.mock.ts","../../../../libs/angular-zen/core/testing/src/mocks/link.mock.ts","../../../../libs/angular-zen/core/testing/src/mocks/head.mock.ts","../../../../libs/angular-zen/core/testing/src/utils/setup.ts","../../../../libs/angular-zen/core/testing/src/bespunky-angular-zen-core-testing.ts"],"sourcesContent":["export class MockElement\n{\n    public parentElement?: MockElement;\n    public children     : any[] = [];\n\n    public dir?      : 'ltr' | 'rtl';\n    public className?: string;\n\n    constructor(public tagName?: string) { }\n\n    public remove(): void\n    {\n        if (this.parentElement) this.parentElement.removeChild(this);\n    }\n\n    public removeChild(node: any): void\n    {\n        if (node.parentElement !== this) return;\n\n        const index = this.children.indexOf(node);\n\n        if (index > -1)\n        {\n            this.children.splice(index, 1);\n\n            node.parentElement = null;\n        }\n    }\n\n    public appendChild(node: any): void\n    {\n        this.children.push(node);\n\n        node.parentElement = this;\n\n        if (node.onload instanceof Function) setTimeout(node.onload, 0);\n    }\n\n    public querySelectorAll(selector: string): any[]\n    {\n        throw new Error(`\n            Providing a general implementation for querySelectorAll() to support all cases is to complex.\n            Use jest.spyOn() and fake this to provide an implementation for the specific use case.\n            See MockElement.extractXXXFromSelector() methods for utils.\n        `);\n    }\n\n    /**\n     * Extracts an array of {name, value} objects mapping the attributes from the specified selector string.\n     * Attributes with no value will be mapped with wildcard value (i.e. '**').\n     *\n     * @param {string} selector\n     * @returns {*}\n     */\n    public extractAttributesFromSelector(selector: string): any\n    {\n        // Searches for [key=\"value\"] and [key] groups and extracts the attribute and value from each\n        const regex = /(?:(\\[(?<attr>\\w+)(?:=\"(?<value>[^\\]]+)\")?)\\]*)/g;\n        let match: RegExpExecArray | null;\n        \n        const attributes = [];\n        \n        while ((match = regex.exec(selector)) !== null)\n        {\n            // This is necessary to avoid infinite loops with zero-width matches\n            if (match.index === regex.lastIndex) regex.lastIndex++;\n\n            attributes.push({ name: match.groups?.['attr'], value: match.groups?.['value'] || '**' });\n        }\n\n        return attributes;\n    }\n}","import { MockElement } from './element.mock';\n\nexport class MockScriptElement extends MockElement\n{\n    constructor() { super('script'); }\n    \n    async?: boolean;\n    defer?: boolean;\n    src?  : string;\n    type? : string;\n\n    onload? : () => void;\n    onerror?: () => void;\n}\n","import { MockElement } from './element.mock';\n\nexport class MockLinkElement extends MockElement\n{\n    constructor() { super('link'); }\n\n    as  ?: string;\n    href?: string;\n    type?: string;\n    rel ?: string;\n    relList = {\n        add: (...tokens: string[]) => this.rel = tokens.join(' ')\n    };\n    \n    onload ?: () => void;\n    onerror?: () => void;\n}","import { MockElement } from './element.mock'\n\nexport class MockHeadElement extends MockElement\n{\n    constructor() { super('head'); }\n}","import { TestBed } from '@angular/core/testing';\nimport { NgZone  } from '@angular/core';\nimport { Router  } from '@angular/router';\n\nimport { CoreModule, DOCUMENT } from '@bespunky/angular-zen/core';\nimport { MockScriptElement    } from '../mocks/script.mock';\nimport { MockLinkElement      } from '../mocks/link.mock';\nimport { MockHeadElement      } from '../mocks/head.mock';\nimport { MockElement          } from '../mocks/element.mock';\n\n/**\n * Configures a testing module provided with a ready-to-use mock for [`DOCUMENT`](/miscellaneous/variables.html#DOCUMENT).\n * \n * Any element created using `DocumentRef.nativeDocument.createElement()` will go through this mock.\n * If a script element was requested, a `MockScriptElement` object is returned.\n * If a link element was requested, the `MockLinkElement` object is returned.\n * If any other tag name is requested, a new `MockElement` object is returned.\n * \n * Used when testing head related services (e.g. HeadService, LazyLoaderService).\n * \n * Internally, this plants the following structure in [`DocumentRef`](/additional-documentation/coremodule/documentref.html):\n * \n * `DocumentRef.nativeDocument.head -> MockHeadElement`  \n * \n * `DocumentRef.nativeDocument.createElement -> () => MockScriptElement | MockLinkElement | MockElement(<tagName>)`\n * \n * The returned mocks can be deconstructed like so:\n * @example\n * let mockHeadElement: MockHeadElement;\n * let mockDocument   : any; \n * ({ mockHeadElement, mockDocument } = setupDocumentRefMock()); // mockDocument is also a jest.SpyInstance\n */\nexport function setupDocumentRefMock(): { mockHeadElement: MockHeadElement, mockDocument: any }\n{\n    const createElement = jest.fn((tagName: string) =>\n    {\n        return tagName === 'script' ? new MockScriptElement() :\n               tagName === 'link' ? new MockLinkElement() :\n                new MockElement(tagName);\n    });\n    \n    // Create a stub for the head element\n    const mockHeadElement = new MockHeadElement();\n    // Mock for the DocumentRef.nativeDocument object\n    // Create the document object allowing to spy on its createElement() function.\n    // When an element should be created, substitute it for the appropriate mock\n    const mockDocument = { createElement, head: mockHeadElement };\n\n    TestBed.configureTestingModule({\n        imports  : [CoreModule],\n        providers: [\n            { provide: DOCUMENT, useValue: mockDocument }\n        ]\n    });\n\n    return { mockHeadElement, mockDocument };\n}\n\n/**\n * Wraps the `navigate` and `navigateByUrl` methods of the router with a call to `NgZone.run()`.\n * Fixes the warning when using the router in unit tests.\n *\n * @export\n * @param {Router} router The router instance.\n */\nexport function forceRoutingInsideAngularZone(router: Router): void\n{\n    const zone          = TestBed.inject(NgZone);\n    \n    const navigate      = router.navigate.bind(router);\n    const navigateByUrl = router.navigateByUrl.bind(router);\n\n    type NavigateArgs      = Parameters<typeof navigate>;\n    type NavigateByUrlArgs = Parameters<typeof navigateByUrl>;\n\n    // Fix for angular's warning of running navigation outside angular's zone\n    jest.spyOn(router, 'navigate'     ).mockImplementation((...args: NavigateArgs)      => zone.run(() => navigate     (...args)));\n    jest.spyOn(router, 'navigateByUrl').mockImplementation((...args: NavigateByUrlArgs) => zone.run(() => navigateByUrl(...args)));\n}\n\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;MAAa,WAAW,CAAA;AAQpB,IAAA,WAAA,CAAmB,OAAgB,EAAA;AAAhB,QAAA,IAAO,CAAA,OAAA,GAAP,OAAO,CAAS;AAL5B,QAAA,IAAQ,CAAA,QAAA,GAAe,EAAE,CAAC;KAKO;IAEjC,MAAM,GAAA;QAET,IAAI,IAAI,CAAC,aAAa;AAAE,YAAA,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;KAChE;AAEM,IAAA,WAAW,CAAC,IAAS,EAAA;AAExB,QAAA,IAAI,IAAI,CAAC,aAAa,KAAK,IAAI;YAAE,OAAO;QAExC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1C,QAAA,IAAI,KAAK,GAAG,CAAC,CAAC,EACd;YACI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;AAE/B,YAAA,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;AAC7B,SAAA;KACJ;AAEM,IAAA,WAAW,CAAC,IAAS,EAAA;AAExB,QAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEzB,QAAA,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;AAE1B,QAAA,IAAI,IAAI,CAAC,MAAM,YAAY,QAAQ;AAAE,YAAA,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;KACnE;AAEM,IAAA,gBAAgB,CAAC,QAAgB,EAAA;QAEpC,MAAM,IAAI,KAAK,CAAC,CAAA;;;;AAIf,QAAA,CAAA,CAAC,CAAC;KACN;AAED;;;;;;AAMG;AACI,IAAA,6BAA6B,CAAC,QAAgB,EAAA;;;QAGjD,MAAM,KAAK,GAAG,kDAAkD,CAAC;AACjE,QAAA,IAAI,KAA6B,CAAC;QAElC,MAAM,UAAU,GAAG,EAAE,CAAC;AAEtB,QAAA,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,IAAI,EAC9C;;AAEI,YAAA,IAAI,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,SAAS;gBAAE,KAAK,CAAC,SAAS,EAAE,CAAC;AAEvD,YAAA,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAA,EAAA,GAAA,KAAK,CAAC,MAAM,MAAG,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,MAAM,CAAC,EAAE,KAAK,EAAE,CAAA,CAAA,EAAA,GAAA,KAAK,CAAC,MAAM,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAG,OAAO,CAAC,KAAI,IAAI,EAAE,CAAC,CAAC;AAC7F,SAAA;AAED,QAAA,OAAO,UAAU,CAAC;KACrB;AACJ;;ACtEK,MAAO,iBAAkB,SAAQ,WAAW,CAAA;AAE9C,IAAA,WAAA,GAAA,EAAgB,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE;AASrC;;ACXK,MAAO,eAAgB,SAAQ,WAAW,CAAA;AAE5C,IAAA,WAAA,GAAA;QAAgB,KAAK,CAAC,MAAM,CAAC,CAAC;QAM9B,IAAA,CAAA,OAAO,GAAG;AACN,YAAA,GAAG,EAAE,CAAC,GAAG,MAAgB,KAAK,IAAI,CAAC,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;SAC5D,CAAC;KAR8B;AAYnC;;ACdK,MAAO,eAAgB,SAAQ,WAAW,CAAA;AAE5C,IAAA,WAAA,GAAA,EAAgB,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE;AACnC;;ACKD;;;;;;;;;;;;;;;;;;;;;AAqBG;SACa,oBAAoB,GAAA;IAEhC,MAAM,aAAa,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,OAAe,KAAI;QAE9C,OAAO,OAAO,KAAK,QAAQ,GAAG,IAAI,iBAAiB,EAAE;YAC9C,OAAO,KAAK,MAAM,GAAG,IAAI,eAAe,EAAE;AACzC,gBAAA,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC;AACrC,KAAC,CAAC,CAAC;;AAGH,IAAA,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC;;;;IAI9C,MAAM,YAAY,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC;IAE9D,OAAO,CAAC,sBAAsB,CAAC;QAC3B,OAAO,EAAI,CAAC,UAAU,CAAC;AACvB,QAAA,SAAS,EAAE;AACP,YAAA,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE;AAChD,SAAA;AACJ,KAAA,CAAC,CAAC;AAEH,IAAA,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,CAAC;AAC7C,CAAC;AAED;;;;;;AAMG;AACG,SAAU,6BAA6B,CAAC,MAAc,EAAA;IAExD,MAAM,IAAI,GAAY,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAE7C,MAAM,QAAQ,GAAQ,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACnD,MAAM,aAAa,GAAG,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;;AAMxD,IAAA,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,UAAU,CAAM,CAAC,kBAAkB,CAAC,CAAC,GAAG,IAAkB,KAAU,IAAI,CAAC,GAAG,CAAC,MAAM,QAAQ,CAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AAC/H,IAAA,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,kBAAkB,CAAC,CAAC,GAAG,IAAuB,KAAK,IAAI,CAAC,GAAG,CAAC,MAAM,aAAa,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AACnI;;AC9EA;;AAEG;;;;"}