From 16713354f4af3792006cc9b46cbbdcd1a89bd396 Mon Sep 17 00:00:00 2001 From: Viacheslav Poturaev Date: Thu, 22 Jul 2021 15:38:02 +0200 Subject: [PATCH] Fix exception on duplicate constant name in enum --- .github/workflows/cloc.yml | 35 +++++++++++ .github/workflows/lint.yml | 37 +++++++++++ .github/workflows/test-unit-cov.yml | 38 ++++++++++++ .github/workflows/test-unit.yml | 37 +++++++++++ .gitlab-ci.yml | 37 ----------- .travis.yml | 32 ---------- CHANGELOG.md | 6 ++ composer.lock | 13 ++-- src/JsonSchema/SchemaBuilder.php | 13 +++- src/PhpClass.php | 5 +- tests/src/PHPUnit/JsonSchema/AdvancedTest.php | 62 +++++++++++++++++++ 11 files changed, 237 insertions(+), 78 deletions(-) create mode 100644 .github/workflows/cloc.yml create mode 100644 .github/workflows/lint.yml create mode 100644 .github/workflows/test-unit-cov.yml create mode 100644 .github/workflows/test-unit.yml delete mode 100644 .gitlab-ci.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/cloc.yml b/.github/workflows/cloc.yml new file mode 100644 index 0000000..28cce0b --- /dev/null +++ b/.github/workflows/cloc.yml @@ -0,0 +1,35 @@ +name: cloc +on: + pull_request: +jobs: + cloc: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + with: + path: pr + - name: Checkout base code + uses: actions/checkout@v2 + with: + ref: ${{ github.event.pull_request.base.sha }} + path: base + - name: Count Lines Of Code + id: loc + run: | + curl -OL https://github.com/vearutop/sccdiff/releases/download/v1.0.1/linux_amd64.tar.gz && tar xf linux_amd64.tar.gz + OUTPUT=$(cd pr && ../sccdiff -basedir ../base) + OUTPUT="${OUTPUT//'%'/'%25'}" + OUTPUT="${OUTPUT//$'\n'/'%0A'}" + OUTPUT="${OUTPUT//$'\r'/'%0D'}" + echo "::set-output name=diff::$OUTPUT" + + - name: Comment Code Lines + uses: marocchino/sticky-pull-request-comment@v2 + with: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + header: LOC + message: | + ### Lines Of Code + + ${{ steps.loc.outputs.diff }} diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..b147d4b --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,37 @@ +name: lint +on: + push: + branches: + - master + - main + pull_request: +jobs: + run: + runs-on: ${{ matrix.operating-system }} + strategy: + matrix: + operating-system: [ 'ubuntu-latest' ] + php-versions: [ '7.4' ] + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Cache vendor + uses: actions/cache@v2 + with: + path: | + vendor + key: vendor-${{ hashFiles('composer.lock') }} + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + ini-values: post_max_size=256M, max_execution_time=180 + tools: composer + + - name: Populate vendor + run: '[ -e vendor ] || composer install' + + - name: Lint + run: make lint \ No newline at end of file diff --git a/.github/workflows/test-unit-cov.yml b/.github/workflows/test-unit-cov.yml new file mode 100644 index 0000000..e390471 --- /dev/null +++ b/.github/workflows/test-unit-cov.yml @@ -0,0 +1,38 @@ +name: test-unit-cov +on: + push: + branches: + - master + - main + pull_request: +jobs: + run: + runs-on: ${{ matrix.operating-system }} + strategy: + matrix: + operating-system: [ 'ubuntu-latest' ] + php-versions: [ '7.4' ] + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Cache vendor + uses: actions/cache@v2 + with: + path: | + vendor + key: vendor-${{ hashFiles('composer.lock') }} + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + ini-values: post_max_size=256M, max_execution_time=180 + coverage: xdebug + tools: composer + + - name: Populate vendor + run: '[ -e vendor ] || composer install' + + - name: Run Tests With Coverage + run: make test-coverage && bash <(curl -s https://codecov.io/bash) \ No newline at end of file diff --git a/.github/workflows/test-unit.yml b/.github/workflows/test-unit.yml new file mode 100644 index 0000000..5ee65b4 --- /dev/null +++ b/.github/workflows/test-unit.yml @@ -0,0 +1,37 @@ +name: test-unit +on: + push: + branches: + - master + - main + pull_request: +jobs: + run: + runs-on: ${{ matrix.operating-system }} + strategy: + matrix: + operating-system: [ 'ubuntu-latest' ] + php-versions: [ '5.6', '7.0', '7.1', '7.2', '7.3', '8.0' ] + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Cache vendor + uses: actions/cache@v2 + with: + path: | + vendor + key: vendor-${{ hashFiles('composer.lock') }} + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + ini-values: post_max_size=256M, max_execution_time=180 + tools: composer + + - name: Populate vendor + run: '[ -e vendor ] || composer install' + + - name: Run Tests + run: make test \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index 4b0cfa2..0000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,37 +0,0 @@ -before_script: - - apt-get update -yqq - - apt-get install git unzip -yqq - - curl https://composer.github.io/installer.sig | tr -d '\n' > installer.sig - - php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" - - php -r "if (hash_file('SHA384', 'composer-setup.php') === file_get_contents('installer.sig')) { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" - - php composer-setup.php - - php -r "unlink('composer-setup.php'); unlink('installer.sig');" - - php composer.phar install --prefer-dist --no-ansi --no-interaction --no-progress - -test:5.6: - image: php:5.6 - script: - - pecl install xdebug-2.5.5 - - docker-php-ext-enable xdebug - - vendor/bin/phpunit --configuration phpunit.xml -v --coverage-text --colors=never --stderr - -test:7.0: - image: php:7.0 - script: - - pecl install xdebug - - docker-php-ext-enable xdebug - - vendor/bin/phpunit --configuration phpunit.xml -v --coverage-text --colors=never --stderr - -test:7.1: - image: php:7.1 - script: - - pecl install xdebug - - docker-php-ext-enable xdebug - - vendor/bin/phpunit --configuration phpunit.xml -v --coverage-text --colors=never --stderr - -test:7.2: - image: php:7.2 - script: - - pecl install xdebug - - docker-php-ext-enable xdebug - - vendor/bin/phpunit --configuration phpunit.xml -v --coverage-text --colors=never --stderr diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 8562361..0000000 --- a/.travis.yml +++ /dev/null @@ -1,32 +0,0 @@ -language: php -php: - - nightly - - 7.3 - - 7.2 - - 7.1 - - 7.0 - - 5.6 - -sudo: false -dist: trusty - -## Cache composer bits -cache: - directories: - - $HOME/.cache/composer - -before_script: - - composer install --dev --no-interaction --prefer-dist - - if ! [[ $(phpenv version-name) =~ 7.3 ]] ; then phpenv config-rm xdebug.ini || true ; fi - -matrix: - allow_failures: - - php: nightly - fast_finish: true - -script: - - if [[ $(phpenv version-name) =~ 7.3 ]] ; then make test-coverage; else make test; fi - - if [[ $(phpenv version-name) =~ 7.2 ]] ; then make lint; fi - -after_script: - - if [[ $(phpenv version-name) =~ 7.3 ]] ; then bash <(curl -s https://codecov.io/bash); fi diff --git a/CHANGELOG.md b/CHANGELOG.md index 4efbeb4..48db360 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.34] - 2021-07-22 + +### Fixes +- Handling of conflicting constant names for `enum` in generated classes. + ## [0.2.33] - 2021-05-27 ### Fixes @@ -93,6 +98,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Description trimming bug. +[0.2.34]: https://github.com/swaggest/php-code-builder/compare/v0.2.33...v0.2.34 [0.2.33]: https://github.com/swaggest/php-code-builder/compare/v0.2.32...v0.2.33 [0.2.32]: https://github.com/swaggest/php-code-builder/compare/v0.2.31...v0.2.32 [0.2.31]: https://github.com/swaggest/php-code-builder/compare/v0.2.30...v0.2.31 diff --git a/composer.lock b/composer.lock index 04a062d..7565f30 100644 --- a/composer.lock +++ b/composer.lock @@ -249,16 +249,16 @@ }, { "name": "swaggest/json-schema", - "version": "v0.12.33", + "version": "v0.12.36", "source": { "type": "git", "url": "https://github.com/swaggest/php-json-schema.git", - "reference": "87919a4564b9682c4c4328d00ba28f9f631b0bbc" + "reference": "cbdf1d92d45ace7e1152714ba878bc57ba896461" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/swaggest/php-json-schema/zipball/87919a4564b9682c4c4328d00ba28f9f631b0bbc", - "reference": "87919a4564b9682c4c4328d00ba28f9f631b0bbc", + "url": "https://api.github.com/repos/swaggest/php-json-schema/zipball/cbdf1d92d45ace7e1152714ba878bc57ba896461", + "reference": "cbdf1d92d45ace7e1152714ba878bc57ba896461", "shasum": "" }, "require": { @@ -292,9 +292,9 @@ "support": { "email": "vearutop@gmail.com", "issues": "https://github.com/swaggest/php-json-schema/issues", - "source": "https://github.com/swaggest/php-json-schema/tree/v0.12.33" + "source": "https://github.com/swaggest/php-json-schema/tree/v0.12.36" }, - "time": "2021-05-27T14:35:43+00:00" + "time": "2021-07-13T22:20:37+00:00" } ], "packages-dev": [ @@ -1563,6 +1563,7 @@ "issues": "https://github.com/sebastianbergmann/resource-operations/issues", "source": "https://github.com/sebastianbergmann/resource-operations/tree/master" }, + "abandoned": true, "time": "2015-07-28T20:34:47+00:00" }, { diff --git a/src/JsonSchema/SchemaBuilder.php b/src/JsonSchema/SchemaBuilder.php index 51c3af0..fb9bb13 100644 --- a/src/JsonSchema/SchemaBuilder.php +++ b/src/JsonSchema/SchemaBuilder.php @@ -285,7 +285,18 @@ private function processEnum() } $value = var_export($enumItem, true); if ($this->saveEnumConstInClass !== null && is_scalar($enumItem) && !is_bool($enumItem)) { - $this->saveEnumConstInClass->addConstant(new PhpConstant($name, $enumItem)); + $checkName = $name; + $i = 1; + do { + try { + $this->saveEnumConstInClass->addConstant(new PhpConstant($checkName, $enumItem)); + $name = $checkName; + break; + } catch (\Swaggest\PhpCodeBuilder\Exception $exception) { + $i++; + $checkName = $name . $i; + } + } while(true); $this->result->addSnippet( " self::$name,\n" ); diff --git a/src/PhpClass.php b/src/PhpClass.php index c8efbe7..72b00f0 100644 --- a/src/PhpClass.php +++ b/src/PhpClass.php @@ -125,7 +125,8 @@ public function addConstant(PhpConstant $constant) { if (array_key_exists($constant->getName(), $this->constants)) { if ($this->constants[$constant->getName()]->getValue() !== $constant->getValue()) { - throw new Exception('Duplicate const with different value'); + throw new Exception('Duplicate const "' . $constant->getName() . '" with different value, ' . + $constant->getValue() . ' !== ' . $this->constants[$constant->getName()]->getValue()); } } else { $this->constants[$constant->getName()] = $constant; @@ -137,8 +138,8 @@ public function addConstant(PhpConstant $constant) * Adds a new trait to the list of traits * * @param PhpTrait $trait - * @throws Exception if a trait already exists with same name * @return self + * @throws Exception if a trait already exists with same name */ public function addTrait(PhpTrait $trait) { diff --git a/tests/src/PHPUnit/JsonSchema/AdvancedTest.php b/tests/src/PHPUnit/JsonSchema/AdvancedTest.php index fe1e3e1..3b2fec4 100644 --- a/tests/src/PHPUnit/JsonSchema/AdvancedTest.php +++ b/tests/src/PHPUnit/JsonSchema/AdvancedTest.php @@ -8,6 +8,68 @@ class AdvancedTest extends \PHPUnit_Framework_TestCase { + public function testEnumConst() + { + $schemaData = json_decode(<<<'JSON' +{ + "properties": { + "foo": {"enum": ["a","b","B"]}, + "bar": {"multipleOf": 3,"const":"A"} + } +} +JSON + ); + + $schema = Schema::import($schemaData); + $builder = new PhpBuilder(); + $builder->makeEnumConstants = true; + $class = $builder->getClass($schema, 'Root'); + + $result = ''; + foreach ($builder->getGeneratedClasses() as $class) { + $result .= $class->class . "\n\n"; + } + + $expected = <<<'JSON' +class Root extends Swaggest\JsonSchema\Structure\ClassStructure +{ + const A = 'a'; + + const B = 'b'; + + const B2 = 'B'; + + /** @var mixed */ + public $foo; + + /** @var mixed */ + public $bar; + + /** + * @param Swaggest\JsonSchema\Constraint\Properties|static $properties + * @param Swaggest\JsonSchema\Schema $ownerSchema + */ + public static function setUpProperties($properties, Swaggest\JsonSchema\Schema $ownerSchema) + { + $properties->foo = new Swaggest\JsonSchema\Schema(); + $properties->foo->enum = array( + self::A, + self::B, + self::B2, + ); + $properties->bar = new Swaggest\JsonSchema\Schema(); + $properties->bar->multipleOf = 3; + $properties->bar->const = "A"; + } +} + + +JSON; +; + + $this->assertSame($expected, $result); + } + public function testOneOf() { $schemaData = json_decode(<<<'JSON'