Skip to content

Commit

Permalink
Merge branch 'release/3.3.4'
Browse files Browse the repository at this point in the history
  • Loading branch information
mikaelcom committed Jan 25, 2021
2 parents 5d2c295 + bcc6027 commit 59c75bd
Show file tree
Hide file tree
Showing 63 changed files with 104,296 additions and 60 deletions.
2 changes: 1 addition & 1 deletion .docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM splitbrain/phpfarm:jessie

RUN apt-get update && apt-get install -y git
RUN apt-get update && apt-get install -y git zip

COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
COPY . /var/www/
Expand Down
2 changes: 0 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,12 @@ jobs:
fast_finish: true
allow_failures:
- php: 'nightly'
- php: '8.0'

cache:
directories:
- $HOME/.composer/cache

install:
- if [[ ${TRAVIS_PHP_VERSION:0:3} == "8.0" ]]; then cat composer-php8.json > composer.json; fi
- composer install

script:
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# CHANGELOG

## 3.3.4 - 2021-01-25
- issue #230 - Avoid repeated meta value within generated meta documentation
- issue #217 - Inherited struct methods should not be overwritten
- issue #214 - element with maxOccurs unbounded inside a sequence gets translated into a string instead of an array

## 3.3.3 - 2020-11-16
- issue #229 - Docker image issues

Expand Down
12 changes: 4 additions & 8 deletions src/File/Struct.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,23 +31,19 @@ protected function getConstantAnnotationBlock(PhpConstant $constant)
{
}
/**
* @param bool $includeInheritanceAttributes include the attributes of parent class, default parent attributes are not included. If true, then the array is an associative array containing and index "attribute" for the StructAttribute object and an index "model" for the Struct object.
* @param bool $requiredFirst places the required attributes first, then the not required in order to have the __construct method with the required attribute at first
* @return StructAttributeContainer
*/
protected function getModelAttributes($includeInheritanceAttributes = false, $requiredFirst = true)
protected function getModelAttributes()
{
return $this->getModel()->getAttributes($includeInheritanceAttributes, $requiredFirst);
return $this->getModel()->getProperAttributes(true);
}
/**
* @param PropertyContainer $properties
*/
protected function getClassProperties(PropertyContainer $properties)
{
if ($this->getModel()->getAttributes()->count() > 0) {
foreach ($this->getModelAttributes() as $attribute) {
$properties->add(new PhpProperty($attribute->getCleanName(), PhpProperty::NO_VALUE));
}
foreach ($this->getModelAttributes() as $attribute) {
$properties->add(new PhpProperty($attribute->getCleanName(), PhpProperty::NO_VALUE));
}
}
/**
Expand Down
2 changes: 1 addition & 1 deletion src/File/Utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public static function getMetaValueAnnotation($metaName, $metaValue)
{
$meta = null;
if (is_array($metaValue)) {
$metaValue = implode(' | ', $metaValue);
$metaValue = implode(' | ', array_unique($metaValue));
}
$metaValue = GeneratorUtils::cleanComment($metaValue, ', ', mb_stripos($metaName, 'SOAPHeader') === false);
if (is_scalar($metaValue)) {
Expand Down
2 changes: 1 addition & 1 deletion src/File/Validation/AbstractBoundRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,6 @@ final public function testConditions($parameterName, $value, $itemType = false)
*/
final public function exceptionMessageOnTestFailure($parameterName, $value, $itemType = false)
{
return sprintf('sprintf(\'Invalid value %%s, the value must be %s %s %s\', var_export($%4$s, true))', is_numeric($value) ? 'numerically' : 'chronologically', $this->comparisonString(), $value, $parameterName);
return sprintf('sprintf(\'Invalid value %%s, the value must be %s %s %s\', var_export($%4$s, true))', is_numeric($value) ? 'numerically' : 'chronologically', $this->comparisonString(), is_array($value) ? implode(',', array_unique($value)) : $value, $parameterName);
}
}
2 changes: 1 addition & 1 deletion src/File/Validation/AbstractLengthRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ final public function testConditions($parameterName, $value, $itemType = false)
final public function exceptionMessageOnTestFailure($parameterName, $value, $itemType = false)
{
if ($itemType || !$this->getAttribute()->isArray()) {
$message = sprintf('sprintf(\'Invalid length of %%s, the number of characters/octets contained by the literal must be %s %s\', mb_strlen($%s))', $this->comparisonString(), $value, $parameterName);
$message = sprintf('sprintf(\'Invalid length of %%s, the number of characters/octets contained by the literal must be %s %s\', mb_strlen($%s))', $this->comparisonString(), is_array($value) ? implode(',', array_unique($value)) : $value, $parameterName);
} else {
$message = $this->getErrorMessageVariableName($parameterName);
}
Expand Down
2 changes: 1 addition & 1 deletion src/File/Validation/AbstractRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ final public function applyRule($parameterName, $value, $itemType = false)
*/
final public function validationRuleComment($value)
{
return sprintf('// %s %s%s', self::VALIDATION_RULE_COMMENT_SENTENCE, $this->name(), is_array($value) ? sprintf('(%s)', implode(', ', $value)) : (empty($value) ? '' : sprintf('(%s)', $value)));
return sprintf('// %s %s%s', self::VALIDATION_RULE_COMMENT_SENTENCE, $this->name(), is_array($value) ? sprintf('(%s)', implode(', ', array_unique($value))) : (empty($value) ? '' : sprintf('(%s)', $value)));
}

/**
Expand Down
7 changes: 4 additions & 3 deletions src/File/Validation/MaxOccursRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace WsdlToPhp\PackageGenerator\File\Validation;

/**
* Class LengthRule
* Class MaxOccursRule
* @link https://www.w3.org/TR/2004/REC-xmlschema-1-20041028/structures.html#p-max_occurs
* Validation Rule: Element Sequence Locally Valid (Particle)
* For a sequence (possibly empty) of element information items to be locally ·valid· with respect to a particle the appropriate case among the following must be true:
Expand Down Expand Up @@ -47,6 +47,7 @@ public function symbol()
}

/**
* If maxOccurs is 'unbounded', no need to check occurrences count
* @param string $parameterName
* @param mixed $value
* @param bool $itemType
Expand All @@ -55,7 +56,7 @@ public function symbol()
final public function testConditions($parameterName, $value, $itemType = false)
{
$test = '';
if ('unbounded' !== $value && $this->getAttribute()->isArray()) {
if ($this->getAttribute()->isArray() && ((is_scalar($value) && 'unbounded' !== $value) || (is_array($value) && !in_array('unbounded', $value)))) {
if ($itemType) {
$test = 'is_array($this->%1$s) && count($this->%1$s) %3$s %2$d';
$symbol = self::SYMBOL_MAX_EXCLUSIVE;
Expand All @@ -81,6 +82,6 @@ final public function exceptionMessageOnTestFailure($parameterName, $value, $ite
} else {
$message = 'sprintf(\'Invalid count of %%s, the number of elements contained by the property must be %1$s %2$s\', count($%3$s))';
}
return sprintf($message, $this->comparisonString(), $value, $parameterName, $this->getAttribute()->getCleanName());
return sprintf($message, $this->comparisonString(), is_array($value) ? implode(',', array_unique($value)) : $value, $parameterName, $this->getAttribute()->getCleanName());
}
}
50 changes: 50 additions & 0 deletions src/File/Validation/MinOccursRule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

namespace WsdlToPhp\PackageGenerator\File\Validation;

/**
* Class MinOccursRule
* @link https://www.w3.org/TR/2004/REC-xmlschema-1-20041028/structures.html#p-min_occurs
* This class is intended to show that this cas has not been forgotten. It simply isn't used as the minimum occurrences count can't be checked.
* Checking the minimum occurrences count would be meaningful just before the request which is done currently.
*/
class MinOccursRule extends AbstractMinMaxRule
{
/**
* @return string
*/
public function name()
{
return 'minOccurs';
}

/**
* @return string
*/
public function symbol()
{
return '';
}

/**
* @param string $parameterName
* @param mixed $value
* @param bool $itemType
* @return string
*/
final public function testConditions($parameterName, $value, $itemType = false)
{
return '';
}

/**
* @param string $parameterName
* @param mixed $value
* @param bool $itemType
* @return string
*/
final public function exceptionMessageOnTestFailure($parameterName, $value, $itemType = false)
{
return '';
}
}
45 changes: 38 additions & 7 deletions src/Model/Struct.php
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,44 @@ public function isArray()
*/
public function getAttributes($includeInheritanceAttributes = false, $requiredFirst = false)
{
if ($includeInheritanceAttributes === false && $requiredFirst === false) {
if (!$includeInheritanceAttributes && !$requiredFirst) {
$attributes = $this->attributes;
} else {
$attributes = $this->getAllAttributes($includeInheritanceAttributes, $requiredFirst);
}
return $attributes;
}

/**
* Returns the attributes of the struct and not the ones that are declared by the parent struct if this struct inherits from a Struct
* This means it removes from the attributes this Struct has the attributes declared by its parent class(es)
* @param bool $requiredFirst places the required attributes first, then the not required in order to have the _construct method with the required attribute at first
* @return StructAttributeContainer
*/
public function getProperAttributes($requiredFirst = false)
{
$properAttributes = new StructAttributeContainer($this->getGenerator());
$parentAttributes = new StructAttributeContainer($this->getGenerator());

if ($this->getInheritance() != '' && ($model = $this->getInheritanceStruct()) instanceof Struct) {
while ($model instanceof Struct && $model->isStruct()) {
foreach ($model->getAttributes() as $attribute) {
$parentAttributes->add($attribute);
}
$model = $model->getInheritanceStruct();
}
}

/** @var StructAttribute $attribute */
foreach ($this->getAttributes() as $attribute) {
if ($parentAttributes->getStructAttributeByName($attribute->getName())) {
continue;
}
$properAttributes->add($attribute);
}

return $requiredFirst ? $this->putRequiredAttributesFirst($properAttributes) : $properAttributes;
}
/**
* @param bool $includeInheritanceAttributes
* @param bool $requiredFirst
Expand All @@ -161,14 +192,14 @@ public function getAttributes($includeInheritanceAttributes = false, $requiredFi
protected function getAllAttributes($includeInheritanceAttributes, $requiredFirst)
{
$allAttributes = new StructAttributeContainer($this->getGenerator());
if ($includeInheritanceAttributes === true) {
if ($includeInheritanceAttributes) {
$this->addInheritanceAttributes($allAttributes);
}
foreach ($this->attributes as $attribute) {
$allAttributes->add($attribute);
}
if ($requiredFirst === true) {
$attributes = $this->putRequiredFirst($allAttributes);
if ($requiredFirst) {
$attributes = $this->putRequiredAttributesFirst($allAttributes);
} else {
$attributes = $allAttributes;
}
Expand All @@ -192,7 +223,7 @@ protected function addInheritanceAttributes(StructAttributeContainer $attributes
* @param StructAttributeContainer $allAttributes
* @return StructAttributeContainer
*/
protected function putRequiredFirst(StructAttributeContainer $allAttributes)
protected function putRequiredAttributesFirst(StructAttributeContainer $allAttributes)
{
$attributes = new StructAttributeContainer($this->getGenerator());
$requiredAttributes = new StructAttributeContainer($this->getGenerator());
Expand Down Expand Up @@ -220,7 +251,7 @@ protected function putRequiredFirst(StructAttributeContainer $allAttributes)
*/
public function countOwnAttributes()
{
return $this->getAttributes(false, false)->count();
return $this->getAttributes()->count();
}
/**
* Returns the number of all attributes
Expand Down Expand Up @@ -384,7 +415,7 @@ public function addValue($value)
$this
->setStruct(true)
->setRestriction(true)
->values->add(new StructValue($this->getGenerator(), $value, $this->getValues()->count(), $this));
->getValues()->add(new StructValue($this->getGenerator(), $value, $this->getValues()->count(), $this));
}
}
return $this;
Expand Down
6 changes: 4 additions & 2 deletions src/Model/StructAttribute.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,13 @@ public function getContainsElements()
}
/**
* Sets the type value
* If already able to contain several occurrences, it must stay as it is, the wider behaviour wins
* @param bool $containsElements
* @return StructAttribute
*/
public function setContainsElements($containsElements)
{
$this->containsElements = $containsElements;
$this->containsElements = $this->containsElements || $containsElements;
return $this;
}
/**
Expand All @@ -148,12 +149,13 @@ public function isAChoice()
return is_array($this->getMetaValue('choice'));
}
/**
* If already able to be removed from request, it must stay as it is, the wider behaviour wins
* @param bool $removableFromRequest
* @return StructAttribute
*/
public function setRemovableFromRequest($removableFromRequest)
{
$this->removableFromRequest = $removableFromRequest;
$this->removableFromRequest = $this->removableFromRequest || $removableFromRequest;
return $this;
}
/**
Expand Down
2 changes: 1 addition & 1 deletion tests/File/AbstractFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ protected function assertSameFileContent($valid, File $file, $fileExtension = 'p
return $this->fail(sprintf('Generated file "%s" could not be found', $file->getFileName()));
}
// uncomment next line to easily regenerate all valid files :)
file_put_contents(sprintf('%s%s.%s', self::getTestDirectory(), $valid, $fileExtension), str_replace($file->getGenerator()->getWsdl()->getName(), '__WSDL_URL__', file_get_contents($file->getFileName())));
// file_put_contents(sprintf('%s%s.%s', self::getTestDirectory(), $valid, $fileExtension), str_replace($file->getGenerator()->getWsdl()->getName(), '__WSDL_URL__', file_get_contents($file->getFileName())));
$validContent = file_get_contents(sprintf('%s%s.%s', self::getTestDirectory(), $valid, $fileExtension));
$validContent = str_replace('__WSDL_URL__', $file->getGenerator()->getWsdl()->getName(), $validContent);
$toBeValidatedContent = file_get_contents($file->getFileName());
Expand Down
42 changes: 42 additions & 0 deletions tests/File/StructTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,32 @@ public function testWriteYandexDirectApiStructAddRequest()
$this->fail('Unable to find AddRequest struct for file generation');
}
}
/**
*
*/
public function testWriteYandexDirectApiStructAddRequestWithRepeatedMetaValueMaxOccurs()
{
$generator = self::yandexDirectApiAdGroupsGeneratorInstance();
if (($model = $generator->getStructByName('AddRequest')) instanceof StructModel) {
$model->getAttribute('AdGroups')
->addMeta('maxOccurs', 1)
->addMeta('maxOccurs', 'unbounded');

$this->assertSame([
'unbounded',
1,
'unbounded',
], $model->getAttribute('AdGroups')->getMetaValue('maxOccurs'));

$struct = new StructFile($generator, $model->getName());
$struct
->setModel($model)
->write();
$this->assertSameFileContent('ValidAddRequestRepeatedMaxOccurs', $struct);
} else {
$this->fail('Unable to find AddRequest struct for file generation');
}
}
/**
*
*/
Expand Down Expand Up @@ -496,4 +522,20 @@ public function testWriteEwsStructProposeNewTimeTypeWithNoConstructor()
$this->assertFalse(true, 'Unable to find ProposeNewTimeType struct for file generation');
}
}
/**
*
*/
public function testWriteVehicleSelectionStructFieldString1000()
{
$generator = self::vehicleSelectionPackGeneratorInstance();
if (($model = $generator->getStructByName('fieldString1000')) instanceof StructModel) {
$struct = new StructFile($generator, $model->getName());
$struct
->setModel($model)
->write();
$this->assertSameFileContent('ValidFieldString1000', $struct);
} else {
$this->fail('Unable to find fieldString1000 struct for file generation');
}
}
}
2 changes: 0 additions & 2 deletions tests/File/Validation/ItemTypeRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ class ItemTypeRuleTest extends AbstractRuleTest
* TypeError introduced in PHP 7, https://www.php.net/manual/fr/class.typeerror.php
* @requires PHP 7.0
* @expectedException \TypeError
* @expectedExceptionMessage Argument 1 passed to Api\StructType\ApiTaxType::addToTaxDescription() must be an instance of Api\StructType\ApiParagraphType, string given
*/
public function testAddToTaxDescriptionValueWithStringValueMustThrowATypeError()
{
Expand All @@ -21,7 +20,6 @@ public function testAddToTaxDescriptionValueWithStringValueMustThrowATypeError()
* TypeError introduced in PHP 7, https://www.php.net/manual/fr/class.typeerror.php
* @requires PHP 7.0
* @expectedException \TypeError
* @expectedExceptionMessage Argument 1 passed to Api\StructType\ApiTaxType::addToTaxDescription() must be an instance of Api\StructType\ApiParagraphType, null given
*/
public function testAddToTaxDescriptionValueWithNullValueMustThrowAnException()
{
Expand Down
Loading

0 comments on commit 59c75bd

Please sign in to comment.