16 changed files with 491 additions and 4 deletions
@ -0,0 +1,30 @@
|
||||
#include <stdlib.h> |
||||
|
||||
#include "munit.h" |
||||
#include "snekobject.h" |
||||
|
||||
munit_case(RUN, test_integer_constant, { |
||||
assert_int(INTEGER, ==, 0, "INTEGER is defined as 0"); |
||||
}); |
||||
|
||||
munit_case(RUN, test_integer_obj, { |
||||
snek_object_t *obj = malloc(sizeof(snek_object_t)); |
||||
obj->kind = INTEGER; |
||||
obj->data.v_int = 0; |
||||
assert_int(obj->kind, ==, INTEGER, "must be INTEGER type"); |
||||
assert_int(obj->data.v_int, ==, 0, "must equal zero"); |
||||
|
||||
free(obj); |
||||
}); |
||||
|
||||
int main() { |
||||
MunitTest tests[] = { |
||||
munit_test("/integer_constant", test_integer_constant), |
||||
munit_test("/integer_obj", test_integer_obj), |
||||
munit_null_test, |
||||
}; |
||||
|
||||
MunitSuite suite = munit_suite("object-integer-def", tests); |
||||
|
||||
return munit_suite_main(&suite, NULL, 0, NULL); |
||||
} |
@ -0,0 +1,13 @@
|
||||
|
||||
typedef enum SnekObjectKind { |
||||
INTEGER, |
||||
} snek_object_kind_t; |
||||
|
||||
typedef union SnekObjectData { |
||||
int v_int; |
||||
} snek_object_data_t; |
||||
|
||||
typedef struct SnekObject { |
||||
snek_object_kind_t kind; |
||||
snek_object_data_t data; |
||||
} snek_object_t; |
@ -0,0 +1,40 @@
|
||||
#include "munit.h" |
||||
#include "snekobject.h" |
||||
|
||||
munit_case(RUN, test_positive, { |
||||
snek_object_t *int_object = new_snek_integer(42); |
||||
assert_int(int_object->data.v_int, ==, 42, "must allow positive numbers"); |
||||
|
||||
free(int_object); |
||||
}); |
||||
|
||||
munit_case(RUN, test_zero, { |
||||
snek_object_t *int_object = new_snek_integer(0); |
||||
|
||||
assert_int(int_object->kind, ==, INTEGER, "must be INTEGER type"); |
||||
assert_int(int_object->data.v_int, ==, 0, "must equal zero"); |
||||
|
||||
free(int_object); |
||||
}); |
||||
|
||||
munit_case(SUBMIT, test_negative, { |
||||
snek_object_t *int_object = new_snek_integer(-5); |
||||
|
||||
assert_int(int_object->kind, ==, INTEGER, "must be INTEGER type"); |
||||
assert_int(int_object->data.v_int, ==, -5, "must allow negative numbers"); |
||||
|
||||
free(int_object); |
||||
}); |
||||
|
||||
int main() { |
||||
MunitTest tests[] = { |
||||
munit_test("/positive", test_positive), |
||||
munit_test("/zero", test_zero), |
||||
munit_test("/negative", test_negative), |
||||
munit_null_test, |
||||
}; |
||||
|
||||
MunitSuite suite = munit_suite("object-integer", tests); |
||||
|
||||
return munit_suite_main(&suite, NULL, 0, NULL); |
||||
} |
@ -0,0 +1,11 @@
|
||||
#include <stdlib.h> |
||||
|
||||
#include "snekobject.h" |
||||
|
||||
snek_object_t *new_snek_integer(int value) { |
||||
snek_object_t *number = (snek_object_t *)malloc(sizeof(snek_object_t)); |
||||
if (number == NULL) return NULL; |
||||
number->kind = INTEGER; |
||||
number->data.v_int = value; |
||||
return number; |
||||
} |
@ -0,0 +1,14 @@
|
||||
typedef enum SnekObjectKind { |
||||
INTEGER, |
||||
} snek_object_kind_t; |
||||
|
||||
typedef union SnekObjectData { |
||||
int v_int; |
||||
} snek_object_data_t; |
||||
|
||||
typedef struct SnekObject { |
||||
snek_object_kind_t kind; |
||||
snek_object_data_t data; |
||||
} snek_object_t; |
||||
|
||||
snek_object_t *new_snek_integer(int value); |
@ -0,0 +1,45 @@
|
||||
#include <stdlib.h> |
||||
|
||||
#include "munit.h" |
||||
#include "snekobject.h" |
||||
|
||||
munit_case(RUN, test_positive, { |
||||
snek_object_t *obj = new_snek_float(42); |
||||
assert_float(obj->data.v_float, ==, 42, "Must accept positive values"); |
||||
|
||||
free(obj); |
||||
// assert(boot_all_freed());
|
||||
}); |
||||
|
||||
munit_case(SUBMIT, test_zero, { |
||||
snek_object_t *obj = new_snek_float(0.0); |
||||
|
||||
assert_float(obj->kind, ==, FLOAT, "Must set type to FLOAT"); |
||||
assert_float(obj->data.v_float, ==, 0.0, "Must accept 0.0"); |
||||
|
||||
free(obj); |
||||
// assert(boot_all_freed());
|
||||
}); |
||||
|
||||
munit_case(SUBMIT, test_negative, { |
||||
snek_object_t *obj = new_snek_float(-5.0); |
||||
|
||||
assert_float(obj->kind, ==, FLOAT, "Must set type to FLOAT"); |
||||
assert_float(obj->data.v_float, ==, -5.0, "Must accept negative numbers"); |
||||
|
||||
free(obj); |
||||
// assert(boot_all_freed());
|
||||
}); |
||||
|
||||
int main() { |
||||
MunitTest tests[] = { |
||||
munit_test("/positive", test_positive), |
||||
munit_test("/zero", test_zero), |
||||
munit_test("/negative", test_negative), |
||||
munit_null_test, |
||||
}; |
||||
|
||||
MunitSuite suite = munit_suite("object-float", tests); |
||||
|
||||
return munit_suite_main(&suite, NULL, 0, NULL); |
||||
} |
@ -0,0 +1,24 @@
|
||||
#include <stdlib.h> |
||||
|
||||
#include "snekobject.h" |
||||
|
||||
snek_object_t *new_snek_float(float value) { |
||||
snek_object_t *obj = (snek_object_t *)malloc(sizeof(snek_object_t)); |
||||
if (obj == NULL) return NULL; |
||||
obj->kind = FLOAT; |
||||
obj->data.v_float = value; |
||||
return obj; |
||||
} |
||||
|
||||
// don't touch below this line
|
||||
|
||||
snek_object_t *new_snek_integer(int value) { |
||||
snek_object_t *obj = malloc(sizeof(snek_object_t)); |
||||
if (obj == NULL) { |
||||
return NULL; |
||||
} |
||||
|
||||
obj->kind = INTEGER; |
||||
obj->data.v_int = value; |
||||
return obj; |
||||
} |
@ -0,0 +1,17 @@
|
||||
typedef enum SnekObjectKind { |
||||
INTEGER, |
||||
FLOAT, |
||||
} snek_object_kind_t; |
||||
|
||||
typedef union SnekObjectData { |
||||
int v_int; |
||||
float v_float; |
||||
} snek_object_data_t; |
||||
|
||||
typedef struct SnekObject { |
||||
snek_object_kind_t kind; |
||||
snek_object_data_t data; |
||||
} snek_object_t; |
||||
|
||||
snek_object_t *new_snek_integer(int value); |
||||
snek_object_t *new_snek_float(float value); |
@ -0,0 +1,41 @@
|
||||
#include <stdlib.h> |
||||
|
||||
#include "munit.h" |
||||
#include "snekobject.h" |
||||
|
||||
munit_case(RUN, test_str_copied, { |
||||
char *input = "Hello, World!"; |
||||
snek_object_t *obj = new_snek_string(input); |
||||
|
||||
assert_int(obj->kind, ==, STRING, "Must be a string!"); |
||||
|
||||
// Should not have pointers be the same, otherwise we didn't copy the value.
|
||||
assert_ptr_not_equal( |
||||
obj->data.v_string, input, "You need to copy the string." |
||||
); |
||||
|
||||
// But should have the same data!
|
||||
// This way the object can free it's own memory later.
|
||||
assert_string_equal( |
||||
obj->data.v_string, input, "Should copy string correctly" |
||||
); |
||||
|
||||
// Should allocate memory for the string with null terminator.
|
||||
// assert_int_equal(boot_alloc_size(), 22, "Must allocate memory for string");
|
||||
|
||||
// Free the string, and then free the object.
|
||||
free(obj->data.v_string); |
||||
free(obj); |
||||
// assert(boot_all_freed());
|
||||
}); |
||||
|
||||
int main() { |
||||
MunitTest tests[] = { |
||||
munit_test("/copies_value", test_str_copied), |
||||
munit_null_test, |
||||
}; |
||||
|
||||
MunitSuite suite = munit_suite("object-string", tests); |
||||
|
||||
return munit_suite_main(&suite, NULL, 0, NULL); |
||||
} |
@ -0,0 +1,46 @@
|
||||
#include <stddef.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
|
||||
#include "snekobject.h" |
||||
|
||||
snek_object_t *new_snek_string(char *value) { |
||||
snek_object_t *obj = malloc(sizeof(snek_object_t)); |
||||
if (obj == NULL) return NULL; |
||||
|
||||
size_t size = strlen(value); |
||||
char *str = (char *)malloc(sizeof(char) * size + 1); |
||||
if (str == NULL) { |
||||
free(obj); |
||||
return NULL; |
||||
} |
||||
|
||||
strcpy(str, value); |
||||
obj->kind = STRING; |
||||
obj->data.v_string = str; |
||||
return obj; |
||||
} |
||||
|
||||
// don't touch below this line
|
||||
|
||||
snek_object_t *new_snek_integer(int value) { |
||||
snek_object_t *obj = malloc(sizeof(snek_object_t)); |
||||
if (obj == NULL) { |
||||
return NULL; |
||||
} |
||||
|
||||
obj->kind = INTEGER; |
||||
obj->data.v_int = value; |
||||
return obj; |
||||
} |
||||
|
||||
snek_object_t *new_snek_float(float value) { |
||||
snek_object_t *obj = malloc(sizeof(snek_object_t)); |
||||
if (obj == NULL) { |
||||
return NULL; |
||||
} |
||||
|
||||
obj->kind = FLOAT; |
||||
obj->data.v_float = value; |
||||
return obj; |
||||
} |
@ -0,0 +1,20 @@
|
||||
typedef enum SnekObjectKind { |
||||
INTEGER, |
||||
FLOAT, |
||||
STRING, |
||||
} snek_object_kind_t; |
||||
|
||||
typedef union SnekObjectData { |
||||
int v_int; |
||||
float v_float; |
||||
char* v_string; |
||||
} snek_object_data_t; |
||||
|
||||
typedef struct SnekObject { |
||||
snek_object_kind_t kind; |
||||
snek_object_data_t data; |
||||
} snek_object_t; |
||||
|
||||
snek_object_t *new_snek_integer(int value); |
||||
snek_object_t *new_snek_float(float value); |
||||
snek_object_t *new_snek_string(char *value); |
@ -0,0 +1,81 @@
|
||||
#include <stdlib.h> |
||||
|
||||
#include "munit.h" |
||||
#include "snekobject.h" |
||||
|
||||
munit_case(RUN, test_returns_null, { |
||||
snek_object_t *vec = new_snek_vector3(NULL, NULL, NULL); |
||||
|
||||
assert_null(vec, "Should return null when input is null"); |
||||
|
||||
// assert(boot_all_freed());
|
||||
}); |
||||
|
||||
|
||||
munit_case(RUN, test_vec_multiple_objects, { |
||||
snek_object_t *x = new_snek_integer(1); |
||||
snek_object_t *y = new_snek_integer(2); |
||||
snek_object_t *z = new_snek_integer(3); |
||||
snek_object_t *vec = new_snek_vector3(x, y, z); |
||||
|
||||
assert_ptr_not_null(vec, "should allocate a new object"); |
||||
|
||||
// Vectors should not copy objects, they get the reference to the objects.
|
||||
assert_ptr(x, ==, vec->data.v_vector3.x, "should reference x"); |
||||
assert_ptr(y, ==, vec->data.v_vector3.y, "should reference y"); |
||||
assert_ptr(z, ==, vec->data.v_vector3.z, "should reference z"); |
||||
|
||||
// Assert we have integer values correct
|
||||
assert_int(vec->data.v_vector3.x->data.v_int, ==, 1, "should have correct x"); |
||||
assert_int(vec->data.v_vector3.y->data.v_int, ==, 2, "should have correct y"); |
||||
assert_int(vec->data.v_vector3.z->data.v_int, ==, 3, "should have correct z"); |
||||
|
||||
// Free all of our objects.
|
||||
free(x); |
||||
free(y); |
||||
free(z); |
||||
free(vec); |
||||
// assert(boot_all_freed());
|
||||
}); |
||||
|
||||
munit_case(SUBMIT, test_vec_same_object, { |
||||
snek_object_t *i = new_snek_integer(1); |
||||
snek_object_t *vec = new_snek_vector3(i, i, i); |
||||
|
||||
assert_ptr_not_null(vec, "should allocate a new object"); |
||||
|
||||
// Vectors should not copy objects, they get the reference to the objects.
|
||||
assert_ptr(i, ==, vec->data.v_vector3.x, "should reference x"); |
||||
assert_ptr(i, ==, vec->data.v_vector3.y, "should reference y"); |
||||
assert_ptr(i, ==, vec->data.v_vector3.z, "should reference z"); |
||||
|
||||
// Assert we have integer values correct
|
||||
assert_int(vec->data.v_vector3.x->data.v_int, ==, 1, "should have correct x"); |
||||
assert_int(vec->data.v_vector3.y->data.v_int, ==, 1, "should have correct y"); |
||||
assert_int(vec->data.v_vector3.z->data.v_int, ==, 1, "should have correct z"); |
||||
|
||||
i->data.v_int = 2; |
||||
|
||||
// Assert we have integer values correct, after update
|
||||
assert_int(vec->data.v_vector3.x->data.v_int, ==, 2, "should have correct x"); |
||||
assert_int(vec->data.v_vector3.y->data.v_int, ==, 2, "should have correct y"); |
||||
assert_int(vec->data.v_vector3.z->data.v_int, ==, 2, "should have correct z"); |
||||
|
||||
// Free all of our objects.
|
||||
free(i); |
||||
free(vec); |
||||
// assert(boot_all_freed());
|
||||
}); |
||||
|
||||
int main() { |
||||
MunitTest tests[] = { |
||||
munit_test("/returns_null", test_returns_null), |
||||
munit_test("/multiple_objects", test_vec_multiple_objects), |
||||
munit_test("/same_object", test_vec_same_object), |
||||
munit_null_test, |
||||
}; |
||||
|
||||
MunitSuite suite = munit_suite("object-vector", tests); |
||||
|
||||
return munit_suite_main(&suite, NULL, 0, NULL); |
||||
} |
@ -0,0 +1,69 @@
|
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
|
||||
#include "snekobject.h" |
||||
|
||||
snek_object_t *new_snek_vector3(snek_object_t *x, snek_object_t *y, snek_object_t *z) |
||||
{ |
||||
if (x == NULL || y == NULL || z == NULL) return NULL; |
||||
|
||||
snek_object_t *obj = (snek_object_t *)malloc(sizeof(snek_object_t)); |
||||
if (obj == NULL) return NULL; |
||||
|
||||
snek_vector_t *vec = (snek_vector_t *)malloc(sizeof(snek_vector_t)); |
||||
if (vec == NULL) { |
||||
free(obj); |
||||
return NULL; |
||||
} |
||||
|
||||
vec->x = x; |
||||
vec->y = y; |
||||
vec->z = z; |
||||
obj->kind = VECTOR3; |
||||
obj->data.v_vector3 = *vec; |
||||
return obj; |
||||
} |
||||
|
||||
// don't touch below this line
|
||||
|
||||
snek_object_t *new_snek_integer(int value) { |
||||
snek_object_t *obj = malloc(sizeof(snek_object_t)); |
||||
if (obj == NULL) { |
||||
return NULL; |
||||
} |
||||
|
||||
obj->kind = INTEGER; |
||||
obj->data.v_int = value; |
||||
return obj; |
||||
} |
||||
|
||||
snek_object_t *new_snek_float(float value) { |
||||
snek_object_t *obj = malloc(sizeof(snek_object_t)); |
||||
if (obj == NULL) { |
||||
return NULL; |
||||
} |
||||
|
||||
obj->kind = FLOAT; |
||||
obj->data.v_float = value; |
||||
return obj; |
||||
} |
||||
|
||||
snek_object_t *new_snek_string(char *value) { |
||||
snek_object_t *obj = malloc(sizeof(snek_object_t)); |
||||
if (obj == NULL) { |
||||
return NULL; |
||||
} |
||||
|
||||
int len = strlen(value); |
||||
char *dst = malloc(len + 1); |
||||
if (dst == NULL) { |
||||
free(obj); |
||||
return NULL; |
||||
} |
||||
|
||||
strcpy(dst, value); |
||||
|
||||
obj->kind = STRING; |
||||
obj->data.v_string = dst; |
||||
return obj; |
||||
} |
@ -0,0 +1,31 @@
|
||||
typedef struct SnekObject snek_object_t; |
||||
|
||||
typedef enum SnekObjectKind { |
||||
INTEGER, |
||||
FLOAT, |
||||
STRING, |
||||
VECTOR3, |
||||
} snek_object_kind_t; |
||||
|
||||
typedef struct SnekVector { |
||||
snek_object_t *x; |
||||
snek_object_t *y; |
||||
snek_object_t *z; |
||||
} snek_vector_t; |
||||
|
||||
typedef union SnekObjectData { |
||||
int v_int; |
||||
float v_float; |
||||
char* v_string; |
||||
snek_vector_t v_vector3; |
||||
} snek_object_data_t; |
||||
|
||||
typedef struct SnekObject { |
||||
snek_object_kind_t kind; |
||||
snek_object_data_t data; |
||||
} snek_object_t; |
||||
|
||||
snek_object_t *new_snek_integer(int value); |
||||
snek_object_t *new_snek_float(float value); |
||||
snek_object_t *new_snek_string(char *value); |
||||
snek_object_t *new_snek_vector3(snek_object_t *x, snek_object_t *y, snek_object_t *z); |
Loading…
Reference in new issue