From a848f933365d7cacf39dc7361c191945dfa00c5f Mon Sep 17 00:00:00 2001 From: "John R. D'Orazio" Date: Tue, 23 Apr 2024 21:24:34 +0200 Subject: [PATCH 1/4] add `lineIndex` and `lineString` properties to Node --- lib/Document.php | 4 ++-- lib/Parser/MimeDir.php | 2 +- lib/Property.php | 24 +++++++++++++++++++++++- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/lib/Document.php b/lib/Document.php index 6f87b5b9..02eaf13c 100644 --- a/lib/Document.php +++ b/lib/Document.php @@ -167,7 +167,7 @@ public function createComponent(string $name, ?array $children = null, bool $def * * @throws InvalidDataException */ - public function createProperty(string $name, $value = null, ?array $parameters = null, ?string $valueType = null): Property + public function createProperty(string $name, $value = null, ?array $parameters = null, ?string $valueType = null, ?int $lineIndex = null, ?string $lineString = null): Property { // If there's a . in the name, it means it's prefixed by a group name. if (false !== ($i = strpos($name, '.'))) { @@ -201,7 +201,7 @@ public function createProperty(string $name, $value = null, ?array $parameters = $parameters = []; } - return new $class($this, $name, $value, $parameters, $group); + return new $class($this, $name, $value, $parameters, $group, $lineIndex, $lineString); } /** diff --git a/lib/Parser/MimeDir.php b/lib/Parser/MimeDir.php index bbef0ea6..ddac9642 100644 --- a/lib/Parser/MimeDir.php +++ b/lib/Parser/MimeDir.php @@ -445,7 +445,7 @@ protected function readProperty(string $line) } } - $propObj = $this->root->createProperty($property['name'], null, $namedParameters); + $propObj = $this->root->createProperty($property['name'], null, $namedParameters, null, $this->startLine, $line); foreach ($namelessParameters as $namelessParameter) { $propObj->add(null, $namelessParameter); diff --git a/lib/Property.php b/lib/Property.php index 574099e6..407a1456 100644 --- a/lib/Property.php +++ b/lib/Property.php @@ -51,6 +51,20 @@ abstract class Property extends Node */ public string $delimiter = ';'; + /** + * The line number in the original iCalendar / vCard file + * that corresponds with the current node + * if the node was read from a file + */ + public ?int $lineIndex; + + /** + * The line string from the original iCalendar / vCard file + * that corresponds with the current node + * if the node was read from a file + */ + public ?string $lineString; + /** * Creates the generic property. * @@ -61,7 +75,7 @@ abstract class Property extends Node * @param array $parameters List of parameters * @param string|null $group The vcard property group */ - public function __construct(Component $root, ?string $name, $value = null, array $parameters = [], ?string $group = null) + public function __construct(Component $root, ?string $name, $value = null, array $parameters = [], ?string $group = null, ?int $lineIndex = null, ?string $lineString = null) { $this->name = $name; $this->group = $group; @@ -75,6 +89,14 @@ public function __construct(Component $root, ?string $name, $value = null, array if (!is_null($value)) { $this->setValue($value); } + + if (!is_null($lineIndex)) { + $this->lineIndex = $lineIndex; + } + + if (!is_null($lineString)) { + $this->lineString = $lineString; + } } /** From 800aac9bb2b0db500840a9cd2992787679070c14 Mon Sep 17 00:00:00 2001 From: "John R. D'Orazio" Date: Thu, 25 Apr 2024 23:26:41 +0200 Subject: [PATCH 2/4] creat Unit Test --- tests/VObject/Component/VCalendarTest.php | 43 +++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/tests/VObject/Component/VCalendarTest.php b/tests/VObject/Component/VCalendarTest.php index bde6a4fa..ad19b5eb 100644 --- a/tests/VObject/Component/VCalendarTest.php +++ b/tests/VObject/Component/VCalendarTest.php @@ -756,6 +756,49 @@ public function testCalDAVMETHOD(): void ); } + public function testNodeInValidationErrorHasLineIndexAndLineStringProps(): void + { + $defectiveInput = <<validate(); + $warningMessages = []; + foreach( $result as $error ) { + $warningMessages[] = $error['message']; + } + self::assertCount(2, $result, 'We expected exactly 2 validation messages, instead we got ' . count( $result ) . ' results:' . implode(', ', $warningMessages) ); + foreach( $result as $idx => $warning ) { + self::assertArrayHasKey( 'node', $warning, 'The validation errors should contain a node key' ); + self::assertInstanceOf( VObject\Property\ICalendar\DateTime::class, $warning[ 'node' ], 'We expected the defective node to be of type Sabre\VObject\Property\ICalendar\DateTime, instead we got type ' . gettype( $warning['node'] ) ); + self::assertObjectHasProperty( 'lineIndex', $warning['node'], 'We expected the defective node in the validation errors array to have a "lineIndex" property' ); + self::assertObjectHasProperty( 'lineString', $warning['node'], 'We expected the defective node in the validation errors array to have a "lineString" property' ); + switch( $idx ) { + case 0: + self::assertEquals( '10', $warning['node']->lineIndex, 'We expected the "lineIndex" property of the first defective node to be 10, instead it was ' . $warning['node']->lineIndex ); + self::assertEquals( 'CREATED:', $warning['node']->lineString, 'We expected the "lineString" property of the first defective node to be "CREATED:", instead it was ' . $warning['node']->lineString ); + break; + case 1: + self::assertEquals( '11', $warning['node']->lineIndex, 'We expected the "lineIndex" property of the second defective node to be 11, instead it was ' . $warning['node']->lineIndex ); + self::assertEquals( 'LAST-MODIFIED:', $warning['node']->lineString, 'We expected the "lineString" property of the second defective node to be "LAST-MODIFIED:", instead it was ' . $warning['node']->lineString ); + break; + } + } + } + public function assertValidate($ics, $options, $expectedLevel, ?string $expectedMessage = null): void { $vcal = VObject\Reader::read($ics); From 9192bfed3de83108d8abbf7da38e30d7e7032617 Mon Sep 17 00:00:00 2001 From: John D'Orazio Date: Wed, 8 May 2024 12:28:35 +0200 Subject: [PATCH 3/4] php-cs-fixer --- lib/Property.php | 4 ++-- tests/VObject/Component/VCalendarTest.php | 24 +++++++++++------------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/lib/Property.php b/lib/Property.php index 407a1456..f4d0bdc0 100644 --- a/lib/Property.php +++ b/lib/Property.php @@ -54,14 +54,14 @@ abstract class Property extends Node /** * The line number in the original iCalendar / vCard file * that corresponds with the current node - * if the node was read from a file + * if the node was read from a file. */ public ?int $lineIndex; /** * The line string from the original iCalendar / vCard file * that corresponds with the current node - * if the node was read from a file + * if the node was read from a file. */ public ?string $lineString; diff --git a/tests/VObject/Component/VCalendarTest.php b/tests/VObject/Component/VCalendarTest.php index ad19b5eb..67dc2fe8 100644 --- a/tests/VObject/Component/VCalendarTest.php +++ b/tests/VObject/Component/VCalendarTest.php @@ -777,23 +777,23 @@ public function testNodeInValidationErrorHasLineIndexAndLineStringProps(): void $vcal = VObject\Reader::read($defectiveInput); $result = $vcal->validate(); $warningMessages = []; - foreach( $result as $error ) { + foreach ($result as $error) { $warningMessages[] = $error['message']; } - self::assertCount(2, $result, 'We expected exactly 2 validation messages, instead we got ' . count( $result ) . ' results:' . implode(', ', $warningMessages) ); - foreach( $result as $idx => $warning ) { - self::assertArrayHasKey( 'node', $warning, 'The validation errors should contain a node key' ); - self::assertInstanceOf( VObject\Property\ICalendar\DateTime::class, $warning[ 'node' ], 'We expected the defective node to be of type Sabre\VObject\Property\ICalendar\DateTime, instead we got type ' . gettype( $warning['node'] ) ); - self::assertObjectHasProperty( 'lineIndex', $warning['node'], 'We expected the defective node in the validation errors array to have a "lineIndex" property' ); - self::assertObjectHasProperty( 'lineString', $warning['node'], 'We expected the defective node in the validation errors array to have a "lineString" property' ); - switch( $idx ) { + self::assertCount(2, $result, 'We expected exactly 2 validation messages, instead we got '.count($result).' results:'.implode(', ', $warningMessages)); + foreach ($result as $idx => $warning) { + self::assertArrayHasKey('node', $warning, 'The validation errors should contain a node key'); + self::assertInstanceOf(VObject\Property\ICalendar\DateTime::class, $warning['node'], 'We expected the defective node to be of type Sabre\VObject\Property\ICalendar\DateTime, instead we got type '.gettype($warning['node'])); + self::assertObjectHasProperty('lineIndex', $warning['node'], 'We expected the defective node in the validation errors array to have a "lineIndex" property'); + self::assertObjectHasProperty('lineString', $warning['node'], 'We expected the defective node in the validation errors array to have a "lineString" property'); + switch ($idx) { case 0: - self::assertEquals( '10', $warning['node']->lineIndex, 'We expected the "lineIndex" property of the first defective node to be 10, instead it was ' . $warning['node']->lineIndex ); - self::assertEquals( 'CREATED:', $warning['node']->lineString, 'We expected the "lineString" property of the first defective node to be "CREATED:", instead it was ' . $warning['node']->lineString ); + self::assertEquals('10', $warning['node']->lineIndex, 'We expected the "lineIndex" property of the first defective node to be 10, instead it was '.$warning['node']->lineIndex); + self::assertEquals('CREATED:', $warning['node']->lineString, 'We expected the "lineString" property of the first defective node to be "CREATED:", instead it was '.$warning['node']->lineString); break; case 1: - self::assertEquals( '11', $warning['node']->lineIndex, 'We expected the "lineIndex" property of the second defective node to be 11, instead it was ' . $warning['node']->lineIndex ); - self::assertEquals( 'LAST-MODIFIED:', $warning['node']->lineString, 'We expected the "lineString" property of the second defective node to be "LAST-MODIFIED:", instead it was ' . $warning['node']->lineString ); + self::assertEquals('11', $warning['node']->lineIndex, 'We expected the "lineIndex" property of the second defective node to be 11, instead it was '.$warning['node']->lineIndex); + self::assertEquals('LAST-MODIFIED:', $warning['node']->lineString, 'We expected the "lineString" property of the second defective node to be "LAST-MODIFIED:", instead it was '.$warning['node']->lineString); break; } } From ec31757d19813993419dc9a98314c0c5d12f3e1e Mon Sep 17 00:00:00 2001 From: John D'Orazio Date: Wed, 8 May 2024 14:51:44 +0200 Subject: [PATCH 4/4] remove unnecessary error descriptions --- tests/VObject/Component/VCalendarTest.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/VObject/Component/VCalendarTest.php b/tests/VObject/Component/VCalendarTest.php index 67dc2fe8..847e17d0 100644 --- a/tests/VObject/Component/VCalendarTest.php +++ b/tests/VObject/Component/VCalendarTest.php @@ -782,18 +782,18 @@ public function testNodeInValidationErrorHasLineIndexAndLineStringProps(): void } self::assertCount(2, $result, 'We expected exactly 2 validation messages, instead we got '.count($result).' results:'.implode(', ', $warningMessages)); foreach ($result as $idx => $warning) { - self::assertArrayHasKey('node', $warning, 'The validation errors should contain a node key'); - self::assertInstanceOf(VObject\Property\ICalendar\DateTime::class, $warning['node'], 'We expected the defective node to be of type Sabre\VObject\Property\ICalendar\DateTime, instead we got type '.gettype($warning['node'])); - self::assertObjectHasProperty('lineIndex', $warning['node'], 'We expected the defective node in the validation errors array to have a "lineIndex" property'); - self::assertObjectHasProperty('lineString', $warning['node'], 'We expected the defective node in the validation errors array to have a "lineString" property'); + self::assertArrayHasKey('node', $warning); + self::assertInstanceOf(VObject\Property\ICalendar\DateTime::class, $warning['node']); + self::assertObjectHasProperty('lineIndex', $warning['node']); + self::assertObjectHasProperty('lineString', $warning['node']); switch ($idx) { case 0: - self::assertEquals('10', $warning['node']->lineIndex, 'We expected the "lineIndex" property of the first defective node to be 10, instead it was '.$warning['node']->lineIndex); - self::assertEquals('CREATED:', $warning['node']->lineString, 'We expected the "lineString" property of the first defective node to be "CREATED:", instead it was '.$warning['node']->lineString); + self::assertEquals('10', $warning['node']->lineIndex); + self::assertEquals('CREATED:', $warning['node']->lineString); break; case 1: - self::assertEquals('11', $warning['node']->lineIndex, 'We expected the "lineIndex" property of the second defective node to be 11, instead it was '.$warning['node']->lineIndex); - self::assertEquals('LAST-MODIFIED:', $warning['node']->lineString, 'We expected the "lineString" property of the second defective node to be "LAST-MODIFIED:", instead it was '.$warning['node']->lineString); + self::assertEquals('11', $warning['node']->lineIndex); + self::assertEquals('LAST-MODIFIED:', $warning['node']->lineString); break; } }