<commit_before>import { NodeVM, VMScript } from "vm2";
import { convertCode } from "power-doctest";
import { ParsedCode } from "@power-doctest/types";

const assert = require("power-assert");

export interface PowerDoctestRunnerOptions {
    // pseudo file path for code
    filePath?: string;
    // sandbox context for code
    // context defined global variables
    context?: {
        [index: string]: any
    }
    // sandbox require mock for code
    requireMock?: {
        [index: string]: any
    }
    // If it is true, console.log output to console
    // If you want to mock console, please pass `console` to `context: { console: consoleMock }`
    //
    // Exception:
    // Always suppress console and assertion, because it is converted to assert function
    // ```
    // console.log(1); // => 1
    // ```
    console?: boolean;
    // Timeout
    // Default: 2000ms
    timeout?: number
    // Default: all
    // If runMode is all, all assertions are finished and resolve it
    // If runMode is any, anyone assertion is finished and resolve it
    // In Both, anyone is failed and reject it
    runMode?: "any" | "all";
    // Internal Option
    powerDoctestCallbackFunctionName?: string;
}

const CALLBACK_FUNCTION_NAME = "__power_doctest_runner_callback__";

export interface testOptions {
    // if it is true and Each testOptions.state is "none", run the test
    // if it is false and Each testOptions.state is "none", do not run the test
    // Default: false
    disableRunning: boolean;
}

export function test(parsedCode: ParsedCode, oprions?: testOptions): Promise<void> {
    if (parsedCode.state === "disabled") {
        return Promise.resolve();
    }
    if (oprions && oprions.disableRunning && parsedCode.state === "none") {
        return Promise.resolve();
    }
    return run(parsedCode.code, parsedCode.doctestOptions).catch(error => {
        // if it is expected error, resolve it
        if (parsedCode.expectedError && error.name === parsedCode.expectedError) {
            return Promise.resolve();
        }
        const doctestOptions: PowerDoctestRunnerOptions | undefined = parsedCode.doctestOptions;
        error.fileName = doctestOptions && doctestOptions.filePath
            ? doctestOptions.filePath
            : error.fileName;
        error.lineNumber = parsedCode.location.start.line;
        error.columnNumber = parsedCode.location.start.column;
        const metadata = parsedCode.metadata;
        if (metadata) {
            error.meta = metadata;
        }
        return Promise.reject(error);
    });
}


export function run(code: string, options: PowerDoctestRunnerOptions = {}): Promise<void> {
    const filePath = options.filePath || "default.js";
    const runMode = options.runMode || "all";
    const timeout = options.timeout !== undefined ? options.timeout : 2000;
    const postCallbackName = options.powerDoctestCallbackFunctionName || CALLBACK_FUNCTION_NAME;
    const context = options.context || {};<commit_msg>feat(tester): add `defaultDoctestRunnerOptions`<commit_after>import { NodeVM, VMScript } from "vm2";
import { convertCode } from "power-doctest";
import { ParsedCode } from "@power-doctest/types";

const assert = require("power-assert");

export interface PowerDoctestRunnerOptions {
    // pseudo file path for code
    filePath?: string;
    // sandbox context for code
    // context defined global variables
    context?: {
        [index: string]: any
    }
    // sandbox require mock for code
    requireMock?: {
        [index: string]: any
    }
    // If it is true, console.log output to console
    // If you want to mock console, please pass `console` to `context: { console: consoleMock }`
    //
    // Exception:
    // Always suppress console and assertion, because it is converted to assert function
    // ```
    // console.log(1); // => 1
    // ```
    console?: boolean;
    // Timeout
    // Default: 2000ms
    timeout?: number
    // Default: all
    // If runMode is all, all assertions are finished and resolve it
    // If runMode is any, anyone assertion is finished and resolve it
    // In Both, anyone is failed and reject it
    runMode?: "any" | "all";
    // Internal Option
    powerDoctestCallbackFunctionName?: string;
}

const CALLBACK_FUNCTION_NAME = "__power_doctest_runner_callback__";

export interface testOptions {
    // if it is true and Each testOptions.state is "none", run the test
    // if it is false and Each testOptions.state is "none", do not run the test
    // Default: false
    disableRunning: boolean;
    // default values for doctestRunnerOptions
    // It is override by test case's `doctestRunnerOptions`.
    defaultDoctestRunnerOptions?: PowerDoctestRunnerOptions;
}


export function test(parsedCode: ParsedCode, oprions?: testOptions): Promise<void> {
    if (parsedCode.state === "disabled") {
        return Promise.resolve();
    }
    if (oprions && oprions.disableRunning && parsedCode.state === "none") {
        return Promise.resolve();
    }
    return run(parsedCode.code, {
        ...(oprions && oprions.defaultDoctestRunnerOptions ? oprions.defaultDoctestRunnerOptions : {}),
        ...parsedCode.doctestOptions
    }).catch(error => {
        // if it is expected error, resolve it
        if (parsedCode.expectedError && error.name === parsedCode.expectedError) {
            return Promise.resolve();
        }
        const doctestOptions: PowerDoctestRunnerOptions | undefined = parsedCode.doctestOptions;
        error.fileName = doctestOptions && doctestOptions.filePath
            ? doctestOptions.filePath
            : error.fileName;
        error.lineNumber = parsedCode.location.start.line;
        error.columnNumber = parsedCode.location.start.column;
        const metadata = parsedCode.metadata;
        if (metadata) {
            error.meta = metadata;
        }
        return Promise.reject(error);
    });
}


export function run(code: string, options: PowerDoctestRunnerOptions = {}): Promise<void> {
    const filePath = options.filePath || "default.js";
    const runMode = options.runMode || "all";
    const timeout = options.timeout !== undefined ? options.timeout : 2000;
    const postCallbackName = options.powerDoctestCallbackFunctionName || CALLBACK_FUNCTION_NAME;
    const context = options.context || {};
{'fraction_non_alphanumeric': 0.10833465127312984, 'fraction_numerical': 0.003479361062786652, 'mean_word_length': 2.877375843041079, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 11, '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': '242100', 'n_tokens_mistral': 1746, 'n_tokens_neox': 1723, 'n_words': 521}