<commit_before>import { suite, test, slow, timeout, skip, pending, only } from "./index";
import { assert } from "chai";
import { spawnSync } from "child_process";
import * as path from "path";
import * as rimraf from "rimraf";

var chai = require("chai");
var fs = require("fs");


function assertContent(actualStr: string, expectedStr: string) {

    let actual: string[] = actualStr.split("\n");
    let expected: string[] = expectedStr.split("\n");

    assert.equal(actual.length, expected.length, "actual and expected differ in length");
    for(var i = 0; i < expected.length; i++) {
      let expectedLine = expected[i].trim();
      let actualLine = actual[i].trim();
      assert.isTrue(actualLine.indexOf(expectedLine) !== -1,
        "Unexpected output on line '" + i + "'. Expected: '" +
        expectedLine + "' to be contained in '" + actualLine + "'");
    }
}

function assertOutput(actual: string, filePath: string) {

    let expected = "";
    try {
        expected = fs.readFileSync(filePath, "utf-8");
        assertContent(cleanup(actual, true), cleanup(expected, true));
    } catch (e) {
        console.log("\nerror while testing " + filePath.replace(__dirname, ""));
        console.log("\n" + e.toString());
        console.log("\n<<<<< expected\n" + expected);
        console.log("\n>>>>> actual\n" + cleanup(actual) + "=====");
        throw e;
    }
}

const ELIMINATE_LINE = "__mts_eliminate_line__";

function cleanup(str: string, eliminateAllEmptyLines = false): string {

    // clean up times
    let result = str.replace(/\s*[(][\d]+[^)]+[)]/g, "");
    // clean up call stacks
    result = result.replace(/at\s<.+>.*/g, ELIMINATE_LINE);
    result = result.replace(/at\s.+[^:]+:[^:]+:[\d]+/g, ELIMINATE_LINE);
    result = result.replace(/at\s.+[(][^:]+:[^:]+:[^)]+[)]/g, ELIMINATE_LINE);
    result = result.replace(/at\s.+[\[]as\s+[^\]]+[\]].*/g, ELIMINATE_LINE);
    // clean up calls
    result = result.replace(/>\s.+/g, ELIMINATE_LINE);

    return trimEmptyLines(result, eliminateAllEmptyLines);
}

function trimEmptyLines(str: string, eliminateAll = false): string {

    const collected: string[] = [];
    const lines = str.split('\n');
    let emptyLinesCount = 0;
    for (const line of lines) {
        if (line === "" || line.match(/^\s*$/) || line.indexOf(ELIMINATE_LINE) !== -1) {
            emptyLinesCount++;
            continue;
        }
        if (emptyLinesCount && !eliminateAll) {
            collected.push('');
        }
        emptyLinesCount = 0;
        collected.push(line);
    }

    return collected.join('\n');
}

@suite("typescript", slow(5000), timeout(15000))
class SuiteTest {

    @test("target v1 es5") es5() {
        this.run("es5", "test.suite");
    }

    @test("target v1 es6") es6() {
        this.run("es6", "test.suite");
    }

    @test("target v2 es5") v2es5() {
        this.run("es5", "test.v2.suite");
    }

    @test("target v2 es6") v2es6() {
        this.run("es6", "test.v2.suite");
    }

    @test "only v2 suite es5"() {
        this.run("es5", "only.v2.suite");
    }

    @test "only v2 suite es6"() {
        this.run("es6", "only.v2.suite");
    }

    @test "pending v2 suite es5"() {
        this.run("es5", "pending.v2.suite");
    }

    @test "pending v2 suite es6"() {
        this.run("es6", "pending.v2.suite");
    }

    @test "only suite es5"() {
        this.run("es5", "only.suite");
    }

    @test "only suite es6"() {
        this.run("es6", "only.suite");
    }

    @test "pending suite es5"() {
        this.run("es5", "pending.suite");
    }

    @test "pending suite es6"() {
        this.run("es6", "pending.suite");
    }

    @test "retries suite es5"() {
        this.run("es5", "retries.suite");
    }

    @test "retries suite es6"() {
        this.run("es6", "retries.suite");
    }

    @test "context suite es6"() {
        this.run("es6", "context.suite");
    }

    @test "abstract inheritance suite es5"() {
        this.run("es5", "abstract.inheritance.suite");
    }

    @test "abstract inheritance suite es6"() {
        this.run("es6", "abstract.inheritance.suite");
    }

    @test "suite inheritance suite es5"() {
        this.run("es5", "suite.inheritance.suite");
    }

    @test "suite inheritance suite es6"() {
        this.run("es6", "suite.inheritance.suite");
    }

    private run(target: string, ts: string) {
        let tsc = spawnSync("node", [path.join(".", "node_modules", "typescript", "bin", "tsc"),
                                     "--experimentalDecorators", "--module", "commonjs", "--target", target, "--lib",
                                     "es6", path.join("tests", "ts", ts + ".ts")]);

        // console.log(tsc.stdout.toString());
        assert.equal(tsc.stdout.toString(), "", "Expected error free tsc.");
        assert.equal(tsc.status, 0);

        let mocha = spawnSync("node", [path.join(".", "node_modules", "mocha", "bin", "_mocha"),
                                       "-C", path.join("tests", "ts", ts + ".js")]);
        // To debug any actual output while developing:
        // assert(mocha.status !== 0);

        // console.log(mocha.stderr.toString());

        // To patch the expected use the output of this, but clean up times and callstacks:
        let actual = cleanup(mocha.stdout.toString());
        assertOutput(actual, path.join("tests", "ts", ts + ".expected.txt"));
    }
}

// These integration tests are slow, you can uncommend the skip version below during development
// @suite.skip(timeout(90000))
@suite(timeout(90000), slow(10000))
class PackageTest {

    static tgzPath: string;

    @test "can be consumed as module"() {
        this.testPackage("module-usage", false);
    }

    @test "can be consumed as custom ui"() {
        this.testPackage("custom-ui", false);
    }

    @test "readme followed custom ui"() {
        this.testPackage("setting-up", false);
    }<commit_msg>fix imports<commit_after>import { suite, test, slow, timeout, skip, pending, only } from "./index";
import { assert } from "chai";
import { spawnSync } from "child_process";
import * as path from "path";
import * as rimraf from "rimraf";
import * as fs from "fs";

function assertContent(actualStr: string, expectedStr: string) {

    let actual: string[] = actualStr.split("\n");
    let expected: string[] = expectedStr.split("\n");

    assert.equal(actual.length, expected.length, "actual and expected differ in length");
    for(var i = 0; i < expected.length; i++) {
      let expectedLine = expected[i].trim();
      let actualLine = actual[i].trim();
      assert.isTrue(actualLine.indexOf(expectedLine) !== -1,
        "Unexpected output on line '" + i + "'. Expected: '" +
        expectedLine + "' to be contained in '" + actualLine + "'");
    }
}

function assertOutput(actual: string, filePath: string) {

    let expected = "";
    try {
        expected = fs.readFileSync(filePath, "utf-8");
        assertContent(cleanup(actual, true), cleanup(expected, true));
    } catch (e) {
        console.log("\nerror while testing " + filePath.replace(__dirname, ""));
        console.log("\n" + e.toString());
        console.log("\n<<<<< expected\n" + expected);
        console.log("\n>>>>> actual\n" + cleanup(actual) + "=====");
        throw e;
    }
}

const ELIMINATE_LINE = "__mts_eliminate_line__";

function cleanup(str: string, eliminateAllEmptyLines = false): string {

    // clean up times
    let result = str.replace(/\s*[(][\d]+[^)]+[)]/g, "");
    // clean up call stacks
    result = result.replace(/at\s<.+>.*/g, ELIMINATE_LINE);
    result = result.replace(/at\s.+[^:]+:[^:]+:[\d]+/g, ELIMINATE_LINE);
    result = result.replace(/at\s.+[(][^:]+:[^:]+:[^)]+[)]/g, ELIMINATE_LINE);
    result = result.replace(/at\s.+[\[]as\s+[^\]]+[\]].*/g, ELIMINATE_LINE);
    // clean up calls
    result = result.replace(/>\s.+/g, ELIMINATE_LINE);

    return trimEmptyLines(result, eliminateAllEmptyLines);
}

function trimEmptyLines(str: string, eliminateAll = false): string {

    const collected: string[] = [];
    const lines = str.split('\n');
    let emptyLinesCount = 0;
    for (const line of lines) {
        if (line === "" || line.match(/^\s*$/) || line.indexOf(ELIMINATE_LINE) !== -1) {
            emptyLinesCount++;
            continue;
        }
        if (emptyLinesCount && !eliminateAll) {
            collected.push('');
        }
        emptyLinesCount = 0;
        collected.push(line);
    }

    return collected.join('\n');
}

@suite("typescript", slow(5000), timeout(15000))
class SuiteTest {

    @test("target v1 es5") es5() {
        this.run("es5", "test.suite");
    }

    @test("target v1 es6") es6() {
        this.run("es6", "test.suite");
    }

    @test("target v2 es5") v2es5() {
        this.run("es5", "test.v2.suite");
    }

    @test("target v2 es6") v2es6() {
        this.run("es6", "test.v2.suite");
    }

    @test "only v2 suite es5"() {
        this.run("es5", "only.v2.suite");
    }

    @test "only v2 suite es6"() {
        this.run("es6", "only.v2.suite");
    }

    @test "pending v2 suite es5"() {
        this.run("es5", "pending.v2.suite");
    }

    @test "pending v2 suite es6"() {
        this.run("es6", "pending.v2.suite");
    }

    @test "only suite es5"() {
        this.run("es5", "only.suite");
    }

    @test "only suite es6"() {
        this.run("es6", "only.suite");
    }

    @test "pending suite es5"() {
        this.run("es5", "pending.suite");
    }

    @test "pending suite es6"() {
        this.run("es6", "pending.suite");
    }

    @test "retries suite es5"() {
        this.run("es5", "retries.suite");
    }

    @test "retries suite es6"() {
        this.run("es6", "retries.suite");
    }

    @test "context suite es6"() {
        this.run("es6", "context.suite");
    }

    @test "abstract inheritance suite es5"() {
        this.run("es5", "abstract.inheritance.suite");
    }

    @test "abstract inheritance suite es6"() {
        this.run("es6", "abstract.inheritance.suite");
    }

    @test "suite inheritance suite es5"() {
        this.run("es5", "suite.inheritance.suite");
    }

    @test "suite inheritance suite es6"() {
        this.run("es6", "suite.inheritance.suite");
    }

    private run(target: string, ts: string) {
        let tsc = spawnSync("node", [path.join(".", "node_modules", "typescript", "bin", "tsc"),
                                     "--experimentalDecorators", "--module", "commonjs", "--target", target, "--lib",
                                     "es6", path.join("tests", "ts", ts + ".ts")]);

        assert.equal(tsc.stdout.toString(), "", "Expected error free tsc.");
        assert.equal(tsc.status, 0);

        let mocha = spawnSync("node", [path.join(".", "node_modules", "mocha", "bin", "_mocha"),
                                       "-C", path.join("tests", "ts", ts + ".js")]);

        let actual = cleanup(mocha.stdout.toString());
        assertOutput(actual, path.join("tests", "ts", ts + ".expected.txt"));
    }
}

// These integration tests are slow, you can uncommend the skip version below during development
// @suite.skip(timeout(90000))
@suite(timeout(90000), slow(10000))
class PackageTest {

    static tgzPath: string;

    @test "can be consumed as module"() {
        this.testPackage("module-usage", false);
    }

    @test "can be consumed as custom ui"() {
        this.testPackage("custom-ui", false);
    }

    @test "readme followed custom ui"() {
        this.testPackage("setting-up", false);
    }
{'fraction_non_alphanumeric': 0.1909390730775907, 'fraction_numerical': 0.01570907828501996, 'mean_word_length': 2.5741315136476426, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1603521', 'n_tokens_mistral': 3874, 'n_tokens_neox': 3727, 'n_words': 852}