<commit_before>"use strict";

const Module = require("module");
const path = require("path");

const callsites = require("callsites");

const new_globals = new Set();
let old_globals = {};

let actual_load;
const module_mocks = new Map();
const used_module_mocks = new Set();

const jquery_path = require.resolve("jquery");
const real_jquery_path = require.resolve("../zjsunit/real_jquery.js");

function load(request, parent, isMain) {
    const filename = Module._resolveFilename(request, parent, isMain);
    if (module_mocks.has(filename)) {
        used_module_mocks.add(filename);
        return module_mocks.get(filename);
    }
    if (filename === jquery_path && parent.filename !== real_jquery_path) {
        // jQuery exposes an incompatible API to Node vs. browser, so
        // this wouldn't work.
        throw new Error("This test will need jquery mocked using zjquery or real_jquery");
    }

    return actual_load(request, parent, isMain);
}

exports.start = () => {
    if (actual_load !== undefined) {
        throw new Error("namespace.start was called twice in a row.");
    }
    actual_load = Module._load;
    Module._load = load;
};

// We provide `mock_cjs` for mocking a CommonJS module, and `mock_esm` for
// mocking an ES6 module.
//
// A CommonJS module:
// - loads other modules using `require()`,
// - assigns its public contents to the `exports` object or `module.exports`,
// - consists of a single JavaScript value, typically an object or function,
// - when imported by an ES6 module:
//   * is shallow-copied to a collection of immutable bindings, if it's an
//     object,
//   * is converted to a single default binding, if not.
//
// An ES6 module:
// - loads other modules using `import`,
// - declares its public contents using `export` statements,
// - consists of a collection of live bindings that may be mutated from inside
//   but not outside the module,
// - may have a default binding (that's just syntactic sugar for a binding
//   named `default`),
// - when required by a CommonJS module, always appears as an object.
//
// Most of our own modules are ES6 modules.
//
// For a third party module available in both formats that might present two
// incompatible APIs (especially if the CommonJS module is a function),
// Webpack will prefer the ES6 module if its availability is indicated by the
// "module" field of package.json, while Node.js will not; we need to mock the
// format preferred by Webpack.

exports.mock_cjs = (request, obj) => {
    const filename = Module._resolveFilename(
        request,
        require.cache[callsites()[1].getFileName()],
        false,
    );

    if (module_mocks.has(filename)) {
        throw new Error(`You already set up a mock for ${filename}`);
    }

    if (filename in require.cache) {
        throw new Error(`It is too late to mock ${filename}; call this earlier.`);
    }

    module_mocks.set(filename, obj);
    return obj;
};

exports.mock_template = (fn) => {
    const obj = {
        f: () => {
            throw new Error(`
                You did render_foo = mock_template("${fn}")
                but you also need to do override(render_foo, "f", () => {...}
            `);
        },
        __template_fn: fn,
    };

    exports.mock_cjs("../../static/templates/" + fn, (...args) => obj.f(...args));
    return obj;
};

exports.mock_esm = (request, obj = {}) => {
    if (typeof obj !== "object") {
        throw new TypeError("An ES module must be mocked with an object");
    }
    return exports.mock_cjs(request, {...obj, __esModule: true});
};

exports.unmock_module = (request) => {
    const filename = Module._resolveFilename(
        request,
        require.cache[callsites()[1].getFileName()],
        false,
    );

    if (!module_mocks.has(filename)) {
        throw new Error(`Cannot unmock ${filename}, which was not mocked`);
    }

    if (!used_module_mocks.has(filename)) {
        throw new Error(`You asked to mock ${filename} but we never saw it during compilation.`);
    }

    module_mocks.delete(filename);
    used_module_mocks.delete(filename);
};

exports.set_global = function (name, val) {
    if (val === null) {<commit_msg>zjsunit: Move template module logic into load().<commit_after>"use strict";

const Module = require("module");
const path = require("path");

const callsites = require("callsites");

const new_globals = new Set();
let old_globals = {};

let actual_load;
const module_mocks = new Map();
const used_module_mocks = new Set();

const jquery_path = require.resolve("jquery");
const real_jquery_path = require.resolve("../zjsunit/real_jquery.js");

function load(request, parent, isMain) {
    const filename = Module._resolveFilename(request, parent, isMain);
    if (module_mocks.has(filename)) {
        used_module_mocks.add(filename);
        const obj = module_mocks.get(filename);

        // Normal mocks are just objects.
        if (!obj.__template_fn) {
            return obj;
        }

        // For template mocks, we have an underlying object that
        // we wrap with a render function.
        const render = (data) => {
            if (obj.f.__default) {
                throw new Error(`
                    You did render_foo = mock_template("${obj.__template_fn}")
                    but you also need to do override(render_foo, "f", () => {...}
                `);
            }

            // User will override "f" for now, which is a bit hacky.
            return obj.f(data);
        };

        return render;
    }

    if (filename === jquery_path && parent.filename !== real_jquery_path) {
        // jQuery exposes an incompatible API to Node vs. browser, so
        // this wouldn't work.
        throw new Error("This test will need jquery mocked using zjquery or real_jquery");
    }

    return actual_load(request, parent, isMain);
}

exports.start = () => {
    if (actual_load !== undefined) {
        throw new Error("namespace.start was called twice in a row.");
    }
    actual_load = Module._load;
    Module._load = load;
};

// We provide `mock_cjs` for mocking a CommonJS module, and `mock_esm` for
// mocking an ES6 module.
//
// A CommonJS module:
// - loads other modules using `require()`,
// - assigns its public contents to the `exports` object or `module.exports`,
// - consists of a single JavaScript value, typically an object or function,
// - when imported by an ES6 module:
//   * is shallow-copied to a collection of immutable bindings, if it's an
//     object,
//   * is converted to a single default binding, if not.
//
// An ES6 module:
// - loads other modules using `import`,
// - declares its public contents using `export` statements,
// - consists of a collection of live bindings that may be mutated from inside
//   but not outside the module,
// - may have a default binding (that's just syntactic sugar for a binding
//   named `default`),
// - when required by a CommonJS module, always appears as an object.
//
// Most of our own modules are ES6 modules.
//
// For a third party module available in both formats that might present two
// incompatible APIs (especially if the CommonJS module is a function),
// Webpack will prefer the ES6 module if its availability is indicated by the
// "module" field of package.json, while Node.js will not; we need to mock the
// format preferred by Webpack.

function get_validated_filename(fn) {
    const filename = Module._resolveFilename(
        fn,
        require.cache[callsites()[1].getFileName()],
        false,
    );

    if (module_mocks.has(filename)) {
        throw new Error(`You already set up a mock for ${filename}`);
    }

    if (filename in require.cache) {
        throw new Error(`It is too late to mock ${filename}; call this earlier.`);
    }

    return filename;
}

exports.mock_cjs = (fn, obj) => {
    const filename = get_validated_filename(fn);
    module_mocks.set(filename, obj);

    return obj;
};

exports.mock_template = (fn) => {
    // We create an object with an f() function that the test author
    // can override.
    const obj = {
        f: () => {},
        __template_fn: fn,
    };
    obj.f.__default = true;

    const filename = get_validated_filename("../../static/templates/" + fn);

    // We update module_mocks with our object, but load() will return
    // its own function that calls our obj.f.
    module_mocks.set(filename, obj);

    return obj;
};

exports.mock_esm = (request, obj = {}) => {
    if (typeof obj !== "object") {
        throw new TypeError("An ES module must be mocked with an object");
    }
    return exports.mock_cjs(request, {...obj, __esModule: true});
};

exports.unmock_module = (request) => {
    const filename = Module._resolveFilename(
        request,
        require.cache[callsites()[1].getFileName()],
        false,
    );

    if (!module_mocks.has(filename)) {
        throw new Error(`Cannot unmock ${filename}, which was not mocked`);
    }

    if (!used_module_mocks.has(filename)) {
        throw new Error(`You asked to mock ${filename} but we never saw it during compilation.`);
    }

    module_mocks.delete(filename);
    used_module_mocks.delete(filename);
};

exports.set_global = function (name, val) {
    if (val === null) {
{'fraction_non_alphanumeric': 0.12268543584190579, 'fraction_numerical': 0.0015159718462371414, 'mean_word_length': 2.769795918367347, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 19, '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': '3500335', 'n_tokens_mistral': 2664, 'n_tokens_neox': 2611, 'n_words': 941}