Created
July 23, 2026 07:15
-
-
Save sevein/312c983195e64fd4a13c2cffd3e7682d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| use PHPUnit\Framework\TestCase; | |
| require_once 'plugins/sfIsadPlugin/lib/sfIsadPlugin.class.php'; | |
| /** | |
| * Exercise every create, update, delete, and no-op path in the | |
| * languageNotes setter. | |
| * | |
| * @covers \sfIsadPlugin::__set | |
| * | |
| * @internal | |
| */ | |
| class sfIsadPluginTest extends TestCase | |
| { | |
| /** | |
| * Each row describes the starting notes, submitted value, and expected | |
| * state after the setter runs. | |
| */ | |
| private const SET_LANGUAGE_NOTES_CASES = [ | |
| 'leave missing note empty' => [ | |
| 'initialContents' => [], | |
| 'value' => '', | |
| 'expectedDeleteCalls' => 0, | |
| 'expectedContents' => [], | |
| ], | |
| 'create missing note' => [ | |
| 'initialContents' => [], | |
| 'value' => 'New note', | |
| 'expectedDeleteCalls' => 0, | |
| 'expectedContents' => ['New note'], | |
| ], | |
| 'delete existing note' => [ | |
| 'initialContents' => ['Existing note'], | |
| 'value' => '', | |
| 'expectedDeleteCalls' => 1, | |
| 'expectedContents' => ['Existing note'], | |
| ], | |
| 'update existing note' => [ | |
| 'initialContents' => ['Existing note'], | |
| 'value' => 'Updated note', | |
| 'expectedDeleteCalls' => 0, | |
| 'expectedContents' => ['Updated note'], | |
| ], | |
| ]; | |
| /** | |
| * @dataProvider setLanguageNotesProvider | |
| * | |
| * @param string[] $initialContents Contents of notes present before the setter runs | |
| * @param string[] $expectedContents Contents expected after the setter runs | |
| */ | |
| public function testSetLanguageNotes( | |
| array $initialContents, | |
| string $value, | |
| int $expectedDeleteCalls, | |
| array $expectedContents | |
| ): void { | |
| $notes = array_map(static function (string $content): sfIsadPluginTestNote { | |
| $note = new sfIsadPluginTestNote(); | |
| $note->typeId = QubitTerm::LANGUAGE_NOTE_ID; | |
| $note->content = $content; | |
| return $note; | |
| }, $initialContents); | |
| $resource = new sfIsadPluginTestResource($notes); | |
| $plugin = new sfIsadPlugin($resource); | |
| $plugin->languageNotes = $value; | |
| $actualNotes = iterator_to_array($resource->notes); | |
| $actualContents = array_map( | |
| static fn (QubitNote $note): string => $note->content, | |
| $actualNotes | |
| ); | |
| $actualTypeIds = array_map( | |
| static fn (QubitNote $note): int => $note->typeId, | |
| $actualNotes | |
| ); | |
| $actualDeleteCalls = array_sum(array_map( | |
| static fn (sfIsadPluginTestNote $note): int => $note->deleteCalls, | |
| $notes | |
| )); | |
| $this->assertSame($expectedContents, $actualContents); | |
| $this->assertSame( | |
| array_fill(0, count($expectedContents), QubitTerm::LANGUAGE_NOTE_ID), | |
| $actualTypeIds | |
| ); | |
| $this->assertSame($expectedDeleteCalls, $actualDeleteCalls); | |
| } | |
| public function setLanguageNotesProvider(): array | |
| { | |
| return self::SET_LANGUAGE_NOTES_CASES; | |
| } | |
| } | |
| /** | |
| * Minimal fake resource containing only the API needed by sfIsadPlugin. | |
| * | |
| * The production resource normally retrieves notes through the database. This | |
| * fake keeps them in memory so this remains a focused unit test. | |
| * | |
| * @internal | |
| */ | |
| final class sfIsadPluginTestResource | |
| { | |
| /** @var ArrayObject<int, QubitNote> */ | |
| public ArrayObject $notes; | |
| /** | |
| * @param QubitNote[] $notes notes available before the setter runs | |
| */ | |
| public function __construct(array $notes) | |
| { | |
| $this->notes = new ArrayObject($notes); | |
| } | |
| /** | |
| * Mirror the production method used by sfIsadPlugin. | |
| * | |
| * The options are accepted for signature compatibility. Filtering is not | |
| * needed because each test constructs exactly the notes it needs. | |
| * | |
| * @return ArrayObject<int, QubitNote> | |
| */ | |
| public function getMemoryNotesByType(array $options = []): ArrayObject | |
| { | |
| return $this->notes; | |
| } | |
| } | |
| /** | |
| * QubitNote spy that records deletion without accessing the database. | |
| * | |
| * A spy is a test double that behaves like the real object while recording an | |
| * interaction for later assertion. All regular note behavior is inherited; | |
| * only delete() is replaced. | |
| * | |
| * @internal | |
| */ | |
| final class sfIsadPluginTestNote extends QubitNote | |
| { | |
| public int $deleteCalls = 0; | |
| /** | |
| * Record the deletion request instead of deleting a database row. | |
| * | |
| * @param null|PropelPDO $connection unused connection argument kept for signature compatibility | |
| */ | |
| public function delete($connection = null) | |
| { | |
| ++$this->deleteCalls; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment