diff --git a/.github/workflows/unit-tests.yaml b/.github/workflows/unit-tests.yaml index 9beddee..4361be1 100644 --- a/.github/workflows/unit-tests.yaml +++ b/.github/workflows/unit-tests.yaml @@ -3,77 +3,33 @@ name: Unit Tests on: push: branches: - - main + - 'main' pull_request: +concurrency: + group: tests-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: phpUnitTests: - runs-on: ubuntu-latest - name: PHP ${{ matrix.phpVersions }} + name: ${{ matrix.operatingSystem }} / PHP ${{ matrix.phpVersion }} + runs-on: ${{ matrix.operatingSystem }} + env: + GITHUB_TOKEN: ${{ secrets.COMPOSER_PUBLIC_TOKEN }} strategy: max-parallel: 4 matrix: - phpVersions: ['8.1', '8.2', '8.3', '8.4'] + operatingSystem: [ubuntu-latest, windows-latest] + phpVersion: ['8.2', '8.3', '8.4'] fail-fast: false - env: - phpExtensions: mbstring, intl, gd, xml, sqlite - cacheKey: ext-cache-v2 - winterCmsRelease: develop steps: - - name: Checkout changes - uses: actions/checkout@v4 - with: - path: builder-plugin - - - name: Setup cache environment - id: extcache - uses: shivammathur/cache-extensions@v1 - with: - php-version: ${{ matrix.phpVersions }} - extensions: ${{ env.phpExtensions }} - key: ${{ env.cacheKey }} - - - name: Cache extensions - uses: actions/cache@v4 + - name: Setup Winter + uses: wintercms/setup-winter-action@v1 with: - path: ${{ steps.extcache.outputs.dir }} - key: ${{ steps.extcache.outputs.key }} - restore-keys: ${{ steps.extcache.outputs.key }} - - - name: Install PHP and extensions - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.phpVersions }} - extensions: ${{ env.phpExtensions }} - tools: composer:v2 - coverage: none - - - name: Install Winter CMS - run: | - wget https://github.com/wintercms/winter/archive/${{ env.winterCmsRelease }}.zip - unzip ${{ env.winterCmsRelease }}.zip - rm ${{ env.winterCmsRelease }}.zip - shopt -s dotglob - mv winter-${{ env.winterCmsRelease }}/* ./ - rmdir winter-${{ env.winterCmsRelease }} - shopt -u dotglob - cp config/cms.php config/testing/cms.php - mkdir -p plugins/winter - mv builder-plugin plugins/winter/builder - - - name: Get Composer cache directory - id: composercache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - - name: Cache dependencies - uses: actions/cache@v4 - with: - path: ${{ steps.composercache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} - restore-keys: ${{ runner.os }}-composer- - - - name: Install Composer dependencies - run: composer install --no-interaction --no-progress + php-version: ${{ matrix.phpVersion }} + winter-ref: wip/1.3 + plugin-author: winter + plugin-name: builder - name: Run unit tests run: php artisan winter:test -p Winter.Builder -- --testdox diff --git a/classes/PhpSourceParser.php b/classes/PhpSourceParser.php index 29134ae..64ed1ba 100644 --- a/classes/PhpSourceParser.php +++ b/classes/PhpSourceParser.php @@ -3,7 +3,6 @@ namespace Winter\Builder\Classes; use PhpParser\Error; -use PhpParser\Lexer\Emulative; use PhpParser\NodeTraverser; use PhpParser\NodeVisitor\CloningVisitor; use PhpParser\NodeVisitor\NameResolver; @@ -41,11 +40,6 @@ abstract class PhpSourceParser */ protected \PhpParser\NodeTraverser $traverser; - /** - * The lexer used to manipulate code. - */ - protected \PhpParser\Lexer\Emulative $lexer; - /** * The path to the parsed file, if loaded from a file. */ @@ -58,15 +52,7 @@ abstract class PhpSourceParser */ public function __construct(string $source, string $file = null) { - $this->lexer = new Emulative([ - 'usedAttributes' => [ - 'comments', - 'startLine', 'endLine', - 'startTokenPos', 'endTokenPos', - ], - ]); - - $parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7, $this->lexer); + $parser = (new ParserFactory())->createForHostVersion(); try { $this->originalAst = $parser->parse($source); @@ -78,7 +64,7 @@ public function __construct(string $source, string $file = null) ); } - $this->originalTokens = $this->lexer->getTokens(); + $this->originalTokens = $parser->getTokens(); $this->traverser = new NodeTraverser; $this->traverser->addVisitor(new CloningVisitor); $this->traverser->addVisitor(new NameResolver(null, [ diff --git a/composer.json b/composer.json index dc6ea5c..1b0ef88 100644 --- a/composer.json +++ b/composer.json @@ -30,7 +30,7 @@ "require": { "php": ">=7.0", "composer/installers": "~1.0", - "nikic/php-parser": "^4.13.2" + "nikic/php-parser": "^5.5" }, "require-dev": { "phpunit/phpunit": "~4.0" diff --git a/phpunit.xml b/phpunit.xml index 49284cb..3f93a25 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,13 +1,7 @@ diff --git a/tests/BuilderPluginTestCase.php b/tests/BuilderPluginTestCase.php index d6d2f86..fd95fce 100644 --- a/tests/BuilderPluginTestCase.php +++ b/tests/BuilderPluginTestCase.php @@ -1,16 +1,10 @@ -cleanUp(); } diff --git a/tests/unit/classes/MigrationFileParserTest.php b/tests/unit/classes/MigrationFileParserTest.php index ed4e975..8a9e23f 100644 --- a/tests/unit/classes/MigrationFileParserTest.php +++ b/tests/unit/classes/MigrationFileParserTest.php @@ -2,18 +2,14 @@ namespace Winter\Builder\Tests\Unit\Classes; +use PHPUnit\Framework\Attributes\CoversClass; use Winter\Builder\Classes\MigrationFileParser; use Winter\Builder\Tests\BuilderPluginTestCase; -/** - * @covers \Winter\Builder\Classes\MigrationFileParser - */ +#[CoversClass(MigrationFileParser::class)] class MigrationFileParserTest extends BuilderPluginTestCase { - /** - * @testdox can determine if a file is a migration class definition. - */ - public function testIsMigration() + public function test_it_can_determine_if_file_is_class_migration() { $firstMigration = MigrationFileParser::fromFile( __DIR__ . '/../../fixtures/pluginfixture/updates/create_simple_model_table.php' @@ -30,10 +26,7 @@ public function testIsMigration() $this->assertFalse($notAMigration->isMigration()); } - /** - * @testdox can determine if a file is an anonymous class definition. - */ - public function testIsAnonymous() + public function test_it_can_determine_if_file_is_anonymous_migration() { $firstMigration = MigrationFileParser::fromFile( __DIR__ . '/../../fixtures/pluginfixture/updates/create_simple_model_table.php' @@ -50,10 +43,7 @@ public function testIsAnonymous() $this->assertTrue($notAMigration->isAnonymous()); } - /** - * @testdox can get the namespace of a class. - */ - public function testGetNamespace() + public function test_it_can_get_namespace_of_class() { $firstMigration = MigrationFileParser::fromFile( __DIR__ . '/../../fixtures/pluginfixture/updates/create_simple_model_table.php' @@ -70,10 +60,7 @@ public function testGetNamespace() $this->assertNull($notAMigration->getNamespace()); } - /** - * @testdox can get the class name of a class. - */ - public function testGetClassName() + public function test_it_can_get_class_name_of_class() { $firstMigration = MigrationFileParser::fromFile( __DIR__ . '/../../fixtures/pluginfixture/updates/create_simple_model_table.php' diff --git a/tests/unit/classes/ModelFileParserTest.php b/tests/unit/classes/ModelFileParserTest.php index d267ad9..510ff89 100644 --- a/tests/unit/classes/ModelFileParserTest.php +++ b/tests/unit/classes/ModelFileParserTest.php @@ -5,15 +5,10 @@ use Winter\Builder\Classes\ModelFileParser; use Winter\Builder\Tests\BuilderPluginTestCase; -/** - * @covers \Winter\Builder\Classes\ModelFileParser - */ +#[\PHPUnit\Framework\Attributes\CoversClass(ModelFileParser::class)] class ModelFileParserTest extends BuilderPluginTestCase { - /** - * @testdox can get information for the model from the parser. - */ - public function testExtractModelInfoFromSource() + public function test_it_can_get_information_for_model_from_parser() { $parser = ModelFileParser::fromFile(__DIR__ . '/../../fixtures/pluginfixture/models/SimpleModel.php'); $modelInfo = $parser->extractModelInfoFromSource(); @@ -23,10 +18,7 @@ public function testExtractModelInfoFromSource() $this->assertEquals('plugin_fixture_simple_model', $modelInfo['table']); } - /** - * @testdox can generate and provide the source code of a given model from the parser. - */ - public function testGetSource() + public function test_it_can_generate_and_provide_source_of_given_model_from_parser() { $parser = ModelFileParser::fromFile(__DIR__ . '/../../fixtures/pluginfixture/models/SimpleModel.php'); $source = $parser->getSource(); @@ -34,10 +26,7 @@ public function testGetSource() $this->assertEquals(file_get_contents(__DIR__ . '/../../fixtures/pluginfixture/models/SimpleModel.php'), $source); } - /** - * @testdox can get the value of the $jsonable property from a model. - */ - public function testGetJsonable() + public function test_it_can_get_value_of_jsonable_from_model() { $parser = ModelFileParser::fromFile(__DIR__ . '/../../fixtures/pluginfixture/models/SimpleModel.php'); $jsonable = $parser->getJsonable(); @@ -50,10 +39,7 @@ public function testGetJsonable() ], $jsonable); } - /** - * @testdox can set the value of the $jsonable property in a model. - */ - public function testSetJsonable() + public function test_it_can_set_value_of_jsonable_in_model() { $parser = ModelFileParser::fromFile(__DIR__ . '/../../fixtures/pluginfixture/models/ArrayDataModel.php'); $parser->setJsonable([ @@ -65,10 +51,7 @@ public function testSetJsonable() $this->assertStringContainsString('public $jsonable = [\'field_1\', \'field_2\'];', $source); } - /** - * @testdox can inject the $jsonable property in a model that does not contain it. - */ - public function testSetJsonableAddProperty() + public function test_it_can_inject_jsonable_property_in_model_without_it() { $parser = ModelFileParser::fromFile(__DIR__ . '/../../fixtures/pluginfixture/models/SimpleModel.php'); $parser->setJsonable([ diff --git a/tests/unit/classes/ModelModelTest.php b/tests/unit/classes/ModelModelTest.php index d5a8805..2398d7c 100644 --- a/tests/unit/classes/ModelModelTest.php +++ b/tests/unit/classes/ModelModelTest.php @@ -1,25 +1,24 @@ -assertTrue(ModelModel::validateModelClassName($unQualifiedClassName)); @@ -34,10 +33,7 @@ public function testValidateValidModelClassNames() $this->assertTrue(ModelModel::validateModelClassName($qualifiedClassNameStartingWithLowerCase)); } - /** - * @testdox does not validate invalid model class names - */ - public function testInvalidateInvalidModelClassNames() + public function test_it_does_not_validate_invalid_model_class_names() { $unQualifiedClassName = 'myClassName'; // starts with lower case $this->assertFalse(ModelModel::validateModelClassName($unQualifiedClassName)); @@ -49,10 +45,7 @@ public function testInvalidateInvalidModelClassNames() $this->assertFalse(ModelModel::validateModelClassName($fullyQualifiedClassName)); } - /** - * @testdox can extract the model fields from a given model - */ - public function testGetModelFields() + public function test_it_can_extract_model_fields_from_model() { // Invalid Class Name try { diff --git a/updates/version.yaml b/updates/version.yaml index 71b978c..996cef5 100644 --- a/updates/version.yaml +++ b/updates/version.yaml @@ -47,3 +47,4 @@ - "Fixed an issue where migration files stored within subdirectories could not be read or saved." - "The permissions data table is now scrollable and will stretch to full height." "2.1.1": "Fix issue when creating new plugins" +"2.2.0": "Support Winter v1.3+"