
/*
 * Copyright 2017-present Open Networking Foundation

 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at

 * http://www.apache.org/licenses/LICENSE-2.0

 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


// Generated by typings
// Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/cd4debea25a280da0808d4ff2ca5a4bdb34bd28b/jasmine-jquery/index.d.ts
declare function sandbox(attributes?: any): string;

declare function readFixtures(...uls: string[]): string;
declare function preloadFixtures(...uls: string[]) : void;
declare function loadFixtures(...uls: string[]): void;
declare function appendLoadFixtures(...uls: string[]): void;
declare function setFixtures(html: string): string;
declare function appendSetFixtures(html: string) : void;

declare function preloadStyleFixtures(...uls: string[]) : void;
declare function loadStyleFixtures(...uls: string[]) : void;
declare function appendLoadStyleFixtures(...uls: string[]) : void;
declare function setStyleFixtures(html: string) : void;
declare function appendSetStyleFixtures(html: string) : void;

declare function loadJSONFixtures(...uls: string[]): jasmine.JSONFixtures;
declare function getJSONFixture(url: string): any;

declare function spyOnEvent(selector: string, eventName: string): jasmine.JQueryEventSpy;

declare namespace jasmine {
    function spiedEventsKey(selector: JQuery, eventName: string): string;

    function getFixtures(): Fixtures;
    function getStyleFixtures(): StyleFixtures;
    function getJSONFixtures(): JSONFixtures;

    interface Fixtures {
        fixturesPath: string;
        containerId: string;
        set(html: string): string;
        appendSet(html: string): void;
        preload(...uls: string[]): void;
        load(...uls: string[]): void;
        appendLoad(...uls: string[]): void;
        read(...uls: string[]): string;
        clearCache(): void;
        cleanUp(): void;
        sandbox(attributes?: any): string;
        createContainer_(html: string) : string;
        addToContainer_(html: string): void;
        getFixtureHtml_(url: string): string;
        loadFixtureIntoCache_(relativeUrl: string): void;
        makeFixtureUrl_(relativeUrl: string): string;
        proxyCallTo_(methodName: string, passedArguments: any): any;
    }

    interface StyleFixtures {
        fixturesPath: string;
        set(html: string): string;
        appendSet(html: string): void;
        preload(...uls: string[]) : void;
        load(...uls: string[]) : void;
        appendLoad(...uls: string[]) : void;
        read_(...uls: string[]): string;
        clearCache() : void;
        cleanUp() : void;
        createStyle_(html: string) : void;
        getFixtureHtml_(url: string): string;
        loadFixtureIntoCache_(relativeUrl: string) : void;
        makeFixtureUrl_(relativeUrl: string): string;
        proxyCallTo_(methodName: string, passedArguments: any): any;
    }

    interface JSONFixtures {
        fixturesPath: string;
        load(...uls: string[]): void;
        read(...uls: string[]): string;
        clearCache(): void;
        getFixtureData_(url: string): any;
        loadFixtureIntoCache_(relativeUrl: string): void;
        proxyCallTo_(methodName: string, passedArguments: any): any;
    }

    interface Matchers {
        /**
         * Check if DOM element has class.
         *
         * @param className Name of the class to check.
         *
         * @example
         * // returns true
         * expect($('<div class="some-class"></div>')).toHaveClass("some-class")
         */
        toHaveClass(className: string): boolean;

        /**
         * Check if DOM element has the given CSS properties.
         *
         * @param css Object containing the properties (and values) to check.
         *
         * @example
         * // returns true
         * expect($('<div style="display: none; margin: 10px;"></div>')).toHaveCss({display: "none", margin: "10px"})
         *
         * @example
         * // returns true
         * expect($('<div style="display: none; margin: 10px;"></div>')).toHaveCss({margin: "10px"})
         */
        toHaveCss(css: any): boolean;

        /**
         * Checks if DOM element is visible.
         * Elements are considered visible if they consume space in the document. Visible elements have a width or height that is greater than zero.
         */
        toBeVisible(): boolean;
        /**
         * Check if DOM element is hidden.
         * Elements can be hidden for several reasons:
         * - They have a CSS display value of none ;
         * - They are form elements with type equal to hidden.
         * - Their width and height are explicitly set to 0.
         * - An ancestor element is hidden, so the element is not shown on the page.
         */
        toBeHidden(): boolean;

        /**
         * Only for tags that have checked attribute
         *
         * @example
         * // returns true
         * expect($('<option selected="selected"></option>')).toBeSelected()
         */
        toBeSelected(): boolean;

        /**
         * Only for tags that have checked attribute
         * @example
         * // returns true
         * expect($('<input type="checkbox" checked="checked"/>')).toBeChecked()
         */
        toBeChecked(): boolean;

        /**
         * Checks for child DOM elements or text
         */
        toBeEmpty(): boolean;

        /**
         * Checks if element exists in or out the DOM.
         */
        toExist(): boolean;

        /**
         * Checks if array has the given length.
         *
         * @param length Expected length
         */
        toHaveLength(length: number): boolean;

        /**
         * Check if DOM element contains an attribute and, optionally, if the value of the attribute is equal to the expected one.
         *
         * @param attributeName Name of the attribute to check
         * @param expectedAttributeValue Expected attribute value
         */
        toHaveAttr(attributeName: string, expectedAttributeValue? : any): boolean;

        /**
         * Check if DOM element contains a property and, optionally, if the value of the property is equal to the expected one.
         *
         * @param propertyName Property name to check
         * @param expectedPropertyValue Expected property value
         */
        toHaveProp(propertyName: string, expectedPropertyValue? : any): boolean;

        /**
         * Check if DOM element has the given Id
         *
         * @param Id Expected identifier
         */
        toHaveId(id: string): boolean;

        /**
         * Check if DOM element has the specified HTML.
         *
         * @example
         * // returns true
         * expect($('<div><span></span></div>')).toHaveHtml('<span></span>')
         */
        toHaveHtml(html: string): boolean;

        /**
         * Check if DOM element contains the specified HTML.
         *
         * @example
         * // returns true
         * expect($('<div><ul></ul><h1>header</h1></div>')).toContainHtml('<ul></ul>')
         */
        toContainHtml(html: string): boolean;

        /**
         * Check if DOM element has the given Text.
         * @param text Accepts a string or regular expression
         *
         * @example
         * // returns true
         * expect($('<div>some text</div>')).toHaveText('some text')
         */
        toHaveText(text: string): boolean;
        /**
         * Check if DOM element contains the specified text.
         *
         * @example
         * // returns true
         * expect($('<div><ul></ul><h1>header</h1></div>')).toContainText('header')
         */
        toContainText(text: string): boolean;

        /**
         * Check if DOM element has the given value.
         * This can only be applied for element on with jQuery val() can be called.
         *
         * @example
         * // returns true
         * expect($('<input type="text" value="some text"/>')).toHaveValue('some text')
         */
        toHaveValue(value : string): boolean;

        /**
         * Check if DOM element has the given data.
         * This can only be applied for element on with jQuery data(key) can be called.
         *
         */
        toHaveData(key : string, expectedValue : string): boolean;
        toBe(selector: JQuery): boolean;

        /**
         * Check if DOM element is matched by the given selector.
         *
         * @example
         * // returns true
         * expect($('<div><span class="some-class"></span></div>')).toContain('some-class')
         */
        toContain(selector: JQuery): boolean;

        /**
         * Check if DOM element exists inside the given parent element.
         *
         * @example
         * // returns true
         * expect($('<div><span class="some-class"></span></div>')).toContainElement('span.some-class')
         */
        toContainElement(selector: string): boolean;

        /**
         * Check to see if the set of matched elements matches the given selector
         *
         * @example
         * expect($('<span></span>').addClass('js-something')).toBeMatchedBy('.js-something')
         *
         * @returns {Boolean} true if DOM contains the element
         */
        toBeMatchedBy(selector: string): boolean;

        /**
         * Only for tags that have disabled attribute
         * @example
         * // returns true
         * expect('<input type="submit" disabled="disabled"/>').toBeDisabled()
         */
        toBeDisabled(): boolean;

        /**
         * Check if DOM element is focused
         * @example
         * // returns true
         * expect($('<input type="text" />').focus()).toBeFocused()
         */
        toBeFocused(): boolean;

        /**
         * Checks if DOM element handles event.
         *
         * @example
         * // returns true
         * expect($form).toHandle("submit")
         */
        toHandle(eventName: string): boolean;

        /**
         * Assigns a callback to an event of the DOM element.
         *
         * @param eventName Name of the event to assign the callback to.
         * @param eventHandler Callback function to be assigned.
         *
         * @example
         * expect($form).toHandleWith("submit", yourSubmitCallback)
         */
        toHandleWith(eventName: string, eventHandler : JQueryCallback): boolean;

        /**
         * Checks if event was triggered.
         */
        toHaveBeenTriggered(): boolean;

        /**
         * Checks if the event has been triggered on selector.
         * @param selector Selector that should have triggered the event.
         */
        toHaveBeenTriggeredOn(selector: string): boolean;

        /**
         * Checks if the event has been triggered on selector.
         * @param selector Selector that should have triggered the event.
         * @param args Extra arguments to be passed to jQuery events functions.
         */
        toHaveBeenTriggeredOnAndWith(selector: string, ...args: any[]): boolean;

        /**
         * Checks if event propagation has been prevented.
         */
        toHaveBeenPrevented(): boolean;

        /**
         * Checks if event propagation has been prevented on element with selector.
         *
         * @param selector Selector that should have prevented the event.
         */
        toHaveBeenPreventedOn(selector: string): boolean;

        /**
         * Checks if event propagation has been stopped.
         *
         * @example
         * // returns true
         * var spyEvent = spyOnEvent('#some_element', 'click')
         * $('#some_element').click(function (event){event.stopPropagation();})
         * $('#some_element').click()
         * expect(spyEvent).toHaveBeenStopped()
         */
        toHaveBeenStopped(): boolean;

        /**
         * Checks if event propagation has been stopped by an element with the given selector.
         * @param selector Selector of the element that should have stopped the event propagation.
         *
         * @example
         * // returns true
         * $('#some_element').click(function (event){event.stopPropagation();})
         * $('#some_element').click()
         * expect('click').toHaveBeenStoppedOn('#some_element')
         */
        toHaveBeenStoppedOn(selector: string): boolean;

        /**
         * Checks to see if the matched element is attached to the DOM.
         * @example
         * expect($('#id-name')[0]).toBeInDOM()
         */
        toBeInDOM(): boolean;

    }

    interface JQueryEventSpy {
        selector: string;
        eventName: string;
        handler(eventObject: JQueryEventObject): any;
        reset(): any;
    }

    interface JasmineJQuery {
        browserTagCaseIndependentHtml(html: string): string;
        elementToString(element: JQuery): string;
        matchersClass: any;
        events: JasmineJQueryEvents;
    }

    interface JasmineJQueryEvents {
        spyOn(selector: string, eventName: string): JQueryEventSpy;
        args(selector: string, eventName: string): any;
        wasTriggered(selector: string, eventName: string): boolean;
        wasTriggeredWith(selector: string, eventName: string, expectedArgs: any, env: jasmine.Env): boolean;
        wasPrevented(selector: string, eventName: string): boolean;
        wasStopped(selector: string, eventName: string): boolean;
        cleanUp() : void;
    }

    var JQuery: JasmineJQuery;
}
