405 lines
13 KiB
C
405 lines
13 KiB
C
#include <unity.h>
|
|
#include "../testutils.h"
|
|
|
|
#include <yamlloader.h>
|
|
|
|
#include <camera.h>
|
|
#include <configuration.h>
|
|
#include <cube.h>
|
|
#include <matrix.h>
|
|
#include <tuples.h>
|
|
|
|
void setUp(void) {}
|
|
void tearDown(void) {}
|
|
|
|
CEXCEPTION_T exception;
|
|
|
|
static int parse_map_entries;
|
|
void validate_key_value(char *key, char *value, void *context) {
|
|
UNUSED(context);
|
|
TEST_ASSERT_EQUAL_STRING("akey", key);
|
|
TEST_ASSERT_EQUAL_STRING("[the value]", value);
|
|
parse_map_entries++;
|
|
}
|
|
|
|
void test_parse_map_entries(void) {
|
|
parse_map_entries = 0;
|
|
char data[] = "\nakey:[the value]\n\n";
|
|
YAMLLOADER_parse_map_entries(data, validate_key_value, NULL);
|
|
TEST_ASSERT_EQUAL(1, parse_map_entries);
|
|
}
|
|
|
|
void test_parse_color(void) {
|
|
TUPLES_Color result, expected;
|
|
TUPLES_init_color(&expected, 100.5, 22.75, 4.123);
|
|
char data[] = "[100.5, 22.75, 4.123]";
|
|
YAMLLOADER_parse_color(data, &result);
|
|
test_tuples(&expected, &result);
|
|
}
|
|
|
|
void test_parse_vector(void) {
|
|
TUPLES_Vector result, expected;
|
|
TUPLES_init_vector(&expected, 1.5, 2.75, 4);
|
|
char data[] = "[1.5, 2.75,4]";
|
|
YAMLLOADER_parse_vector(data, &result);
|
|
test_tuples(&expected, &result);
|
|
}
|
|
|
|
void test_parse_point(void) {
|
|
TUPLES_Point result, expected;
|
|
TUPLES_init_point(&expected, .5, 7.75, 0.4);
|
|
char data[] = "[.5, 7.75, 0.4]";
|
|
YAMLLOADER_parse_point(data, &result);
|
|
test_tuples(&expected, &result);
|
|
}
|
|
|
|
void test_parse_bool(void) {
|
|
bool result = false;
|
|
YAMLLOADER_parse_bool("true", &result);
|
|
TEST_ASSERT_TRUE(result);
|
|
YAMLLOADER_parse_bool("false", &result);
|
|
TEST_ASSERT_FALSE(result);
|
|
}
|
|
|
|
void test_parse_uint(void) {
|
|
unsigned int result = 0;
|
|
YAMLLOADER_parse_uint("5", &result);
|
|
TEST_ASSERT_EQUAL_UINT(5, result);
|
|
}
|
|
|
|
void test_parse_double(void) {
|
|
double result = 0.0;
|
|
YAMLLOADER_parse_double("1.543", &result);
|
|
TEST_ASSERT_EQUAL_DOUBLE(1.543, result);
|
|
}
|
|
|
|
void test_parse_single_transform_scale_entry(void) {
|
|
char data[] = "[ scale , 3, 0.1, 2]";
|
|
|
|
MATRIX_Matrix *expected = MATRIX_new_scaling(3, 0.1, 2);
|
|
MATRIX_Matrix *result = YAMLLOADER_parse_transform_entry(data);
|
|
TEST_ASSERT_NOT_NULL(result);
|
|
TEST_ASSERT_TRUE(MATRIX_is_equal(expected, result));
|
|
MATRIX_delete_all(expected, result);
|
|
}
|
|
|
|
void test_parse_single_transform_translate_entry(void) {
|
|
char data[] = "[ translate , 31, 0.2, 2.19]";
|
|
|
|
MATRIX_Matrix *expected = MATRIX_new_translation(31, 0.2, 2.19);
|
|
MATRIX_Matrix *result = YAMLLOADER_parse_transform_entry(data);
|
|
TEST_ASSERT_NOT_NULL(result);
|
|
TEST_ASSERT_TRUE(MATRIX_is_equal(expected, result));
|
|
MATRIX_delete_all(expected, result);
|
|
}
|
|
|
|
void test_parse_single_transform_rotate_x_entry(void) {
|
|
char data[] = "[ rotate-x, 0.5]";
|
|
|
|
MATRIX_Matrix *expected = MATRIX_new_rotation_x(0.5);
|
|
MATRIX_Matrix *result = YAMLLOADER_parse_transform_entry(data);
|
|
TEST_ASSERT_NOT_NULL(result);
|
|
TEST_ASSERT_TRUE(MATRIX_is_equal(expected, result));
|
|
MATRIX_delete_all(expected, result);
|
|
}
|
|
|
|
void test_parse_single_transform_rotate_y_entry(void) {
|
|
char data[] = "[ rotate-y, 0.25]";
|
|
|
|
MATRIX_Matrix *expected = MATRIX_new_rotation_y(0.25);
|
|
MATRIX_Matrix *result = YAMLLOADER_parse_transform_entry(data);
|
|
TEST_ASSERT_NOT_NULL(result);
|
|
TEST_ASSERT_TRUE(MATRIX_is_equal(expected, result));
|
|
MATRIX_delete_all(expected, result);
|
|
}
|
|
|
|
void test_parse_single_transform_rotate_z_entry(void) {
|
|
char data[] = " [ rotate-z, 0.75]";
|
|
|
|
MATRIX_Matrix *expected = MATRIX_new_rotation_z(0.75);
|
|
MATRIX_Matrix *result = YAMLLOADER_parse_transform_entry(data);
|
|
TEST_ASSERT_NOT_NULL(result);
|
|
TEST_ASSERT_TRUE(MATRIX_is_equal(expected, result));
|
|
MATRIX_delete_all(expected, result);
|
|
}
|
|
|
|
void test_parse_transform_chain(void) {
|
|
char data[] = " - [scale, 0.1, 1.5, 0.1]\n"
|
|
" - [translate, 2.7, 1.5, -1.7]\n"
|
|
" - [rotate-y, 0.5]\n";
|
|
MATRIX_Matrix *scale = MATRIX_new_scaling(0.1, 1.5, 0.1);
|
|
MATRIX_Matrix *translate = MATRIX_new_translation(2.7, 1.5, -1.7);
|
|
MATRIX_Matrix *rotate = MATRIX_new_rotation_y(0.5);
|
|
MATRIX_Matrix *expected = MATRIX_multiply_many(rotate, translate, scale);
|
|
MATRIX_Matrix *result = YAMLLOADER_parse_transform(data);
|
|
TEST_ASSERT_NOT_NULL(result);
|
|
if (!MATRIX_is_equal(expected, result)) {
|
|
printf("expected:\n%s\nresult:\n%s\n", MATRIX_to_string(expected), MATRIX_to_string(result));
|
|
TEST_FAIL();
|
|
}
|
|
MATRIX_delete_all(scale, translate, rotate, expected, result);
|
|
}
|
|
|
|
void test_parse_simple_world(void) {
|
|
char data[] = "- add: light\n"
|
|
" at: [0, 6.9, -5]\n"
|
|
" intensity: [1, 1, 0.9]\n"
|
|
"- add: camera\n"
|
|
" width: 400\n"
|
|
" height: 200\n"
|
|
" field_of_view: 0.785\n"
|
|
" from: [8, 6, -8]\n"
|
|
" to: [0, 3, 0]\n"
|
|
" up: [0, 1, 0]\n\n";
|
|
|
|
CONFIGURATION_Config *config = YAMLLOADER_parse(data);
|
|
|
|
TUPLES_Point p;
|
|
TUPLES_init_point(&p, 0, 6.9, -5);
|
|
TUPLES_Color c;
|
|
TUPLES_init_color(&c, 1, 1, 0.9);
|
|
LIGHTS_Light *result_light = WORLD_get_light(config->world);
|
|
test_tuples(&p, &result_light->corner);
|
|
test_tuples(&c, &result_light->intensity);
|
|
|
|
LIGHTS_delete(result_light);
|
|
WORLD_delete(config->world);
|
|
CAMERA_delete(config->camera);
|
|
free(config);
|
|
}
|
|
|
|
void test_parse_simple_world_with_extra_newlines(void) {
|
|
char data[] = "\n\n- add: light\n"
|
|
" at: [0, 6.9, -5]\n"
|
|
" intensity: [1, 1, 0.9]\n"
|
|
"\n\n"
|
|
"- add: camera\n"
|
|
" width: 400\n"
|
|
" height: 200\n\n\n"
|
|
" field_of_view: 0.785\n"
|
|
" from: [8, 6, -8]\n"
|
|
" to: [0, 3, 0]\n"
|
|
" up: [0, 1, 0]\n\n";
|
|
|
|
CONFIGURATION_Config *config = YAMLLOADER_parse(data);
|
|
|
|
TUPLES_Point p;
|
|
TUPLES_init_point(&p, 0, 6.9, -5);
|
|
TUPLES_Color c;
|
|
TUPLES_init_color(&c, 1, 1, 0.9);
|
|
LIGHTS_Light *result_light = WORLD_get_light(config->world);
|
|
test_tuples(&p, &result_light->corner);
|
|
test_tuples(&c, &result_light->intensity);
|
|
|
|
LIGHTS_delete(result_light);
|
|
WORLD_delete(config->world);
|
|
CAMERA_delete(config->camera);
|
|
free(config);
|
|
}
|
|
|
|
void test_world_parser_should_ignore_comments(void) {
|
|
char data[] = "# ======================================================\n"
|
|
"# light sources\n"
|
|
"# ======================================================\n"
|
|
"\n"
|
|
"- add: light\n"
|
|
" at: [0, 6.9, -5]\n"
|
|
" intensity: [1, 1, 0.9]\n"
|
|
"\n"
|
|
"# ======================================================\n"
|
|
"# the camera\n"
|
|
"# ======================================================\n"
|
|
"\n"
|
|
"- add: camera\n"
|
|
" width: 400\n"
|
|
" height: 200\n"
|
|
" field_of_view: 0.785\n"
|
|
" from: [8, 6, -8]\n"
|
|
" to: [0, 3, 0]\n"
|
|
" up: [0, 1, 0]\n\n";
|
|
|
|
CONFIGURATION_Config *config = YAMLLOADER_parse(data);
|
|
|
|
TUPLES_Point p;
|
|
TUPLES_init_point(&p, 0, 6.9, -5);
|
|
TUPLES_Color c;
|
|
TUPLES_init_color(&c, 1, 1, 0.9);
|
|
LIGHTS_Light *result_light = WORLD_get_light(config->world);
|
|
test_tuples(&p, &result_light->corner);
|
|
test_tuples(&c, &result_light->intensity);
|
|
|
|
LIGHTS_delete(result_light);
|
|
WORLD_delete(config->world);
|
|
CAMERA_delete(config->camera);
|
|
free(config);
|
|
}
|
|
|
|
/*
|
|
void test_separate_yaml_array_entities(void) {
|
|
char data[] = "\n"
|
|
"- add: array1\n"
|
|
" test: value\n"
|
|
" test2: value2\n"
|
|
"\n\n"
|
|
"- add: array2\n"
|
|
" 2test: 2value\n"
|
|
" 2test2: 2value2\n"
|
|
"\n";
|
|
char **result = YAMLLOADER_parse_yaml_array(data);
|
|
char *expected1 = "- add: array1\n"
|
|
" test: value\n"
|
|
" test2: value2\n";
|
|
char *expected2 = "- add: array2\n"
|
|
" 2test: 2value\n"
|
|
" 2test2: 2value2\n";
|
|
TEST_ASSERT_NOT_NULL(result);
|
|
TEST_ASSERT_NOT_NULL(result[0]);
|
|
TEST_ASSERT_EQUAL_STRING(expected1, result[0]);
|
|
TEST_ASSERT_NOT_NULL(result[1]);
|
|
TEST_ASSERT_EQUAL_STRING(expected2, result[1]);
|
|
TEST_ASSERT_NULL(result[2]);
|
|
|
|
}
|
|
*/
|
|
|
|
void test_get_a_cube_from_yaml(void) {
|
|
char data[] = "- add: light\n"
|
|
" at: [0, 6.9, -5]\n"
|
|
" intensity: [1, 1, 0.9]\n"
|
|
"- add: camera\n"
|
|
" width: 400\n"
|
|
" height: 200\n"
|
|
" field_of_view: 0.785\n"
|
|
" from: [8, 6, -8]\n"
|
|
" to: [0, 3, 0]\n"
|
|
" up: [0, 1, 0]\n\n"
|
|
"- add: cube\n";
|
|
|
|
CONFIGURATION_Config *config = YAMLLOADER_parse(data);
|
|
TEST_ASSERT_NOT_NULL(config);
|
|
TEST_ASSERT_NOT_NULL(config->world);
|
|
TEST_ASSERT_EQUAL(1, WORLD_get_object_count(config->world));
|
|
TEST_ASSERT_NOT_NULL(WORLD_get_object(config->world, 0));
|
|
LIGHTS_delete(WORLD_get_light(config->world));
|
|
WORLD_delete_all_objects(config->world);
|
|
WORLD_delete(config->world);
|
|
CAMERA_delete(config->camera);
|
|
free(config);
|
|
}
|
|
|
|
void test_get_a_transformed_cube_from_yaml(void) {
|
|
char data[] = "- add: light\n"
|
|
" at: [0, 6.9, -5]\n"
|
|
" intensity: [1, 1, 0.9]\n"
|
|
"- add: camera\n"
|
|
" width: 400\n"
|
|
" height: 200\n"
|
|
" field_of_view: 0.785\n"
|
|
" from: [8, 6, -8]\n"
|
|
" to: [0, 3, 0]\n"
|
|
" up: [0, 1, 0]\n\n"
|
|
"- add: cube\n"
|
|
" transform:\n"
|
|
" - [translate, 0, 1, 0]\n"
|
|
" - [scale, 20, 7, 20]\n\n";
|
|
|
|
MATRIX_Matrix *translate = MATRIX_new_translation(0, 1, 0);
|
|
MATRIX_Matrix *scale = MATRIX_new_scaling(20, 7, 20);
|
|
MATRIX_Matrix *expected_transform = MATRIX_multiply(scale, translate);
|
|
|
|
CONFIGURATION_Config *config = YAMLLOADER_parse(data);
|
|
TEST_ASSERT_NOT_NULL(config);
|
|
TEST_ASSERT_NOT_NULL(config->world);
|
|
TEST_ASSERT_EQUAL(1, WORLD_get_object_count(config->world));
|
|
TEST_ASSERT_NOT_NULL(WORLD_get_object(config->world, 0));
|
|
MATRIX_Matrix *result_transform = SHAPE_get_transform(WORLD_get_object(config->world, 0));
|
|
|
|
TEST_ASSERT_TRUE(MATRIX_is_equal(expected_transform, result_transform));
|
|
LIGHTS_delete(WORLD_get_light(config->world));
|
|
WORLD_delete_all_objects(config->world);
|
|
WORLD_delete(config->world);
|
|
CAMERA_delete(config->camera);
|
|
MATRIX_delete_all(translate, scale, expected_transform);
|
|
free(config);
|
|
}
|
|
|
|
void test_get_a_sphere_from_yaml(void) {
|
|
char data[] = "- add: light\n"
|
|
" at: [0, 6.9, -5]\n"
|
|
" intensity: [1, 1, 0.9]\n"
|
|
"- add: camera\n"
|
|
" width: 400\n"
|
|
" height: 200\n"
|
|
" field_of_view: 0.785\n"
|
|
" from: [8, 6, -8]\n"
|
|
" to: [0, 3, 0]\n"
|
|
" up: [0, 1, 0]\n\n"
|
|
"- add: sphere\n";
|
|
|
|
CONFIGURATION_Config *config = YAMLLOADER_parse(data);
|
|
TEST_ASSERT_NOT_NULL(config);
|
|
TEST_ASSERT_NOT_NULL(config->world);
|
|
TEST_ASSERT_EQUAL(1, WORLD_get_object_count(config->world));
|
|
TEST_ASSERT_NOT_NULL(WORLD_get_object(config->world, 0));
|
|
LIGHTS_delete(WORLD_get_light(config->world));
|
|
WORLD_delete_all_objects(config->world);
|
|
WORLD_delete(config->world);
|
|
CAMERA_delete(config->camera);
|
|
free(config);
|
|
}
|
|
|
|
void test_get_material_with_color_from_yaml(void) {
|
|
char data[] = "\n"
|
|
"- add: cube\n"
|
|
" transform:\n"
|
|
" - [ scale, 0.05, 0.2, 0.05 ]\n"
|
|
" - [ rotate-y, 0.8 ]\n"
|
|
" - [ translate, -0.6, 3.4, -1 ]\n"
|
|
" material:\n"
|
|
" color: [0.5, 0.15, 1]\n";
|
|
|
|
Try {
|
|
CONFIGURATION_Config *config = YAMLLOADER_parse(data);
|
|
TEST_ASSERT_NOT_NULL(config);
|
|
TEST_ASSERT_NOT_NULL(config->world);
|
|
TEST_ASSERT_EQUAL(1, WORLD_get_object_count(config->world));
|
|
TEST_ASSERT_NOT_NULL(WORLD_get_object(config->world, 0));
|
|
MATERIAL_Material *mat = SHAPE_get_material(WORLD_get_object(config->world, 0));
|
|
TUPLES_Color expected;
|
|
TUPLES_init_color(&expected, 0.5, 0.15, 1);
|
|
test_tuples(&expected, &mat->color);
|
|
WORLD_delete_all_objects(config->world);
|
|
WORLD_delete(config->world);
|
|
free(config);
|
|
} Catch(exception) {
|
|
printf("Exception: %s\n", EXCEPTIONS_strings[exception]);
|
|
TEST_FAIL_MESSAGE("Caught exception");
|
|
}
|
|
}
|
|
|
|
int main(void) {
|
|
UNITY_BEGIN();
|
|
RUN_TEST(test_parse_bool);
|
|
RUN_TEST(test_parse_uint);
|
|
RUN_TEST(test_parse_point);
|
|
RUN_TEST(test_parse_vector);
|
|
RUN_TEST(test_parse_color);
|
|
RUN_TEST(test_parse_map_entries);
|
|
RUN_TEST(test_parse_double);
|
|
RUN_TEST(test_parse_single_transform_scale_entry);
|
|
RUN_TEST(test_parse_single_transform_translate_entry);
|
|
RUN_TEST(test_parse_single_transform_rotate_x_entry);
|
|
RUN_TEST(test_parse_single_transform_rotate_y_entry);
|
|
RUN_TEST(test_parse_single_transform_rotate_z_entry);
|
|
RUN_TEST(test_parse_transform_chain);
|
|
RUN_TEST(test_parse_simple_world);
|
|
RUN_TEST(test_parse_simple_world_with_extra_newlines);
|
|
RUN_TEST(test_world_parser_should_ignore_comments);
|
|
// RUN_TEST(test_separate_yaml_array_entities);
|
|
RUN_TEST(test_get_a_cube_from_yaml);
|
|
RUN_TEST(test_get_a_sphere_from_yaml);
|
|
RUN_TEST(test_get_a_transformed_cube_from_yaml);
|
|
RUN_TEST(test_get_material_with_color_from_yaml);
|
|
return UNITY_END();
|
|
}
|