HOME


Mini Shell 1.0
Redirecting to https://devs.lapieza.net/iniciar-sesion Redirecting to https://devs.lapieza.net/iniciar-sesion.
DIR: /proc/self/root/usr/share/node_modules/tcompare/dist/cjs/
Upload File :
Current File : //proc/self/root/usr/share/node_modules/tcompare/dist/cjs/same.js
"use strict";
// Same is the base class for all comparators
//
// We walk through both of the expect and actual objects,
// creating a Same node for each field in common, based on
// their similarity:
// - true (they're a match) omit from the result (the child node is discarded)
// - false (they're simply nonmatching) format both expect and object
// - COMPLEX - walk through child nodes
//   - if match: child node is discarded
//   - else, child node is retained (along with its non-matching children)
//
// We 'discard' by just having the print method return ''
//
// When walking child nodes, we use the shouldCompare(key) method to determine
// whether to check a given field.  In this class, this is always true (because
// we are testing for full deep sameness), but in Has classes, it's more
// complicated (only test nodes that exist in the expect object).
Object.defineProperty(exports, "__esModule", { value: true });
exports.Same = void 0;
const diff_1 = require("diff");
const format_js_1 = require("./format.js");
const arrayFrom = (obj) => {
    try {
        return Array.from(obj);
    }
    catch (_) {
        return null;
    }
};
const { hasOwnProperty } = Object.prototype;
const { defineProperty } = Object;
class Same extends format_js_1.Format {
    constructor(obj, options) {
        if (!options || typeof options !== 'object') {
            throw new TypeError('must supply options object');
        }
        if (!('expect' in options)) {
            throw new TypeError('must supply expected value');
        }
        super(obj, options);
        this.simple = null;
        this.match = true;
        this.diffContext = 10;
        this.memoDiff = null;
        this.memoExpect = null;
        this.parent = options.parent || null;
        this.expect = options.expect;
        if (!this.style.diffable) {
            throw new Error(`"${options.style}" style not appropriate for diffs`);
        }
        if (options.diffContext) {
            this.diffContext = options.diffContext;
        }
        this.provisional = !!options.provisional;
        this.simpleMatch();
    }
    simpleMatch() {
        this.simple = this.test();
        if (this.seen() !== this.seenExpect()) {
            this.simple = false;
        }
        if (!this.simple) {
            this.unmatch();
        }
    }
    test() {
        const a = this.object;
        const b = this.expect;
        return typeof a === 'function' &&
            typeof b === 'function'
            ? a === b ||
                (a.name === b.name &&
                    a.toString() === b.toString())
            : typeof a === 'symbol' || typeof b === 'symbol'
                ? typeof a === typeof b &&
                    a.toString() === b.toString()
                : typeof a !== 'object' &&
                    typeof b !== 'object' &&
                    a == b
                    ? true
                    : a === b
                        ? true
                        : a === null || b === null
                            ? a == b
                            : a !== a
                                ? b !== b
                                : typeof a !== 'object' || typeof b !== 'object'
                                    ? false
                                    : !this.isError() && b instanceof Error
                                        ? false
                                        : this.isError() &&
                                            ((b.message && b.message !== a.message) ||
                                                (b.name && b.name !== a.name))
                                            ? false
                                            : this.isSet() && !new format_js_1.Format(b).isSet()
                                                ? false
                                                : this.isMap() && !new format_js_1.Format(b).isMap()
                                                    ? false
                                                    : this.isArray() && !new format_js_1.Format(b).isArray()
                                                        ? false
                                                        : Buffer.isBuffer(a) && Buffer.isBuffer(b)
                                                            ? a.equals(b)
                                                            : a instanceof Date && b instanceof Date
                                                                ? a.getTime() === b.getTime()
                                                                : a instanceof RegExp && b instanceof RegExp
                                                                    ? this.regexpSame(a, b)
                                                                    : 'COMPLEX'; // might still be a deeper mismatch, of course
    }
    regexpSame(a, b) {
        return (a.source === b.source &&
            a.global === b.global &&
            a.multiline === b.multiline &&
            a.lastIndex === b.lastIndex &&
            a.ignoreCase === b.ignoreCase);
    }
    unmatch() {
        if (this.match) {
            this.match = false;
            if (!this.provisional) {
                this.parent && this.parent.unmatch();
            }
        }
    }
    // just print the thing as-is
    simplePrint(obj, options = {}) {
        return new format_js_1.Format(obj, {
            ...this.options,
            ...options,
        }).print();
    }
    simplePrintExpect() {
        return new format_js_1.Format(this.expect, {
            ...this.options,
            seen: this.seenExpect,
        }).print();
    }
    seenExpect() {
        if (!this.expect || typeof this.expect !== 'object') {
            return false;
        }
        for (let p = this.parent; p; p = p.parent) {
            if (p.expect === this.expect) {
                p.id = p.id || p.getId();
                return p;
            }
        }
        return false;
    }
    // if it's the root, then we do the diff
    // otherwise, we do the dual-walk of both trees,
    // building up the object and expect memos
    // this actually returns '' for any non-root node.
    print() {
        if (this.memo === null && this.memoExpect === null) {
            this.memo = '';
            this.memoExpect = '';
            if (!this.simple) {
                this.unmatch();
                this.memo += this.simplePrint(this.object);
                this.memoExpect += this.simplePrintExpect();
            }
            else {
                const seen = this.seen();
                const seenExpect = this.seenExpect();
                if (this.simple === true && seen === seenExpect) {
                    this.memo = '';
                    this.memoExpect = '';
                }
                else {
                    if (seen) {
                        this.printCircular(this.object);
                    }
                    else {
                        this.printCollection();
                    }
                }
            }
        }
        return this.diff();
    }
    printCircular(seen) {
        this.memo += this.style.circular(seen);
        const seenExpect = this.seenExpect();
        this.memoExpect = this.memoExpect || '';
        if (seenExpect) {
            this.memoExpect += this.style.circular(seenExpect);
        }
    }
    diff() {
        // impossible
        /* c8 ignore start */
        if (this.memoExpect === null || this.memo === null) {
            throw new TypeError('called diff() prior to print()');
        }
        /* c8 ignore stop */
        if (this.parent ||
            this.match ||
            this.memoExpect === this.memo) {
            return (this.memoDiff = '');
        }
        if (this.memoDiff !== null) {
            return this.memoDiff;
        }
        return (this.memoDiff = (0, diff_1.createTwoFilesPatch)('expected', 'actual', this.memoExpect + '\n', this.memo + '\n', undefined, undefined, { context: this.diffContext }).replace(/^\=+\n/, ''));
    }
    child(obj, options, cls) {
        const expectKey = hasOwnProperty.call(options, 'expectKey')
            ? options.expectKey
            : options.key;
        return super.child(obj, {
            expect: this.childExpect(expectKey),
            ...options,
        }, cls);
    }
    childExpect(key) {
        // if we get here, we know that both expect and actual
        // are collections of the same type.  Otherwise they
        // would have gotten the simple printed diff.
        return this.isSet()
            ? key
            : this.isMap()
                ? this.expect.get(key)
                : this.isArray()
                    ? this.expectAsArray[key]
                    : this.expect[key];
    }
    get expectAsArray() {
        const value = Array.isArray(this.expect)
            ? this.expect
            : new format_js_1.Format(this.expect).isArray()
                ? arrayFrom(this.expect)
                : /* c8 ignore start */
                    null;
        /* c8 ignore stop */
        defineProperty(this, 'expectAsArray', { value });
        return value;
    }
    printStart() {
        if (!this.parent) {
            this.memo = this.nodeId() + this.memo;
            this.memoExpect = this.nodeId() + this.memoExpect;
            return;
        }
        // we always simple print keys
        /* c8 ignore start */
        const indent = this.isKey ? '' : this.indentLevel();
        /* c8 ignore stop */
        // this will always be keyless, because Array and Set
        // objects are always simple printed.  But if that
        // chagnes, this will be relevant.
        /* c8 ignore start */
        const key = this.isKeyless() ? '' : this.getKey();
        /* c8 ignore stop */
        const sep = !key
            ? ''
            : this.parent && this.parent.isMap()
                ? this.style.mapKeyValSep()
                : this.style.pojoKeyValSep();
        const start = this.style.start(indent, key, sep);
        this.memo = start + this.nodeId() + this.memo;
        this.memoExpect =
            start + this.nodeId() + this.memoExpect;
    }
    printEnd() {
        if (!this.parent || this.isKey) {
            return;
        }
        const end = this.parent.isMap()
            ? this.style.mapEntrySep()
            : this.parent.isArray()
                ? this.style.arrayEntrySep()
                : // these types are always simple printed
                    /* c8 ignore start */
                    this.parent.isSet()
                        ? this.style.setEntrySep()
                        : this.parent.isBuffer()
                            ? ''
                            : this.parent.isString()
                                ? ''
                                : /* c8 ignore stop */
                                    this.style.pojoEntrySep();
        this.memo += end;
        this.memoExpect += end;
    }
    printPojo() {
        // even though it's not a simple mismatch, it's possible that
        // a child entry will cause a mismatch, so we have to print
        // the body *before* doing the head.  If we still aren't unmatched
        // after walking the graph, then nothing to do.
        if (this.pojoIsEmpty()) {
            this.memo = this.memo || '';
            this.memo += this.printPojoEmpty();
        }
        else {
            this.printPojoBody();
            if (!this.match) {
                this.printPojoHead();
                this.printStart();
                this.printPojoTail();
                this.printEnd();
            }
        }
    }
    pojoIsEmpty() {
        return super.pojoIsEmpty() && this.pojoExpectIsEmpty();
    }
    pojoExpectIsEmpty() {
        return super.pojoIsEmpty(this.expect);
    }
    printPojoEmpty() {
        // both are empty and not a simple mismatch, nothing to do
    }
    getPojoKeys(obj = this.object) {
        const fromSuper = super.getPojoKeys(obj);
        if (obj === this.expect) {
            return fromSuper;
        }
        return fromSuper.concat(this.getPojoKeys(this.expect).filter(k => k in obj));
    }
    printPojoHead() {
        const h = this.style.pojoHead(this.getClass());
        this.memo = h + this.memo;
        this.memoExpect = h + this.memoExpect;
    }
    printPojoTail() {
        const t = this.style.pojoTail(this.indentLevel());
        this.memo += t;
        this.memoExpect += t;
    }
    printPojoBody() {
        const objEnt = new Map(this.getPojoEntries(this.object));
        const expEnt = new Map(this.getPojoEntries(this.expect));
        for (const [key, val] of objEnt.entries()) {
            if (!expEnt.has(key)) {
                this.unmatch();
            }
            this.printPojoEntry(key, val, false);
        }
        for (const key of expEnt.keys()) {
            if (objEnt.has(key)) {
                continue;
            }
            this.unmatch();
            this.printPojoEntry(key, undefined, true);
        }
    }
    printPojoEntry(key, val, notFound) {
        const child = this.child(val, { key });
        child.print();
        if (!notFound) {
            this.memo += child.memo;
        }
        if (notFound || hasOwnProperty.call(this.expect, key)) {
            this.memoExpect += child.memoExpect;
        }
    }
    // error is just a pojo with some fancy styling
    printError() {
        if (this.errorIsEmpty()) {
            return this.printErrorEmpty();
        }
        else {
            this.printErrorBody();
            if (!this.match) {
                this.printErrorHead();
                this.printStart();
                this.printErrorTail();
                this.printEnd();
            }
        }
    }
    errorIsEmpty() {
        return super.errorIsEmpty() && this.expectErrorIsEmpty();
    }
    expectErrorIsEmpty() {
        return (this.getPojoEntries(this.expect).filter(([k]) => k !== 'name' && k !== 'message').length === 0);
    }
    printErrorEmpty() {
        // nothing to do
    }
    printErrorHead() {
        const headObj = this.style.errorHead(this.object, this.getClass());
        this.memo = headObj + this.memo;
        const headExp = this.style.errorHead(this.expect, this.getClass());
        this.memoExpect = headExp + this.memoExpect;
    }
    printErrorTail() {
        const t = this.style.errorTail(this.indentLevel());
        this.memo += t;
        this.memoExpect += t;
    }
    // maps are like pojos with fancier keys
    printMap() {
        if (this.mapIsEmpty()) {
            this.printMapEmpty();
        }
        else {
            this.printMapBody();
            if (!this.match) {
                this.printMapHead();
                this.printStart();
                this.printMapTail();
                this.printEnd();
            }
        }
    }
    mapIsEmpty() {
        return super.mapIsEmpty() && this.mapExpectIsEmpty();
    }
    mapExpectIsEmpty() {
        return this.expect.size === 0;
    }
    printMapHead() {
        const h = this.style.mapHead(this.getClass());
        this.memo = h + this.memo;
        this.memoExpect = h + this.memoExpect;
    }
    printMapTail() {
        const t = this.style.mapTail(this.indentLevel());
        this.memo += t;
        this.memoExpect += t;
    }
    printMapBody() {
        // new Map([{}:1]) matches another new Map([{}:1])
        // so we can't rely on key identity.
        const seen = new Set();
        // first pass to get any that are key identity matches
        for (const [key, val] of this.object.entries()) {
            if (this.expect.has(key)) {
                seen.add(key);
                this.printMapEntry(key, val);
                continue;
            }
        }
        for (const [key, val] of this.object.entries()) {
            if (seen.has(key)) {
                continue;
            }
            // try to find a matching key not yet seen
            let sawMatch = false;
            for (const expectKey of this.expect.keys()) {
                if (seen.has(expectKey)) {
                    continue;
                }
                const s = this.child(key, {
                    expect: expectKey,
                    provisional: true,
                });
                s.print();
                if (s.match) {
                    // it's a match!  test against this one.
                    sawMatch = true;
                    seen.add(key);
                    seen.add(expectKey);
                    sawMatch = true;
                    this.printMapEntry(key, val, expectKey);
                    break;
                }
            }
            if (!sawMatch) {
                this.printMapEntryUnexpected(key, val);
                seen.add(key);
            }
        }
        // now loop over all expected values not found in object
        for (const [key, val] of this.expect.entries()) {
            if (seen.has(key)) {
                continue;
            }
            this.printMapEntryNotFound(key, val);
        }
    }
    printMapEntry(key, val, expectKey = key) {
        const child = this.child(val, { key, expectKey });
        child.print();
        this.memo += child.memo;
        this.memoExpect += child.memoExpect;
    }
    printMapEntryNotFound(key, val) {
        this.unmatch();
        this.memoExpect += this.simplePrint(val, {
            parent: this,
            key,
            seen: this.seenExpect,
        });
    }
    printMapEntryUnexpected(key, val) {
        this.unmatch();
        this.memo += this.simplePrint(val, {
            key,
            parent: this,
        });
    }
    // arrays and sets don't have useful keys, so it's really hard to see
    // where the mismatch occurs with only the path context. For example,
    // if you have an array of objects with many keys, that mismatches on
    // only one key in one object, we would get a diff that looks like:
    //  [
    // +  {key: value},
    // -  {key: otherValue},
    // ]
    // which isn't super helpful, since you don't know which index it failed
    // on, or even have the other properties of the object or key path to
    // use to find it.
    // So, if it's not a match, we simplePrint both the expected and object,
    // and let the diff sort it out, since it does a pretty good job of that
    // anyway.
    // This can be somewhat noisy, if you have an array with a single large
    // object, of course. An alternative approach to consider is to do the
    // full simplePrint for Sets, but include the Array index in the array
    // print, so it's at least clear where it deviated.
    printArray() {
        if (this.arrayIsEmpty()) {
            this.printArrayEmpty();
        }
        else {
            this.printArrayBody();
        }
    }
    arrayIsEmpty() {
        return super.arrayIsEmpty() && this.arrayExpectIsEmpty();
    }
    arrayExpectIsEmpty() {
        const a = this.expectAsArray;
        return !!a && a.length === 0;
    }
    printArrayEmpty() {
        // nothing to do
    }
    printArrayBody() {
        // we know that they're both arrays if we got this far
        const obj = this.objectAsArray;
        const exp = this.expectAsArray;
        // if lengths match, just call printArrayEntry() for each of them
        if (exp && obj.length === exp.length) {
            super.printArrayBody();
        }
        else {
            this.unmatch();
        }
        if (!this.match) {
            this.memo += this.simplePrint(this.object);
            this.memoExpect = this.memoExpect || '';
            this.memoExpect += this.simplePrintExpect();
        }
    }
    printArrayEntry(key, val) {
        const child = this.child(val, { key });
        child.print();
    }
    printSet() {
        if (this.setIsEmpty()) {
            this.printSetEmpty();
        }
        else {
            this.printSetBody();
        }
    }
    setExpectIsEmpty() {
        return this.expect.size === 0;
    }
    setIsEmpty() {
        return super.setIsEmpty() && this.setExpectIsEmpty();
    }
    printSetBody() {
        if (this.expect.size !== this.object.size) {
            this.unmatch();
            this.memo += this.simplePrint(this.object);
            this.memoExpect = this.memoExpect || '';
            this.memoExpect += this.simplePrintExpect();
            return;
        }
        const seen = new Set();
        // skip all identity matches, nothing to do for these
        for (const val of this.object) {
            if (this.expect.has(val)) {
                seen.add(val);
                continue;
            }
        }
        for (const val of this.object) {
            if (seen.has(val)) {
                continue;
            }
            let sawMatch = false;
            for (const exp of this.expect) {
                if (seen.has(exp)) {
                    continue;
                }
                const s = this.child(val, {
                    expect: exp,
                    provisional: true,
                });
                s.print();
                if (s.match) {
                    sawMatch = true;
                    seen.add(exp);
                    break;
                }
            }
            if (!sawMatch) {
                this.unmatch();
                this.memo += this.simplePrint(this.object);
                this.memoExpect = this.memoExpect || '';
                this.memoExpect += this.simplePrintExpect();
                return;
            }
        }
    }
}
exports.Same = Same;
//# sourceMappingURL=same.js.map