"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.constructSubscriptionMarble = exports.marbleAssert = void 0;
const SubscriptionLog_1 = require("rxjs/internal/testing/SubscriptionLog");
const constructObservableMarble_1 = require("./constructObservableMarble");
const constructSubscriptionMarble_1 = require("./constructSubscriptionMarble");
Object.defineProperty(exports, "constructSubscriptionMarble", { enumerable: true, get: function () { return constructSubscriptionMarble_1.constructSubscriptionMarble; } });
const { matcherHint, printExpected, printReceived } = require('jest-matcher-utils'); //tslint:disable-line:no-require-imports no-var-requires
const { default: matchers } = require('expect/build/matchers'); //tslint:disable-line:no-require-imports no-var-requires
const toEqualAssert = matchers.toEqual.bind({ expand: false });
const subscriptionMarbleAssert = (source) => (expected) => {
    const asserted = toEqualAssert(source, expected);
    if (!asserted.pass) {
        const length = source.length > expected.length ? source.length : expected.length;
        let description = `
${matcherHint(' to equal ')}
    `;
        for (let idx = 0; idx < length; idx++) {
            const sourceMarble = !!source[idx]
                ? constructSubscriptionMarble_1.constructSubscriptionMarble(source[idx])
                : { marbleString: '', frameString: '' };
            const expectedMarble = !!expected[idx]
                ? constructSubscriptionMarble_1.constructSubscriptionMarble(expected[idx])
                : { marbleString: '', frameString: '' };
            if (toEqualAssert(sourceMarble, expectedMarble).pass) {
                continue;
            }
            description += `

${printReceived(`Source:   ${sourceMarble.marbleString}`)}
${printReceived(`          ${sourceMarble.frameString}`)}
${printExpected(`Expected: ${expectedMarble.marbleString}`)}
${printExpected(`          ${expectedMarble.frameString}`)}
      `;
        }
        description += `
${asserted.message()}
`;
        throw new Error(description);
    }
};
const observableMarbleAssert = (source) => (expected) => {
    if (!Array.isArray(expected)) {
        throw new Error('Expected value is not array');
    }
    //polymorphic picks up observablemarbleassert first when empty array, manually falls back
    //if expected is subscriptionlog
    if (expected.every((x) => x instanceof SubscriptionLog_1.SubscriptionLog)) {
        subscriptionMarbleAssert(source)(expected);
        return;
    }
    const sourceMarble = constructObservableMarble_1.constructObservableMarble(source);
    const expectedMarble = constructObservableMarble_1.constructObservableMarble(expected);
    const asserted = toEqualAssert(source, expected);
    if (!asserted.pass) {
        const description = `
${printReceived(`Source:   ${sourceMarble}`)}
${printExpected(`Expected: ${expectedMarble}`)}

${asserted.message()}
    `;
        throw new Error(description);
    }
};
function marbleAssert(source) {
    const isSourceArray = Array.isArray(source);
    if (!isSourceArray) {
        throw new Error('Cannot assert non array');
    }
    const isSourceSubscription = source.length > 0 && source.every((v) => v instanceof SubscriptionLog_1.SubscriptionLog);
    return {
        to: {
            equal: isSourceSubscription ? subscriptionMarbleAssert(source) : observableMarbleAssert(source),
        },
    };
}
exports.marbleAssert = marbleAssert;
//# sourceMappingURL=marbleAssert.js.map