diff options
author | David Robillard <d@drobilla.net> | 2021-02-25 10:27:59 -0500 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2021-03-08 23:23:05 -0500 |
commit | c4821c8e6bf1f81c6ea31e11ebc0fc1666e9337b (patch) | |
tree | a62995534f5f606ac2f8bae22d525532b824cb5e /subprojects/exess/test/test_coerce.c | |
parent | 6bcd18ae60482790b645a345f718e7099250f261 (diff) | |
download | serd-c4821c8e6bf1f81c6ea31e11ebc0fc1666e9337b.tar.gz serd-c4821c8e6bf1f81c6ea31e11ebc0fc1666e9337b.tar.bz2 serd-c4821c8e6bf1f81c6ea31e11ebc0fc1666e9337b.zip |
Add exess from git@gitlab.com:drobilla/exess.git 4638b1f
Diffstat (limited to 'subprojects/exess/test/test_coerce.c')
-rw-r--r-- | subprojects/exess/test/test_coerce.c | 519 |
1 files changed, 519 insertions, 0 deletions
diff --git a/subprojects/exess/test/test_coerce.c b/subprojects/exess/test/test_coerce.c new file mode 100644 index 00000000..dc5ad060 --- /dev/null +++ b/subprojects/exess/test/test_coerce.c @@ -0,0 +1,519 @@ +/* + Copyright 2011-2021 David Robillard <d@drobilla.net> + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#undef NDEBUG + +#include "exess/exess.h" + +#include <assert.h> +#include <string.h> + +static const char* const min_long_str = "-9223372036854775808"; +static const char* const max_long_str = "9223372036854775807"; +static const char* const max_ulong_str = "18446744073709551615"; + +static void +check_from_to(const ExessDatatype from_datatype, + const char* const from_string, + const ExessDatatype to_datatype, + const char* const to_string) +{ + char value_buf[4] = {0, 0, 0, 0}; + char buf[328] = {42}; + + // Read original value + ExessVariant value = {EXESS_HEX, {.as_blob = {sizeof(value_buf), value_buf}}}; + assert(!exess_read_variant(&value, from_datatype, from_string).status); + + // Coerce to target datatype + const ExessVariant coerced = exess_coerce(value, to_datatype, EXESS_LOSSLESS); + assert(coerced.datatype == to_datatype); + + // Write coerced value and check string against expectation + assert(!exess_write_variant(coerced, sizeof(buf), buf).status); + assert(!strcmp(buf, to_string)); + + // Coerce the value back to the original type + const ExessVariant tripped = + exess_coerce(coerced, from_datatype, EXESS_LOSSLESS); + assert(tripped.datatype == from_datatype); + + // Write round-tripped value and check string against the original + assert(!exess_write_variant(tripped, sizeof(buf), buf).status); + assert(!strcmp(buf, from_string)); +} + +static void +check_one_way(const ExessDatatype from_datatype, + const char* const from_string, + const ExessCoercionFlags coercions, + const ExessDatatype to_datatype, + const char* const to_string) +{ + char buf[328] = {42}; + + // Read original value + ExessVariant value = {EXESS_NOTHING, {EXESS_SUCCESS}}; + assert(!exess_read_variant(&value, from_datatype, from_string).status); + + // Coerce to target datatype + ExessVariant coerced = exess_coerce(value, to_datatype, coercions); + assert(coerced.datatype == to_datatype); + + // Write coerced value and check string against expectation + assert(!exess_write_variant(coerced, sizeof(buf), buf).status); + assert(!strcmp(buf, to_string)); +} + +static void +check_failure(const ExessDatatype from_datatype, + const char* const from_string, + const ExessDatatype to_datatype, + const ExessStatus expected_status) +{ + // Read original value + ExessVariant value = {EXESS_NOTHING, {EXESS_SUCCESS}}; + assert(!exess_read_variant(&value, from_datatype, from_string).status); + + // Try to coerce to target datatype + const ExessVariant coerced = exess_coerce(value, to_datatype, EXESS_LOSSLESS); + assert(coerced.datatype == EXESS_NOTHING); + assert(exess_get_status(&coerced) == expected_status); +} + +static void +test_unknown(void) +{ + ExessVariant long_value = exess_make_long(1); + ExessVariant ulong_value = exess_make_ulong(1u); + ExessVariant unknown_value = exess_make_nothing(EXESS_SUCCESS); + + assert(exess_coerce(unknown_value, EXESS_LONG, EXESS_LOSSLESS).datatype == + EXESS_NOTHING); + + assert(exess_coerce(unknown_value, EXESS_ULONG, EXESS_LOSSLESS).datatype == + EXESS_NOTHING); + + assert(exess_coerce(long_value, EXESS_NOTHING, EXESS_LOSSLESS).datatype == + EXESS_NOTHING); + + assert(exess_coerce(ulong_value, EXESS_NOTHING, EXESS_LOSSLESS).datatype == + EXESS_NOTHING); +} + +static void +test_boolean(void) +{ + // Exactly from 0 or 1, lossy from 0 or non-zero + check_from_to(EXESS_BOOLEAN, "false", EXESS_FLOAT, "0.0E0"); + check_from_to(EXESS_BOOLEAN, "true", EXESS_FLOAT, "1.0E0"); + check_from_to(EXESS_BOOLEAN, "false", EXESS_DOUBLE, "0.0E0"); + check_from_to(EXESS_BOOLEAN, "true", EXESS_DOUBLE, "1.0E0"); + check_from_to(EXESS_BOOLEAN, "false", EXESS_LONG, "0"); + check_from_to(EXESS_BOOLEAN, "true", EXESS_LONG, "1"); + check_failure(EXESS_LONG, "-1", EXESS_BOOLEAN, EXESS_WOULD_TRUNCATE); + check_failure(EXESS_LONG, "2", EXESS_BOOLEAN, EXESS_WOULD_TRUNCATE); + check_one_way(EXESS_LONG, "42", EXESS_TRUNCATE, EXESS_BOOLEAN, "true"); + check_one_way(EXESS_LONG, "-1", EXESS_TRUNCATE, EXESS_BOOLEAN, "true"); + check_from_to(EXESS_BOOLEAN, "false", EXESS_ULONG, "0"); + check_from_to(EXESS_BOOLEAN, "true", EXESS_ULONG, "1"); + check_failure(EXESS_LONG, "2", EXESS_BOOLEAN, EXESS_WOULD_TRUNCATE); + check_one_way(EXESS_ULONG, "42", EXESS_TRUNCATE, EXESS_BOOLEAN, "true"); + + // Not convertible to any time types + check_failure(EXESS_BOOLEAN, "true", EXESS_DURATION, EXESS_UNSUPPORTED); + check_failure(EXESS_BOOLEAN, "true", EXESS_DATETIME, EXESS_UNSUPPORTED); + check_failure(EXESS_BOOLEAN, "true", EXESS_TIME, EXESS_UNSUPPORTED); + check_failure(EXESS_BOOLEAN, "true", EXESS_DATE, EXESS_UNSUPPORTED); +} + +static void +test_long(void) +{ + // Truncating boolean conversion + check_one_way(EXESS_LONG, "42", EXESS_TRUNCATE, EXESS_BOOLEAN, "true"); + check_one_way(EXESS_LONG, "-1", EXESS_TRUNCATE, EXESS_BOOLEAN, "true"); + + // All smaller integer types + check_from_to(EXESS_LONG, "-2147483648", EXESS_INT, "-2147483648"); + check_failure(EXESS_LONG, "-2147483649", EXESS_INT, EXESS_OUT_OF_RANGE); + check_from_to(EXESS_LONG, "-32768", EXESS_SHORT, "-32768"); + check_failure(EXESS_LONG, "-32769", EXESS_SHORT, EXESS_OUT_OF_RANGE); + check_from_to(EXESS_LONG, "-128", EXESS_BYTE, "-128"); + check_failure(EXESS_LONG, "-129", EXESS_BYTE, EXESS_OUT_OF_RANGE); + + // Positive values to/from all unsigned types + check_from_to(EXESS_LONG, max_long_str, EXESS_ULONG, max_long_str); + check_failure(EXESS_LONG, "-1", EXESS_ULONG, EXESS_OUT_OF_RANGE); + check_from_to(EXESS_LONG, "4294967295", EXESS_UINT, "4294967295"); + check_failure(EXESS_LONG, "-1", EXESS_UINT, EXESS_OUT_OF_RANGE); + check_from_to(EXESS_LONG, "65535", EXESS_USHORT, "65535"); + check_failure(EXESS_LONG, "-1", EXESS_USHORT, EXESS_OUT_OF_RANGE); + check_from_to(EXESS_LONG, "255", EXESS_UBYTE, "255"); + check_failure(EXESS_LONG, "-1", EXESS_UBYTE, EXESS_OUT_OF_RANGE); + + // Any value to/from integer + check_from_to(EXESS_LONG, min_long_str, EXESS_INTEGER, min_long_str); + check_from_to(EXESS_LONG, max_long_str, EXESS_INTEGER, max_long_str); + + // Non-positive values to/from nonPositiveInteger + check_from_to( + EXESS_LONG, min_long_str, EXESS_NON_POSITIVE_INTEGER, min_long_str); + check_from_to(EXESS_LONG, "0", EXESS_NON_POSITIVE_INTEGER, "0"); + check_failure( + EXESS_LONG, "1", EXESS_NON_POSITIVE_INTEGER, EXESS_OUT_OF_RANGE); + + // Negative values to/from negativeInteger + check_from_to(EXESS_LONG, min_long_str, EXESS_NEGATIVE_INTEGER, min_long_str); + check_from_to(EXESS_LONG, "-1", EXESS_NEGATIVE_INTEGER, "-1"); + check_failure(EXESS_LONG, "0", EXESS_NEGATIVE_INTEGER, EXESS_OUT_OF_RANGE); + + // Non-negative values to/from nonNegativeInteger + check_failure( + EXESS_LONG, "-1", EXESS_NON_NEGATIVE_INTEGER, EXESS_OUT_OF_RANGE); + check_from_to(EXESS_LONG, "0", EXESS_NON_NEGATIVE_INTEGER, "0"); + check_from_to( + EXESS_LONG, max_long_str, EXESS_NON_NEGATIVE_INTEGER, max_long_str); + + // Positive values to/from positiveInteger + check_failure(EXESS_LONG, "-1", EXESS_POSITIVE_INTEGER, EXESS_OUT_OF_RANGE); + check_failure(EXESS_LONG, "0", EXESS_POSITIVE_INTEGER, EXESS_OUT_OF_RANGE); + check_from_to(EXESS_LONG, max_long_str, EXESS_POSITIVE_INTEGER, max_long_str); + check_failure(EXESS_POSITIVE_INTEGER, + "9223372036854775808", + EXESS_LONG, + EXESS_OUT_OF_RANGE); + + // Float + check_failure(EXESS_FLOAT, "1.5", EXESS_LONG, EXESS_WOULD_ROUND); + check_from_to(EXESS_LONG, "-16777215", EXESS_FLOAT, "-1.6777215E7"); + check_failure(EXESS_LONG, "-16777216", EXESS_FLOAT, EXESS_OUT_OF_RANGE); + check_failure(EXESS_FLOAT, "-16777216", EXESS_LONG, EXESS_OUT_OF_RANGE); + check_from_to(EXESS_LONG, "16777215", EXESS_FLOAT, "1.6777215E7"); + check_failure(EXESS_LONG, "16777216", EXESS_FLOAT, EXESS_OUT_OF_RANGE); + check_failure(EXESS_FLOAT, "16777216", EXESS_LONG, EXESS_OUT_OF_RANGE); + check_one_way(EXESS_FLOAT, "1.0", EXESS_LOSSLESS, EXESS_LONG, "1"); + check_one_way(EXESS_FLOAT, "1.5", EXESS_ROUND, EXESS_LONG, "2"); + check_one_way(EXESS_FLOAT, "2.5", EXESS_ROUND, EXESS_LONG, "2"); + check_one_way(EXESS_FLOAT, "3.5", EXESS_ROUND, EXESS_LONG, "4"); + + // Double + check_failure(EXESS_DOUBLE, "1.5", EXESS_LONG, EXESS_WOULD_ROUND); + check_from_to( + EXESS_LONG, "-9007199254740991", EXESS_DOUBLE, "-9.007199254740991E15"); + check_failure( + EXESS_LONG, "-9007199254740992", EXESS_DOUBLE, EXESS_OUT_OF_RANGE); + check_failure( + EXESS_DOUBLE, "-9007199254740992", EXESS_LONG, EXESS_OUT_OF_RANGE); + check_from_to( + EXESS_LONG, "9007199254740991", EXESS_DOUBLE, "9.007199254740991E15"); + check_failure( + EXESS_LONG, "9007199254740992", EXESS_DOUBLE, EXESS_OUT_OF_RANGE); + check_failure( + EXESS_DOUBLE, "9007199254740992", EXESS_LONG, EXESS_OUT_OF_RANGE); + check_one_way(EXESS_DOUBLE, "1.0", EXESS_LOSSLESS, EXESS_LONG, "1"); + check_one_way(EXESS_DOUBLE, "1.5", EXESS_ROUND, EXESS_LONG, "2"); + check_one_way(EXESS_DOUBLE, "2.5", EXESS_ROUND, EXESS_LONG, "2"); + check_one_way(EXESS_DOUBLE, "3.5", EXESS_ROUND, EXESS_LONG, "4"); +} + +static void +test_ulong(void) +{ + ExessVariant unknown = {EXESS_NOTHING, {EXESS_SUCCESS}}; + + assert(exess_coerce(unknown, EXESS_ULONG, EXESS_LOSSLESS).datatype == + EXESS_NOTHING); + + // Truncating boolean conversion + check_one_way(EXESS_ULONG, "42", EXESS_TRUNCATE, EXESS_BOOLEAN, "true"); + + // All integer types + check_from_to(EXESS_ULONG, max_long_str, EXESS_LONG, max_long_str); + check_failure(EXESS_ULONG, max_ulong_str, EXESS_LONG, EXESS_OUT_OF_RANGE); + check_from_to(EXESS_ULONG, "2147483647", EXESS_INT, "2147483647"); + check_failure(EXESS_ULONG, "2147483648", EXESS_INT, EXESS_OUT_OF_RANGE); + check_failure(EXESS_INT, "-1", EXESS_ULONG, EXESS_OUT_OF_RANGE); + check_from_to(EXESS_ULONG, "32767", EXESS_SHORT, "32767"); + check_failure(EXESS_ULONG, "32768", EXESS_SHORT, EXESS_OUT_OF_RANGE); + check_failure(EXESS_SHORT, "-1", EXESS_ULONG, EXESS_OUT_OF_RANGE); + check_from_to(EXESS_ULONG, "127", EXESS_BYTE, "127"); + check_failure(EXESS_ULONG, "128", EXESS_BYTE, EXESS_OUT_OF_RANGE); + check_failure(EXESS_BYTE, "-1", EXESS_ULONG, EXESS_OUT_OF_RANGE); + + // All unsigned types + check_from_to(EXESS_ULONG, "4294967295", EXESS_UINT, "4294967295"); + check_failure(EXESS_ULONG, "4294967296", EXESS_UINT, EXESS_OUT_OF_RANGE); + check_from_to(EXESS_ULONG, "65535", EXESS_USHORT, "65535"); + check_failure(EXESS_ULONG, "65536", EXESS_USHORT, EXESS_OUT_OF_RANGE); + check_from_to(EXESS_ULONG, "255", EXESS_UBYTE, "255"); + check_failure(EXESS_ULONG, "256", EXESS_UBYTE, EXESS_OUT_OF_RANGE); + + // Small enough value Any value to/from integer + check_from_to(EXESS_ULONG, "0", EXESS_INTEGER, "0"); + check_failure( + EXESS_ULONG, "9223372036854775808", EXESS_INTEGER, EXESS_OUT_OF_RANGE); + + // Only zero to/from nonPositiveInteger + check_from_to(EXESS_ULONG, "0", EXESS_NON_POSITIVE_INTEGER, "0"); + check_failure( + EXESS_ULONG, "1", EXESS_NON_POSITIVE_INTEGER, EXESS_OUT_OF_RANGE); + + // Not convertible to/from negativeInteger + check_failure(EXESS_ULONG, "0", EXESS_NEGATIVE_INTEGER, EXESS_OUT_OF_RANGE); + check_failure(EXESS_ULONG, "1", EXESS_NEGATIVE_INTEGER, EXESS_OUT_OF_RANGE); + + // Any value to/from nonNegativeInteger + check_from_to(EXESS_ULONG, "0", EXESS_NON_NEGATIVE_INTEGER, "0"); + check_from_to( + EXESS_ULONG, max_ulong_str, EXESS_NON_NEGATIVE_INTEGER, max_ulong_str); + + // Positive values to/from positiveInteger + check_failure(EXESS_ULONG, "0", EXESS_POSITIVE_INTEGER, EXESS_OUT_OF_RANGE); + check_from_to(EXESS_ULONG, "1", EXESS_POSITIVE_INTEGER, "1"); + + // Float + check_failure(EXESS_FLOAT, "-1", EXESS_ULONG, EXESS_OUT_OF_RANGE); + check_failure(EXESS_FLOAT, "1.5", EXESS_ULONG, EXESS_WOULD_ROUND); + check_from_to(EXESS_ULONG, "0", EXESS_FLOAT, "0.0E0"); + check_from_to(EXESS_ULONG, "16777215", EXESS_FLOAT, "1.6777215E7"); + check_failure(EXESS_ULONG, "16777216", EXESS_FLOAT, EXESS_OUT_OF_RANGE); + check_failure(EXESS_FLOAT, "16777216", EXESS_ULONG, EXESS_OUT_OF_RANGE); + check_one_way(EXESS_FLOAT, "1.0", EXESS_LOSSLESS, EXESS_ULONG, "1"); + check_one_way(EXESS_FLOAT, "1.5", EXESS_ROUND, EXESS_ULONG, "2"); + check_one_way(EXESS_FLOAT, "2.5", EXESS_ROUND, EXESS_ULONG, "2"); + check_one_way(EXESS_FLOAT, "3.5", EXESS_ROUND, EXESS_ULONG, "4"); + + // Double + check_failure(EXESS_DOUBLE, "-1", EXESS_ULONG, EXESS_OUT_OF_RANGE); + check_failure(EXESS_DOUBLE, "1.5", EXESS_ULONG, EXESS_WOULD_ROUND); + check_from_to(EXESS_ULONG, "0", EXESS_DOUBLE, "0.0E0"); + check_from_to( + EXESS_ULONG, "9007199254740991", EXESS_DOUBLE, "9.007199254740991E15"); + check_failure( + EXESS_ULONG, "9007199254740992", EXESS_DOUBLE, EXESS_OUT_OF_RANGE); + check_failure( + EXESS_DOUBLE, "9007199254740992", EXESS_ULONG, EXESS_OUT_OF_RANGE); + check_one_way(EXESS_DOUBLE, "1.0", EXESS_LOSSLESS, EXESS_ULONG, "1"); + check_one_way(EXESS_DOUBLE, "1.5", EXESS_ROUND, EXESS_ULONG, "2"); + check_one_way(EXESS_DOUBLE, "2.5", EXESS_ROUND, EXESS_ULONG, "2"); + check_one_way(EXESS_DOUBLE, "3.5", EXESS_ROUND, EXESS_ULONG, "4"); +} + +static void +test_large_integers(void) +{ + check_failure(EXESS_TIME, "00:00:00", EXESS_INTEGER, EXESS_UNSUPPORTED); + check_failure( + EXESS_TIME, "00:00:00", EXESS_NON_POSITIVE_INTEGER, EXESS_UNSUPPORTED); + check_failure( + EXESS_TIME, "00:00:00", EXESS_NEGATIVE_INTEGER, EXESS_UNSUPPORTED); + check_failure( + EXESS_TIME, "00:00:00", EXESS_NON_NEGATIVE_INTEGER, EXESS_UNSUPPORTED); + check_failure( + EXESS_TIME, "00:00:00", EXESS_POSITIVE_INTEGER, EXESS_UNSUPPORTED); +} + +static void +test_coerce(void) +{ + check_one_way(EXESS_DOUBLE, + "1.0000000000001", + EXESS_REDUCE_PRECISION, + EXESS_FLOAT, + "1.0E0"); + + check_failure( + EXESS_DOUBLE, "1.0000000000001", EXESS_FLOAT, EXESS_WOULD_REDUCE_PRECISION); + + check_one_way(EXESS_FLOAT, "1.5", EXESS_LOSSLESS, EXESS_DOUBLE, "1.5E0"); + + /* check_failure( */ + /* EXESS_LONG, "9007199254740993", EXESS_DOUBLE, EXESS_OUT_OF_RANGE); */ + + /* check_failure(EXESS_FLOAT, "1.0", EXESS_LONG, EXESS_SUCCESS); */ + /* check_from_to(EXESS_BYTE, "-128", EXESS_LONG, "-128"); */ + + // DateTime +} + +static void +test_date_time(void) +{ + check_failure( + EXESS_DATETIME, "2001-02-03T04:05:06", EXESS_TIME, EXESS_WOULD_TRUNCATE); + + check_one_way(EXESS_DATETIME, + "2001-02-03T04:05:06", + EXESS_TRUNCATE, + EXESS_TIME, + "04:05:06"); + + check_one_way(EXESS_DATETIME, + "2001-02-03T04:05:06Z", + EXESS_TRUNCATE, + EXESS_TIME, + "04:05:06Z"); + + check_failure( + EXESS_DATETIME, "2001-02-03T04:05:06", EXESS_DATE, EXESS_WOULD_TRUNCATE); + + check_one_way(EXESS_DATETIME, + "2001-02-03T04:05:06", + EXESS_TRUNCATE, + EXESS_DATE, + "2001-02-03"); + + check_one_way(EXESS_DATETIME, + "2001-02-03T04:05:06Z", + EXESS_TRUNCATE, + EXESS_DATE, + "2001-02-03Z"); +} + +static void +test_number_to_time(void) +{ + check_failure(EXESS_BOOLEAN, "true", EXESS_DURATION, EXESS_UNSUPPORTED); + check_failure(EXESS_BOOLEAN, "true", EXESS_DATETIME, EXESS_UNSUPPORTED); + check_failure(EXESS_BOOLEAN, "true", EXESS_TIME, EXESS_UNSUPPORTED); + check_failure(EXESS_BOOLEAN, "true", EXESS_DATE, EXESS_UNSUPPORTED); + + check_failure(EXESS_LONG, "1", EXESS_DURATION, EXESS_UNSUPPORTED); + check_failure(EXESS_LONG, "1", EXESS_DATETIME, EXESS_UNSUPPORTED); + check_failure(EXESS_LONG, "1", EXESS_TIME, EXESS_UNSUPPORTED); + check_failure(EXESS_LONG, "1", EXESS_DATE, EXESS_UNSUPPORTED); + + check_failure(EXESS_INT, "1", EXESS_DURATION, EXESS_UNSUPPORTED); + check_failure(EXESS_INT, "1", EXESS_DATETIME, EXESS_UNSUPPORTED); + check_failure(EXESS_INT, "1", EXESS_TIME, EXESS_UNSUPPORTED); + check_failure(EXESS_INT, "1", EXESS_DATE, EXESS_UNSUPPORTED); + + check_failure(EXESS_SHORT, "1", EXESS_DURATION, EXESS_UNSUPPORTED); + check_failure(EXESS_SHORT, "1", EXESS_DATETIME, EXESS_UNSUPPORTED); + check_failure(EXESS_SHORT, "1", EXESS_TIME, EXESS_UNSUPPORTED); + check_failure(EXESS_SHORT, "1", EXESS_DATE, EXESS_UNSUPPORTED); + + check_failure(EXESS_BYTE, "1", EXESS_DURATION, EXESS_UNSUPPORTED); + check_failure(EXESS_BYTE, "1", EXESS_DATETIME, EXESS_UNSUPPORTED); + check_failure(EXESS_BYTE, "1", EXESS_TIME, EXESS_UNSUPPORTED); + check_failure(EXESS_BYTE, "1", EXESS_DATE, EXESS_UNSUPPORTED); + + check_failure(EXESS_ULONG, "1", EXESS_DURATION, EXESS_UNSUPPORTED); + check_failure(EXESS_ULONG, "1", EXESS_DATETIME, EXESS_UNSUPPORTED); + check_failure(EXESS_ULONG, "1", EXESS_TIME, EXESS_UNSUPPORTED); + check_failure(EXESS_ULONG, "1", EXESS_DATE, EXESS_UNSUPPORTED); + + check_failure(EXESS_UINT, "1", EXESS_DURATION, EXESS_UNSUPPORTED); + check_failure(EXESS_UINT, "1", EXESS_DATETIME, EXESS_UNSUPPORTED); + check_failure(EXESS_UINT, "1", EXESS_TIME, EXESS_UNSUPPORTED); + check_failure(EXESS_UINT, "1", EXESS_DATE, EXESS_UNSUPPORTED); + + check_failure(EXESS_USHORT, "1", EXESS_DURATION, EXESS_UNSUPPORTED); + check_failure(EXESS_USHORT, "1", EXESS_DATETIME, EXESS_UNSUPPORTED); + check_failure(EXESS_USHORT, "1", EXESS_TIME, EXESS_UNSUPPORTED); + check_failure(EXESS_USHORT, "1", EXESS_DATE, EXESS_UNSUPPORTED); + + check_failure(EXESS_UBYTE, "1", EXESS_DURATION, EXESS_UNSUPPORTED); + check_failure(EXESS_UBYTE, "1", EXESS_DATETIME, EXESS_UNSUPPORTED); + check_failure(EXESS_UBYTE, "1", EXESS_TIME, EXESS_UNSUPPORTED); + check_failure(EXESS_UBYTE, "1", EXESS_DATE, EXESS_UNSUPPORTED); +} + +static void +test_time_to_number(void) +{ + static const char* const duration_str = "P1Y"; + static const char* const datetime_str = "2001-02-03T04:05:06"; + static const char* const time_str = "04:05:06"; + static const char* const date_str = "2001-02-03"; + + check_failure(EXESS_DURATION, duration_str, EXESS_BOOLEAN, EXESS_UNSUPPORTED); + check_failure(EXESS_DATETIME, datetime_str, EXESS_BOOLEAN, EXESS_UNSUPPORTED); + check_failure(EXESS_TIME, time_str, EXESS_BOOLEAN, EXESS_UNSUPPORTED); + check_failure(EXESS_DATE, date_str, EXESS_BOOLEAN, EXESS_UNSUPPORTED); + + check_failure(EXESS_DURATION, duration_str, EXESS_INT, EXESS_UNSUPPORTED); + check_failure(EXESS_DATETIME, datetime_str, EXESS_INT, EXESS_UNSUPPORTED); + check_failure(EXESS_TIME, time_str, EXESS_INT, EXESS_UNSUPPORTED); + check_failure(EXESS_DATE, date_str, EXESS_INT, EXESS_UNSUPPORTED); + + check_failure(EXESS_DURATION, duration_str, EXESS_SHORT, EXESS_UNSUPPORTED); + check_failure(EXESS_DATETIME, datetime_str, EXESS_SHORT, EXESS_UNSUPPORTED); + check_failure(EXESS_TIME, time_str, EXESS_SHORT, EXESS_UNSUPPORTED); + check_failure(EXESS_DATE, date_str, EXESS_SHORT, EXESS_UNSUPPORTED); + + check_failure(EXESS_DURATION, duration_str, EXESS_BYTE, EXESS_UNSUPPORTED); + check_failure(EXESS_DATETIME, datetime_str, EXESS_BYTE, EXESS_UNSUPPORTED); + check_failure(EXESS_TIME, time_str, EXESS_BYTE, EXESS_UNSUPPORTED); + check_failure(EXESS_DATE, date_str, EXESS_BYTE, EXESS_UNSUPPORTED); + + check_failure(EXESS_DURATION, duration_str, EXESS_ULONG, EXESS_UNSUPPORTED); + check_failure(EXESS_DATETIME, datetime_str, EXESS_ULONG, EXESS_UNSUPPORTED); + check_failure(EXESS_TIME, time_str, EXESS_ULONG, EXESS_UNSUPPORTED); + check_failure(EXESS_DATE, date_str, EXESS_ULONG, EXESS_UNSUPPORTED); + + check_failure(EXESS_DURATION, duration_str, EXESS_UINT, EXESS_UNSUPPORTED); + check_failure(EXESS_DATETIME, datetime_str, EXESS_UINT, EXESS_UNSUPPORTED); + check_failure(EXESS_TIME, time_str, EXESS_UINT, EXESS_UNSUPPORTED); + check_failure(EXESS_DATE, date_str, EXESS_UINT, EXESS_UNSUPPORTED); + + check_failure(EXESS_DURATION, duration_str, EXESS_USHORT, EXESS_UNSUPPORTED); + check_failure(EXESS_DATETIME, datetime_str, EXESS_USHORT, EXESS_UNSUPPORTED); + check_failure(EXESS_TIME, time_str, EXESS_USHORT, EXESS_UNSUPPORTED); + check_failure(EXESS_DATE, date_str, EXESS_USHORT, EXESS_UNSUPPORTED); + + check_failure(EXESS_DURATION, duration_str, EXESS_UBYTE, EXESS_UNSUPPORTED); + check_failure(EXESS_DATETIME, datetime_str, EXESS_UBYTE, EXESS_UNSUPPORTED); + check_failure(EXESS_TIME, time_str, EXESS_UBYTE, EXESS_UNSUPPORTED); + check_failure(EXESS_DATE, date_str, EXESS_UBYTE, EXESS_UNSUPPORTED); +} + +static void +test_binary(void) +{ + check_from_to(EXESS_HEX, "666F6F", EXESS_BASE64, "Zm9v"); + + check_failure(EXESS_LONG, "-2147483649", EXESS_HEX, EXESS_UNSUPPORTED); + check_failure(EXESS_LONG, "-2147483649", EXESS_BASE64, EXESS_UNSUPPORTED); + + /* check_from_to(EXESS_BASE64, "Zm9v", EXESS_HEX, "666F6F"); */ + + /* ////////// */ + + /* check_one_way(EXESS_LONG, "-1", EXESS_TRUNCATE, EXESS_BOOLEAN, "true"); */ + + /* // All smaller integer types */ + /* check_from_to(EXESS_LONG, "-2147483648", EXESS_INT, "-2147483648"); */ + /* check_failure(EXESS_LONG, "-2147483649", EXESS_INT, EXESS_OUT_OF_RANGE); */ +} + +int +main(void) +{ + test_unknown(); + test_boolean(); + test_long(); + test_ulong(); + test_large_integers(); + test_coerce(); + test_date_time(); + test_number_to_time(); + test_time_to_number(); + test_binary(); + + return 0; +} |