<commit_before>package dotty.tools.dotc.vulpix;

import org.junit.BeforeClass;
import org.junit.AfterClass;
import java.util.ArrayDeque;
import java.util.function.Supplier;
import scala.Function0;
import scala.Unit;

import dotty.tools.dotc.reporting.TestReporter;

/** Note that while `ParallelTesting` runs in parallel, JUnit tests cannot with
 *  this class
 */
public class SummaryReport {
    public final static boolean isInteractive = !System.getenv().containsKey("DRONE");

    private static TestReporter rep = TestReporter.reporter(System.out, -1);
    private static ArrayDeque<String> failedTests = new ArrayDeque<>();
    private static ArrayDeque<String> reproduceInstructions = new ArrayDeque<>();
    private static int passed;
    private static int failed;

    public final static void reportFailed() {
        failed++;
    }

    public final static void reportPassed() {
        passed++;
    }

    public final static void addFailedTest(String msg) {
        failedTests.offer(msg);
    }

    public final static void addReproduceInstruction(String msg) {
        reproduceInstructions.offer(msg);
    }

    @BeforeClass public final static void setup() {
        rep = TestReporter.reporter(System.out, -1);
        failedTests = new ArrayDeque<>();
        reproduceInstructions = new ArrayDeque<>();
    }

    @AfterClass public final static void teardown() {
        rep.echo(
            "\n================================================================================" +
            "\nTest Report" +
            "\n================================================================================" +
            "\n" +
            passed + " passed, " + failed + " failed, " + (passed + failed) + " total" +
            "\n"
        );

        failedTests
            .stream()
            .map(x -> "    " + x)
            .forEach(rep::echo);

        // If we're compiling locally, we don't need reproduce instructions
        if (isInteractive) rep.flushToStdErr();

        rep.echo("");

        reproduceInstructions
            .stream()
            .forEach(rep::echo);

        // If we're on the CI, we want everything
        if (!isInteractive) rep.flushToStdErr();

        if (failed > 0) rep.flushToFile();
    }
}
<commit_msg>Add cleanup hooks to SummaryReporter<commit_after>package dotty.tools.dotc.vulpix;

import org.junit.BeforeClass;
import org.junit.AfterClass;
import java.util.ArrayDeque;
import java.util.function.Supplier;
import scala.Function0;
import scala.Unit;

import dotty.tools.dotc.reporting.TestReporter;

/** Note that while `ParallelTesting` runs in parallel, JUnit tests cannot with
 *  this class
 */
public class SummaryReport {
    public final static boolean isInteractive = !System.getenv().containsKey("DRONE");

    private static TestReporter rep = TestReporter.reporter(System.out, -1);
    private static ArrayDeque<String> failedTests = new ArrayDeque<>();
    private static ArrayDeque<String> reproduceInstructions = new ArrayDeque<>();
    private static Supplier<Void> cleanup;
    private static int passed;
    private static int failed;

    public final static void reportFailed() {
        failed++;
    }

    public final static void reportPassed() {
        passed++;
    }

    public final static void addFailedTest(String msg) {
        failedTests.offer(msg);
    }

    public final static void addReproduceInstruction(String msg) {
        reproduceInstructions.offer(msg);
    }

    public final static void addCleanup(Function0<Unit> func) {
        // Wow, look at how neatly we - compose cleanup callbacks:
        if (cleanup == null) {
            cleanup = () -> {
                func.apply();
                return null;
            };
        } else {
            Supplier<Void> oldCleanup = cleanup;
            cleanup = () -> {
                oldCleanup.get();
                func.apply();
                return null;
            };
        }
    }

    @BeforeClass public final static void setup() {
        rep = TestReporter.reporter(System.out, -1);
        failedTests = new ArrayDeque<>();
        reproduceInstructions = new ArrayDeque<>();
    }

    @AfterClass public final static void teardown() {
        rep.echo(
            "\n================================================================================" +
            "\nTest Report" +
            "\n================================================================================" +
            "\n" +
            passed + " passed, " + failed + " failed, " + (passed + failed) + " total" +
            "\n"
        );

        failedTests
            .stream()
            .map(x -> "    " + x)
            .forEach(rep::echo);

        // If we're compiling locally, we don't need reproduce instructions
        if (isInteractive) rep.flushToStdErr();

        rep.echo("");

        reproduceInstructions
            .stream()
            .forEach(rep::echo);

        // If we're on the CI, we want everything
        if (!isInteractive) rep.flushToStdErr();

        if (failed > 0) rep.flushToFile();

        // Perform cleanup callback:
        if (cleanup != null) cleanup.get();
    }
}

{'fraction_non_alphanumeric': 0.16612127045235803, 'fraction_numerical': 0.0017324350336862368, 'mean_word_length': 2.409448818897638, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 24, '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': '4623800', 'n_tokens_mistral': 1402, 'n_tokens_neox': 1340, 'n_words': 370}