tests++
authorMichael Wallner <mike@php.net>
Tue, 11 Jan 2022 12:36:38 +0000 (13:36 +0100)
committerMichael Wallner <mike@php.net>
Tue, 11 Jan 2022 12:36:38 +0000 (13:36 +0100)
ion.c
ion.stub.php
ion_arginfo.h
ion_private.h
tests/Reader.phpt [new file with mode: 0644]
tests/Reader/Buffer.phpt [new file with mode: 0644]
tests/Reader/Iterator.phpt [new file with mode: 0644]
tests/Reader/RecursiveIterator.phpt [new file with mode: 0644]
tests/Reader/Stream.phpt
tests/Reader/seek.phpt [new file with mode: 0644]

diff --git a/ion.c b/ion.c
index fe7a38e4b6f732649434ca153c17a3a19a0cf288..5712668a20b182523fe76d144f1c3ae647210142 100644 (file)
--- 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();
index fd9022499c660d71f1b7063ab6481b1ae7ae01c0..cc9f28892a8a9d40de6104a92099ef8e4c9f02b2 100644 (file)
@@ -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;
index 895bb87f70ebdabe7781dc065e17361cf3eda988..bfd758e5975d3b739a731f2d9dd6c5a01258d1f9 100644 (file)
@@ -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);
index 7233f464c4ec2b89b3b58068f4d519568782223e..b168f900ea3b3a2e8f9624ec91242bdd882d837e 100644 (file)
@@ -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 (file)
index 0000000..afe04c2
--- /dev/null
@@ -0,0 +1,143 @@
+--TEST--
+ion\Reader
+--EXTENSIONS--
+ion
+--INI--
+date.timezone=UTC
+--FILE--
+TEST
+<?php
+
+$tests = [
+       "getType" => [
+               ["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 (file)
index 0000000..549b733
--- /dev/null
@@ -0,0 +1,35 @@
+--TEST--
+ion\Reader\Buffer
+--EXTENSIONS--
+ion
+--FILE--
+TEST
+<?php
+$s = "123d0";
+$r = new ion\Reader\Buffer\Reader($s);
+$r->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 (file)
index 0000000..b2f851f
--- /dev/null
@@ -0,0 +1,23 @@
+--TEST--
+ion\Reader/Iterator
+--EXTENSIONS--
+ion
+--FILE--
+TEST
+<?php
+
+foreach (new ion\Reader\Buffer\Reader("[1,2,3,[4,5],6]") as $r) {
+       if (!$r->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 (file)
index 0000000..2e9dee0
--- /dev/null
@@ -0,0 +1,22 @@
+--TEST--
+ion\Reader/RecursiveIterator
+--EXTENSIONS--
+ion
+--FILE--
+TEST
+<?php
+
+foreach (new RecursiveIteratorIterator(new ion\Reader\Buffer\Reader("[1,2,3,[4,5],6]")) as $r) {
+       echo $r->getDepth(), ":", $r->getType()->name, "\n";
+}
+?>
+DONE
+--EXPECT--
+TEST
+1:Int
+1:Int
+1:Int
+2:Int
+2:Int
+1:Int
+DONE
index c8564378873a1de188f9fd457eb5666669490e54..a7d6181fd0a23f4d73ed35b7cede2046c2d3818f 100644 (file)
@@ -6,21 +6,56 @@ ion
 TEST
 <?php
 $s = fopen("php://memory", "r+");
-var_dump(fwrite($s, "123d0"));
+fwrite($s, "123d0 567 890");
 rewind($s);
 $r = new ion\Reader\Stream\Reader($s);
 $r->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 (file)
index 0000000..1e5ef61
--- /dev/null
@@ -0,0 +1,19 @@
+--TEST--
+ion\Reader/seek
+--EXTENSIONS--
+ion
+--FILE--
+TEST
+<?php
+$r = new ion\Reader\Buffer\Reader("{val:123}");
+$r->seek(5,1);
+$r->next();
+echo $r->getType()->name, "\n";
+echo $r->readInt(), "\n";
+?>
+DONE
+--EXPECT--
+TEST
+Int
+123
+DONE