Skip to content

Commit

Permalink
Merge pull request #50 from c-harris/MoreTests
Browse files Browse the repository at this point in the history
More tests
  • Loading branch information
CyberiaResurrection committed Jul 25, 2020
2 parents 8520765 + 3460b72 commit 2b713c2
Show file tree
Hide file tree
Showing 147 changed files with 4,206 additions and 991 deletions.
8 changes: 4 additions & 4 deletions composer.json
Expand Up @@ -30,13 +30,13 @@
"ext-xmlreader": "*"
},
"require-dev": {
"mockery/mockery": "^1.2|dev-master",
"php-coveralls/php-coveralls": ">=v2.1",
"phpspec/phpspec": "^3.0",
"squizlabs/php_codesniffer": "~2.3",
"phpstan/phpstan": "^0.12",
"phpunit/phpunit": "^7.0",
"php-coveralls/php-coveralls": ">=v2.1",
"mockery/mockery": "^1.2|dev-master",
"squizlabs/php_codesniffer": "~2.3",
"symfony/var-dumper": ">=4.0.0"

},
"scripts": {
"test": "phpunit",
Expand Down
51 changes: 40 additions & 11 deletions src/Asserts.php
Expand Up @@ -10,6 +10,7 @@
use ReflectionFunction;
use ReflectionFunctionAbstract;
use ReflectionMethod;
use ReflectionNamedType;

abstract class Asserts
{
Expand Down Expand Up @@ -44,32 +45,52 @@ public static function assertSignatureMatches(callable $expected, callable $actu
$messageBuilder('Missing Return Type')
);
//TODO: improve this to check that the actual type does not return a childType;
$expectedReturnType = $expectedReflection->getReturnType();
$actualReturnType = $actualReflection->getReturnType();
$name = $expectedReturnType instanceof ReflectionNamedType ?
$expectedReturnType->getName() :
strval($expectedReturnType);
$actName = $actualReturnType instanceof ReflectionNamedType ?
$actualReturnType->getName() :
strval($actualReturnType);

assert(
$expectedReflection->getReturnType()->getName() === $actualReflection->getReturnType()->getName(),
$name === $actName,
$messageBuilder('IncorrectOrInvalid ReturnType')
);
if (!$expectedReflection->getReturnType()->allowsNull()) {
if (!$expectedReturnType->allowsNull()) {
assert(
!$actualReflection->getReturnType()->allowsNull(),
!$actualReturnType->allowsNull(),
$messageBuilder('Nullable ReturnType Not allowed')
);
}
}

for ($i = 0; $i < $expectedReflection->getNumberOfParameters(); $i++) {
if ($expectedReflection->getParameters()[$i]->hasType()) {
$expectedParm = $expectedReflection->getParameters()[$i];
if ($expectedParm->hasType()) {
$actualParm = $actualReflection->getParameters()[$i];
assert(
$actualReflection->getParameters()[$i]->hasType(),
$actualParm->hasType(),
$messageBuilder(sprintf('Parameter %s Is missing TypeHint', $i))
);
$expectedParmType = $expectedParm->getType();
$actualParmType = $actualParm->getType();
$name = $expectedParmType instanceof ReflectionNamedType ?
$expectedParmType->getName() :
strval($expectedParmType);
$actName = $actualParmType instanceof ReflectionNamedType ?
$actualParmType->getName() :
strval($actualParmType);

//TODO: improve this to check that the actual type does not return a childType;
assert(
$expectedReflection->getParameters()[$i]->getType()->getName() === $actualReflection->getParameters()[$i]->getType()->getName(),
$name === $actName,
$messageBuilder(sprintf('Parameter %s has Incorrect Type', $i))
);
if (!$expectedReflection->getParameters()[$i]->allowsNull()) {
if (!$expectedParm->allowsNull()) {
assert(
!$actualReflection->getParameters()[$i]->allowsNull(),
!$actualParm->allowsNull(),
$messageBuilder(sprintf('Parameter %s should disallow Nulls', $i))
);
}
Expand All @@ -84,8 +105,12 @@ private static function getSignatureFromReflection(ReflectionFunctionAbstract $r
foreach ($reflection->getParameters() as $parameter) {
$parameterString = '';
if ($parameter->hasType()) {
$parameterString .= $parameter->getType()->allowsNull() ? '?' : '';
$parameterString .=$parameter->getType()->getName() . ' ';
$parmType = $parameter->getType();
$parmName = $parmType instanceof ReflectionNamedType ?
$parmType->getName() :
strval($parmType);
$parameterString .= $parmType->allowsNull() ? '?' : '';
$parameterString .= $parmName . ' ';
}
$parameterString .= $parameter->isVariadic() ? '...$' : '$';
$parameterString .= $parameter->getName();
Expand All @@ -100,7 +125,11 @@ private static function getSignatureFromReflection(ReflectionFunctionAbstract $r
}
$return = '';
if ($reflection->hasReturnType()) {
$return .= ': ' . $reflection->getReturnType()->getName();
$returnType = $reflection->getReturnType();
$name = $returnType instanceof ReflectionNamedType ?
$returnType->getName() :
strval($returnType);
$return .= ': ' . $name;
}
return sprintf('function(%s)%s', implode(',', $parameters), $return);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Csdl/EdmxTarget.php
Expand Up @@ -8,7 +8,7 @@
use AlgoWeb\ODataMetadata\Enums\Enum;

/**
* @method static OData()
* @method static self OData()
*/
class EdmxTarget extends Enum
{
Expand Down
43 changes: 29 additions & 14 deletions src/Csdl/Internal/Serialization/EdmModelCsdlSchemaWriter.php
Expand Up @@ -77,6 +77,7 @@
use AlgoWeb\ODataMetadata\Version;
use ReflectionFunction;
use ReflectionMethod;
use ReflectionNamedType;
use XMLWriter;

class EdmModelCsdlSchemaWriter implements IEdmModelCsdlSchemaWriter
Expand Down Expand Up @@ -126,7 +127,7 @@ public function WriteValueTermElementHeader(IValueTerm $term, bool $inlineType):
$term->getName(),
[EdmValueWriter::class, 'StringAsXml']
);
if ($inlineType && $term->getType() != null) {
if ($inlineType && null !== $term->getType()) {
$this->WriteRequiredAttribute(
CsdlConstants::Attribute_Type,
$term->getType(),
Expand Down Expand Up @@ -730,7 +731,7 @@ public function WriteNamespaceUsingElement(string $usingNamespace, string $alias
public function WriteAnnotationStringAttribute(IDirectValueAnnotation $annotation): void
{
$edmValue = $annotation->getValue();
if ($annotation->getValue() instanceof IPrimitiveValue) {
if ($edmValue instanceof IPrimitiveValue) {
$this->xmlWriter->writeAttributeNs(
'',
$annotation->getName(),
Expand Down Expand Up @@ -834,7 +835,7 @@ public function WriteFunctionImportElementHeader(IFunctionImport $functionImport
[EdmValueWriter::class, 'BooleanAsXml']
);
$entitySetReference = $functionImport->getEntitySet();
if ($functionImport->getEntitySet() != null) {
if (null !== $functionImport->getEntitySet()) {
if ($entitySetReference instanceof IEntitySetReferenceExpression) {
$this->WriteOptionalAttribute(
CsdlConstants::Attribute_EntitySet,
Expand Down Expand Up @@ -1015,7 +1016,6 @@ public function WriteInlineExpression(IExpression $expression): void
throw new InvalidOperationException(
StringConst::UnknownEnumVal_ExpressionKind($expression->getExpressionKind()->getKey())
);
break;
}
}

Expand Down Expand Up @@ -1342,18 +1342,29 @@ public function WriteEndElement(): void
$this->xmlWriter->endElement();
}

/**
* @param string $attribute
* @param mixed $value
* @param mixed $defaultValue
* @param callable $toXml
* @throws \ReflectionException
*/
public function WriteOptionalAttribute(string $attribute, $value, $defaultValue, callable $toXml): void
{
$stem = is_array($toXml) ? new ReflectionMethod(...$toXml) :
new ReflectionFunction($toXml);
/* @noinspection PhpUnhandledExceptionInspection suppressing exceptions for asserts.*/
assert(
count((is_array($toXml) ? new ReflectionMethod(...$toXml) :
new ReflectionFunction($toXml))->getParameters()) === 1,
'$toXml should be a callable takeing one paramater of mixed type'
1 === count(($stem)->getParameters()),
'$toXml should be a callable taking one parameter of mixed type'
);
$stemType = $stem->getReturnType();
$name = $stemType instanceof ReflectionNamedType ?
$stemType->getName() :
strval($stemType);
/* @noinspection PhpUnhandledExceptionInspection suppressing exceptions for asserts.*/
assert(
(is_array($toXml) ? new ReflectionMethod(...$toXml) :
new ReflectionFunction($toXml))->getReturnType()->getName() === 'string',
'string' === $name,
'$toXml should be a callable returning a string'
);
if ($value !== $defaultValue) {
Expand All @@ -1369,16 +1380,20 @@ public function WriteOptionalAttribute(string $attribute, $value, $defaultValue,
*/
public function WriteRequiredAttribute(string $attribute, $value, callable $toXml): void
{
$stem = is_array($toXml) ? new ReflectionMethod(...$toXml) :
new ReflectionFunction($toXml);
/* @noinspection PhpUnhandledExceptionInspection suppressing exceptions for asserts.*/
assert(
count((is_array($toXml) ? new ReflectionMethod(...$toXml) :
new ReflectionFunction($toXml))->getParameters()) === 1,
'$toXml should be a callable takeing one paramater of mixed type'
1 === count($stem->getParameters()),
'$toXml should be a callable taking one parameter of mixed type'
);
$stemType = $stem->getReturnType();
$name = $stemType instanceof ReflectionNamedType ?
$stemType->getName() :
strval($stemType);
/* @noinspection PhpUnhandledExceptionInspection suppressing exceptions for asserts.*/
assert(
(is_array($toXml) ? new ReflectionMethod(...$toXml) :
new ReflectionFunction($toXml))->getReturnType()->getName() === 'string',
'string' === $name,
'$toXml should be a callable returning a string'
);
$this->xmlWriter->writeAttribute($attribute, $toXml($value));
Expand Down
Expand Up @@ -87,7 +87,7 @@ class EdmModelCsdlSerializationVisitor extends EdmModelVisitor
*/
private $schemaWriter;
/**
* @var INavigationProperty
* @var INavigationProperty[]
*/
private $navigationProperties = [];
/**
Expand Down Expand Up @@ -214,9 +214,9 @@ function (Tuple $set) use ($self, $entitySet, $mapping) {
);
// This prevents us from losing association sets if they share the same name.
if (!count($any) > 0) {
$this->associationSets[$associationSetName] =
$this->associationSets[$associationSetName][] =
new Tuple($entitySet, $mapping->getNavigationProperty());
$this->associationSets[$associationSetName] =
$this->associationSets[$associationSetName][] =
new Tuple($mapping->getTargetEntitySet(), $mapping->getNavigationProperty()->getPartner());

$this->ProcessAssociationSet($entitySet, $mapping->getNavigationProperty());
Expand Down Expand Up @@ -248,9 +248,9 @@ protected function ProcessEntitySet(IEntitySet $element): void
protected function ProcessEntityType(IEntityType $element): void
{
$this->BeginElement($element, [$this->schemaWriter, 'WriteEntityTypeElementHeader']);
if ($element->getDeclaredKey() != null &&
if (null !== $element->getDeclaredKey() &&
count($element->getDeclaredKey()) > 0 &&
$element->getBaseType() == null) {
null === $element->getBaseType()) {
$this->VisitEntityTypeDeclaredKey($element->getDeclaredKey());
}

Expand Down Expand Up @@ -396,7 +396,7 @@ protected function ProcessValueTerm(IValueTerm $term): void
*/
protected function ProcessFunction(IFunction $element): void
{
if ($element->getReturnType() != null) {
if (null !== $element->getReturnType()) {
$inlineReturnType = self::IsInlineType($element->getReturnType());
$this->BeginElement($element, function (IFunction $f) use ($inlineReturnType) {
$this->schemaWriter->WriteFunctionElementHeader($f, $inlineReturnType);
Expand Down Expand Up @@ -484,7 +484,7 @@ protected function ProcessRowType(IRowType $element): void
*/
protected function ProcessFunctionImport(IFunctionImport $functionImport): void
{
if ($functionImport->getReturnType() != null && !self::IsInlineType($functionImport->getReturnType())) {
if (null !== $functionImport->getReturnType() && !self::IsInlineType($functionImport->getReturnType())) {
throw new InvalidOperationException(
StringConst::Serializer_NonInlineFunctionImportReturnType(
$functionImport->getContainer()->FullName() . '/' . $functionImport->getName()
Expand Down Expand Up @@ -892,9 +892,9 @@ private function ProcessAssociationEnd(INavigationProperty $element, iterable $a
*/
private function ProcessReferentialConstraint(INavigationProperty $element, iterable $annotations): void
{
if ($element->getDependentProperties() != null) {
if ($element->getDependentProperties() !== null) {
$principalElement = $element->getPartner();
} elseif ($element->getPartner()->getDependentProperties() != null) {
} elseif ($element->getPartner()->getDependentProperties() !== null) {
$principalElement = $element;
} else {
return;
Expand All @@ -905,6 +905,7 @@ private function ProcessReferentialConstraint(INavigationProperty $element, iter
$this->schemaWriter->WriteReferentialConstraintPrincipalEndElementHeader($principalElement);
$dType = $principalElement->getDeclaringType();
assert($dType instanceof IEntityType);
EdmUtil::checkArgumentNull($dType->Key(), 'principalElement->getDeclaringType->Key');
$this->VisitPropertyRefs($dType->Key());
$this->schemaWriter->WriteEndElement();
$this->schemaWriter->WriteReferentialConstraintDependentEndElementHeader($principalElement->getPartner());
Expand Down Expand Up @@ -1262,17 +1263,22 @@ private function SharesEnd(INavigationProperty $end1, INavigationProperty $end2)
* @param array|IStructuralProperty[] $thoseProperties
* @return bool
*/
private function SharesReferentialConstraintEnd(array $theseProperties, array $thoseProperties): bool
private function SharesReferentialConstraintEnd(?array $theseProperties, ?array $thoseProperties): bool
{
if (count($theseProperties) != count($thoseProperties)) {
if (null === $theseProperties || null === $thoseProperties) {
return false;
}
$obj = new ArrayObject($theseProperties);
$thesePropertiesEnumerator = $obj->getIterator();
$numProp = count($theseProperties);
if ($numProp != count($thoseProperties)) {
return false;
}
$theseKeys = array_keys($theseProperties);
$thoseKeys = array_keys($thoseProperties);

foreach ($thoseProperties as $thatProperty) {
$thesePropertiesEnumerator->next();
if (!($thesePropertiesEnumerator->current()->getName() == $thatProperty->getName())) {
for ($i = 0; $i < $numProp; $i++) {
$these = $theseProperties[$theseKeys[$i]];
$those = $thoseProperties[$thoseKeys[$i]];
if ($these->getName() != $those->getName()) {
return false;
}
}
Expand Down Expand Up @@ -1307,18 +1313,15 @@ private function SharesAssociationSet(
$thisOtherEntitySet = $thisEntitySet->findNavigationTarget($thisNavprop);
$thatOtherEntitySet = $thatEntitySet->findNavigationTarget($thatNavprop);

if ($thisOtherEntitySet == null) {
if ($thatOtherEntitySet != null) {
return false;
}
} else {
if ($thatOtherEntitySet == null) {
return false;
}
$nullityMismatch = (null === $thisOtherEntitySet) !== (null === $thatOtherEntitySet);
if ($nullityMismatch) {
return false;
}

if (null !== $thisOtherEntitySet) {
if (!($this->model->GetAssociationEndName($thisNavprop->getPartner()) ==
$this->model->GetAssociationEndName($thatNavprop->getPartner()) &&
$thisOtherEntitySet->getName() == $thatOtherEntitySet->getName())) {
$thisOtherEntitySet->getName() == $thatOtherEntitySet->getName())) {
return false;
}
}
Expand Down
Expand Up @@ -115,7 +115,7 @@ protected function ProcessVocabularyAnnotation(IVocabularyAnnotation $annotation
$this->activeSchema = $this->modelSchemas[$annotationSchemaNamespace];
}

if ($annotation->getTerm() != null) {
if (null !== $annotation->getTerm()) {
$this->CheckSchemaElementReference($annotation->getTerm());
}

Expand Down Expand Up @@ -169,15 +169,15 @@ protected function ProcessEnumTypeReference(IEnumTypeReference $element): void
protected function ProcessEntityType(IEntityType $element): void
{
parent::ProcessEntityType($element);
if ($element->BaseEntityType() != null) {
if (null !== $element->BaseEntityType()) {
$this->CheckSchemaElementReference($element->BaseEntityType());
}
}

protected function ProcessComplexType(IComplexType $element): void
{
parent::ProcessComplexType($element);
if ($element->BaseComplexType() != null) {
if (null !== $element->BaseComplexType()) {
$this->CheckSchemaElementReference($element->BaseComplexType());
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/CsdlConstants.php
Expand Up @@ -328,5 +328,5 @@ public static function EdmToEdmxVersions(Version $edm)
// Basically using it as a static constructor.
(function () {
CsdlConstants::$Default_ConcurrencyMode = ConcurrencyMode::None();
CsdlConstants::$Default_FunctionParameterMode = FunctionParameterMode::IN();
CsdlConstants::$Default_FunctionParameterMode = FunctionParameterMode::In();
});

0 comments on commit 2b713c2

Please sign in to comment.