Add files via upload

This commit is contained in:
StarFinger
2026-02-22 16:50:46 +03:00
committed by GitHub
commit 9f9f22f22c
8 changed files with 1349 additions and 0 deletions

438
tests.c Normal file
View File

@@ -0,0 +1,438 @@
#include "dynamic_array.h"
#include "types.h"
#include <stdio.h>
#include <stdlib.h>
// Подсчёт тестов
static int tests_passed = 0;
static int tests_failed = 0;
#define TEST(name) static bool name(void)
#define RUN(name) do { \
printf(" %-50s", #name); \
if (name()) { \
tests_passed++; \
printf(" [OK]\n"); \
} \
} while (0)
#define ASSERT(cond) do { \
if (!(cond)) { \
printf(" [FAIL] %s:%d: %s\n", __FILE__, __LINE__, #cond); \
tests_failed++; \
return false; \
} \
} while (0)
// --------------- ТЕСТЫ ---------------
// Создание и базовые операции
TEST(test_create_destroy) {
DynamicArray *arr = da_create(get_double_type(), 0);
ASSERT(arr != NULL);
ASSERT(da_size(arr) == 0);
da_destroy(arr);
return true;
}
TEST(test_push_back_double) {
DynamicArray *arr = da_create(get_double_type(), 0);
const double vals[] = {1.1, 2.2, 3.3};
for (size_t i = 0; i < 3; i++) {
da_push_back(arr, &vals[i]);
}
ASSERT(da_size(arr) == 3);
ASSERT(*(double *)da_get(arr, 0) == 1.1);
ASSERT(*(double *)da_get(arr, 1) == 2.2);
ASSERT(*(double *)da_get(arr, 2) == 3.3);
da_destroy(arr);
return true;
}
TEST(test_push_back_complex) {
DynamicArray *arr = da_create(get_complex_type(), 0);
const Complex vals[] = {
{1.1, 1}, {2.2, 2}, {3.3, 3}
};
for (size_t i = 0; i < 3; i++) {
da_push_back(arr, &vals[i]);
}
Complex *c_get;
ASSERT(da_size(arr) == 3);
c_get = (Complex *) da_get(arr, 0);
ASSERT(c_get->re == 1.1 && c_get->im == 1);
c_get = (Complex *) da_get(arr, 1);
ASSERT(c_get->re == 2.2 && c_get->im == 2);
c_get = (Complex *) da_get(arr, 2);
ASSERT(c_get->re == 3.3 && c_get->im == 3);
da_destroy(arr);
return true;
}
TEST(test_set_get) {
DynamicArray *arr = da_create(get_double_type(), 0);
const double v1 = 42, v2 = 99;
da_push_back(arr, &v1);
ASSERT(*(double *)da_get(arr, 0) == 42);
da_set(arr, 0, &v2);
ASSERT(*(double *)da_get(arr, 0) == 99);
da_destroy(arr);
return true;
}
TEST(test_insert) {
DynamicArray *arr = da_create(get_double_type(), 0);
const double a = 1, b = 2, c = 3, ins = 99;
da_push_back(arr, &a);
da_push_back(arr, &b);
da_push_back(arr, &c);
da_insert(arr, 1, &ins);
ASSERT(da_size(arr) == 4);
ASSERT(*(double *)da_get(arr, 0) == 1);
ASSERT(*(double *)da_get(arr, 1) == 99);
ASSERT(*(double *)da_get(arr, 2) == 2);
ASSERT(*(double *)da_get(arr, 3) == 3);
da_destroy(arr);
return true;
}
TEST(test_remove) {
DynamicArray *arr = da_create(get_double_type(), 0);
const double vals[] = {10, 20, 30};
for (int i = 0; i < 3; i++) da_push_back(arr, &vals[i]);
da_remove(arr, 1);
ASSERT(da_size(arr) == 2);
ASSERT(*(double *)da_get(arr, 0) == 10);
ASSERT(*(double *)da_get(arr, 1) == 30);
da_destroy(arr);
return true;
}
// Граничные случаи
TEST(test_get_out_of_bounds) {
DynamicArray *arr = da_create(get_double_type(), 0);
ASSERT(da_get(arr, 0) == NULL);
const double v = 1;
da_push_back(arr, &v);
ASSERT(da_get(arr, 1) == NULL);
ASSERT(da_get(arr, 100) == NULL);
da_destroy(arr);
return true;
}
TEST(test_remove_out_of_bounds) {
DynamicArray *arr = da_create(get_double_type(), 0);
ASSERT(da_remove(arr, 0) == false);
da_destroy(arr);
return true;
}
TEST(test_empty_array_operations) {
DynamicArray *arr = da_create(get_double_type(), 0);
da_sort(arr); // Не должен ломаться
ASSERT(da_size(arr) == 0);
da_destroy(arr);
return true;
}
TEST(test_create_null_type) {
DynamicArray *arr = da_create(NULL, 0);
ASSERT(arr == NULL);
return true;
}
TEST(test_capacity_growth) {
DynamicArray *arr = da_create(get_int_type(), 2);
for (int i = 0; i < 100; i++)
ASSERT(da_push_back(arr, &i));
ASSERT(da_size(arr) >= 100);
for (int i = 0; i < 100; i++)
ASSERT(*(int *)da_get(arr, i) == i);
da_destroy(arr);
return true;
}
// Сортировка
TEST(test_sort_double) {
DynamicArray *arr = da_create(get_double_type(), 0);
const double vals[] = {3.14, 1.0, 2.71, 0.5};
for (int i = 0; i < 4; i++) da_push_back(arr, &vals[i]);
da_sort(arr);
for (size_t i = 1; i < da_size(arr); i++)
ASSERT(*(double *)da_get(arr, i - 1) <= *(double *)da_get(arr, i));
da_destroy(arr);
return true;
}
TEST(test_sort_complex) {
DynamicArray *arr = da_create(get_complex_type(), 0);
const Complex vals[] = {
{3, 4}, {1, 0}, {0, 2}
}; // |5|, |1|, |2|
for (int i = 0; i < 3; i++) da_push_back(arr, &vals[i]);
da_sort(arr);
// Порядок по модулю: (1,0), (0,2), (3,4)
const Complex *c0 = da_get(arr, 0);
const Complex *c1 = da_get(arr, 1);
const Complex *c2 = da_get(arr, 2);
ASSERT(c0->re == 1.0 && c0->im == 0.0);
ASSERT(c1->re == 0.0 && c1->im == 2.0);
ASSERT(c2->re == 3.0 && c2->im == 4.0);
da_destroy(arr);
return true;
}
// map
static void double_value(void *dest, const void *src) {
*(double *)dest = *(const double *)src * 2;
}
TEST(test_map_double) {
DynamicArray *arr = da_create(get_double_type(), 0);
const double vals[] = {1.0, 2.0, 3.0};
for (int i = 0; i < 3; i++) da_push_back(arr, &vals[i]);
DynamicArray *mapped = da_map(arr, double_value);
ASSERT(mapped != NULL);
ASSERT(da_size(mapped) == 3);
ASSERT(*(double *)da_get(mapped, 0) == 2.0);
ASSERT(*(double *)da_get(mapped, 1) == 4.0);
ASSERT(*(double *)da_get(mapped, 2) == 6.0);
da_destroy(arr);
da_destroy(mapped);
return true;
}
TEST(test_map_empty) {
DynamicArray *arr = da_create(get_double_type(), 0);
DynamicArray *mapped = da_map(arr, double_value);
ASSERT(mapped != NULL);
ASSERT(da_size(mapped) == 0);
da_destroy(arr);
da_destroy(mapped);
return true;
}
// where
static bool is_positive(const void *elem) {
return *(const double *)elem > 0;
}
static bool is_real(const void *elem) {
const Complex *c_elem = (Complex *)elem;
return c_elem->im == 0;
}
TEST(test_where_double) {
DynamicArray *arr = da_create(get_double_type(), 0);
const double vals[] = {-1.0, 2.5, -3.0, 4.0};
for (int i = 0; i < 4; i++)
da_push_back(arr, &vals[i]);
DynamicArray *filtered = da_where(arr, is_positive);
ASSERT(da_size(filtered) == 2);
ASSERT(*(double *)da_get(filtered, 0) == 2.5);
ASSERT(*(double *)da_get(filtered, 1) == 4.0);
da_destroy(arr);
da_destroy(filtered);
return true;
}
TEST(test_where_complex) {
DynamicArray *arr = da_create(get_complex_type(), 0);
const Complex vals[] = {
{1.0, 2.0}, {4.0, 0.0}, {-1.0, 1.0}
};
for (int i = 0; i < 3; i++)
da_push_back(arr, &vals[i]);
DynamicArray *filtered = da_where(arr, is_real);
ASSERT(da_size(filtered) == 1);
const Complex *num = da_get(filtered, 0);
ASSERT(num->re == 4.0 && num->im == 0.0);
da_destroy(arr);
da_destroy(filtered);
return true;
}
TEST(test_where_none_match) {
DynamicArray *arr = da_create(get_double_type(), 0);
const double vals[] = {-1.0, -3.0, -5.0};
for (int i = 0; i < 3; i++) da_push_back(arr, &vals[i]);
DynamicArray *filtered = da_where(arr, is_positive);
ASSERT(da_size(filtered) == 0);
da_destroy(arr);
da_destroy(filtered);
return true;
}
// reduce
static void sum_reduce_double(void *acc, const void *elem) {
*(double *)acc += *(const double *)elem;
}
static void sum_reduce_complex(void *acc, const void *elem) {
Complex *c_acc = (Complex *)acc;
const Complex *c_elem = (const Complex *)elem;
c_acc->re += c_elem->re;
c_acc->im += c_elem->im;
}
TEST(test_reduce_sum_double) {
DynamicArray *arr = da_create(get_double_type(), 0);
const double vals[] = {1.0, 2.0, 3.0, 4.0, 5.0};
for (int i = 0; i < 5; i++) da_push_back(arr, &vals[i]);
double initial = 0.0, result = 0.0;
da_reduce(arr, sum_reduce_double, &initial, &result);
ASSERT(result == 15.0);
da_destroy(arr);
return true;
}
TEST(test_reduce_sum_complex) {
DynamicArray *arr = da_create(get_complex_type(), 0);
const Complex vals[] = {
{1.0, 0.0}, {2.0, 1.0}, {3.0, 2.0}
};
for (int i = 0; i < 3; i++) da_push_back(arr, &vals[i]);
Complex initial = {0.0, 0.0}, result = {0.0, 0.0};
da_reduce(arr, sum_reduce_complex, &initial, &result);
ASSERT(result.re == 6.0 && result.im == 3.0);
da_destroy(arr);
return true;
}
TEST(test_reduce_empty) {
DynamicArray *arr = da_create(get_double_type(), 0);
double initial = 42.0, result = 0.0;
da_reduce(arr, sum_reduce_double, &initial, &result);
ASSERT(result == 42);
da_destroy(arr);
return true;
}
// Конкатенация
TEST(test_concat_double) {
DynamicArray *a = da_create(get_double_type(), 0);
DynamicArray *b = da_create(get_double_type(), 0);
const double v1 = 1.0, v2 = 2.0, v3 = 3.0, v4 = 4.0;
da_push_back(a, &v1);
da_push_back(a, &v2);
da_push_back(b, &v3);
da_push_back(b, &v4);
DynamicArray *c = da_concat(a, b);
ASSERT(c != NULL);
ASSERT(da_size(c) == 4);
ASSERT(*(double *)da_get(c, 0) == 1.0);
ASSERT(*(double *)da_get(c, 1) == 2.0);
ASSERT(*(double *)da_get(c, 2) == 3.0);
ASSERT(*(double *)da_get(c, 3) == 4.0);
da_destroy(a);
da_destroy(b);
da_destroy(c);
return true;
}
TEST(test_concat_type_mismatch) {
DynamicArray *a = da_create(get_double_type(), 0);
DynamicArray *b = da_create(get_complex_type(), 0);
DynamicArray *c = da_concat(a, b);
ASSERT(c == NULL); // Несовпадение типов
da_destroy(a);
da_destroy(b);
return true;
}
TEST(test_concat_with_empty) {
DynamicArray *a = da_create(get_double_type(), 0);
DynamicArray *b = da_create(get_double_type(), 0);
const double v = 42.0;
da_push_back(a, &v);
DynamicArray *c = da_concat(a, b);
ASSERT(da_size(c) == 1);
ASSERT(*(double *)da_get(c, 0) == 42.0);
da_destroy(a);
da_destroy(b);
da_destroy(c);
return true;
}
int main() {
printf(" === Модульные тесты ===\n");
printf("--- Создание и базовые операции ---\n");
RUN(test_create_destroy);
RUN(test_push_back_double);
RUN(test_push_back_complex);
RUN(test_set_get);
RUN(test_insert);
RUN(test_remove);
printf("--- Граничные случаи ---\n");
RUN(test_get_out_of_bounds);
RUN(test_remove_out_of_bounds);
RUN(test_empty_array_operations);
RUN(test_create_null_type);
RUN(test_capacity_growth);
printf("--- Сортировка ---\n");
RUN(test_sort_double);
RUN(test_sort_complex);
printf("--- map ---\n");
RUN(test_map_double);
RUN(test_map_empty);
printf("--- where ---\n");
RUN(test_where_double);
RUN(test_where_complex);
RUN(test_where_none_match);
printf("--- reduce ---\n");
RUN(test_reduce_sum_double);
RUN(test_reduce_sum_complex);
RUN(test_reduce_empty);
printf("--- Конкатенация ---\n");
RUN(test_concat_double);
RUN(test_concat_type_mismatch);
RUN(test_concat_with_empty);
printf("\n======================\n");
printf("Итого: %d пройдено, %d провалено\n", tests_passed, tests_failed);
return tests_failed > 0 ? 1 : 0;
}