From ca2062bca42fd108ae6a3b9e635247f1a2f99f8e Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Tue, 11 Jan 2022 13:36:38 +0100 Subject: [PATCH] tests++ --- ion.c | 13 ++- ion.stub.php | 6 +- ion_arginfo.h | 11 +-- ion_private.h | 5 + tests/Reader.phpt | 143 ++++++++++++++++++++++++++++ tests/Reader/Buffer.phpt | 35 +++++++ tests/Reader/Iterator.phpt | 23 +++++ tests/Reader/RecursiveIterator.phpt | 22 +++++ tests/Reader/Stream.phpt | 46 ++++++++- tests/Reader/seek.phpt | 19 ++++ 10 files changed, 307 insertions(+), 16 deletions(-) create mode 100644 tests/Reader.phpt create mode 100644 tests/Reader/Buffer.phpt create mode 100644 tests/Reader/Iterator.phpt create mode 100644 tests/Reader/RecursiveIterator.phpt create mode 100644 tests/Reader/seek.phpt diff --git a/ion.c b/ion.c index fe7a38e..5712668 100644 --- a/ion.c +++ b/ion.c @@ -864,7 +864,12 @@ static ZEND_METHOD(ion_Reader_Reader, getAnnotationSymbols) ZEND_PARSE_PARAMETERS_NONE(); - int32_t count, max = php_ion_obj(reader_options, obj->opt)->opt.max_annotation_count; + int32_t count, max; + if (obj->opt) { + max = php_ion_obj(reader_options, obj->opt)->opt.max_annotation_count; + } else { + max = 10; + } ION_SYMBOL *ptr = ecalloc(sizeof(*ptr), max); iERR err = ion_reader_get_annotation_symbols(obj->reader, ptr, max, &count); if (!err) { @@ -955,7 +960,9 @@ static ZEND_METHOD(ion_Reader_Reader, readFloat) ZEND_PARSE_PARAMETERS_NONE(); - ION_CHECK(ion_reader_read_double(obj->reader, &Z_DVAL_P(return_value))); + double dval; + ION_CHECK(ion_reader_read_double(obj->reader, &dval)); + RETURN_DOUBLE(dval); } static ZEND_METHOD(ion_Reader_Reader, readDecimal) { @@ -1196,7 +1203,7 @@ static ZEND_METHOD(ion_Reader_Stream_Reader, resetStreamWithLength) zval *zstream; zend_long length; - ZEND_PARSE_PARAMETERS_START(1, 2); + ZEND_PARSE_PARAMETERS_START(2, 2); Z_PARAM_RESOURCE(zstream); Z_PARAM_LONG(length) ZEND_PARSE_PARAMETERS_END(); diff --git a/ion.stub.php b/ion.stub.php index fd90224..cc9f288 100644 --- a/ion.stub.php +++ b/ion.stub.php @@ -18,7 +18,7 @@ enum Type : int { case String = 0x800; case CLob = 0x900; case BLob = 0xa00; - case AList = 0xb00; + case List = 0xb00; case SExp = 0xc00; case Struct = 0xd00; case Datagram = 0xf00; @@ -396,7 +396,7 @@ interface Stream extends \ion\Reader { /** @param resource $stream */ public function resetStream($stream) : void; /** @param resource $stream */ - public function resetStreamWithLength($stream, int $position, int $length = -1) : void; + public function resetStreamWithLength($stream, int $length) : void; } namespace ion\Reader\Stream; @@ -412,7 +412,7 @@ class Reader extends \ion\Reader\Reader implements \ion\Reader\Stream { /** @param resource $stream */ public function resetStream($stream) : void {} /** @param resource $stream */ - public function resetStreamWithLength($stream, int $position, int $length = -1) : void {} + public function resetStreamWithLength($stream, int $length) : void {} } namespace ion\Writer; diff --git a/ion_arginfo.h b/ion_arginfo.h index 895bb87..bfd758e 100644 --- a/ion_arginfo.h +++ b/ion_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 8e04adcc2af90243429a756e14d48507f8411309 */ + * Stub hash: 8cd99962a32b5321624d6cb043fb60ff13f93738 */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_ion_Symbol_Table_PHP, 0, 0, ion\\Symbol\\Table, 0) ZEND_END_ARG_INFO() @@ -345,8 +345,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ion_Reader_Stream_resetStreamWithLength, 0, 2, IS_VOID, 0) ZEND_ARG_INFO(0, stream) - ZEND_ARG_TYPE_INFO(0, position, IS_LONG, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, length, IS_LONG, 0, "-1") + ZEND_ARG_TYPE_INFO(0, length, IS_LONG, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ion_Reader_Stream_Reader___construct, 0, 0, 1) @@ -1054,9 +1053,9 @@ static zend_class_entry *register_class_ion_Type(void) ZVAL_LONG(&enum_case_BLob_value, 2560); zend_enum_add_case_cstr(class_entry, "BLob", &enum_case_BLob_value); - zval enum_case_AList_value; - ZVAL_LONG(&enum_case_AList_value, 2816); - zend_enum_add_case_cstr(class_entry, "AList", &enum_case_AList_value); + zval enum_case_List_value; + ZVAL_LONG(&enum_case_List_value, 2816); + zend_enum_add_case_cstr(class_entry, "List", &enum_case_List_value); zval enum_case_SExp_value; ZVAL_LONG(&enum_case_SExp_value, 3072); diff --git a/ion_private.h b/ion_private.h index 7233f46..b168f90 100644 --- a/ion_private.h +++ b/ion_private.h @@ -917,6 +917,11 @@ LOCAL timelib_time* php_time_from_ion(const ION_TIMESTAMP *ts, decContext *ctx, { timelib_time *time = ecalloc(1, sizeof(*time)); + /* defaults */ + time->y = 1970; + time->m = 1; + time->d = 1; + switch (ts->precision & 0x7f) { case ION_TS_FRAC: time->us = php_usec_from_ion(&ts->fraction, ctx); diff --git a/tests/Reader.phpt b/tests/Reader.phpt new file mode 100644 index 0000000..afe04c2 --- /dev/null +++ b/tests/Reader.phpt @@ -0,0 +1,143 @@ +--TEST-- +ion\Reader +--EXTENSIONS-- +ion +--INI-- +date.timezone=UTC +--FILE-- +TEST + [ + ["0d0", ion\Type::Decimal], + ["1.23", ion\Type::Decimal], + ["abc", ion\Type::Symbol], + ["()", ion\Type::SExp], + ], + "hasAnnotations" => [ + ["foo::1", true], + ["1", false], + ], + "hasAnnotation" => [ + ["foo::1", false, "bar"], + ["foo::1", true, "foo"], + ], + "isNull" => [ + ["null", true], + ["1", false], + ], + "isInStruct" => [ + ["{a:b}", false], + "step" => ["{a:b}", true], + ], + "getFieldName" => [ + ["{a:b}", ""], + "step" => ["{a:b}", "a"], + ], + "getFieldNameSymbol" => [ + ["{a:b}", new ion\Symbol("")], + "step" => ["{a:b}", new ion\Symbol("a")], + ], + "getAnnotations" => [ + ["foo::bar::1", ["foo", "bar"]], + ["1", []], + ], + "getAnnotationSymbols" => [ + ["f::b::1", [new ion\Symbol("f"), new ion\Symbol("b")]], + ["1", []], + ], + "countAnnotations" => [ + ["f::b::z::1", 3], + ["1", 0], + ], + "getAnnotation" => [ + ["foo::bar::1", "bar", 1], + ], + "getAnnotationSymbol" => [ + ["foo::bar::1", new ion\Symbol("foo"), 0], + ], + "readNull" => [ + ["null.int", ion\Type::Int], + ["null", ion\Type::Null], + ], + "readBool" => [ + ["true", true], + ["false", false], + ], + "readInt" => [ + ["0", 0], + ["1234", 1234], + [PHP_INT_MAX, PHP_INT_MAX], + [PHP_INT_MIN, PHP_INT_MIN], + ], + "readFloat" => [ + ["1e", 1e0], + ], + "readDecimal" => [ + ["1.23", new ion\Decimal("1.23")], + ], + "readTimestamp" => [ + ["2003-05T", new ion\Timestamp(ion\Timestamp\Precision::Month, "!Y-m", "2003-05")], + ], + "readSymbol" => [ + ["abc", new ion\Symbol("abc")], + ], + "readString" => [ + ["'''abc'''", "abc"], + ], + "readLob" => [ + ["{{'''abcdef'''}}", "abcdef"], + ], + "getPosition" => [ + ["{}", 1], + "next" => ["{}", 2], + ], + "getDepth" => [ + ["{}", 0], + "step" => ["{}", 1], + ], + "hasChildren" => [ + ["{a:b}", true], + "step" => ["{a:b}", false], + ], + "getValueOffset" => [ + ["a", 0], + "step" => ["{ab:'''cdefgh'''", 4], + ], + "getValueLength" => [ // always returns -1 for text readers + ["a", -1], + "step" => ["{ab:'''cdefgh'''", -1], + ], +]; + +foreach ($tests as $test => $specs) { + foreach ($specs as $prep => $spec) { + [$data, $check] = $spec; + $args = array_slice($spec, 2); + + $r = new ion\Reader\Buffer\Reader($data); + $r->next(); + try { + switch ($prep) { + case "step": $r->getChildren(); /* fall through */ + case "next": $r->next(); break; + } + $result = $r->$test(...$args); + } catch (Throwable $e) { + $result = $e; + } + + if ($check != $result) { + echo "$test@$prep\n"; + var_dump(compact("check", "result")); + var_dump((string)$result); + echo "\n"; + } + } +} +?> +DONE +--EXPECT-- +TEST +DONE diff --git a/tests/Reader/Buffer.phpt b/tests/Reader/Buffer.phpt new file mode 100644 index 0000000..549b733 --- /dev/null +++ b/tests/Reader/Buffer.phpt @@ -0,0 +1,35 @@ +--TEST-- +ion\Reader\Buffer +--EXTENSIONS-- +ion +--FILE-- +TEST +next(); +var_dump($r->readDecimal()); +var_dump($s === $r->getBuffer()); +?> +DONE +--EXPECTF-- +TEST +object(ion\Decimal)#%d (2) { + ["number"]=> + int(123) + ["context"]=> + object(ion\Decimal\Context)#%d (5) { + ["digits"]=> + int(999999999) + ["eMax"]=> + int(999999999) + ["eMin"]=> + int(-999999999) + ["round"]=> + int(3) + ["clamp"]=> + bool(false) + } +} +bool(true) +DONE diff --git a/tests/Reader/Iterator.phpt b/tests/Reader/Iterator.phpt new file mode 100644 index 0000000..b2f851f --- /dev/null +++ b/tests/Reader/Iterator.phpt @@ -0,0 +1,23 @@ +--TEST-- +ion\Reader/Iterator +--EXTENSIONS-- +ion +--FILE-- +TEST +getDepth()) $r->getChildren(); // step in once + echo $r->getType()->name, "\n"; +} +?> +DONE +--EXPECT-- +TEST +List +Int +Int +Int +List +Int +DONE diff --git a/tests/Reader/RecursiveIterator.phpt b/tests/Reader/RecursiveIterator.phpt new file mode 100644 index 0000000..2e9dee0 --- /dev/null +++ b/tests/Reader/RecursiveIterator.phpt @@ -0,0 +1,22 @@ +--TEST-- +ion\Reader/RecursiveIterator +--EXTENSIONS-- +ion +--FILE-- +TEST +getDepth(), ":", $r->getType()->name, "\n"; +} +?> +DONE +--EXPECT-- +TEST +1:Int +1:Int +1:Int +2:Int +2:Int +1:Int +DONE diff --git a/tests/Reader/Stream.phpt b/tests/Reader/Stream.phpt index c856437..a7d6181 100644 --- a/tests/Reader/Stream.phpt +++ b/tests/Reader/Stream.phpt @@ -6,21 +6,56 @@ ion TEST next(); var_dump($r->readDecimal()); +var_dump($s === $r->getStream()); + +fseek($s, 2); +$r->resetStream($s); +var_dump($s === $r->getStream()); +$r->next(); +echo $r->getType()->name, "\n"; +var_dump($r->readDecimal()); + +fseek($s, 6); +$r->resetStreamWithLength($s, 3); +var_dump($s === $r->getStream()); +$r->next(); +echo $r->getType()->name, "\n"; +var_dump($r->readInt()); + ?> DONE --EXPECTF-- TEST -int(5) -object(ion\Decimal)#2 (2) { +object(ion\Decimal)#%d (2) { ["number"]=> int(123) ["context"]=> - object(ion\Decimal\Context)#3 (5) { + object(ion\Decimal\Context)#%d (5) { + ["digits"]=> + int(999999999) + ["eMax"]=> + int(999999999) + ["eMin"]=> + int(-999999999) + ["round"]=> + int(3) + ["clamp"]=> + bool(false) + } +} +bool(true) +bool(true) +Decimal +object(ion\Decimal)#%d (2) { + ["number"]=> + int(3) + ["context"]=> + object(ion\Decimal\Context)#%d (5) { ["digits"]=> int(999999999) ["eMax"]=> @@ -33,4 +68,7 @@ object(ion\Decimal)#2 (2) { bool(false) } } +bool(true) +Int +int(567) DONE diff --git a/tests/Reader/seek.phpt b/tests/Reader/seek.phpt new file mode 100644 index 0000000..1e5ef61 --- /dev/null +++ b/tests/Reader/seek.phpt @@ -0,0 +1,19 @@ +--TEST-- +ion\Reader/seek +--EXTENSIONS-- +ion +--FILE-- +TEST +seek(5,1); +$r->next(); +echo $r->getType()->name, "\n"; +echo $r->readInt(), "\n"; +?> +DONE +--EXPECT-- +TEST +Int +123 +DONE -- 2.30.2