From fd04b2b256fbdc7da8cf1334bb48c58f770d3347 Mon Sep 17 00:00:00 2001 From: Wilmer Arambula Date: Mon, 18 Aug 2025 16:02:04 -0400 Subject: [PATCH 01/11] feat(tests): Add `TestSupport` trait and corresponding test suite for inaccessible properties and methods. --- README.md | 29 ++++++++- composer.json | 12 ++-- src/{Assert.php => TestSupport.php} | 59 ++++++++----------- tests/{AssertTest.php => TestSupportTest.php} | 51 ++++++++-------- 4 files changed, 86 insertions(+), 65 deletions(-) rename src/{Assert.php => TestSupport.php} (83%) rename tests/{AssertTest.php => TestSupportTest.php} (76%) diff --git a/README.md b/README.md index 12e2718..ab71c6b 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ - Invoke inaccessible methods to expand testing coverage. ✅ **Cross-Platform String Assertions** -- Eliminate false positives/negatives caused by Windows vs. Unix line-ending differences. +- Eliminate false positives/negatives caused by windows vs. unix line ending differences. - Normalize line endings for consistent string comparisons across platforms. ✅ **File System Test Management** @@ -73,6 +73,33 @@ composer update ## Basic Usage +### Using TestSupport trait + +```php +inaccessibleProperty($object, 'secretValue'); + + self::assertSame('hidden', $value); + } +} +``` + ### Accessing private properties ```php diff --git a/composer.json b/composer.json index bb1cb90..7900ca4 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "php-forge/support", "type": "library", - "description": "Support library tests for PHP", + "description": "Support utilities for enhanced testing capabilities.", "keywords": [ "php", "php-forge", @@ -11,16 +11,16 @@ ], "license": "BSD-3-Clause", "require": { - "php": "^8.1", - "phpunit/phpunit": "^10.5" + "php": "^8.1" }, "require-dev": { "infection/infection": "^0.27|^0.31", "maglnet/composer-require-checker": "^4.7", - "phpstan/phpstan-strict-rules": "^2.0.3", - "symplify/easy-coding-standard": "^12.5", "phpstan/phpstan": "^2.1", - "rector/rector": "^2.1" + "phpstan/phpstan-strict-rules": "^2.0.3", + "phpunit/phpunit": "^10.5", + "rector/rector": "^2.1", + "symplify/easy-coding-standard": "^12.5" }, "autoload": { "psr-4": { diff --git a/src/Assert.php b/src/TestSupport.php similarity index 83% rename from src/Assert.php rename to src/TestSupport.php index b5ada78..9e54d25 100644 --- a/src/Assert.php +++ b/src/TestSupport.php @@ -20,46 +20,20 @@ use function unlink; /** - * Assertion utility class for advanced test introspection and manipulation. + * Trait providing utilities for testing inaccessible properties, methods, and filesystem cleanup. * - * Provides static helper methods for accessing and modifying inaccessible properties and methods invoking parent class - * logic, and performing file system cleanup in test environments. + * Supplies static helper methods for normalizing line endings, accessing or modifying private/protected properties and + * methods (including those inherited from parent classes), invoking inaccessible methods, and recursively removing + * files from directories. * - * Extends {@see \PHPUnit\Framework\Assert} to offer additional capabilities for testing private/protected members and - * for managing test artifacts, supporting robust and isolated unit tests. + * These utilities are designed to facilitate comprehensive unit testing by enabling assertions and manipulations that + * would otherwise be restricted by visibility constraints or platform differences. * - * Key features. - * - Access and modify inaccessible (private/protected) properties and methods via reflection. - * - Invoke parent class methods and properties for testing inheritance scenarios. - * - Normalize line endings for cross-platform string assertions. - * - Remove files and directories recursively for test environment cleanup. - * - * @copyright Copyright (C) 2025 PHPForge. + * @copyright Copyright (C) 2025 Terabytesoftw. * @license https://opensource.org/license/bsd-3-clause BSD 3-Clause License. */ -final class Assert extends \PHPUnit\Framework\Assert +trait TestSupport { - /** - * Asserts that two strings are equal after normalizing line endings to unix style ('\n'). - * - * Replaces all windows style ('\r\n') line endings with unix style ('\n') in both the expected and actual strings - * before performing the equality assertion. - * - * This ensures cross-platform consistency in string comparisons where line ending differences may otherwise cause - * `false` negatives. - * - * @param string $expected Expected string value, with any line endings. - * @param string $actual Actual string value, with any line endings. - * @param string $message Optional failure message to display if the assertion fails. Default is an empty string. - */ - public static function equalsWithoutLE(string $expected, string $actual, string $message = ''): void - { - $expected = str_replace("\r\n", "\n", $expected); - $actual = str_replace("\r\n", "\n", $actual); - - self::assertEquals($expected, $actual, $message); - } - /** * Retrieves the value of an inaccessible property from a parent class instance. * @@ -185,6 +159,23 @@ public static function invokeParentMethod( return $result ?? null; } + /** + * Normalizes line endings to unix style ('\n') for cross-platform string assertions. + * + * Converts windows style ('\r\n') line endings to unix style ('\n') to ensure consistent string comparisons across + * different operating systems during testing. + * + * This method is useful for eliminating false negatives in assertions caused by platform-specific line endings. + * + * @param string $line Input string potentially containing windows style line endings. + * + * @return string String with normalized unix style line endings. + */ + public static function normalizeLineEndings(string $line): string + { + return str_replace("\r\n", "\n", $line); + } + /** * Removes all files and directories recursively from the specified base path, excluding '.gitignore' and * '.gitkeep'. diff --git a/tests/AssertTest.php b/tests/TestSupportTest.php similarity index 76% rename from tests/AssertTest.php rename to tests/TestSupportTest.php index 7e90880..5f6733b 100644 --- a/tests/AssertTest.php +++ b/tests/TestSupportTest.php @@ -4,41 +4,35 @@ namespace PHPForge\Support\Tests; -use PHPForge\Support\Assert; use PHPForge\Support\Tests\Stub\{TestBaseClass, TestClass}; +use PHPForge\Support\TestSupport; use PHPUnit\Framework\TestCase; use ReflectionException; use RuntimeException; /** - * Test suite for {@see Assert} utility methods and reflection helpers. + * Test suite for {@see TestSupport} trait utility methods. * - * Verifies the behavior of assertion and reflection-based utility methods for testing inaccessible properties, parent - * properties, and methods, as well as file system operations for test directories. + * Verifies the behavior of utility methods provided by the {@see TestSupport} trait for testing inaccessible + * properties, parent properties, and methods, as well as file system operations for test directories. * * These tests ensure correct access and mutation of private/protected members, invocation of inaccessible methods, and * robust file removal logic, including error handling for non-existent directories. * - * Test coverage. + * Test coverage: * - Accessing and asserting values of inaccessible properties and parent properties. * - Ensuring correct exception handling for invalid operations. * - Invoking inaccessible methods and parent methods. + * - Normalizing line endings. * - Removing files from directories and handling missing directories. * - Setting values for inaccessible properties and parent properties. * * @copyright Copyright (C) 2025 Terabytesoftw. * @license https://opensource.org/license/bsd-3-clause BSD 3-Clause License. */ -final class AssertTest extends TestCase +final class TestSupportTest extends TestCase { - public function testEqualsWithoutLEReturnsTrueWhenStringsAreIdenticalWithLineEndings(): void - { - Assert::equalsWithoutLE( - "foo\r\nbar", - "foo\r\nbar", - "Should return 'true' when both strings are identical including line endings.", - ); - } + use TestSupport; /** * @throws ReflectionException @@ -47,7 +41,7 @@ public function testInaccessibleParentPropertyReturnsExpectedValue(): void { self::assertSame( 'valueParent', - Assert::inaccessibleParentProperty( + self::inaccessibleParentProperty( new TestClass(), TestBaseClass::class, 'propertyParent', @@ -56,6 +50,15 @@ public function testInaccessibleParentPropertyReturnsExpectedValue(): void ); } + public function testNormalizeLineEndingsWhenStringsAreIdenticalWithLineEndings(): void + { + self::assertSame( + self::normalizeLineEndings("foo\r\nbar"), + self::normalizeLineEndings("foo\r\nbar"), + "Should return 'true' when both strings are identical including line endings.", + ); + } + public function testRemoveFilesFromDirectoryRemovesAllFiles(): void { $dir = dirname(__DIR__) . '/runtime'; @@ -64,7 +67,7 @@ public function testRemoveFilesFromDirectoryRemovesAllFiles(): void touch("{$dir}/test.txt"); touch("{$dir}/subdir/test.txt"); - Assert::removeFilesFromDirectory($dir); + self::removeFilesFromDirectory($dir); $this->assertFileDoesNotExist( "{$dir}/test.txt", @@ -83,7 +86,7 @@ public function testReturnInaccessiblePropertyValueWhenPropertyIsPrivate(): void { self::assertSame( 'value', - Assert::inaccessibleProperty(new TestClass(), 'property'), + self::inaccessibleProperty(new TestClass(), 'property'), "Should return the value of the private property 'property' when accessed via reflection.", ); } @@ -95,7 +98,7 @@ public function testReturnValueWhenInvokingInaccessibleMethod(): void { $this->assertSame( 'value', - Assert::invokeMethod(new TestClass(), 'inaccessibleMethod'), + self::invokeMethod(new TestClass(), 'inaccessibleMethod'), "Should return 'value' when invoking the inaccessible method 'inaccessibleParentMethod' on 'TestClass' " . 'via reflection.', ); @@ -108,7 +111,7 @@ public function testReturnValueWhenInvokingInaccessibleParentMethod(): void { $this->assertSame( 'valueParent', - Assert::invokeParentMethod( + self::invokeParentMethod( new TestClass(), TestBaseClass::class, 'inaccessibleParentMethod', @@ -125,11 +128,11 @@ public function testSetInaccessibleParentProperty(): void { $object = new TestClass(); - Assert::setInaccessibleParentProperty($object, TestBaseClass::class, 'propertyParent', 'foo'); + self::setInaccessibleParentProperty($object, TestBaseClass::class, 'propertyParent', 'foo'); $this->assertSame( 'foo', - Assert::inaccessibleParentProperty($object, TestBaseClass::class, 'propertyParent'), + self::inaccessibleParentProperty($object, TestBaseClass::class, 'propertyParent'), "Should return 'foo' after setting the parent property 'propertyParent' via " . "'setInaccessibleParentProperty' method.", ); @@ -142,11 +145,11 @@ public function testSetInaccessiblePropertySetsValueCorrectly(): void { $object = new TestClass(); - Assert::setInaccessibleProperty($object, 'property', 'foo'); + self::setInaccessibleProperty($object, 'property', 'foo'); $this->assertSame( 'foo', - Assert::inaccessibleProperty($object, 'property'), + self::inaccessibleProperty($object, 'property'), "Should return 'foo' after setting the private property 'property' via 'setInaccessibleProperty' method.", ); } @@ -156,6 +159,6 @@ public function testThrowRuntimeExceptionWhenRemoveFilesFromDirectoryNonExisting $this->expectException(RuntimeException::class); $this->expectExceptionMessage('Unable to open directory: non-existing-directory'); - Assert::removeFilesFromDirectory(__DIR__ . '/non-existing-directory'); + self::removeFilesFromDirectory(__DIR__ . '/non-existing-directory'); } } From 7b4b129a7f70fb5d356fa0d774862c84b9cbfcc0 Mon Sep 17 00:00:00 2001 From: Wilmer Arambula Date: Mon, 18 Aug 2025 16:09:33 -0400 Subject: [PATCH 02/11] chore: Update version in `composer.json` to `0.3.x-dev` and README for installation instructions. --- README.md | 32 +++++++++++--------------------- composer.json | 2 +- 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index ab71c6b..0cfdfa0 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ Install the extension. ```bash -composer require --dev --prefer-dist php-forge/support:^0.1 +composer require --dev --prefer-dist php-forge/support:^0.2 ``` #### Method 2: Manual installation @@ -60,7 +60,7 @@ Add to your `composer.json`. ```json { "require-dev": { - "php-forge/support": "^0.1" + "php-forge/support": "^0.2" } } ``` @@ -93,7 +93,7 @@ final class MyTest extends TestCase private string $secretValue = 'hidden'; }; - $value = $this->inaccessibleProperty($object, 'secretValue'); + $value = self::inaccessibleProperty($object, 'secretValue'); self::assertSame('hidden', $value); } @@ -107,14 +107,12 @@ final class MyTest extends TestCase declare(strict_types=1); -use PHPForge\Support\Assert; - $object = new class () { private string $secretValue = 'hidden'; }; // access private properties for testing -$value = Assert::inaccessibleProperty($object, 'secretValue'); +$value = self::inaccessibleProperty($object, 'secretValue'); self::assertSame('hidden', $value); ``` @@ -126,12 +124,10 @@ self::assertSame('hidden', $value); declare(strict_types=1); -use PHPForge\Support\Assert; - // normalize line endings for consistent comparisons -Assert::equalsWithoutLE( - "Foo\r\nBar", - "Foo\nBar", +self::assertSame( + self::normalizeLineEndings("Foo\r\nBar"), + self::normalizeLineEndings("Foo\nBar"), "Should match regardless of line ending style" ); ``` @@ -143,8 +139,6 @@ Assert::equalsWithoutLE( declare(strict_types=1); -use PHPForge\Support\Assert; - $object = new class () { protected function calculate(int $a, int $b): int { @@ -153,7 +147,7 @@ $object = new class () { }; // test protected method behavior -$result = Assert::invokeMethod($object, 'calculate', [5, 3]); +$result = self::invokeMethod($object, 'calculate', [5, 3]); self::assertSame(8, $result); ``` @@ -165,12 +159,10 @@ self::assertSame(8, $result); declare(strict_types=1); -use PHPForge\Support\Assert; - $testDir = dirname(__DIR__) . '/runtime'; // clean up test artifacts (preserves '.gitignore' and '.gitkeep') -Assert::removeFilesFromDirectory($testDir); +self::removeFilesFromDirectory($testDir); ``` ### Set inaccessible property @@ -180,16 +172,14 @@ Assert::removeFilesFromDirectory($testDir); declare(strict_types=1); -use PHPForge\Support\Assert; - $object = new class () { private string $config = 'default'; }; // set private property for testing scenarios -Assert::setInaccessibleProperty($object, 'config', 'test-mode'); +self::setInaccessibleProperty($object, 'config', 'test-mode'); -$newValue = Assert::inaccessibleProperty($object, 'config'); +$newValue = self::inaccessibleProperty($object, 'config'); self::assertSame('test-mode', $newValue); ``` diff --git a/composer.json b/composer.json index 7900ca4..9c8063d 100644 --- a/composer.json +++ b/composer.json @@ -34,7 +34,7 @@ }, "extra": { "branch-alias": { - "dev-main": "0.1-dev" + "dev-main": "0.3.x-dev" } }, "config": { From aeb0902236e9727573070e59380c7499707ae065 Mon Sep 17 00:00:00 2001 From: Wilmer Arambula Date: Mon, 18 Aug 2025 16:13:29 -0400 Subject: [PATCH 03/11] Apply fixed review coderabbitai nitpick comments. --- tests/TestSupportTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/TestSupportTest.php b/tests/TestSupportTest.php index 5f6733b..6e29d36 100644 --- a/tests/TestSupportTest.php +++ b/tests/TestSupportTest.php @@ -54,8 +54,8 @@ public function testNormalizeLineEndingsWhenStringsAreIdenticalWithLineEndings() { self::assertSame( self::normalizeLineEndings("foo\r\nbar"), - self::normalizeLineEndings("foo\r\nbar"), - "Should return 'true' when both strings are identical including line endings.", + self::normalizeLineEndings("foo\nbar"), + "Should produce the same normalized string for CRLF and LF inputs.", ); } From d90df75d58221e9f525b2a41c50f185c8b2cc693 Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Mon, 18 Aug 2025 20:13:55 +0000 Subject: [PATCH 04/11] Apply fixes from StyleCI --- tests/TestSupportTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/TestSupportTest.php b/tests/TestSupportTest.php index 6e29d36..45276e0 100644 --- a/tests/TestSupportTest.php +++ b/tests/TestSupportTest.php @@ -55,7 +55,7 @@ public function testNormalizeLineEndingsWhenStringsAreIdenticalWithLineEndings() self::assertSame( self::normalizeLineEndings("foo\r\nbar"), self::normalizeLineEndings("foo\nbar"), - "Should produce the same normalized string for CRLF and LF inputs.", + 'Should produce the same normalized string for CRLF and LF inputs.', ); } From a4d9d4e019c5b1b27a1cc75fd52e93f790c05f29 Mon Sep 17 00:00:00 2001 From: Wilmer Arambula Date: Mon, 18 Aug 2025 16:14:56 -0400 Subject: [PATCH 05/11] fix(tests): Update assertion message for line ending normalization test. --- tests/TestSupportTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/TestSupportTest.php b/tests/TestSupportTest.php index 45276e0..5fd41d5 100644 --- a/tests/TestSupportTest.php +++ b/tests/TestSupportTest.php @@ -55,7 +55,7 @@ public function testNormalizeLineEndingsWhenStringsAreIdenticalWithLineEndings() self::assertSame( self::normalizeLineEndings("foo\r\nbar"), self::normalizeLineEndings("foo\nbar"), - 'Should produce the same normalized string for CRLF and LF inputs.', + "Should produce the same normalized string for 'CRLF' and 'LF' inputs.", ); } From a1c96d1155909363efa2c4403c1a8593d6520865 Mon Sep 17 00:00:00 2001 From: Wilmer Arambula Date: Mon, 18 Aug 2025 16:50:37 -0400 Subject: [PATCH 06/11] refactor(tests): Improve test class names and assertion messages for clarity. --- CHANGELOG.md | 3 +- README.md | 120 ++++++++++++++++++++++++++++++--------------------- 2 files changed, 73 insertions(+), 50 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5222d47..495ba0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,10 @@ Change Log ========== -## 0.1.1 August 18, 2025 +## 0.2.0 August 18, 2025 - Bug #11: Refactor project structure and update dependencies (@terabytesoftw) +- Enh #12: Add `TestSupport` trait and corresponding test suite for inaccessible properties and methods (@terabytesoftw) ## 0.1.0 January 21, 2024 diff --git a/README.md b/README.md index 0cfdfa0..6b88b71 100644 --- a/README.md +++ b/README.md @@ -73,21 +73,20 @@ composer update ## Basic Usage -### Using TestSupport trait +### Accessing private properties ```php Date: Mon, 18 Aug 2025 16:53:21 -0400 Subject: [PATCH 07/11] fix: Correct capitalization of "Windows" and "Unix" in documentation for consistency. --- README.md | 2 +- src/TestSupport.php | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 6b88b71..4c8cb54 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ - Invoke inaccessible methods to expand testing coverage. ✅ **Cross-Platform String Assertions** -- Eliminate false positives/negatives caused by windows vs. unix line ending differences. +- Eliminate false positives/negatives caused by Windows vs. Unix line ending differences. - Normalize line endings for consistent string comparisons across platforms. ✅ **File System Test Management** diff --git a/src/TestSupport.php b/src/TestSupport.php index 9e54d25..f8b66ed 100644 --- a/src/TestSupport.php +++ b/src/TestSupport.php @@ -160,16 +160,16 @@ public static function invokeParentMethod( } /** - * Normalizes line endings to unix style ('\n') for cross-platform string assertions. + * Normalizes line endings to Unix style ('\n') for cross-platform string assertions. * - * Converts windows style ('\r\n') line endings to unix style ('\n') to ensure consistent string comparisons across + * Converts Windows style ('\r\n') line endings to Unix style ('\n') to ensure consistent string comparisons across * different operating systems during testing. * * This method is useful for eliminating false negatives in assertions caused by platform-specific line endings. * - * @param string $line Input string potentially containing windows style line endings. + * @param string $line Input string potentially containing Windows style line endings. * - * @return string String with normalized unix style line endings. + * @return string String with normalized Unix style line endings. */ public static function normalizeLineEndings(string $line): string { From 37938967acb11bee4f5bd038aec815e926433990 Mon Sep 17 00:00:00 2001 From: Wilmer Arambula Date: Mon, 18 Aug 2025 16:57:37 -0400 Subject: [PATCH 08/11] Apply fixed review coderabbitai nitpick comments. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4c8cb54..33e3dbc 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,7 @@ final class AccessPrivatePropertyTest extends TestCase { use TestSupport; - public function testInaccesibleProperty():void + public function testInaccessibleProperty(): void { $object = new class () { private string $secretValue = 'hidden'; @@ -201,7 +201,7 @@ final class SetInaccessiblePropertyTest extends TestCase $newValue = self::inaccessibleProperty($object, 'config'); - self::assertSame('test-mode', $newValue, "Should set the inaccessible property to 'test-mode'."); + self::assertSame('test-mode', $newValue, "Should set the inaccessible property to 'test-mode'."); } } ``` From 06dcb1deb95f7ecafa6a003f41c87e78b805b1c3 Mon Sep 17 00:00:00 2001 From: Wilmer Arambula Date: Mon, 18 Aug 2025 17:05:49 -0400 Subject: [PATCH 09/11] Apply fixed review coderabbitai nitpick comments. --- src/TestSupport.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TestSupport.php b/src/TestSupport.php index f8b66ed..567c9b2 100644 --- a/src/TestSupport.php +++ b/src/TestSupport.php @@ -173,7 +173,7 @@ public static function invokeParentMethod( */ public static function normalizeLineEndings(string $line): string { - return str_replace("\r\n", "\n", $line); + return str_replace(["\r\n", "\r"], "\n", $line); } /** From c702bf808003e4affd4c93f3fee6e0f5ecab8732 Mon Sep 17 00:00:00 2001 From: Wilmer Arambula Date: Mon, 18 Aug 2025 17:15:09 -0400 Subject: [PATCH 10/11] fix: Improve wording for clarity in `README.md` and add return type to test method. --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 33e3dbc..fa37ce7 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ - Invoke inaccessible methods to expand testing coverage. ✅ **Cross-Platform String Assertions** -- Eliminate false positives/negatives caused by Windows vs. Unix line ending differences. +- Avoid false positives and negatives caused by Windows vs Unix line-ending differences. - Normalize line endings for consistent string comparisons across platforms. ✅ **File System Test Management** @@ -190,7 +190,7 @@ final class SetInaccessiblePropertyTest extends TestCase { use TestSupport; - public function testSetProperty() + public function testSetProperty(): void { $object = new class () { private string $config = 'default'; @@ -201,7 +201,7 @@ final class SetInaccessiblePropertyTest extends TestCase $newValue = self::inaccessibleProperty($object, 'config'); - self::assertSame('test-mode', $newValue, "Should set the inaccessible property to 'test-mode'."); + self::assertSame('test-mode', $newValue, "Should set the inaccessible property to 'test-mode'."); } } ``` From 741bab0223940b42362d88275b05fbdbae8c76c4 Mon Sep 17 00:00:00 2001 From: Wilmer Arambula Date: Mon, 18 Aug 2025 17:33:57 -0400 Subject: [PATCH 11/11] Apply fixed review coderabbitai nitpick comments. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fa37ce7..7a2e317 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ - Invoke inaccessible methods to expand testing coverage. ✅ **Cross-Platform String Assertions** -- Avoid false positives and negatives caused by Windows vs Unix line-ending differences. +- Avoid false positives and negatives caused by Windows vs. Unix line ending differences. - Normalize line endings for consistent string comparisons across platforms. ✅ **File System Test Management**