Skip to content

Commit 6b9a126

Browse files
committed
Add inline json encode testing
1 parent fbc3dba commit 6b9a126

File tree

8 files changed

+139
-20
lines changed

8 files changed

+139
-20
lines changed

CMakeLists.txt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,15 +283,26 @@ if(PROJECT_IS_TOP_LEVEL)
283283
APPEND_STRING
284284
PROPERTY COMPILE_FLAGS "-frandom-seed=${src}")
285285
endforeach()
286+
if(NOT "${test_dir}/main.c" IN_LIST TEST_SRCS)
287+
list(APPEND TEST_SRCS test/default_main.c)
288+
endif()
286289
add_executable(c_${test_name}_tests ${TEST_SRCS})
287290
target_link_libraries(
288-
c_${test_name}_tests PRIVATE gg-sdk++ gg-sdk gg-ipc-mock unity-config
291+
c_${test_name}_tests PRIVATE gg-sdk gg-ipc-mock unity-config
289292
unity)
290293
install(TARGETS c_${test_name}_tests)
291294
add_test(c_${test_name}_tests
292295
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/c_${test_name}_tests)
293296
endforeach()
294297
endif()
298+
299+
target_compile_definitions(gg-sdk PUBLIC GG_TESTING)
300+
target_link_libraries(gg-sdk PRIVATE unity-config unity)
301+
302+
add_executable(gg-sdk-test test/default_main.c)
303+
target_link_libraries(gg-sdk-test PRIVATE unity-config unity gg-sdk)
304+
add_test(gg-sdk-test ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/gg-sdk-test)
305+
295306
endif()
296307

297308
if(BUILD_CPP)

cpp/test/client/connect.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,6 @@ extern "C" {
1111
#include <unity.h>
1212
}
1313

14-
#define GG_TEST_ASSERT_OK(expr) TEST_ASSERT_EQUAL(GG_ERR_OK, (expr))
15-
#define GG_TEST_ASSERT_BAD(expr) TEST_ASSERT_NOT_EQUAL(GG_ERR_OK, (expr))
16-
1714
namespace {
1815
std::string_view as_view(gg::Buffer buf) noexcept {
1916
return { reinterpret_cast<char *>(buf.data()), buf.size() };

src/json_encode.c

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,3 +212,111 @@ GgReader gg_json_reader(const GgObject *obj) {
212212
assert(obj != NULL);
213213
return (GgReader) { .read = obj_read, .ctx = (void *) obj };
214214
}
215+
216+
#ifdef GG_TESTING
217+
218+
#include <gg/map.h>
219+
#include <gg/test.h>
220+
#include <unity.h>
221+
#include <stdlib.h>
222+
223+
GG_TEST_DEFINE(json_encode_null_ok) {
224+
GgObject null = GG_OBJ_NULL;
225+
GgBuffer buf = GG_BUF((uint8_t[4]) { 0 });
226+
GgByteVec vec = gg_byte_vec_init(buf);
227+
GG_TEST_ASSERT_OK(gg_json_encode(null, gg_byte_vec_writer(&vec)));
228+
TEST_ASSERT_EQUAL_UINT(4, vec.buf.len);
229+
TEST_ASSERT_EQUAL_CHAR_ARRAY("null", (char *) vec.buf.data, vec.buf.len);
230+
}
231+
232+
GG_TEST_DEFINE(json_encode_bool_ok) {
233+
{
234+
GgObject obj_false = gg_obj_bool(false);
235+
GgBuffer buf = GG_BUF((uint8_t[5]) { 0 });
236+
GgByteVec vec = gg_byte_vec_init(buf);
237+
GG_TEST_ASSERT_OK(gg_json_encode(obj_false, gg_byte_vec_writer(&vec)));
238+
GG_TEST_ASSERT_BUF_EQUAL(GG_STR("false"), vec.buf);
239+
}
240+
241+
{
242+
GgObject obj_true = gg_obj_bool(true);
243+
GgBuffer buf = GG_BUF((uint8_t[4]) { 0 });
244+
GgByteVec vec = gg_byte_vec_init(buf);
245+
GG_TEST_ASSERT_OK(gg_json_encode(obj_true, gg_byte_vec_writer(&vec)));
246+
GG_TEST_ASSERT_BUF_EQUAL(GG_STR("true"), vec.buf);
247+
}
248+
}
249+
250+
GG_TEST_DEFINE(json_encode_i64_ok) {
251+
GgObject obj = gg_obj_i64(123);
252+
GgBuffer buf = GG_BUF((uint8_t[3]) { 0 });
253+
GgByteVec vec = gg_byte_vec_init(buf);
254+
GG_TEST_ASSERT_OK(gg_json_encode(obj, gg_byte_vec_writer(&vec)));
255+
GG_TEST_ASSERT_BUF_EQUAL(GG_STR("123"), vec.buf);
256+
}
257+
258+
GG_TEST_DEFINE(json_encode_f64_ok) {
259+
GgObject obj = gg_obj_f64(123.456);
260+
GgBuffer buf = GG_BUF((uint8_t[DBL_DECIMAL_DIG + 9 + 1]) { 0 });
261+
buf.len -= 1;
262+
GgByteVec vec = gg_byte_vec_init(buf);
263+
GG_TEST_ASSERT_OK(gg_json_encode(obj, gg_byte_vec_writer(&vec)));
264+
265+
// Only feasible to test that round-tripping results in a similar value
266+
TEST_ASSERT_EQUAL_DOUBLE(123.456, strtod((char *) buf.data, NULL));
267+
}
268+
269+
GG_TEST_DEFINE(json_encode_buf_ok) {
270+
{
271+
GgObject obj = gg_obj_buf(GG_BUF((uint8_t[1]) { 0x1F }));
272+
GgBuffer buf = GG_BUF((uint8_t[8]) { 0 });
273+
GgByteVec vec = gg_byte_vec_init(buf);
274+
GG_TEST_ASSERT_OK(gg_json_encode(obj, gg_byte_vec_writer(&vec)));
275+
GG_TEST_ASSERT_BUF_EQUAL(GG_STR("\"\\u001F\""), vec.buf);
276+
}
277+
278+
{
279+
GgObject obj = gg_obj_buf(GG_STR("Hello, world!"));
280+
GgBuffer buf = GG_BUF((uint8_t[15]) { 0 });
281+
GgByteVec vec = gg_byte_vec_init(buf);
282+
GG_TEST_ASSERT_OK(gg_json_encode(obj, gg_byte_vec_writer(&vec)));
283+
GG_TEST_ASSERT_BUF_EQUAL(GG_STR("\"Hello, world!\""), vec.buf);
284+
}
285+
286+
{
287+
GgObject obj = gg_obj_buf(GG_STR("\"escape \\ me \" \0"));
288+
GgBuffer buf = GG_BUF((uint8_t[26]) { 0 });
289+
GgByteVec vec = gg_byte_vec_init(buf);
290+
GG_TEST_ASSERT_OK(gg_json_encode(obj, gg_byte_vec_writer(&vec)));
291+
GG_TEST_ASSERT_BUF_EQUAL(
292+
GG_STR("\"\\\"escape \\\\ me \\\" \\u0000\""), vec.buf
293+
);
294+
}
295+
}
296+
297+
GG_TEST_DEFINE(json_encode_map_ok) {
298+
{
299+
GgObject obj = gg_obj_map(GG_MAP(
300+
gg_kv(GG_STR("a"), gg_obj_i64(1)),
301+
gg_kv(GG_STR("b"), gg_obj_i64(2)),
302+
gg_kv(GG_STR("c"), gg_obj_i64(3))
303+
));
304+
GgBuffer buf = GG_BUF((uint8_t[20]) { 0 });
305+
GgByteVec vec = gg_byte_vec_init(buf);
306+
GG_TEST_ASSERT_OK(gg_json_encode(obj, gg_byte_vec_writer(&vec)));
307+
GG_TEST_ASSERT_BUF_EQUAL(GG_STR("{\"a\":1,\"b\":2,\"c\":3}"), vec.buf);
308+
}
309+
}
310+
311+
GG_TEST_DEFINE(json_encode_list_ok) {
312+
{
313+
GgObject obj
314+
= gg_obj_list(GG_LIST(gg_obj_i64(1), gg_obj_i64(2), gg_obj_i64(3)));
315+
GgBuffer buf = GG_BUF((uint8_t[7]) { 0 });
316+
GgByteVec vec = gg_byte_vec_init(buf);
317+
GG_TEST_ASSERT_OK(gg_json_encode(obj, gg_byte_vec_writer(&vec)));
318+
GG_TEST_ASSERT_BUF_EQUAL(GG_STR("[1,2,3]"), vec.buf);
319+
}
320+
}
321+
322+
#endif

test/client/connect.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
#include <errno.h>
32
#include <gg/arena.h>
43
#include <gg/buffer.h>
@@ -19,9 +18,6 @@
1918
#include <unity.h>
2019
#include <stdlib.h>
2120

22-
#define GG_TEST_ASSERT_OK(expr) TEST_ASSERT_EQUAL(GG_ERR_OK, (expr))
23-
#define GG_TEST_ASSERT_BAD(expr) TEST_ASSERT_NOT_EQUAL(GG_ERR_OK, (expr))
24-
2521
GG_TEST_DEFINE(connect_okay) {
2622
GgipcPacketSequence seq
2723
= gg_test_connect_accepted_sequence(gg_test_get_auth_token());

test/client/mqtt.c

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
2-
#include "bits/time.h"
3-
#include "unity_internals.h"
41
#include <errno.h>
52
#include <gg/arena.h>
63
#include <gg/base64.h>
@@ -26,9 +23,6 @@
2623

2724
#define GG_MODULE "test_mqtt"
2825

29-
#define GG_TEST_ASSERT_OK(expr) TEST_ASSERT_EQUAL(GG_ERR_OK, (expr))
30-
#define GG_TEST_ASSERT_BAD(expr) TEST_ASSERT_NOT_EQUAL(GG_ERR_OK, (expr))
31-
3226
static uint8_t too_large_payload[0x20000];
3327

3428
typedef struct {
@@ -239,13 +233,9 @@ static void subscribe_to_iot_core_okay_subscription_response(
239233
) {
240234
SubscribeOkayContext *context = ctx;
241235
TEST_ASSERT_EQUAL_PTR(&subscribe_okay_context, context);
242-
TEST_ASSERT_EQUAL_size_t(GG_STR("my/topic").len, topic.len);
243-
TEST_ASSERT_EQUAL_CHAR_ARRAY("my/topic", topic.data, topic.len);
236+
GG_TEST_ASSERT_BUF_EQUAL(GG_STR("my/topic"), topic);
244237

245-
TEST_ASSERT_EQUAL_size_t(payloads[0].payload.len, payload.len);
246-
TEST_ASSERT_EQUAL_CHAR_ARRAY(
247-
payloads[0].payload.data, payload.data, payload.len
248-
);
238+
GG_TEST_ASSERT_BUF_EQUAL(payloads[0].payload, payload);
249239

250240
TEST_ASSERT_EQUAL_UINT32(context->handle.val, handle.val);
251241

File renamed without changes.

unity_config/include/gg/test.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define GG_TEST_UNITY_HELPERS_H
33

44
#include <sys/types.h>
5+
#include <unity.h>
56
#include <stddef.h>
67

78
typedef void (*GgTestFunction)(void);
@@ -37,6 +38,19 @@ void gg_test_register(GgTestListNode *entry);
3738
for (GgTestListNode * (name) = gg_test_list_head; (name) != NULL; \
3839
(name) = (name)->next)
3940

41+
#define GG_TEST_ASSERT_OK(expr) TEST_ASSERT_EQUAL(GG_ERR_OK, (expr))
42+
#define GG_TEST_ASSERT_BAD(expr) TEST_ASSERT_NOT_EQUAL(GG_ERR_OK, (expr))
43+
44+
#define GG_TEST_ASSERT_BUF_EQUAL(expected, actual) \
45+
do { \
46+
TEST_ASSERT_EQUAL_size_t_MESSAGE( \
47+
(expected).len, (actual).len, "Size mismatch" \
48+
); \
49+
TEST_ASSERT_EQUAL_CHAR_ARRAY( \
50+
(char *) (expected).data, (char *) (actual).data, (expected).len \
51+
); \
52+
} while (0)
53+
4054
int gg_test_run_suite(void);
4155

4256
#endif

unity_config/include/unity/unity_config.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,7 @@
66
#define UNITY_TEST_PROTECT() gg_test_protect()
77
#define UNITY_TEST_ABORT() gg_test_abort()
88

9+
#define UNITY_INCLUDE_DOUBLE
10+
#define UNITY_INCLUDE_FLOAT
11+
912
#endif

0 commit comments

Comments
 (0)