<commit_before>"use strict";

var deepEqual = require("./util/core/deep-equal").use(match); // eslint-disable-line no-use-before-define
var every = require("./util/core/every");
var functionName = require("./util/core/function-name");
var iterableToString = require("./util/core/iterable-to-string");
var typeOf = require("./util/core/typeOf");
var valueToString = require("./util/core/value-to-string");

var indexOf = Array.prototype.indexOf;

function assertType(value, type, name) {
    var actual = typeOf(value);
    if (actual !== type) {
        throw new TypeError("Expected type of " + name + " to be " +
            type + ", but was " + actual);
    }
}

var matcher = {
    toString: function () {
        return this.message;
    }
};

function isMatcher(object) {
    return matcher.isPrototypeOf(object);
}

function matchObject(expectation, actual) {
    if (actual === null || actual === undefined) {
        return false;
    }

    return Object.keys(expectation).every(function (key) {
        var exp = expectation[key];
        var act = actual[key];

        if (isMatcher(exp)) {
            if (!exp.test(act)) {
                return false;
            }
        } else if (typeOf(exp) === "object") {
            if (!matchObject(exp, act)) {
                return false;
            }
        } else if (!deepEqual(exp, act)) {
            return false;
        }

        return true;
    });
}

var TYPE_MAP = {
    "function": function (m, expectation, message) {
        m.test = expectation;
        m.message = message || "match(" + functionName(expectation) + ")";
    },
    number: function (m, expectation) {
        m.test = function (actual) {
            // we need type coercion here
            return expectation == actual; // eslint-disable-line eqeqeq
        };
    },
    object: function (m, expectation) {
        var array = [];

        if (typeof expectation.test === "function") {
            m.test = function (actual) {
                return expectation.test(actual) === true;
            };
            m.message = "match(" + functionName(expectation.test) + ")";
            return m;
        }

        array = Object.keys(expectation).map(function (key) {
            return key + ": " + valueToString(expectation[key]);
        });

        m.test = function (actual) {
            return matchObject(expectation, actual);
        };
        m.message = "match(" + array.join(", ") + ")";

        return m;
    },
    regexp: function (m, expectation) {
        m.test = function (actual) {
            return typeof actual === "string" && expectation.test(actual);
        };
    },
    string: function (m, expectation) {
        m.test = function (actual) {
            return typeof actual === "string" && actual.indexOf(expectation) !== -1;
        };
        m.message = "match(\"" + expectation + "\")";
    }
};

function match(expectation, message) {
    var m = Object.create(matcher);
    var type = typeOf(expectation);

    if (type in TYPE_MAP) {
        TYPE_MAP[type](m, expectation, message);
    } else {
        m.test = function (actual) {
            return deepEqual(expectation, actual);
        };
    }

    if (!m.message) {
        m.message = "match(" + valueToString(expectation) + ")";
    }

    return m;
}

matcher.or = function (m2) {
    if (!arguments.length) {
        throw new TypeError("Matcher expected");
    } else if (!isMatcher(m2)) {
        m2 = match(m2);
    }
    var m1 = this;
    var or = Object.create(matcher);
    or.test = function (actual) {
        return m1.test(actual) || m2.test(actual);
    };
    or.message = m1.message + ".or(" + m2.message + ")";
    return or;
};

matcher.and = function (m2) {
    if (!arguments.length) {
        throw new TypeError("Matcher expected");
    } else if (!isMatcher(m2)) {
        m2 = match(m2);
    }
    var m1 = this;
    var and = Object.create(matcher);
    and.test = function (actual) {
        return m1.test(actual) && m2.test(actual);
    };
    and.message = m1.message + ".and(" + m2.message + ")";
    return and;
};

match.isMatcher = isMatcher;

match.any = match(function () {
    return true;
}, "any");

match.defined = match(function (actual) {
    return actual !== null && actual !== undefined;
}, "defined");

match.truthy = match(function (actual) {
    return !!actual;
}, "truthy");

match.falsy = match(function (actual) {
    return !actual;
}, "falsy");

match.same = function (expectation) {
    return match(function (actual) {
        return expectation === actual;
    }, "same(" + valueToString(expectation) + ")");
};

match.typeOf = function (type) {
    assertType(type, "string", "type");
    return match(function (actual) {
        return typeOf(actual) === type;
    }, "typeOf(\"" + type + "\")");
};

match.instanceOf = function (type) {
    assertType(type, "function", "type");
    return match(function (actual) {
        return actual instanceof type;
    }, "instanceOf(" + functionName(type) + ")");
};
<commit_msg>Allow custom defined instance checks if supported<commit_after>"use strict";

var deepEqual = require("./util/core/deep-equal").use(match); // eslint-disable-line no-use-before-define
var every = require("./util/core/every");
var functionName = require("./util/core/function-name");
var iterableToString = require("./util/core/iterable-to-string");
var typeOf = require("./util/core/typeOf");
var valueToString = require("./util/core/value-to-string");

var indexOf = Array.prototype.indexOf;

function assertType(value, type, name) {
    var actual = typeOf(value);
    if (actual !== type) {
        throw new TypeError("Expected type of " + name + " to be " +
            type + ", but was " + actual);
    }
}

function assertMethodExists(value, method, name, methodPath) {
    if (value[method] == null) {
        throw new TypeError("Expected " + name + " to have method " + methodPath);
    }
}

var matcher = {
    toString: function () {
        return this.message;
    }
};

function isMatcher(object) {
    return matcher.isPrototypeOf(object);
}

function matchObject(expectation, actual) {
    if (actual === null || actual === undefined) {
        return false;
    }

    return Object.keys(expectation).every(function (key) {
        var exp = expectation[key];
        var act = actual[key];

        if (isMatcher(exp)) {
            if (!exp.test(act)) {
                return false;
            }
        } else if (typeOf(exp) === "object") {
            if (!matchObject(exp, act)) {
                return false;
            }
        } else if (!deepEqual(exp, act)) {
            return false;
        }

        return true;
    });
}

var TYPE_MAP = {
    "function": function (m, expectation, message) {
        m.test = expectation;
        m.message = message || "match(" + functionName(expectation) + ")";
    },
    number: function (m, expectation) {
        m.test = function (actual) {
            // we need type coercion here
            return expectation == actual; // eslint-disable-line eqeqeq
        };
    },
    object: function (m, expectation) {
        var array = [];

        if (typeof expectation.test === "function") {
            m.test = function (actual) {
                return expectation.test(actual) === true;
            };
            m.message = "match(" + functionName(expectation.test) + ")";
            return m;
        }

        array = Object.keys(expectation).map(function (key) {
            return key + ": " + valueToString(expectation[key]);
        });

        m.test = function (actual) {
            return matchObject(expectation, actual);
        };
        m.message = "match(" + array.join(", ") + ")";

        return m;
    },
    regexp: function (m, expectation) {
        m.test = function (actual) {
            return typeof actual === "string" && expectation.test(actual);
        };
    },
    string: function (m, expectation) {
        m.test = function (actual) {
            return typeof actual === "string" && actual.indexOf(expectation) !== -1;
        };
        m.message = "match(\"" + expectation + "\")";
    }
};

function match(expectation, message) {
    var m = Object.create(matcher);
    var type = typeOf(expectation);

    if (type in TYPE_MAP) {
        TYPE_MAP[type](m, expectation, message);
    } else {
        m.test = function (actual) {
            return deepEqual(expectation, actual);
        };
    }

    if (!m.message) {
        m.message = "match(" + valueToString(expectation) + ")";
    }

    return m;
}

matcher.or = function (m2) {
    if (!arguments.length) {
        throw new TypeError("Matcher expected");
    } else if (!isMatcher(m2)) {
        m2 = match(m2);
    }
    var m1 = this;
    var or = Object.create(matcher);
    or.test = function (actual) {
        return m1.test(actual) || m2.test(actual);
    };
    or.message = m1.message + ".or(" + m2.message + ")";
    return or;
};

matcher.and = function (m2) {
    if (!arguments.length) {
        throw new TypeError("Matcher expected");
    } else if (!isMatcher(m2)) {
        m2 = match(m2);
    }
    var m1 = this;
    var and = Object.create(matcher);
    and.test = function (actual) {
        return m1.test(actual) && m2.test(actual);
    };
    and.message = m1.message + ".and(" + m2.message + ")";
    return and;
};

match.isMatcher = isMatcher;

match.any = match(function () {
    return true;
}, "any");

match.defined = match(function (actual) {
    return actual !== null && actual !== undefined;
}, "defined");

match.truthy = match(function (actual) {
    return !!actual;
}, "truthy");

match.falsy = match(function (actual) {
    return !actual;
}, "falsy");

match.same = function (expectation) {
    return match(function (actual) {
        return expectation === actual;
    }, "same(" + valueToString(expectation) + ")");
};

match.typeOf = function (type) {
    assertType(type, "string", "type");
    return match(function (actual) {
        return typeOf(actual) === type;
    }, "typeOf(\"" + type + "\")");
};

match.instanceOf = function (type) {
    if (typeof Symbol === "undefined") {
        assertType(type, "function", "type");
    } else {
        assertMethodExists(type, Symbol.hasInstance, "type", "[Symbol.hasInstance]");
    }
    return match(function (actual) {
        return actual instanceof type;
    }, "instanceOf(" + (functionName(type) || Object.prototype.toString.call(type)) + ")");
};

{'fraction_non_alphanumeric': 0.16001908396946565, 'fraction_numerical': 0.0036259541984732823, 'mean_word_length': 2.3357733927434756, 'pattern_counts': {'":': 4, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1830282', 'n_tokens_mistral': 3160, 'n_tokens_neox': 3133, 'n_words': 746}