110ff414cSEd Maste /* 210ff414cSEd Maste * Copyright (c) 2014-2020 Pavel Kalvoda <me@pavelkalvoda.com> 310ff414cSEd Maste * 410ff414cSEd Maste * libcbor is free software; you can redistribute it and/or modify 510ff414cSEd Maste * it under the terms of the MIT license. See LICENSE for details. 610ff414cSEd Maste */ 710ff414cSEd Maste 810ff414cSEd Maste #include <stdio.h> 9*abd87254SEd Maste #include <string.h> 10*abd87254SEd Maste 115d3e7166SEd Maste #include "assertions.h" 1210ff414cSEd Maste #include "cbor.h" 1310ff414cSEd Maste 14*abd87254SEd Maste void assert_describe_result(cbor_item_t *item, char *expected_result) { 1510ff414cSEd Maste #if CBOR_PRETTY_PRINTER 16*abd87254SEd Maste // We know the expected size based on `expected_result`, but read everything 17*abd87254SEd Maste // in order to get the full actual output in a useful error message. 18*abd87254SEd Maste const size_t buffer_size = 512; 1910ff414cSEd Maste FILE *outfile = tmpfile(); 2010ff414cSEd Maste cbor_describe(item, outfile); 21*abd87254SEd Maste rewind(outfile); 22*abd87254SEd Maste // Treat string as null-terminated since cmocka doesn't have asserts 23*abd87254SEd Maste // for explicit length strings. 24*abd87254SEd Maste char *output = malloc(buffer_size); 25*abd87254SEd Maste assert_non_null(output); 26*abd87254SEd Maste size_t output_size = fread(output, sizeof(char), buffer_size, outfile); 27*abd87254SEd Maste output[output_size] = '\0'; 28*abd87254SEd Maste assert_string_equal(output, expected_result); 29*abd87254SEd Maste assert_true(feof(outfile)); 30*abd87254SEd Maste free(output); 3110ff414cSEd Maste fclose(outfile); 3210ff414cSEd Maste #endif 3310ff414cSEd Maste } 3410ff414cSEd Maste 35*abd87254SEd Maste static void test_uint(void **_CBOR_UNUSED(_state)) { 36*abd87254SEd Maste cbor_item_t *item = cbor_build_uint8(42); 37*abd87254SEd Maste assert_describe_result(item, "[CBOR_TYPE_UINT] Width: 1B, Value: 42\n"); 38*abd87254SEd Maste cbor_decref(&item); 39*abd87254SEd Maste } 40*abd87254SEd Maste 41*abd87254SEd Maste static void test_negint(void **_CBOR_UNUSED(_state)) { 42*abd87254SEd Maste cbor_item_t *item = cbor_build_negint16(40); 43*abd87254SEd Maste assert_describe_result(item, 44*abd87254SEd Maste "[CBOR_TYPE_NEGINT] Width: 2B, Value: -40 - 1\n"); 45*abd87254SEd Maste cbor_decref(&item); 46*abd87254SEd Maste } 47*abd87254SEd Maste 48*abd87254SEd Maste static void test_definite_bytestring(void **_CBOR_UNUSED(_state)) { 49*abd87254SEd Maste unsigned char data[] = {0x01, 0x02, 0x03}; 50*abd87254SEd Maste cbor_item_t *item = cbor_build_bytestring(data, 3); 51*abd87254SEd Maste assert_describe_result(item, 52*abd87254SEd Maste "[CBOR_TYPE_BYTESTRING] Definite, Length: 3B, Data:\n" 53*abd87254SEd Maste " 010203\n"); 54*abd87254SEd Maste cbor_decref(&item); 55*abd87254SEd Maste } 56*abd87254SEd Maste 57*abd87254SEd Maste static void test_indefinite_bytestring(void **_CBOR_UNUSED(_state)) { 58*abd87254SEd Maste unsigned char data[] = {0x01, 0x02, 0x03}; 59*abd87254SEd Maste cbor_item_t *item = cbor_new_indefinite_bytestring(); 60*abd87254SEd Maste assert_true(cbor_bytestring_add_chunk( 61*abd87254SEd Maste item, cbor_move(cbor_build_bytestring(data, 3)))); 62*abd87254SEd Maste assert_true(cbor_bytestring_add_chunk( 63*abd87254SEd Maste item, cbor_move(cbor_build_bytestring(data, 2)))); 64*abd87254SEd Maste assert_describe_result( 65*abd87254SEd Maste item, 66*abd87254SEd Maste "[CBOR_TYPE_BYTESTRING] Indefinite, Chunks: 2, Chunk data:\n" 67*abd87254SEd Maste " [CBOR_TYPE_BYTESTRING] Definite, Length: 3B, Data:\n" 68*abd87254SEd Maste " 010203\n" 69*abd87254SEd Maste " [CBOR_TYPE_BYTESTRING] Definite, Length: 2B, Data:\n" 70*abd87254SEd Maste " 0102\n"); 71*abd87254SEd Maste cbor_decref(&item); 72*abd87254SEd Maste } 73*abd87254SEd Maste 74*abd87254SEd Maste static void test_definite_string(void **_CBOR_UNUSED(_state)) { 75*abd87254SEd Maste char *string = "Hello!"; 76*abd87254SEd Maste cbor_item_t *item = cbor_build_string(string); 77*abd87254SEd Maste assert_describe_result( 78*abd87254SEd Maste item, 79*abd87254SEd Maste "[CBOR_TYPE_STRING] Definite, Length: 6B, Codepoints: 6, Data:\n" 80*abd87254SEd Maste " Hello!\n"); 81*abd87254SEd Maste cbor_decref(&item); 82*abd87254SEd Maste } 83*abd87254SEd Maste 84*abd87254SEd Maste static void test_indefinite_string(void **_CBOR_UNUSED(_state)) { 85*abd87254SEd Maste char *string = "Hello!"; 86*abd87254SEd Maste cbor_item_t *item = cbor_new_indefinite_string(); 87*abd87254SEd Maste assert_true( 88*abd87254SEd Maste cbor_string_add_chunk(item, cbor_move(cbor_build_string(string)))); 89*abd87254SEd Maste assert_true( 90*abd87254SEd Maste cbor_string_add_chunk(item, cbor_move(cbor_build_string(string)))); 91*abd87254SEd Maste assert_describe_result( 92*abd87254SEd Maste item, 93*abd87254SEd Maste "[CBOR_TYPE_STRING] Indefinite, Chunks: 2, Chunk data:\n" 94*abd87254SEd Maste " [CBOR_TYPE_STRING] Definite, Length: 6B, Codepoints: 6, Data:\n" 95*abd87254SEd Maste " Hello!\n" 96*abd87254SEd Maste " [CBOR_TYPE_STRING] Definite, Length: 6B, Codepoints: 6, Data:\n" 97*abd87254SEd Maste " Hello!\n"); 98*abd87254SEd Maste cbor_decref(&item); 99*abd87254SEd Maste } 100*abd87254SEd Maste 101*abd87254SEd Maste static void test_multibyte_string(void **_CBOR_UNUSED(_state)) { 102*abd87254SEd Maste // "Štěstíčko" in UTF-8 103*abd87254SEd Maste char *string = "\xc5\xa0t\xc4\x9bst\xc3\xad\xc4\x8dko"; 104*abd87254SEd Maste cbor_item_t *item = cbor_build_string(string); 105*abd87254SEd Maste assert_describe_result( 106*abd87254SEd Maste item, 107*abd87254SEd Maste "[CBOR_TYPE_STRING] Definite, Length: 13B, Codepoints: 9, Data:\n" 108*abd87254SEd Maste " \xc5\xa0t\xc4\x9bst\xc3\xad\xc4\x8dko\n"); 109*abd87254SEd Maste cbor_decref(&item); 110*abd87254SEd Maste } 111*abd87254SEd Maste 112*abd87254SEd Maste static void test_definite_array(void **_CBOR_UNUSED(_state)) { 113*abd87254SEd Maste cbor_item_t *item = cbor_new_definite_array(2); 114*abd87254SEd Maste assert_true(cbor_array_push(item, cbor_move(cbor_build_uint8(1)))); 115*abd87254SEd Maste assert_true(cbor_array_push(item, cbor_move(cbor_build_uint8(2)))); 116*abd87254SEd Maste assert_describe_result(item, 117*abd87254SEd Maste "[CBOR_TYPE_ARRAY] Definite, Size: 2, Contents:\n" 118*abd87254SEd Maste " [CBOR_TYPE_UINT] Width: 1B, Value: 1\n" 119*abd87254SEd Maste " [CBOR_TYPE_UINT] Width: 1B, Value: 2\n"); 120*abd87254SEd Maste cbor_decref(&item); 121*abd87254SEd Maste } 122*abd87254SEd Maste 123*abd87254SEd Maste static void test_indefinite_array(void **_CBOR_UNUSED(_state)) { 124*abd87254SEd Maste cbor_item_t *item = cbor_new_indefinite_array(); 125*abd87254SEd Maste assert_true(cbor_array_push(item, cbor_move(cbor_build_uint8(1)))); 126*abd87254SEd Maste assert_true(cbor_array_push(item, cbor_move(cbor_build_uint8(2)))); 127*abd87254SEd Maste assert_describe_result(item, 128*abd87254SEd Maste "[CBOR_TYPE_ARRAY] Indefinite, Size: 2, Contents:\n" 129*abd87254SEd Maste " [CBOR_TYPE_UINT] Width: 1B, Value: 1\n" 130*abd87254SEd Maste " [CBOR_TYPE_UINT] Width: 1B, Value: 2\n"); 131*abd87254SEd Maste cbor_decref(&item); 132*abd87254SEd Maste } 133*abd87254SEd Maste 134*abd87254SEd Maste static void test_definite_map(void **_CBOR_UNUSED(_state)) { 135*abd87254SEd Maste cbor_item_t *item = cbor_new_definite_map(1); 136*abd87254SEd Maste assert_true(cbor_map_add( 137*abd87254SEd Maste item, (struct cbor_pair){.key = cbor_move(cbor_build_uint8(1)), 138*abd87254SEd Maste .value = cbor_move(cbor_build_uint8(2))})); 139*abd87254SEd Maste assert_describe_result(item, 140*abd87254SEd Maste "[CBOR_TYPE_MAP] Definite, Size: 1, Contents:\n" 141*abd87254SEd Maste " Map entry 0\n" 142*abd87254SEd Maste " [CBOR_TYPE_UINT] Width: 1B, Value: 1\n" 143*abd87254SEd Maste " [CBOR_TYPE_UINT] Width: 1B, Value: 2\n"); 144*abd87254SEd Maste cbor_decref(&item); 145*abd87254SEd Maste } 146*abd87254SEd Maste 147*abd87254SEd Maste static void test_indefinite_map(void **_CBOR_UNUSED(_state)) { 148*abd87254SEd Maste cbor_item_t *item = cbor_new_indefinite_map(); 149*abd87254SEd Maste assert_true(cbor_map_add( 150*abd87254SEd Maste item, (struct cbor_pair){.key = cbor_move(cbor_build_uint8(1)), 151*abd87254SEd Maste .value = cbor_move(cbor_build_uint8(2))})); 152*abd87254SEd Maste assert_describe_result(item, 153*abd87254SEd Maste "[CBOR_TYPE_MAP] Indefinite, Size: 1, Contents:\n" 154*abd87254SEd Maste " Map entry 0\n" 155*abd87254SEd Maste " [CBOR_TYPE_UINT] Width: 1B, Value: 1\n" 156*abd87254SEd Maste " [CBOR_TYPE_UINT] Width: 1B, Value: 2\n"); 157*abd87254SEd Maste cbor_decref(&item); 158*abd87254SEd Maste } 159*abd87254SEd Maste 160*abd87254SEd Maste static void test_tag(void **_CBOR_UNUSED(_state)) { 161*abd87254SEd Maste cbor_item_t *item = cbor_build_tag(42, cbor_move(cbor_build_uint8(1))); 162*abd87254SEd Maste assert_describe_result(item, 163*abd87254SEd Maste "[CBOR_TYPE_TAG] Value: 42\n" 164*abd87254SEd Maste " [CBOR_TYPE_UINT] Width: 1B, Value: 1\n"); 165*abd87254SEd Maste cbor_decref(&item); 166*abd87254SEd Maste } 167*abd87254SEd Maste 168*abd87254SEd Maste static void test_floats(void **_CBOR_UNUSED(_state)) { 169*abd87254SEd Maste cbor_item_t *item = cbor_new_indefinite_array(); 170*abd87254SEd Maste assert_true(cbor_array_push(item, cbor_move(cbor_build_bool(true)))); 171*abd87254SEd Maste assert_true( 172*abd87254SEd Maste cbor_array_push(item, cbor_move(cbor_build_ctrl(CBOR_CTRL_UNDEF)))); 173*abd87254SEd Maste assert_true( 174*abd87254SEd Maste cbor_array_push(item, cbor_move(cbor_build_ctrl(CBOR_CTRL_NULL)))); 175*abd87254SEd Maste assert_true(cbor_array_push(item, cbor_move(cbor_build_ctrl(24)))); 176*abd87254SEd Maste assert_true(cbor_array_push(item, cbor_move(cbor_build_float4(3.14f)))); 177*abd87254SEd Maste assert_describe_result( 178*abd87254SEd Maste item, 179*abd87254SEd Maste "[CBOR_TYPE_ARRAY] Indefinite, Size: 5, Contents:\n" 180*abd87254SEd Maste " [CBOR_TYPE_FLOAT_CTRL] Bool: true\n" 181*abd87254SEd Maste " [CBOR_TYPE_FLOAT_CTRL] Undefined\n" 182*abd87254SEd Maste " [CBOR_TYPE_FLOAT_CTRL] Null\n" 183*abd87254SEd Maste " [CBOR_TYPE_FLOAT_CTRL] Simple value: 24\n" 184*abd87254SEd Maste " [CBOR_TYPE_FLOAT_CTRL] Width: 4B, Value: 3.140000\n"); 185*abd87254SEd Maste cbor_decref(&item); 186*abd87254SEd Maste } 187*abd87254SEd Maste 18810ff414cSEd Maste int main(void) { 189*abd87254SEd Maste const struct CMUnitTest tests[] = { 190*abd87254SEd Maste cmocka_unit_test(test_uint), 191*abd87254SEd Maste cmocka_unit_test(test_negint), 192*abd87254SEd Maste cmocka_unit_test(test_definite_bytestring), 193*abd87254SEd Maste cmocka_unit_test(test_indefinite_bytestring), 194*abd87254SEd Maste cmocka_unit_test(test_definite_string), 195*abd87254SEd Maste cmocka_unit_test(test_indefinite_string), 196*abd87254SEd Maste cmocka_unit_test(test_multibyte_string), 197*abd87254SEd Maste cmocka_unit_test(test_definite_array), 198*abd87254SEd Maste cmocka_unit_test(test_indefinite_array), 199*abd87254SEd Maste cmocka_unit_test(test_definite_map), 200*abd87254SEd Maste cmocka_unit_test(test_indefinite_map), 201*abd87254SEd Maste cmocka_unit_test(test_tag), 202*abd87254SEd Maste cmocka_unit_test(test_floats), 203*abd87254SEd Maste }; 20410ff414cSEd Maste return cmocka_run_group_tests(tests, NULL, NULL); 20510ff414cSEd Maste } 206