From 05c6dc6dab3c4c19493e07ed6cd8cfb5f29da893 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Mon, 29 Jan 2024 09:42:08 +0800 Subject: [PATCH] add more tests --- src/SPC/store/FileSystem.php | 4 +- src/globals/test-extensions.php | 2 +- tests/SPC/globals/GlobalFunctionsTest.php | 101 +++++++++++++ tests/SPC/store/ConfigTest.php | 96 ++++++++++++ tests/SPC/util/ConfigValidatorTest.php | 172 ++++++++++++++++++++++ tests/SPC/util/LicenseDumperTest.php | 8 +- 6 files changed, 379 insertions(+), 4 deletions(-) create mode 100644 tests/SPC/globals/GlobalFunctionsTest.php create mode 100644 tests/SPC/store/ConfigTest.php create mode 100644 tests/SPC/util/ConfigValidatorTest.php diff --git a/src/SPC/store/FileSystem.php b/src/SPC/store/FileSystem.php index f786c8ef..8da010e2 100644 --- a/src/SPC/store/FileSystem.php +++ b/src/SPC/store/FileSystem.php @@ -14,13 +14,13 @@ class FileSystem /** * @throws FileSystemException */ - public static function loadConfigArray(string $config): array + public static function loadConfigArray(string $config, ?string $config_dir = null): array { $whitelist = ['ext', 'lib', 'source']; if (!in_array($config, $whitelist)) { throw new FileSystemException('Reading ' . $config . '.json is not allowed'); } - $tries = [ + $tries = $config_dir !== null ? [FileSystem::convertPath($config_dir . '/' . $config . '.json')] : [ WORKING_DIR . '/config/' . $config . '.json', ROOT_DIR . '/config/' . $config . '.json', ]; diff --git a/src/globals/test-extensions.php b/src/globals/test-extensions.php index 32bbd082..b65431b9 100644 --- a/src/globals/test-extensions.php +++ b/src/globals/test-extensions.php @@ -27,7 +27,7 @@ $with_libs = match (PHP_OS_FAMILY) { // You can use `common`, `bulk`, `minimal` or `none`. // note: combination is only available for *nix platform. Windows must use `none` combination $base_combination = match (PHP_OS_FAMILY) { - 'Linux', 'Darwin' => 'bulk', + 'Linux', 'Darwin' => 'minimal', 'Windows' => 'none', }; diff --git a/tests/SPC/globals/GlobalFunctionsTest.php b/tests/SPC/globals/GlobalFunctionsTest.php new file mode 100644 index 00000000..25c22198 --- /dev/null +++ b/tests/SPC/globals/GlobalFunctionsTest.php @@ -0,0 +1,101 @@ +assertTrue(is_assoc_array(['a' => 1, 'b' => 2])); + $this->assertFalse(is_assoc_array([1, 2, 3])); + } + + public function testLogger(): void + { + $this->assertInstanceOf('Psr\Log\LoggerInterface', logger()); + } + + /** + * @throws WrongUsageException + */ + public function testArch2Gnu(): void + { + $this->assertEquals('x86_64', arch2gnu('x86_64')); + $this->assertEquals('x86_64', arch2gnu('x64')); + $this->assertEquals('x86_64', arch2gnu('amd64')); + $this->assertEquals('aarch64', arch2gnu('arm64')); + $this->assertEquals('aarch64', arch2gnu('aarch64')); + $this->expectException('SPC\exception\WrongUsageException'); + arch2gnu('armv7'); + } + + public function testQuote(): void + { + $this->assertEquals('"hello"', quote('hello')); + $this->assertEquals("'hello'", quote('hello', "'")); + } + + /** + * @throws RuntimeException + */ + public function testFPassthru(): void + { + if (PHP_OS_FAMILY === 'Windows') { + $this->markTestSkipped('Windows not support f_passthru'); + } + $this->assertEquals(null, f_passthru('echo ""')); + $this->expectException('SPC\exception\RuntimeException'); + f_passthru('false'); + } + + public function testFPutenv(): void + { + $this->assertTrue(f_putenv('SPC_TEST_ENV=1')); + $this->assertEquals('1', getenv('SPC_TEST_ENV')); + } + + public function testShell(): void + { + if (PHP_OS_FAMILY === 'Windows') { + $this->markTestSkipped('Windows not support shell'); + } + $shell = shell(); + $this->assertInstanceOf('SPC\util\UnixShell', $shell); + $this->assertInstanceOf('SPC\util\UnixShell', $shell->cd('/')); + $this->assertInstanceOf('SPC\util\UnixShell', $shell->exec('echo ""')); + $this->assertInstanceOf('SPC\util\UnixShell', $shell->setEnv(['SPC_TEST_ENV' => '1'])); + + [$code, $out] = $shell->execWithResult('echo "_"'); + $this->assertEquals(0, $code); + $this->assertEquals('_', implode('', $out)); + + $this->expectException('SPC\exception\RuntimeException'); + $shell->exec('false'); + } +} diff --git a/tests/SPC/store/ConfigTest.php b/tests/SPC/store/ConfigTest.php new file mode 100644 index 00000000..6b7555c9 --- /dev/null +++ b/tests/SPC/store/ConfigTest.php @@ -0,0 +1,96 @@ +assertTrue(is_assoc_array(Config::getExts())); + } + + /** + * @throws FileSystemException + * @throws WrongUsageException + */ + public function testGetLib() + { + $this->assertIsArray(Config::getLib('zlib')); + match (PHP_OS_FAMILY) { + 'FreeBSD', 'Darwin', 'Linux' => $this->assertStringEndsWith('.a', Config::getLib('zlib', 'static-libs', [])[0]), + 'Windows' => $this->assertStringEndsWith('.lib', Config::getLib('zlib', 'static-libs', [])[0]), + default => null, + }; + } + + /** + * @throws WrongUsageException + * @throws FileSystemException + */ + public function testGetExt() + { + $this->assertIsArray(Config::getExt('bcmath')); + $this->assertEquals('builtin', Config::getExt('bcmath', 'type')); + } + + /** + * @throws FileSystemException + */ + public function testGetSources() + { + $this->assertTrue(is_assoc_array(Config::getSources())); + } + + /** + * @throws FileSystemException + */ + public function testGetSource() + { + $this->assertIsArray(Config::getSource('php-src')); + } + + /** + * @throws FileSystemException + */ + public function testGetLibs() + { + $this->assertTrue(is_assoc_array(Config::getLibs())); + } +} diff --git a/tests/SPC/util/ConfigValidatorTest.php b/tests/SPC/util/ConfigValidatorTest.php new file mode 100644 index 00000000..78ecd27b --- /dev/null +++ b/tests/SPC/util/ConfigValidatorTest.php @@ -0,0 +1,172 @@ + [ + 'type' => 'filelist', + 'url' => 'https://example.com', + 'regex' => '.*', + ], + 'source2' => [ + 'type' => 'git', + 'url' => 'https://example.com', + 'rev' => 'master', + ], + 'source3' => [ + 'type' => 'ghtagtar', + 'repo' => 'aaaa/bbbb', + ], + 'source4' => [ + 'type' => 'ghtar', + 'repo' => 'aaa/bbb', + 'path' => 'path/to/dir', + ], + 'source5' => [ + 'type' => 'ghrel', + 'repo' => 'aaa/bbb', + 'match' => '.*', + ], + 'source6' => [ + 'type' => 'url', + 'url' => 'https://example.com', + ], + ]; + try { + ConfigValidator::validateSource($good_source); + $this->assertTrue(true); + } catch (ValidationException $e) { + $this->fail($e->getMessage()); + } + } + + public function testValidateSourceBad(): void + { + $bad_source = [ + 'source1' => [ + 'type' => 'filelist', + 'url' => 'https://example.com', + // no regex + ], + 'source2' => [ + 'type' => 'git', + 'url' => true, // not string + 'rev' => 'master', + ], + 'source3' => [ + 'type' => 'ghtagtar', + 'url' => 'aaaa/bbbb', // not repo + ], + 'source4' => [ + 'type' => 'ghtar', + 'repo' => 'aaa/bbb', + 'path' => true, // not string + ], + 'source5' => [ + 'type' => 'ghrel', + 'repo' => 'aaa/bbb', + 'match' => 1, // not string + ], + 'source6' => [ + 'type' => 'url', // no url + ], + ]; + foreach ($bad_source as $name => $src) { + try { + ConfigValidator::validateSource([$name => $src]); + $this->fail("should throw ValidationException for source {$name}"); + } catch (ValidationException) { + $this->assertTrue(true); + } + } + } + + public function testValidateLibsGood(): void + { + $good_libs = [ + 'lib1' => [ + 'source' => 'source1', + ], + 'lib2' => [ + 'source' => 'source2', + 'lib-depends' => [ + 'lib1', + ], + ], + 'lib3' => [ + 'source' => 'source3', + 'lib-suggests' => [ + 'lib1', + ], + ], + ]; + try { + ConfigValidator::validateLibs($good_libs, ['source1' => [], 'source2' => [], 'source3' => []]); + $this->assertTrue(true); + } catch (ValidationException $e) { + $this->fail($e->getMessage()); + } + } + + public function testValidateLibsBad(): void + { + // lib.json is broken + try { + ConfigValidator::validateLibs('not array'); + $this->fail('should throw ValidationException'); + } catch (ValidationException) { + $this->assertTrue(true); + } + // lib source not exists + try { + ConfigValidator::validateLibs(['lib1' => ['source' => 'source3']], ['source1' => [], 'source2' => []]); + $this->fail('should throw ValidationException'); + } catch (ValidationException) { + $this->assertTrue(true); + } + // source must be string + try { + ConfigValidator::validateLibs(['lib1' => ['source' => true]], ['source1' => [], 'source2' => []]); + $this->fail('should throw ValidationException'); + } catch (ValidationException) { + $this->assertTrue(true); + } + // lib-depends must be list + try { + ConfigValidator::validateLibs(['lib1' => ['source' => 'source1', 'lib-depends' => ['a' => 'not list']]], ['source1' => [], 'source2' => []]); + $this->fail('should throw ValidationException'); + } catch (ValidationException) { + $this->assertTrue(true); + } + // lib-suggests must be list + try { + ConfigValidator::validateLibs(['lib1' => ['source' => 'source1', 'lib-suggests' => ['a' => 'not list']]], ['source1' => [], 'source2' => []]); + $this->fail('should throw ValidationException'); + } catch (ValidationException) { + $this->assertTrue(true); + } + } + + /** + * @throws ValidationException + */ + public function testValidateExts(): void + { + ConfigValidator::validateExts([]); + $this->expectException(ValidationException::class); + ConfigValidator::validateExts(null); + } +} diff --git a/tests/SPC/util/LicenseDumperTest.php b/tests/SPC/util/LicenseDumperTest.php index e1ca06c9..3fdfcf8e 100644 --- a/tests/SPC/util/LicenseDumperTest.php +++ b/tests/SPC/util/LicenseDumperTest.php @@ -13,7 +13,13 @@ use SPC\util\LicenseDumper; */ final class LicenseDumperTest extends TestCase { - private const DIRECTORY = '../../var/license-dump'; + private const DIRECTORY = __DIR__ . '/../../var/license-dump'; + + public static function tearDownAfterClass(): void + { + @rmdir(self::DIRECTORY); + @rmdir(dirname(self::DIRECTORY)); + } protected function setUp(): void {