<commit_before>#include <cgreen/unit.h>
#include <cgreen/reporter.h>
#include <cgreen/mocks.h>
#include <cgreen/parameters.h>
#include <cgreen/assertions.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>

enum {test_function, test_suite};

typedef void (*sighandler_t)(int);

typedef struct {
    int type;
    union {
        void (*test)();
        TestSuite *suite;
    } sPtr;
    char *name;
} UnitTest;

struct TestSuite_ {
	const char *name;
    UnitTest *tests;
    void (*setup)();
    void (*teardown)();
    int size;
};

static void clean_up_test_run(TestSuite *suite, TestReporter *reporter);
static void run_every_test(TestSuite *suite, TestReporter *reporter);
static void run_named_test(TestSuite *suite, char *name, TestReporter *reporter);
static int has_test(TestSuite *suite, char *name);
static void run_test_in_the_current_process(TestSuite *suite, UnitTest *test, TestReporter *reporter);
static void run_test_in_its_own_process(TestSuite *suite, UnitTest *test, TestReporter *reporter);
static int in_child_process();
static void wait_for_child_process();
static void ignore_ctrl_c();
static void allow_ctrl_c();
static void stop();
static void run_the_test_code(TestSuite *suite, UnitTest *test, TestReporter *reporter);
static void tally_counter(const char *file, int line, int expected, int actual, void *abstract_reporter);
static void die(const char *message, ...);
static void do_nothing();

TestSuite *create_named_test_suite(const char *name) {
    TestSuite *suite = (TestSuite *)malloc(sizeof(TestSuite));
	suite->name = name;
    suite->tests = NULL;
    suite->setup = &do_nothing;
    suite->teardown = &do_nothing;
    suite->size = 0;
    return suite;
}

void destroy_test_suite(TestSuite *suiteToDestroy) {
	int i;
	for (i = 0; i < suiteToDestroy->size; i++) {
		UnitTest test = suiteToDestroy->tests[i];
		TestSuite* suite = test.sPtr.suite;
		if (suite != NULL) {
			suiteToDestroy->tests[i].sPtr.suite = NULL;
			free(suite->tests);
			free(suite);
		}
	}
    free(suiteToDestroy->tests);
    free(suiteToDestroy);
}

void add_test_(TestSuite *suite, char *name, CgreenTest *test) {
    suite->size++;
    suite->tests = (UnitTest *)realloc(suite->tests, sizeof(UnitTest) * suite->size);
    suite->tests[suite->size - 1].type = test_function;
    suite->tests[suite->size - 1].name = name;
    suite->tests[suite->size - 1].sPtr.test = test;
}

void add_tests_(TestSuite *suite, const char *names, ...) {
    CgreenVector *test_names = create_vector_of_names(names);
    int i;
    va_list tests;
    va_start(tests, names);
    for (i = 0; i < cgreen_vector_size(test_names); i++) {
        add_test_(suite, (char *)cgreen_vector_get(test_names, i), va_arg(tests, CgreenTest *));
    }
    va_end(tests);
    destroy_cgreen_vector(test_names);
}

void add_suite_(TestSuite *owner, char *name, TestSuite *suite) {
    owner->size++;
    owner->tests = (UnitTest *)realloc(owner->tests, sizeof(UnitTest) * owner->size);<commit_msg> r304@localhost:  joaohf | 2009-07-02 21:11:55 -0300  Patch from <NAME> to destroy the suites recursively. Thanks<commit_after>#include <cgreen/unit.h>
#include <cgreen/reporter.h>
#include <cgreen/mocks.h>
#include <cgreen/parameters.h>
#include <cgreen/assertions.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>

enum {test_function, test_suite};

typedef void (*sighandler_t)(int);

typedef struct {
    int type;
    union {
        void (*test)();
        TestSuite *suite;
    } sPtr;
    char *name;
} UnitTest;

struct TestSuite_ {
	const char *name;
    UnitTest *tests;
    void (*setup)();
    void (*teardown)();
    int size;
};

static void clean_up_test_run(TestSuite *suite, TestReporter *reporter);
static void run_every_test(TestSuite *suite, TestReporter *reporter);
static void run_named_test(TestSuite *suite, char *name, TestReporter *reporter);
static int has_test(TestSuite *suite, char *name);
static void run_test_in_the_current_process(TestSuite *suite, UnitTest *test, TestReporter *reporter);
static void run_test_in_its_own_process(TestSuite *suite, UnitTest *test, TestReporter *reporter);
static int in_child_process();
static void wait_for_child_process();
static void ignore_ctrl_c();
static void allow_ctrl_c();
static void stop();
static void run_the_test_code(TestSuite *suite, UnitTest *test, TestReporter *reporter);
static void tally_counter(const char *file, int line, int expected, int actual, void *abstract_reporter);
static void die(const char *message, ...);
static void do_nothing();

TestSuite *create_named_test_suite(const char *name) {
    TestSuite *suite = (TestSuite *)malloc(sizeof(TestSuite));
	suite->name = name;
    suite->tests = NULL;
    suite->setup = &do_nothing;
    suite->teardown = &do_nothing;
    suite->size = 0;
    return suite;
}

void destroy_test_suite(TestSuite *suiteToDestroy) {
	int i;
	for (i = 0; i < suiteToDestroy->size; i++) {
		UnitTest test = suiteToDestroy->tests[i];
		TestSuite* suite = test.sPtr.suite;
		if (test_suite == test.type && suite != NULL) { 
			suiteToDestroy->tests[i].sPtr.suite = NULL;
                        destroy_test_suite(suite); 
		}
	}
    if(suiteToDestroy->tests != NULL)
      free(suiteToDestroy->tests);
    
    free(suiteToDestroy);
}

void add_test_(TestSuite *suite, char *name, CgreenTest *test) {
    suite->size++;
    suite->tests = (UnitTest *)realloc(suite->tests, sizeof(UnitTest) * suite->size);
    suite->tests[suite->size - 1].type = test_function;
    suite->tests[suite->size - 1].name = name;
    suite->tests[suite->size - 1].sPtr.test = test;
}

void add_tests_(TestSuite *suite, const char *names, ...) {
    CgreenVector *test_names = create_vector_of_names(names);
    int i;
    va_list tests;
    va_start(tests, names);
    for (i = 0; i < cgreen_vector_size(test_names); i++) {
        add_test_(suite, (char *)cgreen_vector_get(test_names, i), va_arg(tests, CgreenTest *));
    }
    va_end(tests);
    destroy_cgreen_vector(test_names);
}

void add_suite_(TestSuite *owner, char *name, TestSuite *suite) {
    owner->size++;
    owner->tests = (UnitTest *)realloc(owner->tests, sizeof(UnitTest) * owner->size);
{'fraction_non_alphanumeric': 0.13994307400379508, 'fraction_numerical': 0.005218216318785579, 'mean_word_length': 4.557996485061511, 'pattern_counts': {'":': 0, '<': 32, '<?xml version=': 0, '>': 76, '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': '3977915', 'n_tokens_mistral': 2221, 'n_tokens_neox': 2152, 'n_words': 520}