diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 83c800a..10b872c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,17 +7,17 @@ on: branches: [ master ] jobs: - build: + ci: runs-on: ubuntu-latest strategy: matrix: - php-versions: [ '8.1', '8.2', '8.3' ] + php-versions: [ '8.3', '8.4', '8.5' ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: - fetch-depth: 0 # To avoid "Shallow clone detected" error in SonarCloud report + fetch-depth: 0 #~ PHP Setup - name: Setup PHP ${{ matrix.php-versions }} @@ -48,30 +48,18 @@ jobs: #~ CI part - name: Dependencies - run: make deps + run: make php/deps - name: Check Code Style - run: make phpcs + run: make php/check - name: Units Tests - run: make tests + run: make php/tests - name: Fix unit tests report path run: | sed -i 's+'$GITHUB_WORKSPACE'+/github/workspace+g' build/reports/phpunit/clover.xml sed -i 's+'$GITHUB_WORKSPACE'+/github/workspace+g' build/reports/phpunit/unit.xml - - name: PHP 8.1 Compatibility - run: make php-min-compatibility - - - name: PHP 8.3 Compatibility - run: make php-max-compatibility - - name: PHP Static Analyze - run: make analyze - - - name: SonarCloud Scan - uses: SonarSource/sonarcloud-github-action@v2.1.1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + run: make php/analyze diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml new file mode 100644 index 0000000..9130fbb --- /dev/null +++ b/.github/workflows/sonarcloud.yml @@ -0,0 +1,46 @@ +name: SonarQube + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + sonarcloud: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # To avoid "Shallow clone detected" error in SonarCloud report + + #~ PHP Setup + - name: Setup PHP 8.3 # Minimum version + uses: shivammathur/setup-php@v2 + with: + php-version: '8.3' + + #~ Composer Cache + - name: Get Composer Cache Directory + id: composer-cache + run: | + echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + + - uses: actions/cache@v3 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer- + + - name: Install dependencies + if: steps.composer-cache.outputs.cache-hit != 'true' + run: make install + + - name: Units Tests + run: make php/tests # To generate the coverage report + + - name: SonarQube Scan + uses: SonarSource/sonarqube-scan-action@v7 + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 87d2ce9..1eb221a 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -4,7 +4,7 @@ //~ Rules ->setRules( [ - '@PER-CS2.0' => true, + '@PER-CS3x0' => true, ] ) diff --git a/CHANGELOG.md b/CHANGELOG.md index a67d6e6..1b61b68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,21 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Removed ``` +## [7.0.0] - 2026-01-05 +[7.0.0]: https://github.com/eureka-framework/kernel-http/compare/6.1.0...7.0.0 +### Added +- Add PHP 8.3+ support +- Add Symfony 8+ support +### Removed +- Drop PHP 8.1 & 8.2 support +- Drop Symfony 5 support +### Changed +- Allow Symfony 7.0+ in dependencies +- Update dependencies +- Update CI configs +- Update Makefile + +--- ## [6.1.0] - 2024-09-26 [6.1.0]: https://github.com/eureka-framework/kernel-http/compare/6.0.0...6.1.0 ### Changed diff --git a/Makefile b/Makefile index 53c015d..8227c3c 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,8 @@ -.PHONY: validate install update phpcs phpcbf deps php-min-compatibility php-max-compatibility phpstan analyze tests testdox ci clean +.PHONY: validate install update php/deps php/check php/fix php/min-compatibility php/max-compatibility php/phpstan php/analyze php/tests php/test php/testdox ci clean -PHP_MIN_VERSION := "8.1" -PHP_MAX_VERSION := "8.3" +PHP_MIN_VERSION := "8.3" +PHP_MAX_VERSION := "8.5" COMPOSER_BIN := composer - -ifneq (,$(wildcard ./.env)) - include .env - export -endif - define header = @if [ -t 1 ]; then printf "\n\e[37m\e[100m \e[104m $(1) \e[0m\n"; else printf "\n### $(1)\n"; fi endef @@ -16,27 +10,23 @@ endef #~ Composer dependency validate: $(call header,Composer Validation) - @composer validate + @${COMPOSER_BIN} validate install: $(call header,Composer Install) - @composer install + @${COMPOSER_BIN} install update: $(call header,Composer Update) - @composer update - @composer bump --dev-only - -outdated: - $(call header,Composer Outdated) - @composer outdated --direct + @${COMPOSER_BIN} update + @${COMPOSER_BIN} bump --dev-only composer.lock: install #~ Vendor binaries dependencies -vendor/bin/php-cs-fixer: -vendor/bin/phpstan: -vendor/bin/phpunit: +vendor/bin/php-cs-fixer: composer.lock +vendor/bin/phpstan: composer.lock +vendor/bin/phpunit: composer.lock #~ Report directories dependencies build/reports/phpunit: @@ -46,49 +36,45 @@ build/reports/phpstan: @mkdir -p build/reports/phpstan #~ main commands -deps: composer.json # ci + manual +php/deps: composer.json $(call header,Checking Dependencies) - @XDEBUG_MODE=off ./vendor/bin/composer-dependency-analyser --config=./ci/composer-dependency-analyser.php # for shadow & unused required dependencies - @XDEBUG_MODE=off ./vendor/bin/composer-require-checker check # mainly for ext-* missing dependencies + @XDEBUG_MODE=off ./vendor/bin/composer-dependency-analyser --config ./ci/composer-dependency-analyser.php # for shadow, unused required dependencies and ext-* missing dependencies -phpcs: vendor/bin/php-cs-fixer # ci + manual +php/check: vendor/bin/php-cs-fixer $(call header,Checking Code Style) - @XDEBUG_MODE=off ./vendor/bin/php-cs-fixer check -v --diff - -phpcbf: vendor/bin/php-cs-fixer # manual + @XDEBUG_MODE=off ./vendor/bin/php-cs-fixer check +php/fix: vendor/bin/php-cs-fixer $(call header,Fixing Code Style) @XDEBUG_MODE=off ./vendor/bin/php-cs-fixer fix -v -php-min-compatibility: vendor/bin/phpstan build/reports/phpstan # ci + manual - $(call header,Checking PHP $(PHP_MIN_VERSION) compatibility) - @XDEBUG_MODE=off ./vendor/bin/phpstan analyse --configuration=./ci/php-min-compatibility.neon --error-format=table - -php-max-compatibility: vendor/bin/phpstan build/reports/phpstan # ci + manual - $(call header,Checking PHP $(PHP_MAX_VERSION) compatibility) - @XDEBUG_MODE=off ./vendor/bin/phpstan analyse --configuration=./ci/php-max-compatibility.neon --error-format=table +php/min-compatibility: vendor/bin/phpstan build/reports/phpstan + $(call header,Checking PHP ${PHP_MIN_VERSION} compatibility) + @XDEBUG_MODE=off ./vendor/bin/phpstan analyse --configuration=./ci/phpmin-compatibility.neon --error-format=table -phpstan: vendor/bin/phpstan build/reports/phpstan # ci - $(call header,Running Static Analyze) - @XDEBUG_MODE=off ./vendor/bin/phpstan analyse --error-format=checkstyle > ./build/reports/phpstan/phpstan.xml +php/max-compatibility: vendor/bin/phpstan build/reports/phpstan #ci + $(call header,Checking PHP ${PHP_MAX_VERSION} compatibility) + @XDEBUG_MODE=off ./vendor/bin/phpstan analyse --configuration=./ci/phpmax-compatibility.neon --error-format=table -analyze: vendor/bin/phpstan build/reports/phpstan # manual +php/analyze: vendor/bin/phpstan build/reports/phpstan #manual & ci $(call header,Running Static Analyze - Pretty tty format) @XDEBUG_MODE=off ./vendor/bin/phpstan analyse --error-format=table -tests: vendor/bin/phpunit build/reports/phpunit # ci + manual +php/tests: vendor/bin/phpunit build/reports/phpunit #ci $(call header,Running Unit Tests) - @XDEBUG_MODE=coverage php -dzend_extension=xdebug.so ./vendor/bin/phpunit --testsuite=unit --coverage-clover=./build/reports/phpunit/clover.xml --log-junit=./build/reports/phpunit/unit.xml --coverage-php=./build/reports/phpunit/unit.cov --coverage-html=./build/reports/coverage/ --fail-on-warning + @XDEBUG_MODE=coverage php ./vendor/bin/phpunit --testsuite=unit --coverage-clover=./build/reports/phpunit/clover.xml --log-junit=./build/reports/phpunit/unit.xml --coverage-php=./build/reports/phpunit/unit.cov --coverage-html=./build/reports/coverage/ --fail-on-warning + +php/test: php/tests -integration: vendor/bin/phpunit build/reports/phpunit # manual +php/integration: vendor/bin/phpunit build/reports/phpunit #manual $(call header,Running Integration Tests) - @XDEBUG_MODE=coverage php -dzend_extension=xdebug.so ./vendor/bin/phpunit --testsuite=integration --fail-on-warning + @XDEBUG_MODE=coverage php ./vendor/bin/phpunit --testsuite=integration --fail-on-warning -testdox: vendor/bin/phpunit # manual +php/testdox: vendor/bin/phpunit #manual $(call header,Running Unit Tests (Pretty format)) - @XDEBUG_MODE=coverage php -dzend_extension=xdebug.so ./vendor/bin/phpunit --testsuite=unit --fail-on-warning --testdox + @XDEBUG_MODE=coverage php ./vendor/bin/phpunit --testsuite=unit --fail-on-warning --testdox -clean: # manual - $(call header,Cleaning previous build) +clean: + $(call header,Cleaning previous build) #manual @if [ "$(shell ls -A ./build)" ]; then rm -rf ./build/*; fi; echo " done" -ci: clean validate deps phpcs tests php-min-compatibility php-max-compatibility analyze +ci: clean validate install php/deps php/check php/tests php/integration php/min-compatibility php/max-compatibility php/analyze diff --git a/README.md b/README.md index f0f8ce5..f04ea65 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # kernel-http [![Current version](https://img.shields.io/packagist/v/eureka/kernel-console.svg?logo=composer)](https://packagist.org/packages/eureka/kernel-console) -[![Supported PHP version](https://img.shields.io/static/v1?logo=php&label=PHP&message=8.1|8.2|8.3&color=777bb4)](https://packagist.org/packages/eureka/kernel-console) +[![Supported PHP version](https://img.shields.io/static/v1?logo=php&label=PHP&message=>%3D8.3&color=777bb4)](https://packagist.org/packages/eureka/kernel-console) ![Build](https://github.com/eureka-framework/kernel-console/workflows/CI/badge.svg) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=eureka-framework_kernel-console&metric=alert_status)](https://sonarcloud.io/dashboard?id=eureka-framework_kernel-console) [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=eureka-framework_kernel-console&metric=coverage)](https://sonarcloud.io/dashboard?id=eureka-framework_kernel-console) @@ -16,7 +16,7 @@ Define global Application & Component kernel version If you wish to install it in your project, require it via composer: ```bash -composer require eureka-framework/kernek-console +composer require eureka/kernel-console ``` @@ -64,6 +64,30 @@ try { ``` +### Config tree example +``` +config/ +|_ packages/ +| |_ domains/ +| - user.yaml +| - app.yaml +| - database.yaml +| - services.yaml +|_ dev/ +| - app.yaml +|_ test/ +| - app.yaml +|_ secrets/ +| - database.yaml +|_ services.yaml +``` + +Config loading order and overrides: +1. `packages/` yaml files +2. Then `services.yaml` yaml file +3. Then `{current_env}/` yaml files +4. Finally `secrets/` yaml files + ## Contributing See the [CONTRIBUTING](CONTRIBUTING.md) file. @@ -81,41 +105,47 @@ And update with the following command: make update ``` -NB: For the kernel, the `composer.lock` file is not committed. +NB: For the components, the `composer.lock` file is not committed. ### Testing & CI (Continuous Integration) #### Tests You can run unit tests (with coverage) on your side with following command: ```bash -make tests +make php/tests ``` -You can run integration tests (but without coverage) on your side with following command: +You can run integration tests (without coverage) on your side with following command: ```bash -make integration +make php/integration ``` For prettier output (but without coverage), you can use the following command: ```bash -make testdox # run tests without coverage reports but with prettified output +make php/testdox # run tests without coverage reports but with prettified output ``` #### Code Style You also can run code style check with following commands: ```bash -make phpcs +make php/check ``` You also can run code style fixes with following commands: ```bash -make phpcbf +make php/fix +``` + +#### Check for missing explicit dependencies +You can check if any explicit dependency is missing with the following command: +```bash +make php/deps ``` #### Static Analysis To perform a static analyze of your code (with phpstan, lvl 9 at default), you can use the following command: ```bash -make phpstan +make php/analyse ``` To ensure you code still compatible with current supported version at Deezer and futures versions of php, you need to @@ -123,12 +153,12 @@ run the following commands (both are required for full support): Minimal supported version: ```bash -make php81compatibility +make php/min-compatibility ``` Maximal supported version: ```bash -make php83compatibility +make php/max-compatibility ``` #### CI Simulation @@ -137,7 +167,6 @@ And the last "helper" commands, you can run before commit and push, is: make ci ``` - ## License -This project is currently **proprietary** and should NOT be used outside Deezer +This project is currently under The MIT License (MIT). See [LICENCE](LICENSE) file for more information. diff --git a/ci/composer-dependency-analyser.php b/ci/composer-dependency-analyser.php index 2ca8367..fefed55 100644 --- a/ci/composer-dependency-analyser.php +++ b/ci/composer-dependency-analyser.php @@ -9,5 +9,5 @@ ->addPathToScan(__DIR__ . '/../src', isDev: false) ->addPathToScan(__DIR__ . '/../tests', isDev: true) - ->ignoreErrorsOnPackage('symfony/yaml', [ErrorType::UNUSED_DEPENDENCY]) // required in dependencies of symfony/dependency-injection + ->ignoreErrorsOnPackages(['symfony/finder', 'symfony/yaml'], [ErrorType::UNUSED_DEPENDENCY]) // required in dependencies of symfony/dependency-injection ; diff --git a/ci/php-max-compatibility.neon b/ci/phpmax-compatibility.neon similarity index 88% rename from ci/php-max-compatibility.neon rename to ci/phpmax-compatibility.neon index 2de36c8..085b5a0 100644 --- a/ci/php-max-compatibility.neon +++ b/ci/phpmax-compatibility.neon @@ -3,7 +3,7 @@ includes: - ./../vendor/phpstan/phpstan-phpunit/rules.neon parameters: - phpVersion: 80300 # PHP 8.3 + phpVersion: 80500 level: 0 paths: - ./../src diff --git a/ci/php-min-compatibility.neon b/ci/phpmin-compatibility.neon similarity index 77% rename from ci/php-min-compatibility.neon rename to ci/phpmin-compatibility.neon index c925042..ac7cd7b 100644 --- a/ci/php-min-compatibility.neon +++ b/ci/phpmin-compatibility.neon @@ -3,7 +3,7 @@ includes: - ./../vendor/phpstan/phpstan-phpunit/rules.neon parameters: - phpVersion: 80100 # PHP 8.1 - Current minimal version supported + phpVersion: 80300 level: 0 paths: - ./../src diff --git a/composer.json b/composer.json index a81e831..f94196d 100644 --- a/composer.json +++ b/composer.json @@ -19,8 +19,7 @@ }, "autoload-dev": { "psr-4": { - "Eureka\\Kernel\\Console\\Tests\\Unit\\": "./tests/unit/", - "Eureka\\Kernel\\Console\\Tests\\Integration\\": "./tests/integration/" + "Eureka\\Kernel\\Console\\Tests\\": "./tests/" } }, @@ -29,23 +28,24 @@ }, "require": { - "php": "8.1.*||8.2.*||8.3.*", - "eureka/component-console": "^6.0", - - "symfony/config": "^5.4||^6.3||^7.0", - "symfony/dependency-injection": "^5.4||^6.3||^7.0", - "symfony/yaml": "^v5.4||^6.3||^7.0" + "php": ">=8.3", + "eureka/component-console": "^6.0||^7.0", + "symfony/config": "^6.0||^7.0||^8.0", + "symfony/dependency-injection": "^6.0||^7.0||^8.0", + "symfony/finder": "^7.4", + "symfony/yaml": "^6.0||^7.0||^8.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.64.0", - "maglnet/composer-require-checker": "^4.7.1", - "phpstan/phpstan": "^1.12.4", - "phpstan/phpstan-phpunit": "^1.4.0", - "phpunit/phpcov": "^9.0.2", - "phpunit/phpunit": "^10.5.35", - "psr/container": "^1.0||^2.0.2", - "shipmonk/composer-dependency-analyser": "^1.7.0", - "symfony/cache": "^6.4.12||^7.0" + "friendsofphp/php-cs-fixer": "^3.92.4", + "phpstan/phpstan": "^2.1.33", + "phpstan/phpstan-deprecation-rules": "^2.0.3", + "phpstan/phpstan-phpunit": "^2.0.11", + "phpstan/phpstan-strict-rules": "^2.0.7", + "phpunit/phpcov": "^11.0.3", + "phpunit/phpunit": "^12.5.4", + "psr/container": "^2.0.2", + "shipmonk/composer-dependency-analyser": "^1.8.4", + "symfony/cache": "^6.4.12||^7.4.3||^8.0.3" } } diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 065459e..321e2a0 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,9 +1,12 @@ includes: - ./vendor/phpstan/phpstan-phpunit/extension.neon - ./vendor/phpstan/phpstan-phpunit/rules.neon + - ./vendor/phpstan/phpstan-deprecation-rules/rules.neon + - ./vendor/phpstan/phpstan-strict-rules/rules.neon + - phar://phpstan.phar/conf/bleedingEdge.neon parameters: - phpVersion: 80100 # PHP 8.1 - Current minimal version supported + phpVersion: 80300 level: max paths: - ./src diff --git a/phpunit.xml.dist b/phpunit.xml.dist index aef54c5..ec4e1f6 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,34 +1,11 @@ - - - +> @@ -38,10 +15,10 @@ - ./tests/unit + ./tests/Unit - ./tests/integration + ./tests/Integration diff --git a/src/Kernel.php b/src/Kernel.php index f9351fd..4f32104 100644 --- a/src/Kernel.php +++ b/src/Kernel.php @@ -34,7 +34,7 @@ */ class Kernel { - private const CONFIG_EXTENSIONS = '.{php,xml,yaml,yml}'; + private const string CONFIG_EXTENSIONS = '.{php,yaml,yml}'; private ContainerInterface $container; private ContainerBuilder $containerBuilder; @@ -106,8 +106,8 @@ protected function initContainer(): self */ protected function initErrorReporting(int $reporting, string $display): self { - error_reporting($reporting); - ini_set('display_errors', $display); + \error_reporting($reporting); + \ini_set('display_errors', $display); return $this; } @@ -121,14 +121,14 @@ protected function overrideErrorReporting(): self { //~ Override reporting value from config $reporting = $this->container->getParameter('kernel.error.reporting'); - $errorLevel = (int) (!is_scalar($reporting) ? error_reporting(0) : $reporting); + $errorLevel = (int) (!\is_scalar($reporting) ? \error_reporting(0) : $reporting); //~ Override display value from config $display = $this->container->getParameter('kernel.error.display'); - $errorDisplay = (string) (!is_scalar($display) ? ini_get('display_errors') : $display); + $errorDisplay = (string) (!\is_scalar($display) ? \ini_get('display_errors') : $display); - error_reporting($errorLevel); - ini_set('display_errors', $errorDisplay); + \error_reporting($errorLevel); + \ini_set('display_errors', $errorDisplay); return $this; } @@ -144,7 +144,6 @@ protected function loadConfig(): self //~ Load kernel config files $loader->load($this->getConfigDir() . '/{kernel}' . self::CONFIG_EXTENSIONS, 'glob'); - $loader->load($this->getConfigDir() . '/{kernel}_' . $this->environment . self::CONFIG_EXTENSIONS, 'glob'); // @deprecated $this->containerBuilder->setParameter('kernel.environment', $this->environment); $this->containerBuilder->setParameter('kernel.directory.root', $this->rootDirectory); @@ -153,15 +152,14 @@ protected function loadConfig(): self $loader->load($this->getConfigDir() . '/{packages}/*' . self::CONFIG_EXTENSIONS, 'glob'); $loader->load($this->getConfigDir() . '/{packages}/**/*' . self::CONFIG_EXTENSIONS, 'glob'); - //~ Load specific env config files - $loader->load($this->getConfigDir() . '/{' . $this->environment . '}/*' . self::CONFIG_EXTENSIONS, 'glob'); - $loader->load($this->getConfigDir() . '/{' . $this->environment . '}/**/*' . self::CONFIG_EXTENSIONS, 'glob'); - //~ Load services config files $loader->load($this->getConfigDir() . '/{services}' . self::CONFIG_EXTENSIONS, 'glob'); - $loader->load($this->getConfigDir() . '/{services}_' . $this->environment . self::CONFIG_EXTENSIONS, 'glob'); // @deprecated - //~ Load secrets config files + //~ Load specific env config files that can override base config + $loader->load($this->getConfigDir() . '/{' . $this->environment . '}/*' . self::CONFIG_EXTENSIONS, 'glob'); + $loader->load($this->getConfigDir() . '/{' . $this->environment . '}/**/*' . self::CONFIG_EXTENSIONS, 'glob'); + + //~ Load secrets config files that can override base & env configs $loader->load($this->getConfigDir() . '/{secrets}/*' . self::CONFIG_EXTENSIONS, 'glob'); $loader->load($this->getConfigDir() . '/{secrets}/**/*' . self::CONFIG_EXTENSIONS, 'glob'); @@ -224,7 +222,6 @@ protected function getContainerLoader(ContainerBuilder $container): DelegatingLo $resolver = new LoaderResolver( [ - new XmlFileLoader($container, $locator), new YamlFileLoader($container, $locator), new IniFileLoader($container, $locator), new PhpFileLoader($container, $locator), diff --git a/tests/integration/.gitkeep b/tests/Integration/.gitkeep similarity index 100% rename from tests/integration/.gitkeep rename to tests/Integration/.gitkeep diff --git a/tests/unit/KernelTest.php b/tests/Unit/KernelTest.php similarity index 87% rename from tests/unit/KernelTest.php rename to tests/Unit/KernelTest.php index 7e8b5c8..b96ba52 100644 --- a/tests/unit/KernelTest.php +++ b/tests/Unit/KernelTest.php @@ -34,7 +34,7 @@ public function testCanInstantiateKernel(): void $kernel = new Kernel($root, $env, $debug); - $this->assertInstanceOf(Kernel::class, $kernel); + $this->expectNotToPerformAssertions(); } /** @@ -49,6 +49,6 @@ public function testCanGetContainer(): void $kernel = new Kernel($root, $env, $debug); - $this->assertInstanceOf(ContainerInterface::class, $kernel->getContainer()); + $this->expectNotToPerformAssertions(); } }