PHP Classes

File: tests/functional/FunctionalTest.php

Recommend this page to a friend!
  Packages of Rubens Takiguti Ribeiro   Lazy JSON   tests/functional/FunctionalTest.php   Download  
File: tests/functional/FunctionalTest.php
Role: Unit test script
Content type: text/plain
Description: Functional test
Class: Lazy JSON
Load and parse JSON files progressively
Author: By
Last change:
Date: 1 year ago
Size: 5,541 bytes
 

Contents

Class file image Download
<?php

namespace LazyJson\Tests\Functional;

use PHPUnit\Framework\Attributes\{
    CoversNothing,
    TestDox,
};
use PHPUnit\Framework\TestCase;
use RuntimeException;

#[TestDox('Functional')]
#[CoversNothing]
class FunctionalTest extends TestCase
{
    // Tests

    #[TestDox('Installing the lib.')]
    public function testInstall(): void
    {
        // Check
        if (!is_executable('/usr/bin/composer')) {
            $this->markTestSkipped('The composer binary is not available at /usr/bin/composer');
        }

        // Prepare
        $dir = $this->createTempDir();
        chdir($dir);
        $cmd = sprintf(
            '/usr/bin/composer require %s --working-dir=%s --no-interaction --no-progress --quiet',
            escapeshellarg('lazy-json/lazy-json:dev-main'),
            escapeshellarg($dir),
        );

        // Execute
        $output = [];
        $exitCode = null;
        exec($cmd, $output, $exitCode);

        // Expect
        $this->assertEquals(0, $exitCode);
        $this->assertDirectoryExists(sprintf('%s/vendor', $dir));
        $this->assertDirectoryExists(sprintf('%s/vendor/lazy-json', $dir));
        $this->assertDirectoryExists(sprintf('%s/vendor/lazy-json/lazy-json', $dir));
        $this->assertDirectoryDoesNotExist(sprintf('%s/vendor/lazy-json/lazy-json/.github', $dir));
        $this->assertDirectoryDoesNotExist(sprintf('%s/vendor/lazy-json/lazy-json/docs', $dir));
        $this->assertDirectoryDoesNotExist(sprintf('%s/vendor/lazy-json/lazy-json/examples', $dir));
        $this->assertDirectoryDoesNotExist(sprintf('%s/vendor/lazy-json/lazy-json/tests', $dir));
    }

    #[TestDox('Installing the lib and using it.')]
    public function testUsage(): void
    {
        // Check
        if (!is_executable('/usr/bin/composer')) {
            $this->markTestSkipped('The composer binary is not available at /usr/bin/composer');
        }

        // Prepare
        $dir = $this->createTempDir();
        chdir($dir);
        $cmd = sprintf(
            '/usr/bin/composer require %s --working-dir=%s --no-interaction --no-progress --quiet',
            escapeshellarg('lazy-json/lazy-json:dev-main'),
            escapeshellarg($dir),
        );
        $output = [];
        $exitCode = null;
        exec($cmd, $output, $exitCode);

        $content = json_encode([
            'a' => null,
            'b' => true,
            'c' => false,
            'd' => 1,
            'e' => 1.2e2,
            'f' => 'abc',
            'g' => [1, 2, 3],
            'h' => ['x' => 1, 'y' => 2],
        ]);
        file_put_contents(sprintf('%s/sample.json', $dir), $content);

        $content = <<<'EOF'
        <?php
        require(__DIR__ . '/vendor/autoload.php');

        $file = new SplFileObject(sprintf('%s/sample.json', __DIR__), 'r');

        $json = LazyJson\JsonElement::load($file);

        var_dump($json->getDecodedValue());
        EOF;
        file_put_contents(sprintf('%s/test.php', $dir), $content);

        // Execute
        $output = [];
        $exitCode = null;
        $cmd = sprintf('php %s', escapeshellarg(sprintf('%s/test.php', $dir)));
        exec($cmd, $output, $exitCode);
        $strOutput = trim(implode("\n", $output));

        // Expect
        $expectedOutput = <<<'EOF'
        object(stdClass)#6 (8) {
          ["a"]=>
          NULL
          ["b"]=>
          bool(true)
          ["c"]=>
          bool(false)
          ["d"]=>
          int(1)
          ["e"]=>
          int(120)
          ["f"]=>
          string(3) "abc"
          ["g"]=>
          array(3) {
            [0]=>
            int(1)
            [1]=>
            int(2)
            [2]=>
            int(3)
          }
          ["h"]=>
          object(stdClass)#10 (2) {
            ["x"]=>
            int(1)
            ["y"]=>
            int(2)
          }
        }
        EOF;

        $this->assertEquals(0, $exitCode);
        $this->assertEquals($expectedOutput, $strOutput);
    }

    /**
     * Create a temp dir to run the functional test
     * @return string The full path of the directory
     */
    private function createTempDir(): string
    {
        $dir = tempnam(sys_get_temp_dir(), 'test-functional-');
        if ($dir === false) {
            throw new RuntimeException('Failed to create temp dir to run functional test');
        }
        unlink($dir);
        $created = mkdir($dir, 0777, true);
        if ($created === false) {
            throw new RuntimeException('Failed to create temp dir to run functional test');
        }

        register_shutdown_function([self::class, 'clearTempDir'], $dir);

        return $dir;
    }

    /**
     * Clear a directory recursivelly
     * @param string $dir
     * @return void
     */
    protected static function clearTempDir(string $dir): void
    {
        foreach (scandir($dir) as $item) {
            if ($item === '.' || $item === '..') {
                continue;
            }
            $fullItem = sprintf('%s/%s', $dir, $item);
            if (is_file($fullItem)) {
                $deleted = unlink($fullItem);
                if ($deleted === false) {
                    throw new RuntimeException(sprintf('Failed to delete temp file: %s', $fullItem));
                }
            } elseif (is_dir($fullItem)) {
                self::clearTempDir($fullItem);
            }
        }
        $deleted = rmdir($dir);
        if ($deleted === false) {
            throw new RuntimeException(sprintf('Failed to delete temp dir: %s', $dir));
        }
    }
}