/* * Copyright (c) 2015-2016 Nicholas Fraser * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "test-expect.h" #if MPACK_EXPECT static const char test_example[] = "\x82\xA7""compact\xC3\xA6""schema\x00"; #define TEST_EXAMPLE_SIZE (sizeof(test_example) - 1) static void test_expect_example_read() { mpack_reader_t reader; mpack_reader_init_data(&reader, test_example, TEST_EXAMPLE_SIZE); // tests the example on the messagepack homepage using fixed // ordering for keys (mpack_expect_key_cstr_basic() tests re-ordering) TEST_TRUE(2 == mpack_expect_map(&reader)); mpack_expect_cstr_match(&reader, "compact"); TEST_TRUE(true == mpack_expect_bool(&reader)); mpack_expect_cstr_match(&reader, "schema"); TEST_TRUE(0 == mpack_expect_u8(&reader)); mpack_done_map(&reader); TEST_READER_DESTROY_NOERROR(&reader); } /* [ 1,-32,128,-129,65536,-65537,2147483649,-2147483648,9223372036854775807,-9223372036854775808, ] */ static void test_expect_uint_fixnum() { // positive fixnums with u8 TEST_SIMPLE_READ("\x00", 0 == mpack_expect_u8(&reader)); TEST_SIMPLE_READ("\x01", 1 == mpack_expect_u8(&reader)); TEST_SIMPLE_READ("\x02", 2 == mpack_expect_u8(&reader)); TEST_SIMPLE_READ("\x0f", 0x0f == mpack_expect_u8(&reader)); TEST_SIMPLE_READ("\x10", 0x10 == mpack_expect_u8(&reader)); TEST_SIMPLE_READ("\x7f", 0x7f == mpack_expect_u8(&reader)); // positive fixnums with u16 TEST_SIMPLE_READ("\x00", 0 == mpack_expect_u16(&reader)); TEST_SIMPLE_READ("\x01", 1 == mpack_expect_u16(&reader)); TEST_SIMPLE_READ("\x02", 2 == mpack_expect_u16(&reader)); TEST_SIMPLE_READ("\x0f", 0x0f == mpack_expect_u16(&reader)); TEST_SIMPLE_READ("\x10", 0x10 == mpack_expect_u16(&reader)); TEST_SIMPLE_READ("\x7f", 0x7f == mpack_expect_u16(&reader)); // positive fixnums with u32 TEST_SIMPLE_READ("\x00", 0 == mpack_expect_u32(&reader)); TEST_SIMPLE_READ("\x01", 1 == mpack_expect_u32(&reader)); TEST_SIMPLE_READ("\x02", 2 == mpack_expect_u32(&reader)); TEST_SIMPLE_READ("\x0f", 0x0f == mpack_expect_u32(&reader)); TEST_SIMPLE_READ("\x10", 0x10 == mpack_expect_u32(&reader)); TEST_SIMPLE_READ("\x7f", 0x7f == mpack_expect_u32(&reader)); // positive fixnums with u64 TEST_SIMPLE_READ("\x00", 0 == mpack_expect_u64(&reader)); TEST_SIMPLE_READ("\x01", 1 == mpack_expect_u64(&reader)); TEST_SIMPLE_READ("\x02", 2 == mpack_expect_u64(&reader)); TEST_SIMPLE_READ("\x0f", 0x0f == mpack_expect_u64(&reader)); TEST_SIMPLE_READ("\x10", 0x10 == mpack_expect_u64(&reader)); TEST_SIMPLE_READ("\x7f", 0x7f == mpack_expect_u64(&reader)); } static void test_expect_uint_signed_fixnum() { // positive fixnums with i8 TEST_SIMPLE_READ("\x00", 0 == mpack_expect_i8(&reader)); TEST_SIMPLE_READ("\x01", 1 == mpack_expect_i8(&reader)); TEST_SIMPLE_READ("\x02", 2 == mpack_expect_i8(&reader)); TEST_SIMPLE_READ("\x0f", 0x0f == mpack_expect_i8(&reader)); TEST_SIMPLE_READ("\x10", 0x10 == mpack_expect_i8(&reader)); TEST_SIMPLE_READ("\x7f", 0x7f == mpack_expect_i8(&reader)); // positive fixnums with i16 TEST_SIMPLE_READ("\x00", 0 == mpack_expect_i16(&reader)); TEST_SIMPLE_READ("\x01", 1 == mpack_expect_i16(&reader)); TEST_SIMPLE_READ("\x02", 2 == mpack_expect_i16(&reader)); TEST_SIMPLE_READ("\x0f", 0x0f == mpack_expect_i16(&reader)); TEST_SIMPLE_READ("\x10", 0x10 == mpack_expect_i16(&reader)); TEST_SIMPLE_READ("\x7f", 0x7f == mpack_expect_i16(&reader)); // positive fixnums with i32 TEST_SIMPLE_READ("\x00", 0 == mpack_expect_i32(&reader)); TEST_SIMPLE_READ("\x01", 1 == mpack_expect_i32(&reader)); TEST_SIMPLE_READ("\x02", 2 == mpack_expect_i32(&reader)); TEST_SIMPLE_READ("\x0f", 0x0f == mpack_expect_i32(&reader)); TEST_SIMPLE_READ("\x10", 0x10 == mpack_expect_i32(&reader)); TEST_SIMPLE_READ("\x7f", 0x7f == mpack_expect_i32(&reader)); // positive fixnums with i64 TEST_SIMPLE_READ("\x00", 0 == mpack_expect_i64(&reader)); TEST_SIMPLE_READ("\x01", 1 == mpack_expect_i64(&reader)); TEST_SIMPLE_READ("\x02", 2 == mpack_expect_i64(&reader)); TEST_SIMPLE_READ("\x0f", 0x0f == mpack_expect_i64(&reader)); TEST_SIMPLE_READ("\x10", 0x10 == mpack_expect_i64(&reader)); TEST_SIMPLE_READ("\x7f", 0x7f == mpack_expect_i64(&reader)); } static void test_expect_negative_fixnum() { // negative fixnums with i8 TEST_SIMPLE_READ("\xff", -1 == mpack_expect_i8(&reader)); TEST_SIMPLE_READ("\xfe", -2 == mpack_expect_i8(&reader)); TEST_SIMPLE_READ("\xf0", -16 == mpack_expect_i8(&reader)); TEST_SIMPLE_READ("\xe0", -32 == mpack_expect_i8(&reader)); // negative fixnums with i16 TEST_SIMPLE_READ("\xff", -1 == mpack_expect_i16(&reader)); TEST_SIMPLE_READ("\xfe", -2 == mpack_expect_i16(&reader)); TEST_SIMPLE_READ("\xf0", -16 == mpack_expect_i16(&reader)); TEST_SIMPLE_READ("\xe0", -32 == mpack_expect_i16(&reader)); // negative fixnums with i32 TEST_SIMPLE_READ("\xff", -1 == mpack_expect_i32(&reader)); TEST_SIMPLE_READ("\xfe", -2 == mpack_expect_i32(&reader)); TEST_SIMPLE_READ("\xf0", -16 == mpack_expect_i32(&reader)); TEST_SIMPLE_READ("\xe0", -32 == mpack_expect_i32(&reader)); // negative fixnums with i64 TEST_SIMPLE_READ("\xff", -1 == mpack_expect_i64(&reader)); TEST_SIMPLE_READ("\xfe", -2 == mpack_expect_i64(&reader)); TEST_SIMPLE_READ("\xf0", -16 == mpack_expect_i64(&reader)); TEST_SIMPLE_READ("\xe0", -32 == mpack_expect_i64(&reader)); } static void test_expect_uint() { // positive signed into u8 TEST_SIMPLE_READ("\xd0\x7f", 0x7f == mpack_expect_u8(&reader)); TEST_SIMPLE_READ("\xd0\x7f", 0x7f == mpack_expect_u16(&reader)); TEST_SIMPLE_READ("\xd0\x7f", 0x7f == mpack_expect_u32(&reader)); TEST_SIMPLE_READ("\xd0\x7f", 0x7f == mpack_expect_u64(&reader)); TEST_SIMPLE_READ("\xd0\x7f", 0x7f == mpack_expect_uint(&reader)); TEST_SIMPLE_READ("\xd1\x7f\xff", 0x7fff == mpack_expect_u16(&reader)); TEST_SIMPLE_READ("\xd1\x7f\xff", 0x7fff == mpack_expect_u32(&reader)); TEST_SIMPLE_READ("\xd1\x7f\xff", 0x7fff == mpack_expect_u64(&reader)); TEST_SIMPLE_READ("\xd1\x7f\xff", 0x7fff == mpack_expect_uint(&reader)); TEST_SIMPLE_READ("\xd2\x7f\xff\xff\xff", 0x7fffffff == mpack_expect_u32(&reader)); TEST_SIMPLE_READ("\xd2\x7f\xff\xff\xff", 0x7fffffff == mpack_expect_u64(&reader)); TEST_SIMPLE_READ("\xd2\x7f\xff\xff\xff", 0x7fffffff == mpack_expect_uint(&reader)); TEST_SIMPLE_READ("\xd3\x7f\xff\xff\xff\xff\xff\xff\xff", 0x7fffffffffffffff == mpack_expect_u64(&reader)); // positive unsigned into u8 TEST_SIMPLE_READ("\xcc\x80", 0x80 == mpack_expect_u8(&reader)); TEST_SIMPLE_READ("\xcc\x80", 0x80 == mpack_expect_u16(&reader)); TEST_SIMPLE_READ("\xcc\x80", 0x80 == mpack_expect_u32(&reader)); TEST_SIMPLE_READ("\xcc\x80", 0x80 == mpack_expect_u64(&reader)); TEST_SIMPLE_READ("\xcc\x80", 0x80 == mpack_expect_uint(&reader)); TEST_SIMPLE_READ("\xcc\xff", 0xff == mpack_expect_u8(&reader)); TEST_SIMPLE_READ("\xcc\xff", 0xff == mpack_expect_u16(&reader)); TEST_SIMPLE_READ("\xcc\xff", 0xff == mpack_expect_u32(&reader)); TEST_SIMPLE_READ("\xcc\xff", 0xff == mpack_expect_u64(&reader)); TEST_SIMPLE_READ("\xcc\xff", 0xff == mpack_expect_uint(&reader)); TEST_SIMPLE_READ("\xcd\x01\x00", 0x100 == mpack_expect_u16(&reader)); TEST_SIMPLE_READ("\xcd\x01\x00", 0x100 == mpack_expect_u32(&reader)); TEST_SIMPLE_READ("\xcd\x01\x00", 0x100 == mpack_expect_u64(&reader)); TEST_SIMPLE_READ("\xcd\x01\x00", 0x100 == mpack_expect_uint(&reader)); TEST_SIMPLE_READ("\xcd\xff\xff", 0xffff == mpack_expect_u16(&reader)); TEST_SIMPLE_READ("\xcd\xff\xff", 0xffff == mpack_expect_u32(&reader)); TEST_SIMPLE_READ("\xcd\xff\xff", 0xffff == mpack_expect_u64(&reader)); TEST_SIMPLE_READ("\xcd\xff\xff", 0xffff == mpack_expect_uint(&reader)); TEST_SIMPLE_READ("\xce\x00\x01\x00\x00", 0x10000 == mpack_expect_u32(&reader)); TEST_SIMPLE_READ("\xce\x00\x01\x00\x00", 0x10000 == mpack_expect_u64(&reader)); TEST_SIMPLE_READ("\xce\x00\x01\x00\x00", 0x10000 == mpack_expect_uint(&reader)); TEST_SIMPLE_READ("\xce\xff\xff\xff\xff", 0xffffffff == mpack_expect_u32(&reader)); TEST_SIMPLE_READ("\xce\xff\xff\xff\xff", 0xffffffff == mpack_expect_u64(&reader)); TEST_SIMPLE_READ("\xce\xff\xff\xff\xff", 0xffffffff == mpack_expect_uint(&reader)); TEST_SIMPLE_READ("\xcf\x00\x00\x00\x01\x00\x00\x00\x00", 0x100000000 == mpack_expect_u64(&reader)); TEST_SIMPLE_READ("\xcf\xff\xff\xff\xff\xff\xff\xff\xff", 0xffffffffffffffff == mpack_expect_u64(&reader)); } static void test_expect_uint_signed() { TEST_SIMPLE_READ("\xcc\x80", 0x80 == mpack_expect_i16(&reader)); TEST_SIMPLE_READ("\xcc\x80", 0x80 == mpack_expect_i32(&reader)); TEST_SIMPLE_READ("\xcc\x80", 0x80 == mpack_expect_i64(&reader)); TEST_SIMPLE_READ("\xcc\x80", 0x80 == mpack_expect_int(&reader)); TEST_SIMPLE_READ("\xcc\xff", 0xff == mpack_expect_i16(&reader)); TEST_SIMPLE_READ("\xcc\xff", 0xff == mpack_expect_i32(&reader)); TEST_SIMPLE_READ("\xcc\xff", 0xff == mpack_expect_i64(&reader)); TEST_SIMPLE_READ("\xcc\xff", 0xff == mpack_expect_int(&reader)); TEST_SIMPLE_READ("\xcd\x01\x00", 0x100 == mpack_expect_i16(&reader)); TEST_SIMPLE_READ("\xcd\x01\x00", 0x100 == mpack_expect_i32(&reader)); TEST_SIMPLE_READ("\xcd\x01\x00", 0x100 == mpack_expect_i64(&reader)); TEST_SIMPLE_READ("\xcd\x01\x00", 0x100 == mpack_expect_int(&reader)); TEST_SIMPLE_READ("\xcd\xff\xff", 0xffff == mpack_expect_i32(&reader)); TEST_SIMPLE_READ("\xcd\xff\xff", 0xffff == mpack_expect_i64(&reader)); TEST_SIMPLE_READ("\xcd\xff\xff", 0xffff == mpack_expect_int(&reader)); TEST_SIMPLE_READ("\xce\x00\x01\x00\x00", 0x10000 == mpack_expect_i32(&reader)); TEST_SIMPLE_READ("\xce\x00\x01\x00\x00", 0x10000 == mpack_expect_i64(&reader)); TEST_SIMPLE_READ("\xce\x00\x01\x00\x00", 0x10000 == mpack_expect_int(&reader)); TEST_SIMPLE_READ("\xce\xff\xff\xff\xff", 0xffffffff == mpack_expect_i64(&reader)); TEST_SIMPLE_READ("\xcf\x00\x00\x00\x01\x00\x00\x00\x00", 0x100000000 == mpack_expect_i64(&reader)); } static void test_expect_int() { TEST_SIMPLE_READ("\xd0\xdf", -33 == mpack_expect_i8(&reader)); TEST_SIMPLE_READ("\xd0\xdf", -33 == mpack_expect_i16(&reader)); TEST_SIMPLE_READ("\xd0\xdf", -33 == mpack_expect_i32(&reader)); TEST_SIMPLE_READ("\xd0\xdf", -33 == mpack_expect_i64(&reader)); TEST_SIMPLE_READ("\xd0\xdf", -33 == mpack_expect_int(&reader)); TEST_SIMPLE_READ("\xd0\x80", INT8_MIN == mpack_expect_i8(&reader)); TEST_SIMPLE_READ("\xd0\x80", INT8_MIN == mpack_expect_i16(&reader)); TEST_SIMPLE_READ("\xd0\x80", INT8_MIN == mpack_expect_i32(&reader)); TEST_SIMPLE_READ("\xd0\x80", INT8_MIN == mpack_expect_i64(&reader)); TEST_SIMPLE_READ("\xd0\x80", INT8_MIN == mpack_expect_int(&reader)); TEST_SIMPLE_READ("\xd1\xff\x7f", INT8_MIN - 1 == mpack_expect_i16(&reader)); TEST_SIMPLE_READ("\xd1\xff\x7f", INT8_MIN - 1 == mpack_expect_i32(&reader)); TEST_SIMPLE_READ("\xd1\xff\x7f", INT8_MIN - 1 == mpack_expect_i64(&reader)); TEST_SIMPLE_READ("\xd1\xff\x7f", INT8_MIN - 1 == mpack_expect_int(&reader)); TEST_SIMPLE_READ("\xd1\x80\x00", INT16_MIN == mpack_expect_i16(&reader)); TEST_SIMPLE_READ("\xd1\x80\x00", INT16_MIN == mpack_expect_i32(&reader)); TEST_SIMPLE_READ("\xd1\x80\x00", INT16_MIN == mpack_expect_i64(&reader)); TEST_SIMPLE_READ("\xd1\x80\x00", INT16_MIN == mpack_expect_int(&reader)); TEST_SIMPLE_READ("\xd2\xff\xff\x7f\xff", INT16_MIN - 1 == mpack_expect_i32(&reader)); TEST_SIMPLE_READ("\xd2\xff\xff\x7f\xff", INT16_MIN - 1 == mpack_expect_i64(&reader)); TEST_SIMPLE_READ("\xd2\xff\xff\x7f\xff", INT16_MIN - 1 == mpack_expect_int(&reader)); TEST_SIMPLE_READ("\xd2\x80\x00\x00\x00", INT32_MIN == mpack_expect_i32(&reader)); TEST_SIMPLE_READ("\xd2\x80\x00\x00\x00", INT32_MIN == mpack_expect_i64(&reader)); TEST_SIMPLE_READ("\xd2\x80\x00\x00\x00", INT32_MIN == mpack_expect_int(&reader)); TEST_SIMPLE_READ("\xd3\xff\xff\xff\xff\x7f\xff\xff\xff", (int64_t)INT32_MIN - 1 == mpack_expect_i64(&reader)); TEST_SIMPLE_READ("\xd3\x80\x00\x00\x00\x00\x00\x00\x00", INT64_MIN == mpack_expect_i64(&reader)); } static void test_expect_ints_dynamic_int() { // we don't bother to test with different signed/unsigned value // functions; they are tested for equality in test-value.c // positive fixnums TEST_SIMPLE_READ("\x00", mpack_tag_equal(mpack_tag_uint(0), mpack_read_tag(&reader))); TEST_SIMPLE_READ("\x01", mpack_tag_equal(mpack_tag_uint(1), mpack_read_tag(&reader))); TEST_SIMPLE_READ("\x02", mpack_tag_equal(mpack_tag_uint(2), mpack_read_tag(&reader))); TEST_SIMPLE_READ("\x0f", mpack_tag_equal(mpack_tag_uint(0x0f), mpack_read_tag(&reader))); TEST_SIMPLE_READ("\x10", mpack_tag_equal(mpack_tag_uint(0x10), mpack_read_tag(&reader))); TEST_SIMPLE_READ("\x7f", mpack_tag_equal(mpack_tag_uint(0x7f), mpack_read_tag(&reader))); // negative fixnums TEST_SIMPLE_READ("\xff", mpack_tag_equal(mpack_tag_int(-1), mpack_read_tag(&reader))); TEST_SIMPLE_READ("\xfe", mpack_tag_equal(mpack_tag_int(-2), mpack_read_tag(&reader))); TEST_SIMPLE_READ("\xf0", mpack_tag_equal(mpack_tag_int(-16), mpack_read_tag(&reader))); TEST_SIMPLE_READ("\xe0", mpack_tag_equal(mpack_tag_int(-32), mpack_read_tag(&reader))); // uints TEST_SIMPLE_READ("\xcc\x80", mpack_tag_equal(mpack_tag_uint(0x80), mpack_read_tag(&reader))); TEST_SIMPLE_READ("\xcc\xff", mpack_tag_equal(mpack_tag_uint(0xff), mpack_read_tag(&reader))); TEST_SIMPLE_READ("\xcd\x01\x00", mpack_tag_equal(mpack_tag_uint(0x100), mpack_read_tag(&reader))); TEST_SIMPLE_READ("\xcd\xff\xff", mpack_tag_equal(mpack_tag_uint(0xffff), mpack_read_tag(&reader))); TEST_SIMPLE_READ("\xce\x00\x01\x00\x00", mpack_tag_equal(mpack_tag_uint(0x10000), mpack_read_tag(&reader))); TEST_SIMPLE_READ("\xce\xff\xff\xff\xff", mpack_tag_equal(mpack_tag_uint(0xffffffff), mpack_read_tag(&reader))); TEST_SIMPLE_READ("\xcf\x00\x00\x00\x01\x00\x00\x00\x00", mpack_tag_equal(mpack_tag_uint(UINT64_C(0x100000000)), mpack_read_tag(&reader))); TEST_SIMPLE_READ("\xcf\xff\xff\xff\xff\xff\xff\xff\xff", mpack_tag_equal(mpack_tag_uint(UINT64_C(0xffffffffffffffff)), mpack_read_tag(&reader))); // ints TEST_SIMPLE_READ("\xd0\xdf", mpack_tag_equal(mpack_tag_int(-33), mpack_read_tag(&reader))); TEST_SIMPLE_READ("\xd0\x80", mpack_tag_equal(mpack_tag_int(INT8_MIN), mpack_read_tag(&reader))); TEST_SIMPLE_READ("\xd1\xff\x7f", mpack_tag_equal(mpack_tag_int(INT8_MIN - 1), mpack_read_tag(&reader))); TEST_SIMPLE_READ("\xd1\x80\x00", mpack_tag_equal(mpack_tag_int(INT16_MIN), mpack_read_tag(&reader))); TEST_SIMPLE_READ("\xd2\xff\xff\x7f\xff", mpack_tag_equal(mpack_tag_int(INT16_MIN - 1), mpack_read_tag(&reader))); TEST_SIMPLE_READ("\xd2\x80\x00\x00\x00", mpack_tag_equal(mpack_tag_int(INT32_MIN), mpack_read_tag(&reader))); TEST_SIMPLE_READ("\xd3\xff\xff\xff\xff\x7f\xff\xff\xff", mpack_tag_equal(mpack_tag_int((int64_t)INT32_MIN - 1), mpack_read_tag(&reader))); TEST_SIMPLE_READ("\xd3\x80\x00\x00\x00\x00\x00\x00\x00", mpack_tag_equal(mpack_tag_int(INT64_MIN), mpack_read_tag(&reader))); } static void test_expect_int_bounds() { TEST_SIMPLE_READ_ERROR("\xd1\xff\x7f", 0 == mpack_expect_i8(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xd1\x80\x00", 0 == mpack_expect_i8(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xd2\xff\xff\x7f\xff", 0 == mpack_expect_i8(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xd2\xff\xff\x7f\xff", 0 == mpack_expect_i16(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xd2\x80\x00\x00\x00", 0 == mpack_expect_i8(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xd2\x80\x00\x00\x00", 0 == mpack_expect_i16(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xd3\xff\xff\xff\xff\x7f\xff\xff\xff", 0 == mpack_expect_i8(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xd3\xff\xff\xff\xff\x7f\xff\xff\xff", 0 == mpack_expect_i16(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xd3\xff\xff\xff\xff\x7f\xff\xff\xff", 0 == mpack_expect_i32(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xd3\x80\x00\x00\x00\x00\x00\x00\x00", 0 == mpack_expect_i8(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xd3\x80\x00\x00\x00\x00\x00\x00\x00", 0 == mpack_expect_i16(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xd3\x80\x00\x00\x00\x00\x00\x00\x00", 0 == mpack_expect_i32(&reader), mpack_error_type); } static void test_expect_uint_bounds() { TEST_SIMPLE_READ_ERROR("\xcd\x01\x00", 0 == mpack_expect_u8(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xcd\xff\xff", 0 == mpack_expect_u8(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xce\x00\x01\x00\x00", 0 == mpack_expect_u8(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xce\x00\x01\x00\x00", 0 == mpack_expect_u16(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xce\xff\xff\xff\xff", 0 == mpack_expect_u8(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xce\xff\xff\xff\xff", 0 == mpack_expect_u16(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xcf\x00\x00\x00\x01\x00\x00\x00\x00", 0 == mpack_expect_u8(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xcf\x00\x00\x00\x01\x00\x00\x00\x00", 0 == mpack_expect_u16(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xcf\x00\x00\x00\x01\x00\x00\x00\x00", 0 == mpack_expect_u32(&reader), mpack_error_type); } #define TEST_EXPECT_UINT_RANGE(name) \ TEST_SIMPLE_READ("\x00", 0 == mpack_expect_##name##_max(&reader, 0)); \ TEST_SIMPLE_READ_ERROR("\x01", 0 == mpack_expect_##name##_max(&reader, 0), mpack_error_type); \ \ TEST_SIMPLE_READ_ERROR("\x00", 1 == mpack_expect_##name##_range(&reader, 1, 3), mpack_error_type); \ TEST_SIMPLE_READ("\x01", 1 == mpack_expect_##name##_range(&reader, 1, 3)); \ TEST_SIMPLE_READ("\x02", 2 == mpack_expect_##name##_range(&reader, 1, 3)); \ TEST_SIMPLE_READ("\x03", 3 == mpack_expect_##name##_range(&reader, 1, 3)); \ TEST_SIMPLE_READ_ERROR("\x04", 1 == mpack_expect_##name##_range(&reader, 1, 3), mpack_error_type); \ \ TEST_SIMPLE_READ_ASSERT("\x00", mpack_expect_##name##_range(reader, 1, 0)); #define TEST_EXPECT_INT_RANGE(name) \ TEST_SIMPLE_READ("\x00", 0 == mpack_expect_##name##_max(&reader, 0)); \ TEST_SIMPLE_READ_ERROR("\x01", 0 == mpack_expect_##name##_max(&reader, 0), mpack_error_type); \ TEST_SIMPLE_READ_ERROR("\xff", 0 == mpack_expect_##name##_max(&reader, 0), mpack_error_type); \ \ TEST_SIMPLE_READ_ERROR("\xfe", -1 == mpack_expect_##name##_range(&reader, -1, 1), mpack_error_type); \ TEST_SIMPLE_READ("\xff", -1 == mpack_expect_##name##_range(&reader, -1, 1)); \ TEST_SIMPLE_READ("\x00", 0 == mpack_expect_##name##_range(&reader, -1, 1)); \ TEST_SIMPLE_READ("\x01", 1 == mpack_expect_##name##_range(&reader, -1, 1)); \ TEST_SIMPLE_READ_ERROR("\x02", -1 == mpack_expect_##name##_range(&reader, -1, 1), mpack_error_type); \ \ TEST_SIMPLE_READ_ASSERT("\x00", mpack_expect_##name##_range(reader, 1, -1)); static void test_expect_int_range() { // these currently don't test anything involving the limits of // each data type; there doesn't seem to be much point in doing // so, since they all wrap the normal expect functions. TEST_EXPECT_UINT_RANGE(u8); TEST_EXPECT_UINT_RANGE(u16); TEST_EXPECT_UINT_RANGE(u32); TEST_EXPECT_UINT_RANGE(u64); TEST_EXPECT_UINT_RANGE(uint); TEST_EXPECT_INT_RANGE(i8); TEST_EXPECT_INT_RANGE(i16); TEST_EXPECT_INT_RANGE(i32); TEST_EXPECT_INT_RANGE(i64); TEST_EXPECT_INT_RANGE(int); } static void test_expect_int_match() { TEST_SIMPLE_READ("\x00", (mpack_expect_uint_match(&reader, 0), true)); TEST_SIMPLE_READ("\x01", (mpack_expect_uint_match(&reader, 1), true)); TEST_SIMPLE_READ("\xcc\x80", (mpack_expect_uint_match(&reader, 0x80), true)); TEST_SIMPLE_READ("\xcc\xff", (mpack_expect_uint_match(&reader, 0xff), true)); TEST_SIMPLE_READ("\xcd\x01\x00", (mpack_expect_uint_match(&reader, 0x100), true)); TEST_SIMPLE_READ("\xcd\xff\xff", (mpack_expect_uint_match(&reader, 0xffff), true)); TEST_SIMPLE_READ("\xce\x00\x01\x00\x00", (mpack_expect_uint_match(&reader, 0x10000), true)); TEST_SIMPLE_READ("\xce\xff\xff\xff\xff", (mpack_expect_uint_match(&reader, 0xffffffff), true)); TEST_SIMPLE_READ("\xce\xff\xff\xff\xff", (mpack_expect_uint_match(&reader, 0xffffffff), true)); TEST_SIMPLE_READ("\xcf\x00\x00\x00\x01\x00\x00\x00\x00", (mpack_expect_uint_match(&reader, 0x100000000), true)); TEST_SIMPLE_READ("\xcf\xff\xff\xff\xff\xff\xff\xff\xff", (mpack_expect_uint_match(&reader, 0xffffffffffffffff), true)); TEST_SIMPLE_READ_ERROR("\xff", (mpack_expect_uint_match(&reader, 0), true), mpack_error_type); TEST_SIMPLE_READ("\x00", (mpack_expect_int_match(&reader, 0), true)); TEST_SIMPLE_READ("\x01", (mpack_expect_int_match(&reader, 1), true)); TEST_SIMPLE_READ("\xd0\xdf", (mpack_expect_int_match(&reader, -33), true)); TEST_SIMPLE_READ("\xd0\x80", (mpack_expect_int_match(&reader, INT8_MIN), true)); TEST_SIMPLE_READ("\xd1\xff\x7f", (mpack_expect_int_match(&reader, INT8_MIN - 1), true)); TEST_SIMPLE_READ("\xd1\x80\x00", (mpack_expect_int_match(&reader, INT16_MIN), true)); TEST_SIMPLE_READ("\xd2\xff\xff\x7f\xff", (mpack_expect_int_match(&reader, INT16_MIN - 1), true)); TEST_SIMPLE_READ("\xd2\x80\x00\x00\x00", (mpack_expect_int_match(&reader, INT32_MIN), true)); TEST_SIMPLE_READ("\xd3\xff\xff\xff\xff\x7f\xff\xff\xff", (mpack_expect_int_match(&reader, (int64_t)INT32_MIN - 1), true)); TEST_SIMPLE_READ("\xd3\x80\x00\x00\x00\x00\x00\x00\x00", (mpack_expect_int_match(&reader, INT64_MIN), true)); TEST_SIMPLE_READ_ERROR("\xc0", (mpack_expect_int_match(&reader, 0), true), mpack_error_type); } static void test_expect_misc() { TEST_SIMPLE_READ("\xc0", (mpack_expect_nil(&reader), true)); TEST_SIMPLE_READ("\xc0", (mpack_expect_tag(&reader, mpack_tag_nil()), true)); TEST_SIMPLE_READ_ERROR("\x90", (mpack_expect_tag(&reader, mpack_tag_nil()), true), mpack_error_type); TEST_SIMPLE_READ("\xc2", false == mpack_expect_bool(&reader)); TEST_SIMPLE_READ("\xc3", true == mpack_expect_bool(&reader)); TEST_SIMPLE_READ("\xc2", (mpack_expect_false(&reader), true)); TEST_SIMPLE_READ("\xc3", (mpack_expect_true(&reader), true)); TEST_SIMPLE_READ_ERROR("\xc0", (mpack_expect_false(&reader), true), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xc0", (mpack_expect_true(&reader), true), mpack_error_type); } #if MPACK_READ_TRACKING static void test_expect_tracking() { char buf[4]; mpack_reader_t reader; // tracking depth growth TEST_READER_INIT_STR(&reader, "\x91\x91\x91\x91\x91\x91\x90"); TEST_TRUE(1 == mpack_expect_array(&reader)); TEST_TRUE(1 == mpack_expect_array(&reader)); TEST_TRUE(1 == mpack_expect_array(&reader)); TEST_TRUE(1 == mpack_expect_array(&reader)); TEST_TRUE(1 == mpack_expect_array(&reader)); TEST_TRUE(1 == mpack_expect_array(&reader)); TEST_TRUE(0 == mpack_expect_array(&reader)); mpack_done_array(&reader); mpack_done_array(&reader); mpack_done_array(&reader); mpack_done_array(&reader); mpack_done_array(&reader); mpack_done_array(&reader); mpack_done_array(&reader); TEST_READER_DESTROY_NOERROR(&reader); // cancel TEST_READER_INIT_STR(&reader, "\x90"); mpack_expect_array(&reader); mpack_reader_flag_error(&reader, mpack_error_data); TEST_READER_DESTROY_ERROR(&reader, mpack_error_data); // done type when nothing was open TEST_READER_INIT_STR(&reader, "\x90"); TEST_BREAK((mpack_done_map(&reader), true)); TEST_READER_DESTROY_ERROR(&reader, mpack_error_bug); // closing incomplete type TEST_READER_INIT_STR(&reader, "\x91\xc0"); mpack_expect_array(&reader); TEST_BREAK((mpack_done_array(&reader), true)); TEST_READER_DESTROY_ERROR(&reader, mpack_error_bug); // reading elements in a string TEST_READER_INIT_STR(&reader, "\xa2""xx"); mpack_expect_str(&reader); TEST_BREAK((mpack_read_tag(&reader), true)); TEST_READER_DESTROY_ERROR(&reader, mpack_error_bug); // reading too many elements TEST_READER_INIT_STR(&reader, "\x90"); mpack_expect_array(&reader); TEST_BREAK((mpack_read_tag(&reader), true)); TEST_READER_DESTROY_ERROR(&reader, mpack_error_bug); // reading bytes with nothing open TEST_READER_INIT_STR(&reader, "\x90"); TEST_BREAK((mpack_read_bytes(&reader, buf, sizeof(buf)), true)); TEST_READER_DESTROY_ERROR(&reader, mpack_error_bug); // reading bytes in an array TEST_READER_INIT_STR(&reader, "\x90"); mpack_expect_array(&reader); TEST_BREAK((mpack_read_bytes(&reader, buf, sizeof(buf)), true)); TEST_READER_DESTROY_ERROR(&reader, mpack_error_bug); // reading too many bytes TEST_READER_INIT_STR(&reader, "\xa2""xx"); mpack_expect_str(&reader); TEST_BREAK((mpack_read_bytes(&reader, buf, sizeof(buf)), true)); TEST_READER_DESTROY_ERROR(&reader, mpack_error_bug); // checking remaining bytes with unclosed type TEST_READER_INIT_STR(&reader, "\xa2""xx"); mpack_expect_str(&reader); TEST_BREAK((mpack_reader_remaining(&reader, NULL), true)); TEST_READER_DESTROY_ERROR(&reader, mpack_error_bug); } #endif static void test_expect_reals() { // these are some very simple floats that don't really test IEEE 742 conformance; // this section could use some improvement TEST_SIMPLE_READ("\x00", 0.0f == mpack_expect_float(&reader)); TEST_SIMPLE_READ("\xd0\x00", 0.0f == mpack_expect_float(&reader)); TEST_SIMPLE_READ("\xca\x00\x00\x00\x00", 0.0f == mpack_expect_float(&reader)); TEST_SIMPLE_READ("\xcb\x00\x00\x00\x00\x00\x00\x00\x00", 0.0f == mpack_expect_float(&reader)); TEST_SIMPLE_READ("\x00", 0.0 == mpack_expect_double(&reader)); TEST_SIMPLE_READ("\xd0\x00", 0.0 == mpack_expect_double(&reader)); TEST_SIMPLE_READ("\xca\x00\x00\x00\x00", 0.0 == mpack_expect_double(&reader)); TEST_SIMPLE_READ("\xcb\x00\x00\x00\x00\x00\x00\x00\x00", 0.0 == mpack_expect_double(&reader)); TEST_SIMPLE_READ("\xca\x00\x00\x00\x00", 0.0f == mpack_expect_float_strict(&reader)); TEST_SIMPLE_READ("\xca\x00\x00\x00\x00", 0.0 == mpack_expect_double_strict(&reader)); TEST_SIMPLE_READ("\xcb\x00\x00\x00\x00\x00\x00\x00\x00", 0.0 == mpack_expect_double_strict(&reader)); // when -ffinite-math-only is enabled, isnan() can always return false. // TODO: we should probably add at least a reader option to // generate an error on non-finite reals. #if !MPACK_FINITE_MATH TEST_SIMPLE_READ("\xca\xff\xff\xff\xff", isnanf(mpack_expect_float(&reader)) != 0); TEST_SIMPLE_READ("\xcb\xff\xff\xff\xff\xff\xff\xff\xff", isnanf(mpack_expect_float(&reader)) != 0); TEST_SIMPLE_READ("\xca\xff\xff\xff\xff", isnan(mpack_expect_double(&reader)) != 0); TEST_SIMPLE_READ("\xcb\xff\xff\xff\xff\xff\xff\xff\xff", isnan(mpack_expect_double(&reader)) != 0); TEST_SIMPLE_READ("\xca\xff\xff\xff\xff", 0 != isnanf(mpack_expect_float_strict(&reader))); TEST_SIMPLE_READ("\xca\xff\xff\xff\xff", 0 != isnan(mpack_expect_double_strict(&reader))); TEST_SIMPLE_READ("\xcb\xff\xff\xff\xff\xff\xff\xff\xff", isnan(mpack_expect_double_strict(&reader))); #endif TEST_SIMPLE_READ_ERROR("\x00", 0.0f == mpack_expect_float_strict(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xd0\x00", 0.0f == mpack_expect_float_strict(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xcb\x00\x00\x00\x00\x00\x00\x00\x00", 0.0f == mpack_expect_float_strict(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\x00", 0.0 == mpack_expect_double_strict(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xd0\x00", 0.0 == mpack_expect_double_strict(&reader), mpack_error_type); } static void test_expect_reals_range() { TEST_SIMPLE_READ("\x00", 0.0f == mpack_expect_float_range(&reader, 0.0f, 0.0f)); TEST_SIMPLE_READ("\x00", 0.0f == mpack_expect_float_range(&reader, 0.0f, 1.0f)); TEST_SIMPLE_READ("\x00", 0.0f == mpack_expect_float_range(&reader, -1.0f, 0.0f)); TEST_SIMPLE_READ_ERROR("\x00", 1.0f == mpack_expect_float_range(&reader, 1.0f, 2.0f), mpack_error_type); TEST_SIMPLE_READ_ASSERT("\x00", mpack_expect_float_range(reader, 1.0f, -1.0f)); TEST_SIMPLE_READ("\x00", 0.0 == mpack_expect_double_range(&reader, 0.0, 0.0f)); TEST_SIMPLE_READ("\x00", 0.0 == mpack_expect_double_range(&reader, 0.0, 1.0f)); TEST_SIMPLE_READ("\x00", 0.0 == mpack_expect_double_range(&reader, -1.0, 0.0f)); TEST_SIMPLE_READ_ERROR("\x00", 1.0 == mpack_expect_double_range(&reader, 1.0, 2.0f), mpack_error_type); TEST_SIMPLE_READ_ASSERT("\x00", mpack_expect_double_range(reader, 1.0, -1.0)); } static void test_expect_bad_type() { // test that all reader functions correctly handle badly typed data TEST_SIMPLE_READ_ERROR("\xc2", (mpack_expect_nil(&reader), true), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xc0", false == mpack_expect_bool(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xc0", 0 == mpack_expect_u8(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xc0", 0 == mpack_expect_u16(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xc0", 0 == mpack_expect_u32(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xc0", 0 == mpack_expect_u64(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xc0", 0 == mpack_expect_i8(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xc0", 0 == mpack_expect_i16(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xc0", 0 == mpack_expect_i32(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xc0", 0 == mpack_expect_i64(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xc0", 0.0f == mpack_expect_float(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xc0", 0.0 == mpack_expect_double(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xc0", 0.0f == mpack_expect_float_strict(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xc0", 0.0 == mpack_expect_double_strict(&reader), mpack_error_type); } static void test_expect_pre_error() { // test that all reader functinvalidns correctly handle pre-existing errors TEST_SIMPLE_READ_ERROR("", (mpack_expect_nil(&reader), true), mpack_error_invalid); TEST_SIMPLE_READ_ERROR("", false == mpack_expect_bool(&reader), mpack_error_invalid); TEST_SIMPLE_READ_ERROR("", 0 == mpack_expect_u8(&reader), mpack_error_invalid); TEST_SIMPLE_READ_ERROR("", 0 == mpack_expect_u16(&reader), mpack_error_invalid); TEST_SIMPLE_READ_ERROR("", 0 == mpack_expect_u32(&reader), mpack_error_invalid); TEST_SIMPLE_READ_ERROR("", 0 == mpack_expect_u64(&reader), mpack_error_invalid); TEST_SIMPLE_READ_ERROR("", 0 == mpack_expect_i8(&reader), mpack_error_invalid); TEST_SIMPLE_READ_ERROR("", 0 == mpack_expect_i16(&reader), mpack_error_invalid); TEST_SIMPLE_READ_ERROR("", 0 == mpack_expect_i32(&reader), mpack_error_invalid); TEST_SIMPLE_READ_ERROR("", 0 == mpack_expect_i64(&reader), mpack_error_invalid); TEST_SIMPLE_READ_ERROR("", 0.0f == mpack_expect_float(&reader), mpack_error_invalid); TEST_SIMPLE_READ_ERROR("", 0.0 == mpack_expect_double(&reader), mpack_error_invalid); TEST_SIMPLE_READ_ERROR("", 0.0f == mpack_expect_float_strict(&reader), mpack_error_invalid); TEST_SIMPLE_READ_ERROR("", 0.0 == mpack_expect_double_strict(&reader), mpack_error_invalid); } static void test_expect_str() { char buf[256]; #ifdef MPACK_MALLOC char* test = NULL; #endif // str TEST_SIMPLE_READ("\xa0", 0 == mpack_expect_str(&reader) && (mpack_done_str(&reader), true)); TEST_SIMPLE_READ_CANCEL("\xbf", 31 == mpack_expect_str(&reader)); TEST_SIMPLE_READ_CANCEL("\xd9\x80", 128 == mpack_expect_str(&reader)); // TODO: test str8 compatibility TEST_SIMPLE_READ_CANCEL("\xda\x80\x80", 0x8080 == mpack_expect_str(&reader)); TEST_SIMPLE_READ_CANCEL("\xdb\xff\xff\xff\xff", 0xffffffff == mpack_expect_str(&reader)); TEST_SIMPLE_READ("\xa0", 0 == mpack_expect_str_buf(&reader, buf, 0)); TEST_SIMPLE_READ("\xa0", 0 == mpack_expect_str_buf(&reader, buf, 4)); TEST_SIMPLE_READ("\xa4test", 4 == mpack_expect_str_buf(&reader, buf, 4)); TEST_SIMPLE_READ_ERROR("\xa5hello", 0 == mpack_expect_str_buf(&reader, buf, 4), mpack_error_too_big); TEST_SIMPLE_READ_ERROR("\xa8test", 0 == mpack_expect_str_buf(&reader, buf, sizeof(buf)), mpack_error_invalid); TEST_SIMPLE_READ("\xa1\x00", 1 == mpack_expect_str_buf(&reader, buf, 4)); TEST_SIMPLE_READ("\xa0", (mpack_expect_str_length(&reader, 0), mpack_done_str(&reader), true)); TEST_SIMPLE_READ_ERROR("\xa0", (mpack_expect_str_length(&reader, 4), true), mpack_error_type); TEST_SIMPLE_READ_CANCEL("\xa4", (mpack_expect_str_length(&reader, 4), true)); TEST_SIMPLE_READ_ERROR("\xa5", (mpack_expect_str_length(&reader, 4), true), mpack_error_type); // cstr TEST_SIMPLE_READ_ASSERT("\xa0", mpack_expect_cstr(reader, buf, 0)); TEST_SIMPLE_READ("\xa0", (mpack_expect_cstr(&reader, buf, 4), true)); TEST_TRUE(strlen(buf) == 0); TEST_SIMPLE_READ("\xa4test", (mpack_expect_cstr(&reader, buf, 5), true)); TEST_TRUE(strlen(buf) == 4); TEST_SIMPLE_READ_ERROR("\xa5hello", (mpack_expect_cstr(&reader, buf, 5), true), mpack_error_too_big); TEST_TRUE(strlen(buf) == 0); TEST_SIMPLE_READ("\xa5hello", (mpack_expect_cstr(&reader, buf, sizeof(buf)), true)); TEST_TRUE(strlen(buf) == 5); TEST_SIMPLE_READ_ERROR("\xa5he\x0lo", (mpack_expect_cstr(&reader, buf, sizeof(buf)), true), mpack_error_type); #ifdef MPACK_MALLOC // cstr alloc TEST_SIMPLE_READ_BREAK("\xa0", NULL == mpack_expect_cstr_alloc(&reader, 0)); TEST_SIMPLE_READ("\xa0", NULL != (test = mpack_expect_cstr_alloc(&reader, 4))); if (test) { TEST_TRUE(strlen(test) == 0); MPACK_FREE(test); } TEST_SIMPLE_READ_ERROR("\xa4test", NULL == mpack_expect_cstr_alloc(&reader, 4), mpack_error_too_big); TEST_SIMPLE_READ("\xa4test", NULL != (test = mpack_expect_cstr_alloc(&reader, 5))); if (test) { TEST_TRUE(strlen(test) == 4); TEST_TRUE(memcmp(test, "test", 4) == 0); MPACK_FREE(test); } TEST_SIMPLE_READ("\xa4test", NULL != (test = mpack_expect_cstr_alloc(&reader, SIZE_MAX))); if (test) { TEST_TRUE(strlen(test) == 4); TEST_TRUE(memcmp(test, "test", 4) == 0); MPACK_FREE(test); } TEST_SIMPLE_READ_ERROR("\xa5he\00lo", NULL == mpack_expect_cstr_alloc(&reader, 256), mpack_error_type); TEST_SIMPLE_READ_ERROR("\x01", NULL == mpack_expect_cstr_alloc(&reader, 3), mpack_error_type); #endif // cstr match TEST_SIMPLE_READ("\xa0", (mpack_expect_cstr_match(&reader, ""), true)); TEST_SIMPLE_READ("\xa3""abc", (mpack_expect_cstr_match(&reader, "abc"), true)); TEST_SIMPLE_READ_ERROR("\xa0", (mpack_expect_cstr_match(&reader, "abc"), true), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xa3""abc", (mpack_expect_cstr_match(&reader, ""), true), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xa3""zbc", (mpack_expect_cstr_match(&reader, "abc"), true), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xa3""azc", (mpack_expect_cstr_match(&reader, "abc"), true), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xa3""abz", (mpack_expect_cstr_match(&reader, "abc"), true), mpack_error_type); // bin is never allowed to be read as str TEST_SIMPLE_READ_ERROR("\xc4\x10", 0 == mpack_expect_str(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xc4\x10", (mpack_expect_str_buf(&reader, buf, sizeof(buf)), true), mpack_error_type); TEST_TRUE(strlen(buf) == 0); TEST_SIMPLE_READ_ERROR("\xc4\x10", (mpack_expect_cstr(&reader, buf, sizeof(buf)), true), mpack_error_type); TEST_TRUE(strlen(buf) == 0); // utf-8 // the first byte of each of these is the MessagePack object header const char utf8_null[] = "\xa1\x00"; const char utf8_valid[] = "\xac \xCF\x80 \xe4\xb8\xad \xf0\xa0\x80\xb6"; const char utf8_trimmed[] = "\xa4\xf0\xa0\x80\xb6"; const char utf8_invalid[] = "\xa3 \x80 "; const char utf8_invalid_trimmed[] = "\xa1\xa0"; const char utf8_truncated[] = "\xa2\xf0\xa0"; // we don't accept any of these UTF-8 variants; only pure UTF-8 is allowed. const char utf8_modified[] = "\xa4 \xc0\x80 "; const char utf8_cesu8[] = "\xa8 \xED\xA0\x81\xED\xB0\x80 "; const char utf8_wobbly[] = "\xa5 \xED\xA0\x81 "; // utf8 str TEST_SIMPLE_READ("\xa0", 0 == mpack_expect_utf8(&reader, buf, 0)); TEST_SIMPLE_READ("\xa0", 0 == mpack_expect_utf8(&reader, buf, 4)); TEST_SIMPLE_READ("\xa4test", 4 == mpack_expect_utf8(&reader, buf, 4)); TEST_SIMPLE_READ_ERROR("\xa5hello", 0 == mpack_expect_utf8(&reader, buf, 4), mpack_error_too_big); TEST_SIMPLE_READ(utf8_null, (mpack_expect_utf8(&reader, buf, sizeof(buf)), true)); TEST_SIMPLE_READ(utf8_valid, (mpack_expect_utf8(&reader, buf, sizeof(buf)), true)); TEST_SIMPLE_READ(utf8_trimmed, (mpack_expect_utf8(&reader, buf, sizeof(buf)), true)); TEST_SIMPLE_READ_ERROR(utf8_invalid, (mpack_expect_utf8(&reader, buf, sizeof(buf)), true), mpack_error_type); TEST_SIMPLE_READ_ERROR(utf8_invalid_trimmed, (mpack_expect_utf8(&reader, buf, sizeof(buf)), true), mpack_error_type); TEST_SIMPLE_READ_ERROR(utf8_truncated, (mpack_expect_utf8(&reader, buf, sizeof(buf)), true), mpack_error_type); TEST_SIMPLE_READ_ERROR(utf8_modified, (mpack_expect_utf8(&reader, buf, sizeof(buf)), true), mpack_error_type); TEST_SIMPLE_READ_ERROR(utf8_cesu8, (mpack_expect_utf8(&reader, buf, sizeof(buf)), true), mpack_error_type); TEST_SIMPLE_READ_ERROR(utf8_wobbly, (mpack_expect_utf8(&reader, buf, sizeof(buf)), true), mpack_error_type); // utf8 cstr TEST_SIMPLE_READ_ASSERT("\xa0", mpack_expect_utf8_cstr(reader, buf, 0)); TEST_SIMPLE_READ("\xa0", (mpack_expect_utf8_cstr(&reader, buf, 4), true)); TEST_TRUE(strlen(buf) == 0); TEST_SIMPLE_READ("\xa4test", (mpack_expect_utf8_cstr(&reader, buf, 5), true)); TEST_TRUE(strlen(buf) == 4); TEST_SIMPLE_READ_ERROR("\xa5hello", (mpack_expect_utf8_cstr(&reader, buf, 5), true), mpack_error_too_big); TEST_TRUE(strlen(buf) == 0); TEST_SIMPLE_READ_ERROR(utf8_null, (mpack_expect_utf8_cstr(&reader, buf, sizeof(buf)), true), mpack_error_type); TEST_SIMPLE_READ(utf8_valid, (mpack_expect_utf8_cstr(&reader, buf, sizeof(buf)), true)); TEST_SIMPLE_READ(utf8_trimmed, (mpack_expect_utf8_cstr(&reader, buf, sizeof(buf)), true)); TEST_SIMPLE_READ_ERROR(utf8_invalid, (mpack_expect_utf8_cstr(&reader, buf, sizeof(buf)), true), mpack_error_type); TEST_SIMPLE_READ_ERROR(utf8_invalid_trimmed, (mpack_expect_utf8_cstr(&reader, buf, sizeof(buf)), true), mpack_error_type); TEST_SIMPLE_READ_ERROR(utf8_truncated, (mpack_expect_utf8_cstr(&reader, buf, sizeof(buf)), true), mpack_error_type); TEST_SIMPLE_READ_ERROR(utf8_modified, (mpack_expect_utf8_cstr(&reader, buf, sizeof(buf)), true), mpack_error_type); TEST_SIMPLE_READ_ERROR(utf8_cesu8, (mpack_expect_utf8_cstr(&reader, buf, sizeof(buf)), true), mpack_error_type); TEST_SIMPLE_READ_ERROR(utf8_wobbly, (mpack_expect_utf8_cstr(&reader, buf, sizeof(buf)), true), mpack_error_type); #ifdef MPACK_MALLOC // utf8 cstr alloc TEST_SIMPLE_READ_BREAK("\xa0", NULL == mpack_expect_utf8_cstr_alloc(&reader, 0)); TEST_SIMPLE_READ("\xa0", NULL != (test = mpack_expect_utf8_cstr_alloc(&reader, 4))); if (test) { TEST_TRUE(strlen(test) == 0); MPACK_FREE(test); } TEST_SIMPLE_READ_ERROR("\xa4test", NULL == mpack_expect_utf8_cstr_alloc(&reader, 4), mpack_error_too_big); TEST_SIMPLE_READ("\xa4test", NULL != (test = mpack_expect_utf8_cstr_alloc(&reader, 5))); if (test) { TEST_TRUE(strlen(test) == 4); TEST_TRUE(memcmp(test, "test", 4) == 0); MPACK_FREE(test); } TEST_SIMPLE_READ("\xa4test", NULL != (test = mpack_expect_utf8_cstr_alloc(&reader, SIZE_MAX))); if (test) { TEST_TRUE(strlen(test) == 4); TEST_TRUE(memcmp(test, "test", 4) == 0); MPACK_FREE(test); } TEST_SIMPLE_READ_ERROR("\x01", NULL == mpack_expect_utf8_cstr_alloc(&reader, 3), mpack_error_type); TEST_SIMPLE_READ_ERROR(utf8_null, ((test = mpack_expect_utf8_cstr_alloc(&reader, 256)), true), mpack_error_type); TEST_SIMPLE_READ(utf8_valid, ((test = mpack_expect_utf8_cstr_alloc(&reader, 256)), true)); MPACK_FREE(test); TEST_SIMPLE_READ(utf8_trimmed, ((test = mpack_expect_utf8_cstr_alloc(&reader, 256)), true)); MPACK_FREE(test); TEST_SIMPLE_READ_ERROR(utf8_invalid, ((test = mpack_expect_utf8_cstr_alloc(&reader, 256)), true), mpack_error_type); TEST_SIMPLE_READ_ERROR(utf8_invalid_trimmed, ((test = mpack_expect_utf8_cstr_alloc(&reader, 256)), true), mpack_error_type); TEST_SIMPLE_READ_ERROR(utf8_truncated, ((test = mpack_expect_utf8_cstr_alloc(&reader, 256)), true), mpack_error_type); TEST_SIMPLE_READ_ERROR(utf8_modified, ((test = mpack_expect_utf8_cstr_alloc(&reader, 256)), true), mpack_error_type); TEST_SIMPLE_READ_ERROR(utf8_cesu8, ((test = mpack_expect_utf8_cstr_alloc(&reader, 256)), true), mpack_error_type); TEST_SIMPLE_READ_ERROR(utf8_wobbly, ((test = mpack_expect_utf8_cstr_alloc(&reader, 256)), true), mpack_error_type); #endif } static void test_expect_bin() { char buf[256]; TEST_SIMPLE_READ_CANCEL("\xc4\x80", 128 == mpack_expect_bin(&reader)); TEST_SIMPLE_READ_CANCEL("\xc5\x80\x80", 0x8080 == mpack_expect_bin(&reader)); TEST_SIMPLE_READ_CANCEL("\xc6\xff\xff\xff\xff", 0xffffffff == mpack_expect_bin(&reader)); // TODO: test strict/compatibility modes. currently, we do not // support old MessagePack version compatibility; bin will not // accept str types. TEST_SIMPLE_READ_ERROR("\xbf", 0 == mpack_expect_bin(&reader), mpack_error_type); TEST_SIMPLE_READ_ERROR("\xbf", 0 == mpack_expect_bin_buf(&reader, buf, sizeof(buf)), mpack_error_type); TEST_SIMPLE_READ("\xc4\x00", 0 == mpack_expect_bin_buf(&reader, buf, 0)); TEST_SIMPLE_READ("\xc4\x00", 0 == mpack_expect_bin_buf(&reader, buf, 4)); TEST_SIMPLE_READ("\xc4\x04test", 4 == mpack_expect_bin_buf(&reader, buf, 4)); TEST_SIMPLE_READ_ERROR("\xc4\x05hello", 0 == mpack_expect_bin_buf(&reader, buf, 4), mpack_error_too_big); TEST_SIMPLE_READ_ERROR("\xc4\x08hello", 0 == mpack_expect_bin_buf(&reader, buf, sizeof(buf)), mpack_error_invalid); TEST_SIMPLE_READ("\xc4\x01\x00", 1 == mpack_expect_bin_buf(&reader, buf, 4)); TEST_SIMPLE_READ("\xc4\x00", (mpack_expect_bin_size(&reader, 0), mpack_done_bin(&reader), true)); TEST_SIMPLE_READ_ERROR("\xc4\x00", (mpack_expect_bin_size(&reader, 4), true), mpack_error_type); TEST_SIMPLE_READ_CANCEL("\xc4\x04", (mpack_expect_bin_size(&reader, 4), true)); TEST_SIMPLE_READ_ERROR("\xc4\x05", (mpack_expect_bin_size(&reader, 4), true), mpack_error_type); #ifdef MPACK_MALLOC size_t length; char* test = NULL; TEST_SIMPLE_READ("\xc4\x00", (NULL == mpack_expect_bin_alloc(&reader, 0, &length))); TEST_TRUE(length == 0); TEST_SIMPLE_READ("\xc4\x00", (NULL == mpack_expect_bin_alloc(&reader, 4, &length))); TEST_TRUE(length == 0); TEST_SIMPLE_READ("\xc4\x04test", NULL != (test = mpack_expect_bin_alloc(&reader, 4, &length))); if (test) { TEST_TRUE(length == 4); TEST_TRUE(memcmp(test, "test", 4) == 0); MPACK_FREE(test); } TEST_SIMPLE_READ_ERROR("\xc4\x04test", NULL == mpack_expect_bin_alloc(&reader, 3, &length), mpack_error_type); TEST_SIMPLE_READ_ERROR("\x01", NULL == mpack_expect_bin_alloc(&reader, 3, &length), mpack_error_type); #endif } static void test_expect_ext() { } static void test_expect_arrays() { uint32_t count; // arrays TEST_SIMPLE_READ_CANCEL("\x90", 0 == mpack_expect_array(&reader)); TEST_SIMPLE_READ_CANCEL("\x91", 1 == mpack_expect_array(&reader)); TEST_SIMPLE_READ_CANCEL("\x9f", 15 == mpack_expect_array(&reader)); TEST_SIMPLE_READ_CANCEL("\xdc\x00\x00", 0 == mpack_expect_array(&reader)); TEST_SIMPLE_READ_CANCEL("\xdc\x01\x00", 0x100 == mpack_expect_array(&reader)); TEST_SIMPLE_READ_CANCEL("\xdc\xff\xff", 0xffff == mpack_expect_array(&reader)); TEST_SIMPLE_READ_CANCEL("\xdd\x00\x00\x00\x00", 0 == mpack_expect_array(&reader)); TEST_SIMPLE_READ_CANCEL("\xdd\x00\x00\x01\x00", 0x100 == mpack_expect_array(&reader)); TEST_SIMPLE_READ_CANCEL("\xdd\x00\x01\x00\x00", 0x10000 == mpack_expect_array(&reader)); TEST_SIMPLE_READ_CANCEL("\xdd\xff\xff\xff\xff", UINT32_MAX == mpack_expect_array(&reader)); TEST_SIMPLE_READ_ERROR("\x00", 0 == mpack_expect_array(&reader), mpack_error_type); // array ranges TEST_SIMPLE_READ_CANCEL("\x91", 1 == mpack_expect_array_range(&reader, 0, 1)); TEST_SIMPLE_READ_CANCEL("\x91", 1 == mpack_expect_array_range(&reader, 1, 1)); TEST_SIMPLE_READ_ERROR("\x91", 2 == mpack_expect_array_range(&reader, 2, 2), mpack_error_type); TEST_SIMPLE_READ_ASSERT("\x91", mpack_expect_array_range(reader, 2, 1)); TEST_SIMPLE_READ_CANCEL("\x91", 1 == mpack_expect_array_max(&reader, 1)); TEST_SIMPLE_READ_ERROR("\x91", 0 == mpack_expect_array_max(&reader, 0), mpack_error_type); TEST_SIMPLE_READ("\x90", (mpack_expect_array_match(&reader, 0), mpack_done_array(&reader), true)); TEST_SIMPLE_READ_CANCEL("\x9f", (mpack_expect_array_match(&reader, 15), true)); TEST_SIMPLE_READ_CANCEL("\xdc\xff\xff", (mpack_expect_array_match(&reader, 0xffff), true)); TEST_SIMPLE_READ_CANCEL("\xdd\xff\xff\xff\xff", (mpack_expect_array_match(&reader, UINT32_MAX), true)); TEST_SIMPLE_READ_ERROR("\x91", (mpack_expect_array_match(&reader, 2), true), mpack_error_type); TEST_SIMPLE_READ_CANCEL("\x91", true == mpack_expect_array_or_nil(&reader, &count)); TEST_TRUE(count == 1); TEST_SIMPLE_READ_CANCEL("\xc0", false == mpack_expect_array_or_nil(&reader, &count)); TEST_TRUE(count == 0); TEST_SIMPLE_READ_ERROR("\x81", false == mpack_expect_array_or_nil(&reader, &count), mpack_error_type); TEST_TRUE(count == 0); TEST_SIMPLE_READ_CANCEL("\x91", true == mpack_expect_array_max_or_nil(&reader, 1, &count)); TEST_TRUE(count == 1); TEST_SIMPLE_READ_CANCEL("\xc0", false == mpack_expect_array_max_or_nil(&reader, 0, &count)); TEST_TRUE(count == 0); TEST_SIMPLE_READ_ERROR("\x92", false == mpack_expect_array_max_or_nil(&reader, 1, &count), mpack_error_type); TEST_TRUE(count == 0); TEST_SIMPLE_READ_ERROR("\x81", false == mpack_expect_array_max_or_nil(&reader, 1, &count), mpack_error_type); TEST_TRUE(count == 0); // array allocs #ifdef MPACK_MALLOC int* elements; TEST_SIMPLE_READ("\x90", (elements = mpack_expect_array_alloc(&reader, int, 1, &count), mpack_done_array(&reader), true)); TEST_TRUE(elements == NULL); TEST_SIMPLE_READ_CANCEL("\x91", NULL != (elements = mpack_expect_array_alloc(&reader, int, 1, &count))); if (elements) { elements[0] = 0; MPACK_FREE(elements); } TEST_SIMPLE_READ_CANCEL("\x92", NULL != (elements = mpack_expect_array_alloc(&reader, int, 2, &count))); if (elements) { elements[0] = 0; elements[1] = 1; MPACK_FREE(elements); } TEST_SIMPLE_READ_ERROR("\x92", (elements = mpack_expect_array_alloc(&reader, int, 1, &count), true), mpack_error_type); TEST_TRUE(elements == NULL); TEST_SIMPLE_READ_ERROR("\xc0", (elements = mpack_expect_array_alloc(&reader, int, 1, &count), true), mpack_error_type); TEST_TRUE(elements == NULL); TEST_SIMPLE_READ("\x90", (elements = mpack_expect_array_or_nil_alloc(&reader, int, 1, &count), true)); TEST_TRUE(elements == NULL); TEST_SIMPLE_READ_CANCEL("\x91", NULL != (elements = mpack_expect_array_or_nil_alloc(&reader, int, 1, &count))); if (elements) { elements[0] = 0; MPACK_FREE(elements); } TEST_SIMPLE_READ_CANCEL("\x92", NULL != (elements = mpack_expect_array_or_nil_alloc(&reader, int, 2, &count))); if (elements) { elements[0] = 0; elements[1] = 1; MPACK_FREE(elements); } TEST_SIMPLE_READ_ERROR("\x92", (elements = mpack_expect_array_or_nil_alloc(&reader, int, 1, &count), true), mpack_error_type); TEST_TRUE(elements == NULL); TEST_SIMPLE_READ("\xc0", (elements = mpack_expect_array_or_nil_alloc(&reader, int, 1, &count), true)); TEST_TRUE(elements == NULL); #endif } static void test_expect_maps() { uint32_t count; // maps TEST_SIMPLE_READ_CANCEL("\x80", 0 == mpack_expect_map(&reader)); TEST_SIMPLE_READ_CANCEL("\x81", 1 == mpack_expect_map(&reader)); TEST_SIMPLE_READ_CANCEL("\x8f", 15 == mpack_expect_map(&reader)); TEST_SIMPLE_READ_CANCEL("\xde\x00\x00", 0 == mpack_expect_map(&reader)); TEST_SIMPLE_READ_CANCEL("\xde\x01\x00", 0x100 == mpack_expect_map(&reader)); TEST_SIMPLE_READ_CANCEL("\xde\xff\xff", 0xffff == mpack_expect_map(&reader)); TEST_SIMPLE_READ_CANCEL("\xdf\x00\x00\x00\x00", 0 == mpack_expect_map(&reader)); TEST_SIMPLE_READ_CANCEL("\xdf\x00\x00\x01\x00", 0x100 == mpack_expect_map(&reader)); TEST_SIMPLE_READ_CANCEL("\xdf\x00\x01\x00\x00", 0x10000 == mpack_expect_map(&reader)); TEST_SIMPLE_READ_CANCEL("\xdf\xff\xff\xff\xff", UINT32_MAX == mpack_expect_map(&reader)); TEST_SIMPLE_READ_ERROR("\x00", 0 == mpack_expect_map(&reader), mpack_error_type); // map ranges TEST_SIMPLE_READ_CANCEL("\x81", 1 == mpack_expect_map_range(&reader, 0, 1)); TEST_SIMPLE_READ_CANCEL("\x81", 1 == mpack_expect_map_range(&reader, 1, 1)); TEST_SIMPLE_READ_ERROR("\x81", 2 == mpack_expect_map_range(&reader, 2, 2), mpack_error_type); TEST_SIMPLE_READ_ASSERT("\x81", mpack_expect_map_range(reader, 2, 1)); TEST_SIMPLE_READ_CANCEL("\x81", 1 == mpack_expect_map_max(&reader, 1)); TEST_SIMPLE_READ_ERROR("\x81", 0 == mpack_expect_map_max(&reader, 0), mpack_error_type); TEST_SIMPLE_READ("\x80", (mpack_expect_map_match(&reader, 0), mpack_done_map(&reader), true)); TEST_SIMPLE_READ_CANCEL("\x8f", (mpack_expect_map_match(&reader, 15), true)); TEST_SIMPLE_READ_CANCEL("\xde\xff\xff", (mpack_expect_map_match(&reader, 0xffff), true)); TEST_SIMPLE_READ_CANCEL("\xdf\xff\xff\xff\xff", (mpack_expect_map_match(&reader, UINT32_MAX), true)); TEST_SIMPLE_READ_ERROR("\x81", (mpack_expect_map_match(&reader, 2), true), mpack_error_type); TEST_SIMPLE_READ_CANCEL("\x81", true == mpack_expect_map_or_nil(&reader, &count)); TEST_TRUE(count == 1); TEST_SIMPLE_READ_CANCEL("\xc0", false == mpack_expect_map_or_nil(&reader, &count)); TEST_TRUE(count == 0); TEST_SIMPLE_READ_ERROR("\x91", false == mpack_expect_map_or_nil(&reader, &count), mpack_error_type); TEST_TRUE(count == 0); TEST_SIMPLE_READ_CANCEL("\x81", true == mpack_expect_map_max_or_nil(&reader, 1, &count)); TEST_TRUE(count == 1); TEST_SIMPLE_READ_CANCEL("\xc0", false == mpack_expect_map_max_or_nil(&reader, 0, &count)); TEST_TRUE(count == 0); TEST_SIMPLE_READ_ERROR("\x82", false == mpack_expect_map_max_or_nil(&reader, 1, &count), mpack_error_type); TEST_TRUE(count == 0); TEST_SIMPLE_READ_ERROR("\x91", false == mpack_expect_map_max_or_nil(&reader, 1, &count), mpack_error_type); TEST_TRUE(count == 0); } static void test_expect_key_cstr_basic() { mpack_reader_t reader; mpack_reader_init_data(&reader, test_example, TEST_EXAMPLE_SIZE); static const char* keys[] = {"schema","compact"}; #define KEY_COUNT (sizeof(keys) / sizeof(keys[0])) bool found[KEY_COUNT]; memset(found, 0, sizeof(found)); TEST_TRUE(2 == mpack_expect_map(&reader)); TEST_TRUE(1 == mpack_expect_key_cstr(&reader, keys, found, KEY_COUNT)); TEST_TRUE(true == mpack_expect_bool(&reader)); TEST_TRUE(0 == mpack_expect_key_cstr(&reader, keys, found, KEY_COUNT)); TEST_TRUE(0 == mpack_expect_u8(&reader)); mpack_done_map(&reader); TEST_READER_DESTROY_NOERROR(&reader); TEST_TRUE(found[0]); TEST_TRUE(found[1]); #undef KEY_COUNT } static void test_expect_key_cstr_mixed() { mpack_reader_t reader; mpack_reader_init_data(&reader, test_example, TEST_EXAMPLE_SIZE); static const char* keys[] = { "unknown", "schema", "unknown2" }; #define KEY_COUNT (sizeof(keys) / sizeof(keys[0])) bool found[KEY_COUNT]; memset(found, 0, sizeof(found)); TEST_TRUE(2 == mpack_expect_map(&reader)); TEST_TRUE(KEY_COUNT == mpack_expect_key_cstr(&reader, keys, found, KEY_COUNT)); // unknown mpack_discard(&reader); TEST_TRUE(1 == mpack_expect_key_cstr(&reader, keys, found, KEY_COUNT)); TEST_TRUE(0 == mpack_expect_u8(&reader)); mpack_done_map(&reader); TEST_READER_DESTROY_NOERROR(&reader); TEST_TRUE(!found[0]); TEST_TRUE(found[1]); TEST_TRUE(!found[2]); #undef KEY_COUNT } static void test_expect_key_cstr_duplicate() { static const char data[] = "\x83\xA3""dup\xC0\xA3""dup\xC0\xA5""valid\xC0"; mpack_reader_t reader; mpack_reader_init_data(&reader, data, sizeof(data)-1); static const char* keys[] = { "valid", "dup" }; #define KEY_COUNT (sizeof(keys) / sizeof(keys[0])) bool found[KEY_COUNT]; memset(found, 0, sizeof(found)); TEST_TRUE(3 == mpack_expect_map(&reader)); TEST_TRUE(1 == mpack_expect_key_cstr(&reader, keys, found, KEY_COUNT)); mpack_expect_nil(&reader); TEST_TRUE(KEY_COUNT == mpack_expect_key_cstr(&reader, keys, found, KEY_COUNT)); // duplicate mpack_discard(&reader); // should be no-op due to error TEST_TRUE(KEY_COUNT == mpack_expect_key_cstr(&reader, keys, found, KEY_COUNT)); // already in error, not valid TEST_READER_DESTROY_ERROR(&reader, mpack_error_invalid); #undef KEY_COUNT } static void test_expect_key_uint() { static const char data[] = "\x85\x02\xC0\x00\xC0\xC3\xC0\x03\xC0\x03\xC0"; mpack_reader_t reader; mpack_reader_init_data(&reader, data, sizeof(data)-1); #define KEY_COUNT 4 bool found[KEY_COUNT]; memset(found, 0, sizeof(found)); TEST_TRUE(5 == mpack_expect_map(&reader)); TEST_TRUE(2 == mpack_expect_key_uint(&reader, found, KEY_COUNT)); mpack_expect_nil(&reader); TEST_TRUE(0 == mpack_expect_key_uint(&reader, found, KEY_COUNT)); mpack_expect_nil(&reader); TEST_TRUE(KEY_COUNT == mpack_expect_key_uint(&reader, found, KEY_COUNT)); // key has value "true", unrecognized mpack_discard(&reader); TEST_TRUE(3 == mpack_expect_key_uint(&reader, found, KEY_COUNT)); mpack_expect_nil(&reader); TEST_TRUE(mpack_reader_error(&reader) == mpack_ok); TEST_TRUE(found[0]); TEST_TRUE(!found[1]); TEST_TRUE(found[2]); TEST_TRUE(found[2]); TEST_TRUE(KEY_COUNT == mpack_expect_key_uint(&reader, found, KEY_COUNT)); TEST_READER_DESTROY_ERROR(&reader, mpack_error_invalid); #undef KEY_COUNT } void test_expect() { test_expect_example_read(); // int/uint test_expect_uint_fixnum(); test_expect_uint_signed_fixnum(); test_expect_negative_fixnum(); test_expect_uint(); test_expect_uint_signed(); test_expect_int(); test_expect_uint_bounds(); test_expect_int_bounds(); test_expect_ints_dynamic_int(); test_expect_int_range(); test_expect_int_match(); // compound types test_expect_str(); test_expect_bin(); test_expect_ext(); test_expect_arrays(); test_expect_maps(); // key switches test_expect_key_cstr_basic(); test_expect_key_cstr_mixed(); test_expect_key_cstr_duplicate(); test_expect_key_uint(); // other test_expect_misc(); #if MPACK_READ_TRACKING test_expect_tracking(); #endif test_expect_reals(); test_expect_reals_range(); test_expect_bad_type(); test_expect_pre_error(); } #endif