Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 17 additions & 61 deletions .github/workflows/unit-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
18 changes: 2 additions & 16 deletions classes/PhpSourceParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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.
*/
Expand All @@ -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);
Expand All @@ -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, [
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
6 changes: 0 additions & 6 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
backupGlobals="false"
backupStaticAttributes="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"
>
<testsuites>
Expand Down
16 changes: 5 additions & 11 deletions tests/BuilderPluginTestCase.php
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
<?php namespace Winter\Builder\Tests;
<?php

if (class_exists('System\Tests\Bootstrap\PluginTestCase')) {
class BaseTestCase extends \System\Tests\Bootstrap\PluginTestCase
{
}
} else {
class BaseTestCase extends \PluginTestCase
{
}
}
namespace Winter\Builder\Tests;

use System\Tests\Bootstrap\PluginTestCase;

abstract class BuilderPluginTestCase extends BaseTestCase
abstract class BuilderPluginTestCase extends PluginTestCase
{
protected $refreshPlugins = [
'Winter.Builder',
Expand Down
8 changes: 6 additions & 2 deletions tests/unit/classes/FilesystemGeneratorTest.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
<?php namespace Winter\Builder\Tests\Unit\Classes;
<?php

namespace Winter\Builder\Tests\Unit\Classes;

use File;
use Winter\Builder\Classes\FilesystemGenerator;
use Winter\Builder\Tests\BuilderPluginTestCase;
use Winter\Storm\Support\Facades\File;

class FilesystemGeneratorTest extends BuilderPluginTestCase
{
Expand All @@ -15,6 +17,8 @@ public function setUp(): void

public function tearDown(): void
{
parent::tearDown();

$this->cleanUp();
}

Expand Down
25 changes: 6 additions & 19 deletions tests/unit/classes/MigrationFileParserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -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'
Expand All @@ -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'
Expand All @@ -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'
Expand Down
29 changes: 6 additions & 23 deletions tests/unit/classes/ModelFileParserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -23,21 +18,15 @@ 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();

$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();
Expand All @@ -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([
Expand All @@ -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([
Expand Down
27 changes: 10 additions & 17 deletions tests/unit/classes/ModelModelTest.php
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
<?php namespace Winter\Builder\Tests\Unit\Classes;
<?php

namespace Winter\Builder\Tests\Unit\Classes;

use SystemException;
use Winter\Builder\Classes\ModelModel;
use Winter\Builder\Classes\PluginCode;
use Winter\Builder\Tests\BuilderPluginTestCase;
use Winter\Storm\Exception\SystemException;

/**
* @covers \Winter\Builder\Classes\ModelModel
*/
#[\PHPUnit\Framework\Attributes\CoversClass(ModelModel::class)]
class ModelModelTest extends BuilderPluginTestCase
{
public function tearDown(): void
{
parent::tearDown();

// Ensure cleanup for testGetModelFields
@unlink(__DIR__.'/../../../models/MyMock.php');
}

/**
* @testdox validates valid model class names
*/
public function testValidateValidModelClassNames()
public function test_it_validates_model_class_names()
{
$unQualifiedClassName = 'MyClassName';
$this->assertTrue(ModelModel::validateModelClassName($unQualifiedClassName));
Expand All @@ -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));
Expand All @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions updates/version.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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+"