diff --git a/README.md b/README.md index adfa571..a140318 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,8 @@ ## About This library will allow you to save a snapshot of your PHP object in various formats like XML or JSON (encoding). -When your project has been setup properly you can reuse this by decoding the snapshot. It will return the -same PHP object. +When your project has been setup properly you can reuse the snapshot by decoding it. The decoding process will return +the same PHP object you started with. This library is useful for you if you want to quickly find a way to save a state of your PHP object. Think about a configurator that allows you to customize a certain product in various ways for example. diff --git a/src/PE/Encoder.php b/src/PE/Encoder.php index 9ecd0cb..6942425 100644 --- a/src/PE/Encoder.php +++ b/src/PE/Encoder.php @@ -11,6 +11,8 @@ use PE\Enums\ActionVariable; use PE\Exceptions\EncoderException; use PE\Options\EncoderOptions; +use PE\Variables\Types\NodeAccessor; +use PE\Variables\Types\ObjectAccessor; /** * Class Encoder @@ -59,10 +61,11 @@ protected function decodeRawToArray($nodeName, $node, $array) { foreach ($decodedData as $decodedName => $data) { // if data belongs to a child if ($nodeType->childNodeExists($decodedName)) { + $childNodeSetter = $nodeType->getChild($decodedName)->getSetter(); // decode it, unset it and add it back into the array at the correct place $childArrDecoded = $this->decodeRawToArray($decodedName, $nodeChildData, $array); unset($decodedData[$decodedName]); - $decodedData = $nodeType->getChild($decodedName)->setAfterChildren() === false ? array($decodedName => $childArrDecoded) + $decodedData : array_merge($decodedData, array($decodedName => $childArrDecoded)); + $decodedData = $childNodeSetter->setAfterChildren() === false ? array($decodedName => $childArrDecoded) + $decodedData : array_merge($decodedData, array($decodedName => $childArrDecoded)); } // if data belongs to an attribute simply else if (is_array($data)) { @@ -116,8 +119,10 @@ protected function _decodeNode($nodeName, $nodeData, EncoderOptions $options, En $addAfterAttributes = true; if ($parentNode) { $childNode = $parentNode->getChild($nodeName); - $addAfterDecode = $childNode->setAfterChildren(); - $addAfterAttributes = $childNode->setAfterAttributes(); + + $childNodeSetter = $childNode->getSetter(); + $addAfterDecode = $childNodeSetter->setAfterChildren(); + $addAfterAttributes = $childNodeSetter->setAfterAttributes(); } $objects = array(); @@ -129,6 +134,7 @@ protected function _decodeNode($nodeName, $nodeData, EncoderOptions $options, En $nodeChildType = $proxyNode->getObjectType($parentObject, $nodeDataItem); $nodeType = ($nodeChildType !== null && !empty($nodeChildType) ? $nodeChildType : $proxyNode->getDefaultType()); $type = $proxyNode->getType($nodeType); + $variableCollection = $type->getVariableCollection(); // make sure the variables are all dashed as this is the default foreach ($nodeDataItem as $nodeDataName => $nodeDataValue) { @@ -139,18 +145,24 @@ protected function _decodeNode($nodeName, $nodeData, EncoderOptions $options, En } } + $preNodeStaticOptions = array( + NodeAccessor::VARIABLE_NODE => $type, + NodeAccessor::VARIABLE_PARENT => $parentObject + ); // call node methods. It can be useful when you want to change the outcome of the node data in the node // that does not have a certain setter but is used in other ways - $nodeMethodVariables = $type->getVariablesSetterActionByType(EncoderNodeVariable::ACTION_TYPE_NODE); - foreach ($nodeMethodVariables as $variableId => $nodeMethodVariable) { - if (isset($nodeDataItem[$variableId])) { - $setterOptions = array( - ActionVariable::SETTER_NODE_DATA => $nodeDataItem, - ActionVariable::SETTER_NAME => $variableId, - ActionVariable::SETTER_PARENT => $parentObject, - ActionVariable::SETTER_VALUE => $nodeDataItem[$variableId] - ); - if ($newNode = $nodeMethodVariable->callNodeSetterAction($type, $setterOptions)) { + $preNodeSetterVariables = $variableCollection->getPreNodeSetterVariables(); + foreach ($preNodeSetterVariables as $preNodeSetterVariable) { + $variableId = $preNodeSetterVariable->getId(); + $variableIsset = isset($nodeDataItem[$variableId]); + $preNodeSetter = $preNodeSetterVariable->getPreNodeSetter(); + if (isset($nodeDataItem[$variableId]) || $preNodeSetter->alwaysExecute()) { + $setterOptions = array_merge($preNodeStaticOptions, array( + NodeAccessor::VARIABLE_NODE_DATA => $nodeDataItem, + NodeAccessor::VARIABLE_NAME => $variableId, + NodeAccessor::VARIABLE_VALUE => $variableIsset ? $nodeDataItem[$variableId] : null + )); + if ($newNode = $preNodeSetter->apply($setterOptions)) { $nodeDataItem = $newNode; } } @@ -183,12 +195,15 @@ protected function _decodeNode($nodeName, $nodeData, EncoderOptions $options, En throw new EncoderException(sprintf('Variable "%s" for "%s" does not exist but is required to create an object for node "%s" (Node type: "%s") at index "%s"', $processedVariable, $nodeClassName, $nodeName, $type->getNodeName(), $nodeIndex)); } $requiredValue = $nodeDataItem[$processedVariable]; - $processedRequiredValue = $type->processValue($processedVariable, $requiredValue); - if ($processedRequiredValue === null) { - throw new EncoderException(sprintf('Variable "%s" for "%s" cannot process its value (%s). Presumably because the NodeType does not recognize the variable', $processedVariable, $nodeClassName, $requiredValue)); + $objectSetterVariable = $variableCollection->getVariableById($processedVariable); + if (!$objectSetterVariable) { + throw new EncoderException(sprintf('Variable "%s" for "%s" is required but there is no EncoderNodeVariable available to retrieve the value for node "%s" (Node type: "%s") at index "%s".', $processedVariable, $nodeClassName, $nodeName, $type->getNodeName(), $nodeIndex)); } - array_push($requiredVariableValues, $processedRequiredValue); + $objectSetter = $objectSetterVariable->getObjectSetter(); + $processedRequiredValue = $objectSetter->processValue($requiredValue); + + $requiredVariableValues[$processedVariable] = $processedRequiredValue; unset($nodeDataItem[$processedVariable]); } @@ -203,14 +218,40 @@ protected function _decodeNode($nodeName, $nodeData, EncoderOptions $options, En $parentNode->addChildrenToObject($nodeName, $parentObject, array($nodeInstance)); } - foreach ($nodeDataItem as $name => $value) { - $type->applyToVariable($name, array( - ActionVariable::SETTER_NODE_DATA => $nodeDataItem, - ActionVariable::SETTER_OBJECT => $nodeInstance, - ActionVariable::SETTER_PARENT => $parentObject, - ActionVariable::SETTER_NAME => $name, - ActionVariable::SETTER_VALUE => $value - )); + // run the post setter variable types + $postNodeStaticOptions = array_merge($preNodeStaticOptions, array( + ObjectAccessor::VARIABLE_OBJECT => $nodeInstance, + )); + $postNodeSetterVariables = $variableCollection->getPostNodeSetterVariables(); + foreach ($postNodeSetterVariables as $postNodeSetterVariable) { + $variableId = $postNodeSetterVariable->getId(); + $variableIsset = isset($nodeDataItem[$variableId]); + $postNodeSetter = $postNodeSetterVariable->getPostNodeSetter(); + if ($variableIsset || $postNodeSetter->alwaysExecute()) { + $setterOptions = array_merge($postNodeStaticOptions, array( + NodeAccessor::VARIABLE_NODE_DATA => $nodeDataItem, + NodeAccessor::VARIABLE_NAME => $variableId, + NodeAccessor::VARIABLE_VALUE => $variableIsset ? $nodeDataItem[$variableId] : null + )); + if ($newNode = $postNodeSetter->apply($setterOptions)) { + $nodeDataItem = $newNode; + } + } + } + + // run the optional object setter variable types + $objectSetterVariables = $variableCollection->getObjectSetterVariables(); + foreach ($objectSetterVariables as $objectSetterVariable) { + $variableId = $objectSetterVariable->getId(); + if (array_key_exists($variableId, $requiredVariableValues)) { + // if the variable was an required variable do not try to set it again + continue; + } + $variableIsset = isset($nodeDataItem[$variableId]); + $objectSetter = $objectSetterVariable->getObjectSetter(); + if ($variableIsset || $objectSetter->alwaysExecute()) { + $objectSetter->apply($nodeInstance, $variableIsset ? $nodeDataItem[$variableId] : null); + } } if (!$addAfterDecode && $addAfterAttributes) { @@ -222,7 +263,7 @@ protected function _decodeNode($nodeName, $nodeData, EncoderOptions $options, En if ($type->childNodeExists($childName)) { $children = $this->_decodeNode($childName, $nodeDataItem, $options, $type, $nodeInstance, $nodeDataItem); - if ($type->getChild($childName)->setAfterChildren()) { + if ($type->getChild($childName)->getSetter()->setAfterChildren()) { $isSingleChildNode = $type->isSingleNode($childName); $type->addChildrenToObject($childName, $nodeInstance, $isSingleChildNode ? array($children) : $children); } @@ -232,7 +273,7 @@ protected function _decodeNode($nodeName, $nodeData, EncoderOptions $options, En $nodeIndex++; } - $proxyNode->variablesAreValid($decodedChildren, true); + $variableCollection->objectVariablesAreValidWithData($decodedChildren, true); if ($isSingleNode) { return $objects[0]; @@ -295,38 +336,64 @@ public function encode($object, EncoderOptions $options = null) { } protected function _encode($object, EncoderNode $node, EncoderOptions $options, $parent = null, $nodeIterationIndex = null, $childObjectIterationIndex = null) { - $variables = $node->getVariables(); + $variableCollection = $node->getVariableCollection(); + $objectGetterVariables = $variableCollection->getObjectGetterVariables(); $optionNodeIndex = $node->getNodeName() . '[' . $childObjectIterationIndex . ']'; $attributesRaw = array(); - foreach ($variables as $variable) { - if (!$variable->hasGetterAction() || $variable->alwaysExecute()) { - $variableId = $variable->getId(); + $postNodeStaticOptions = array( + NodeAccessor::VARIABLE_NODE => $node, + NodeAccessor::VARIABLE_OBJECT => $object, + NodeAccessor::VARIABLE_PARENT => $parent, + NodeAccessor::VARIABLE_OPTIONS => $options, + NodeAccessor::VARIABLE_NODE_ITERATION_INDEX => $nodeIterationIndex, + NodeAccessor::VARIABLE_CHILD_OBJECT_ITERATION_INDEX => $childObjectIterationIndex, + ); - $attributeValue = null; - $getAttributeMethod = $variable->getGetterMethod(); - if (method_exists($object, $getAttributeMethod)) { - $attributeValue = $object->$getAttributeMethod(); - } else { - throw new EncoderException(sprintf('Getter method "%s" does not exist in object "%s" for node type "%s" (%s) and variable with id "%s".', $getAttributeMethod, get_class($object), $node->getNodeTypeName(), get_class($node), $variableId)); + $preNodeGetterVariables = $variableCollection->getPreNodeGetterVariables(); + foreach ($preNodeGetterVariables as $preNodeGetterVariable) { + $variableId = $preNodeGetterVariable->getId(); + $postNodeGetter = $preNodeGetterVariable->getPreNodeGetter(); + $actionOptions = array_merge($postNodeStaticOptions, array( + NodeAccessor::VARIABLE_NODE_DATA => $attributesRaw, + NodeAccessor::VARIABLE_NAME => $variableId, + )); + if ($newAttributeData = $postNodeGetter->apply($actionOptions)) { + if (is_array($newAttributeData)) { + $attributesRaw = $newAttributeData; } - - $attributesRaw[$variableId] = $attributeValue; } } - $actionVariables = array( - ActionVariable::GETTER_OBJECT => $object, - ActionVariable::GETTER_PARENT => $parent, - ActionVariable::GETTER_OPTIONS => $options, - ActionVariable::GETTER_NODE_ITERATION_INDEX => $nodeIterationIndex, - ActionVariable::GETTER_CHILD_OBJECT_ITERATION_INDEX => $childObjectIterationIndex, - ); + // get all the variables values from the object + foreach ($objectGetterVariables as $objectGetterVariable) { + $variableId = $objectGetterVariable->getId(); + + $objectGetter = $objectGetterVariable->getObjectGetter(); + $attributesRaw[$variableId] = $objectGetter->apply($object); + } + + $postNodeGetterVariables = $variableCollection->getPostNodeGetterVariables(); + foreach ($postNodeGetterVariables as $postNodeGetterVariable) { + $variableId = $postNodeGetterVariable->getId(); + $hasVariable = array_key_exists($variableId, $attributesRaw); + $postNodeGetter = $postNodeGetterVariable->getPostNodeGetter(); + if ($hasVariable || $postNodeGetter->alwaysExecute()) { + $actionOptions = array_merge($postNodeStaticOptions, array( + NodeAccessor::VARIABLE_NODE_DATA => $attributesRaw, + NodeAccessor::VARIABLE_NAME => $variableId, + NodeAccessor::VARIABLE_VALUE => $hasVariable ? $attributesRaw[$variableId] : null, + )); + if ($newAttributeData = $postNodeGetter->apply($actionOptions)) { + if (is_array($newAttributeData)) { + $attributesRaw = $newAttributeData; + } + } + } + } - $nodeMethodVariables = $node->getVariablesGetterActionByType(EncoderNodeVariable::ACTION_TYPE_NODE); - $attributesRaw = $this->loopNodeVariables($node, $nodeMethodVariables, $attributesRaw, $actionVariables); $optionNodeKey = $options->option('key', $node); $optionNodeValue = $options->option('value', $node); @@ -367,7 +434,7 @@ protected function _encode($object, EncoderNode $node, EncoderOptions $options, $isIterated = $optionChildIteration !== null; $childIteration = $optionChildIteration === null ? 1 : $optionChildIteration; - $getChildObjectsMethod = $child->getGetterMethod(); + $getChildObjectsMethod = $child->getGetter()->getMethod(); if (!method_exists($object, $getChildObjectsMethod)) { throw new EncoderException(sprintf('Getter method "%s" for node "%s" does not exist in class "%s"', $getChildObjectsMethod, $childNodeName, get_class($object))); } @@ -473,25 +540,4 @@ protected function encodeNodeChildren(EncoderNode $node, $nodeName, EncoderNodeC protected function encodeAttributes($attributes) { return $attributes; } - - - protected function loopNodeVariables($node, $variables, $data, $actionOptions) { - $temp = $data; - foreach ($variables as $variableId => $nodeMethodVariable) { - $hasVariable = array_key_exists($variableId, $data); - if ($hasVariable || $nodeMethodVariable->alwaysExecute()) { - $actionOptions = array_merge(array( - ActionVariable::GETTER_NODE_DATA => $data, - ActionVariable::GETTER_NAME => $variableId, - ActionVariable::GETTER_VALUE => $hasVariable ? $data[$variableId] : null, - ), $actionOptions); - if ($newAttributeData = $nodeMethodVariable->callNodeGetterAction($node, $actionOptions)) { - if (is_array($newAttributeData)) { - $temp = $newAttributeData; - } - } - } - } - return $temp; - } } \ No newline at end of file diff --git a/src/PE/Enums/ActionVariable.php b/src/PE/Enums/ActionVariable.php deleted file mode 100644 index d01a9de..0000000 --- a/src/PE/Enums/ActionVariable.php +++ /dev/null @@ -1,24 +0,0 @@ -method = $method; + } + + public function getMethod() { + return $this->method; + } + +} + +?> \ No newline at end of file diff --git a/src/PE/Nodes/Children/NodeChildGetter.php b/src/PE/Nodes/Children/NodeChildGetter.php new file mode 100644 index 0000000..dbebfdb --- /dev/null +++ b/src/PE/Nodes/Children/NodeChildGetter.php @@ -0,0 +1,13 @@ + \ No newline at end of file diff --git a/src/PE/Nodes/Children/NodeChildSetter.php b/src/PE/Nodes/Children/NodeChildSetter.php new file mode 100644 index 0000000..9b8144e --- /dev/null +++ b/src/PE/Nodes/Children/NodeChildSetter.php @@ -0,0 +1,30 @@ +setAfterChildren = $bool; + } + return $this->setAfterChildren; + } + + public function setAfterAttributes($bool = null) { + if ($bool !== null) { + $this->setAfterAttributes = $bool; + } + return $this->setAfterAttributes; + } + +} + +?> \ No newline at end of file diff --git a/src/PE/Nodes/EncoderNode.php b/src/PE/Nodes/EncoderNode.php index 7aab7e7..21830cb 100644 --- a/src/PE/Nodes/EncoderNode.php +++ b/src/PE/Nodes/EncoderNode.php @@ -3,6 +3,9 @@ namespace PE\Nodes; use PE\Enums\ActionVariable; +use PE\Variables\Types\NodeAccessor; +use PE\Variables\Types\ObjectSetter; +use PE\Variables\Types\VariableType; use ReflectionClass; use PE\Exceptions\EncoderNodeException; @@ -475,7 +478,7 @@ public function addChildrenToObject($childName, $target, $values) { * @see EncoderNodeVariable::addNodeVariable() */ public function addVariable(EncoderNodeVariable $variable) { - return $this->variables->addNodeVariable($variable); + return $this->variables->addVariable($variable); } /** @@ -489,103 +492,12 @@ public function getVariable($variable) { } /** - * @param string $id - * @return null|EncoderNodeVariable - * - * @see EncoderNodeVariable::getVariableById() - */ - public function getVariableById($id) { - return $this->variables->getVariableById($id); - } - - /** - * @param string $type - * @return EncoderNodeVariable[] - * - * @see EncoderNodeVariable::getVariablesSetterActionByType() + * @return EncoderNodeVariableCollection */ - public function getVariablesSetterActionByType($type) { - return $this->variables->getVariablesSetterActionByType($type); + public function getVariableCollection() { + return $this->variables; } - /** - * @param string $type - * @return EncoderNodeVariable[] - * - * @see EncoderNodeVariable::getVariablesGetterActionByType() - */ - public function getVariablesGetterActionByType($type) { - return $this->variables->getVariablesGetterActionByType($type); - } - - /** - * @return EncoderNodeVariable[] - * - * @see EncoderNodeVariable::getAlwaysExecutedVariables() - */ - public function getAlwaysExecutedVariables() { - return $this->variables->getAlwaysExecutedVariables(); - } - - /** - * @param bool $order - * @return EncoderNodeVariable[] - * - * @see EncoderNodeVariable::getAlwaysExecutedVariables() - */ - public function getVariables($order = true) { - return $this->variables->getVariables($order); - } - - /** - * @param string $id - * @return bool - * - * @see EncoderNodeVariable::variableExists() - */ - public function variableExists($id) { - return $this->variables->variableExists($id); - } - - /** - * @param array $nodeDataArray - * @param bool $throwErrorIfFails Set to true if you want it to throw an error if it fails - * @return bool Returns true if all requirements are met - * - * @see EncoderNodeVariable::variablesAreValidWithData() - */ - public function variablesAreValid($nodeDataArray, $throwErrorIfFails = false) { - return $this->variables->variablesAreValidWithData($nodeDataArray, $throwErrorIfFails); - } - - /** - * @param string $name - * @param mixed $value - * @return mixed - * - * @see EncoderNodeVariable::processValue() - */ - public function processValue($name, $value) { - return $this->variables->processValue($name, $value); - } - - /** - * @param string $name Variable name you want to apply the parameters to - * @param array $parameters Array of all the information required for the several methods needing it - * @return bool|mixed - * - * @see EncoderNodeVariable::applyToSetter() - */ - public function applyToVariable($name, $parameters) { - $variable = $this->getVariable($name); - if ($variable == null) { - return false; - } - $parameters[ActionVariable::SETTER_NODE] = $this; - return $variable->applyToSetter($parameters); - } - - diff --git a/src/PE/Nodes/EncoderNodeChild.php b/src/PE/Nodes/EncoderNodeChild.php index 7e51375..07b8a9c 100644 --- a/src/PE/Nodes/EncoderNodeChild.php +++ b/src/PE/Nodes/EncoderNodeChild.php @@ -3,17 +3,36 @@ namespace PE\Nodes; use PE\Exceptions\EncoderNodeChildException; +use PE\Nodes\Children\NodeChildGetter; +use PE\Nodes\Children\NodeChildSetter; -class EncoderNodeChild extends EncoderNodeVariable { +class EncoderNodeChild { + /** + * @var string + */ private $childNodeName; + + /** + * @var NodeChildSetter Setter of the child objects + */ + private $setter; + + /** + * @var NodeChildGetter Setter of the child objects + */ + private $getter; + + /** + * @var bool + */ private $isArray = true; - private $setAfterChildren = true; - private $setAfterAttributes = true; - function __construct($nodeName, $options = null) { - parent::__construct('', $options); + function __construct($nodeName, NodeChildSetter $setter = null, NodeChildGetter $getter = null) { $this->setChildNodeName($nodeName); + + if ($setter) $this->setter($setter); + if ($getter) $this->getter($getter); } public function setChildNodeName($childNodeName) { @@ -26,26 +45,41 @@ public function getChildNodeName() { return $this->childNodeName; } - // @todo Figure out if this feature is still necessary. Because if you use a single node, can't we simply assume it isn't an array? - public function isArray($bool = null) { - if ($bool !== null) { - $this->isArray = $bool; - } - return $this->isArray; + /** + * @param NodeChildSetter $setter + */ + protected function setter(NodeChildSetter $setter) { + $this->setter = $setter; + } + /** + * @return NodeChildSetter + */ + public function getSetter() { + return $this->setter; } - public function setAfterChildren($bool = null) { - if ($bool !== null) { - $this->setAfterChildren = $bool; - } - return $this->setAfterChildren; + /** + * @param NodeChildGetter $getter + */ + protected function getter(NodeChildGetter $getter) { + $this->getter = $getter; + } + /** + * @return NodeChildGetter + */ + public function getGetter() { + return $this->getter; } - public function setAfterAttributes($bool = null) { + /** + * @param null $bool + * @return bool + */ + public function isArray($bool = null) { if ($bool !== null) { - $this->setAfterAttributes = $bool; + $this->isArray = (bool) $bool; } - return $this->setAfterAttributes; + return $this->isArray; } /** @@ -56,13 +90,13 @@ public function setAfterAttributes($bool = null) { * @return bool Returns true if the action succeeded and false when it couldn't find the child */ public function addChildrenToObject($target, $values) { - $methodName = $this->getSetterMethod(); + $methodName = $this->getSetter()->getMethod(); if ($methodName === null) { throw new EncoderNodeChildException(sprintf('Setter method (%s) for class "%s" does not exist', $this->getChildNodeName(), get_class($target))); } else if (method_exists($target, $methodName)) { foreach ($values as $value) { - $target->$methodName($this->processValue($value)); + $target->$methodName($value); } } else { diff --git a/src/PE/Nodes/EncoderNodeVariable.php b/src/PE/Nodes/EncoderNodeVariable.php index ffedfb1..b485b6d 100644 --- a/src/PE/Nodes/EncoderNodeVariable.php +++ b/src/PE/Nodes/EncoderNodeVariable.php @@ -2,457 +2,279 @@ namespace PE\Nodes; -use PE\Exceptions\EncoderNodeVariableException; -use PE\Enums\ActionVariable; -use PE\Library\Inflector; -use PE\Variables\Variable; +use PE\Variables\Types\ObjectAccessor; +use PE\Variables\Types\ObjectGetter; +use PE\Variables\Types\ObjectSetter; +use PE\Variables\Types\PostNodeGetter; +use PE\Variables\Types\PostNodeSetter; +use PE\Variables\Types\PreNodeGetter; +use PE\Variables\Types\PreNodeSetter; -class EncoderNodeVariable extends Variable { +class EncoderNodeVariable { - private $_cache; + /** + * @var string + */ + private $id; + /** + * @var int + */ + private $order; + /** + * @var string + */ + private $type; - private $setterAction; - private $getterAction; + /** + * @var PreNodeSetter + */ + private $preNodeSetter; - private $alwaysExecute; - private $mustBeUnique; + /** + * @var PreNodeGetter + */ + private $preNodeGetter; - const ACTION_TYPE_NODE = 'node'; - const ACTION_TYPE_OBJECT = 'object'; + /** + * @var PostNodeSetter + */ + private $postNodeSetter; - const ACTION_VARIABLE_SETTER_NODE_DATA = 'node_data'; - const ACTION_VARIABLE_GETTER_NODE_DATA = 'node_data'; + /** + * @var PostNodeGetter + */ + private $postNodeGetter; - function __construct($id, $options = null) { - $this->_cache = array(); + /** + * @var ObjectSetter + */ + private $objectSetter; - parent::__construct($options, $id); - } + /** + * @var ObjectGetter + */ + private $objectGetter; - public function parseOptions($options) { - $options = (array) $options; - foreach ($options as $option => $value) { - switch ($option) { - case 'setterAction' : - $this->setSetterAction($value); - break; - case 'getterAction' : - $this->setGetterAction($value); - break; - case 'unique' : - $this->mustBeUnique($value); - break; - case 'alwaysExecute' : - $this->alwaysExecute($value); - break; - } - } - parent::parseOptions($options); - } - - protected function _cache($method, $value = false) { - if ($value !== false) { - $this->_cache[$method] = $value; - return $value; - } - if (!array_key_exists($method, $this->_cache)) { - return false; - } - return $this->_cache[$method]; - } - protected function _cacheReset($method) { - if (array_key_exists($method, $this->_cache)) { - unset($this->_cache[$method]); - return true; - } - return false; - } /** - * This node variable value must unique in relation to other nodes in a series - * - * @param null|bool $bool Set to true to enable the this variable to be unique. Leave empty to retrieve the current value - * @return bool Default is false + * Boolean variable type */ - public function mustBeUnique($bool = null) { - if ($bool !== null && is_bool($bool)) { - $this->mustBeUnique = $bool; - } - return (bool) $this->mustBeUnique; - } - + const TYPE_BOOL = 'bool'; /** - * This node variable is always executed even though there is not value set. This way you can force a value - * to be set manually - * - * @param null|bool $bool Set to true to enable the this variable to always be executed. Leave empty to retrieve the current value - * @return bool Default is false + * Array variable type */ - public function alwaysExecute($bool = null) { - if ($bool !== null && is_bool($bool)) { - $this->alwaysExecute = $bool; - } - return (bool) $this->alwaysExecute; - } - + const TYPE_ARRAY = 'array'; /** - * Set the setter action method. The way the variable knows how to set the value when it's his turn - * - * ```php - * $variable = new EncoderNodeVariable('variableName'); - * // string - * $variable->setSetterAction('methodName'); - * - * // array - available options: method (required), type, variables - * $variable->setSetterAction(array( - * 'method' => 'methodName', - * 'type' => EncoderNodeVariable::ACTION_TYPE_NODE, - * 'variable' => array(ActionVariable::SETTER_VALUE, ActionVariable::SETTER_PARENT); - * )); - * ``` - * @param string|array $method Can either be the name of the method in the object as a string or an array like - * in the example - */ - public function setSetterAction($method) { - if (!(is_string($method) || (is_array($method) && isset($method['method']) && is_string($method['method'])))) { - throw new EncoderNodeVariableException('Either method must be a string or an array with a "method" key being a string'); + * String variable type + */ + const TYPE_STRING = 'string'; + + function __construct($id, $enableObjectAccessors = true) { + $this->setId($id); + + if ($enableObjectAccessors) { + $this->objectSetter(new ObjectSetter()); + $this->objectGetter(new ObjectGetter()); } - $this->_cacheReset('getSetterActionMethod'); - $this->_cacheReset('getSetterActionType'); - $this->setterAction = $method; } /** - * @return string|array Get the current setter action + * @param string $id + * @return null|string */ - public function getSetterAction() { - return $this->setterAction; + protected function setId($id) { + $this->id = $id; + return $id; } /** - * @return bool Does it have a setter action or not? + * @return string */ - public function hasSetterAction() { - return $this->getSetterAction() != null; + public function getId() { + return $this->id; } + /** - * Specifically get the method of the setter action - * @return false|string Either returns false if no setter action method has been set or returns the string of the method + * Sets the data type of the variable + * @param string $type */ - public function getSetterActionMethod() { - if (($result = self::_cache(__FUNCTION__)) === false) { - // it's being cached because it is requested a lot - $result = $this->getActionMethod($this->getSetterAction()); - self::_cache(__FUNCTION__, $result); - } - return $result; + public function setType($type) { + $this->type = $type; } - /** - * Specifically get the type of the setter action - * @return false|string Either returns false if no setter action type has been set or returns the type of method + * @return string */ - public function getSetterActionType() { - if (($result = self::_cache(__FUNCTION__)) === false) { - // it's being cached because it is requested a lot - $result = $this->getActionType($this->getSetterAction()); - self::_cache(__FUNCTION__, $result); - } - return $result; + public function getType() { + return $this->type; } + /** - * Set the getter action method. The way the variable knows how to get the value for this variable + * Set the order the variable (when it is a collection) * - * @param string|array $method Can either be the name of the method in the object as a string or an array like - * @see EncoderNodeVariable::setSetterAction() It shows what to provide to this method + * A lower number means it will end up near the beginning of the array + * @param int $index */ - public function setGetterAction($method) { - if (!(is_string($method) || (is_array($method) && isset($method['method']) && is_string($method['method'])))) { - throw new EncoderNodeVariableException('Either method must be a string or an array with a "method" key being a string'); - } - $this->_cacheReset('getGetterActionMethod'); - $this->_cacheReset('getGetterActionType'); - $this->getterAction = $method; + public function setOrder($index) { + $this->order = $index; } - /** - * @return string|array Get the current getter action + * @return int */ - public function getGetterAction() { - return $this->getterAction; + public function getOrder() { + return $this->order; } + /** - * @return bool Does it have a getter action or not? + * @param PreNodeSetter $setter + * @return PreNodeSetter */ - public function hasGetterAction() { - return $this->getGetterAction() != null; + public function preNodeSetter(PreNodeSetter $setter) { + $setter->setVariable($this); + $this->preNodeSetter = $setter; + return $setter; } /** - * Specifically get the method of the getter action - * @return false|string Either returns false if no getter action method has been set or returns the string of the method + * @return bool */ - public function getGetterActionMethod() { - if (($result = self::_cache(__FUNCTION__)) === false) { - $result = $this->getActionMethod($this->getGetterAction()); - self::_cache(__FUNCTION__, $result); - } - return $result; + public function hasPreNodeSetter() { + return $this->preNodeSetter !== null; } /** - * Specifically get the type of the getter action - * @return false|string Either returns false if no getter action type has been set or returns the type of method + * @return PreNodeSetter */ - public function getGetterActionType() { - if (($result = self::_cache(__FUNCTION__)) === false) { - $result = $this->getActionType($this->getGetterAction()); - self::_cache(__FUNCTION__, $result); - } - return $result; + public function getPreNodeSetter() { + return $this->preNodeSetter; } + /** - * Generic method to get the action method - * - * @param string|array $action Action object or string - * @return null|string Returns null if nothing has been found or the string if it has + * @param PreNodeGetter $getter + * @return PreNodeGetter */ - protected function getActionMethod($action) { - if (is_array($action) && isset($action['method'])) { - return $action['method']; - } - else if (is_string($action)) { - return $action; - } - return null; + public function preNodeGetter(PreNodeGetter $getter) { + $getter->setVariable($this); + $this->preNodeGetter = $getter; + return $getter; } /** - * Generic method to get the action type - * - * @param string|array $action Action object or string - * @return null|string Returns null if nothing has been found or the type if it has. If no type has been set but - * there is an action object, the default is "object" - */ - protected function getActionType($action) { - $type = null; - if ($action) { - $type = self::ACTION_TYPE_OBJECT; - if (is_array($action) && isset($action['type'])) { - $type = $action['type']; - } - } - return $type; + * @return bool + */ + public function hasPreNodeGetter() { + return $this->preNodeGetter !== null; } /** - * Returns the name of the variable - * - * @return string The id supplied to this instance is the name + * @return PreNodeGetter */ - public function getName() { - return $this->getId(); + public function getPreNodeGetter() { + return $this->preNodeGetter; } - /** - * @return false|string Returns the setter method if available. Otherwise it returns false - * - * @todo Figure out if this is still necessary because the actions have this feature too - */ - public function getSetterMethod() { - if (($result = self::_cache(__FUNCTION__)) === false) { - $result = parent::getSetterMethod(); - if ($result === null && $this->getName()) { - $result = 'set' . $this->camelCased($this->getName()); - } - self::_cache(__FUNCTION__, $result); - } - return $result; - } /** - * @return false|string Returns the getter method if available. Otherwise it returns false - * - * @todo Figure out if this is still necessary because the actions have this feature too - */ - public function getGetterMethod() { - if (($result = self::_cache(__FUNCTION__)) === false) { - $result = parent::getGetterMethod(); - if ($result === null && $this->getName()) { - $result = 'get' . $this->camelCased($this->getName()); - } - self::_cache(__FUNCTION__, $result); - } - return $result; + * @param PostNodeSetter $setter + * @return PostNodeSetter + */ + public function postNodeSetter(PostNodeSetter $setter) { + $setter->setVariable($this); + $this->postNodeSetter = $setter; + return $setter; } /** - * @param string $str Spinal cased string - * @return string Camel cased string + * @return bool */ - protected function camelCased($str) { - return ucfirst(Inflector::camelize($str, true, '-')); + public function hasPostNodeSetter() { + return $this->postNodeSetter !== null; } /** - * Call the setter action of the node. The setter action type must be set to "node", otherwise it will not execute. - * - * @param EncoderNode $node The EncoderNode of which you wish to call the setter action from - * @param array $options All the available options - * @return mixed|null Returns null if setter action type is not "node". Returns an array with the possibly altered node data + * @return PostNodeSetter */ - public function callNodeSetterAction(EncoderNode $node, $options) { - if ($this->getSetterActionType() != self::ACTION_TYPE_NODE) { - return null; - } - $required = array( - self::ACTION_VARIABLE_SETTER_NODE_DATA - ); - $variables = $this->_setupNodeActionVariables($this->getSetterAction(), $required, $options); - return $this->_callNodeAction($node, $this->getSetterActionMethod(), $variables); + public function getPostNodeSetter() { + return $this->postNodeSetter; } + /** - * Call the getter action of the node. The getter action type must be set to "node", otherwise it will not execute. - * - * @param EncoderNode $node The EncoderNode of which you wish to call the getter action from - * @param array $options All the available options - * @return mixed|null Returns null if getter action type is not "node". Returns an array with the possibly altered node data + * @param PostNodeGetter $getter + * @return PostNodeGetter */ - public function callNodeGetterAction(EncoderNode $node, $options) { - if ($this->getGetterActionType() != self::ACTION_TYPE_NODE) { - return null; - } - $required = array( - self::ACTION_VARIABLE_GETTER_NODE_DATA - ); - $variables = $this->_setupNodeActionVariables($this->getGetterAction(), $required, $options); - return $this->_callNodeAction($node, $this->getGetterActionMethod(), $variables); + public function postNodeGetter(PostNodeGetter $getter) { + $getter->setVariable($this); + $this->postNodeGetter = $getter; + return $getter; } /** - * Prepares the variables so they can be used - * - * @param array $action Action object - * @param array $required Will be used to determine if options are missing or not - * @param array $options All available options. If options are missing an error will be thrown - * @return array The prepared array of variables - */ - protected function _setupNodeActionVariables($action, $required, $options) { - - $variablesNames = array_merge($required, isset($action['variables']) ? $action['variables'] : array()); - - $variables = array(); - foreach ($variablesNames as $variableName) { - if (array_key_exists($variableName, $options)) { - $variables[] = $options[$variableName]; - } - else { - throw new EncoderNodeVariableException(sprintf('Action variable "%s" is not known', $variableName)); - } - } - return $variables; + * @return bool + */ + public function hasPostNodeGetter() { + return $this->postNodeGetter !== null; } /** - * Makes a call to the actual node method - * - * @param EncoderNode $node Node being used to make the call - * @param string $actionMethodName The method name from the node being called - * @param array $parameters All variables being set to the node in the order they are supplied - * @return mixed + * @return PostNodeGetter */ - protected function _callNodeAction(EncoderNode $node, $actionMethodName, $parameters) { - return call_user_func_array(array($node, $actionMethodName), $parameters); + public function getPostNodeGetter() { + return $this->postNodeGetter; } + + /** - * Depending on he settings in this variable it will either call a method in the supplied EncoderNode or in the - * supplied object. The node will be called if a setterAction has been set with a type of - * EncoderNodeVariable::ACTION_TYPE_NODE. Otherwise it will call the object. Depending on the method it chooses, - * certain parameter are required. - * - * @param array $parameters Associated array based on all "SETTER_*" constants from ActionVariable. - * @return mixed Returns whatever the object returns - * - * @see ActionVariable All "SETTER_*" constants can be a key of the $parameters array + * @param ObjectAccessor $setter + * @return ObjectAccessor */ - public function applyToSetter($parameters) { - if ($this->hasSetterAction() && $this->getSetterActionType() === EncoderNodeVariable::ACTION_TYPE_NODE) { - return $this->applyToNodeSetter($parameters); - } - else { - return $this->applyToObjectSetter($parameters[ActionVariable::SETTER_OBJECT], $parameters[ActionVariable::SETTER_VALUE]); - } + public function objectSetter(ObjectAccessor $setter) { + $setter->setVariable($this); + $this->objectSetter = $setter; + return $setter; } /** - * Applies a certain value to certain object - * - * @param object $object The object you want to have called - * @param mixed $value The value this method should receive - * @return mixed Returns whatever the object returns - */ - protected function applyToObjectSetter($object, $value) { - $methodName = $this->getSetterActionMethod() ? $this->getSetterActionMethod() : $this->getSetterMethod(); - if (!method_exists($object, $methodName)) { - throw new EncoderNodeVariableException(sprintf('Method "%s" does not exist for class %s does not exist', $methodName, get_class($object))); - } - else { - return $object->$methodName($this->processValue($value)); - } + * @return bool + */ + public function hasObjectSetter() { + return $this->objectSetter !== null; } /** - * Calls a certain node and provides any variables the method requires - * - * @param array $parameters Associated array based on all "SETTER_*" constants from ActionVariable. - * @return mixed Returns whatever the object returns - * - * @see ActionVariable All "SETTER_*" constants can be a key of the $parameters array + * @return ObjectSetter */ - protected function applyToNodeSetter($parameters) { + public function getObjectSetter() { + return $this->objectSetter; + } - $nodeData = $parameters[ActionVariable::SETTER_NODE_DATA]; - $actionMethod = $this->getSetterActionMethod(); - // get custom parameters and prepend the object in front of it - $customParameters = $this->gatherAccessorParameters($parameters); - if ($customParameters) { - array_unshift($customParameters, $nodeData); - } - // if it fails to get any kind of custom object, create a default one - $methodParameters = $customParameters ? $customParameters : array($nodeData, $parameters[ActionVariable::SETTER_VALUE]); + /** + * @param ObjectAccessor $getter + * @return ObjectAccessor + */ + public function objectGetter(ObjectAccessor $getter) { + $getter->setVariable($this); + $this->objectGetter = $getter; + return $getter; + } - // using those parameters, call the node action method - return $this->_callNodeAction($parameters[ActionVariable::SETTER_NODE], $actionMethod, $methodParameters); + /** + * @return bool + */ + public function hasObjectGetter() { + return $this->objectGetter !== null; } /** - * Gathers all required variables - * - * @param array $parameters Associated array based on all "SETTER_*" constants from ActionVariable. - * @return array Returns an array with all required parameters extracted from the $parameters variable in the - * right order. - * - * @see ActionVariable All "SETTER_*" constants can be a key of the $parameters array - */ - protected function gatherAccessorParameters($parameters) { - $actionVariables = array(); - $variableAction = $this->getSetterAction(); - if (isset($variableAction['variables']) && count($variableAction['variables'])) { - foreach ($variableAction['variables'] as $actionVariableId) { - if (!isset($parameters[$actionVariableId])) { - throw new EncoderNodeVariableException(sprintf('Action variable id "%s" is not known', $actionVariableId)); - } - array_push($actionVariables, $parameters[$actionVariableId]); - } - } - return $actionVariables; + * @return ObjectGetter + */ + public function getObjectGetter() { + return $this->objectGetter; } } \ No newline at end of file diff --git a/src/PE/Nodes/EncoderNodeVariableCollection.php b/src/PE/Nodes/EncoderNodeVariableCollection.php index 6b14349..f38fd0f 100644 --- a/src/PE/Nodes/EncoderNodeVariableCollection.php +++ b/src/PE/Nodes/EncoderNodeVariableCollection.php @@ -2,77 +2,232 @@ namespace PE\Nodes; -use PE\Exceptions\EncoderNodeVariableException; -use PE\Variables\Variable; -use PE\Variables\VariableCollection; +use PE\Exceptions\EncoderNodeVariableCollectionException; +use PE\Variables\Types\NodeAccessor; +use PE\Variables\Types\ObjectAccessor; -class EncoderNodeVariableCollection extends VariableCollection { +class EncoderNodeVariableCollection { - private $_cachedAlwaysExecutedVariables; + private $_cache; - public function getVariablesSetterActionByType($type) { - return $this->_getVariablesActionByType($type, 'getSetterAction'); + /** + * @var EncoderNodeVariable[] + */ + private $variables; + + function __construct() { + $this->_cache = array(); + $this->variables = array(); } - public function getVariablesGetterActionByType($type) { - return $this->_getVariablesActionByType($type, 'getGetterAction'); + + /** + * Adds a EncoderNodeVariable to the collection + * @param EncoderNodeVariable $variable + * @return EncoderNodeVariable + */ + public function addVariable(EncoderNodeVariable $variable) { + $id = $variable->getId(); + if ($this->variableExists($id)) { + throw new EncoderNodeVariableCollectionException(sprintf('Trying to add a EncoderNodeVariable but a variable with id "%s" already exists', $id)); + } + $this->variables[$id] = $variable; + return $variable; } /** - * @param $type - * @param $actionMethod - * @return EncoderNodeVariable[] + * @param EncoderNodeVariable|string $variable + * @return EncoderNodeVariable */ - protected function _getVariablesActionByType($type, $actionMethod) { - $variables = array(); - foreach ($this->getVariables() as $variable) { - $action = $variable->$actionMethod(); - if (isset($action['type']) && $action['type'] == $type) { - $variables[$variable->getId()] = $variable; + public function getVariable($variable) { + if (is_string($variable)) { + if ($object = $this->getVariableById($variable)) { + return $object; } } - return $variables; + else if (is_object($variable)) { + return $variable; + } + return null; } /** - * @param EncoderNodeVariable $variable - * @return EncoderNodeVariable + * @return EncoderNodeVariable[] */ - public function addNodeVariable(EncoderNodeVariable $variable) { - $this->_cachedAlwaysExecutedVariables = null; - $variable = parent::addVariable($variable); - return $variable; + public function getVariables() { + return $this->variables; } /** - * You cannot use this method, use "addNodeVariable" instead - * - * @param Variable $variable - * @return void + * Get a variable based on its id + * @param $id + * @return null|EncoderNodeVariable */ - public function addVariable(Variable $variable) { - throw new EncoderNodeVariableException('Use "addNodeVariable" to add variables'); + public function getVariableById($id) { + return $this->variableExists($id) ? $this->variables[$id] : null; } + /** + * @param string $id + * @return bool + */ + public function variableExists($id) { + return isset($this->variables[$id]); + } + + + /** + * @param bool $ordered + * @return EncoderNodeVariable[] + */ + public function getPreNodeSetterVariables($ordered = true) { + $parameters = $ordered; + if (($result = $this->_cache(__FUNCTION__, $parameters)) === false) { + $result = $this->_getVariables('has' . ucfirst(NodeAccessor::ORDER_PRE) . 'Node' . ucfirst(NodeAccessor::ACCESSOR_SETTER), $ordered); + $this->_cache(__FUNCTION__, $parameters, $result); + } + return $result; + } + + /** + * @param bool $ordered + * @return EncoderNodeVariable[] + */ + public function getPreNodeGetterVariables($ordered = true) { + $parameters = $ordered; + if (($result = $this->_cache(__FUNCTION__, $parameters)) === false) { + $result = $this->_getVariables('has' . ucfirst(NodeAccessor::ORDER_PRE) . 'Node' . ucfirst(NodeAccessor::ACCESSOR_GETTER), $ordered); + $this->_cache(__FUNCTION__, $parameters, $result); + } + return $result; + } + + + /** + * @param bool $ordered + * @return EncoderNodeVariable[] + */ + public function getPostNodeSetterVariables($ordered = true) { + $parameters = $ordered; + if (($result = $this->_cache(__FUNCTION__, $parameters)) === false) { + $result = $this->_getVariables('has' . ucfirst(NodeAccessor::ORDER_POST) . 'Node' . ucfirst(NodeAccessor::ACCESSOR_SETTER), $ordered); + $this->_cache(__FUNCTION__, $parameters, $result); + } + return $result; + } + + /** + * @param bool $ordered + * @return EncoderNodeVariable[] + */ + public function getPostNodeGetterVariables($ordered = true) { + $parameters = $ordered; + if (($result = $this->_cache(__FUNCTION__, $parameters)) === false) { + $result = $this->_getVariables('has' . ucfirst(NodeAccessor::ORDER_POST) . 'Node' . ucfirst(NodeAccessor::ACCESSOR_GETTER), $ordered); + $this->_cache(__FUNCTION__, $parameters, $result); + } + return $result; + } + + + /** + * @param bool $ordered + * @return EncoderNodeVariable[] + */ + public function getObjectSetterVariables($ordered = true) { + $parameters = $ordered; + if (($result = $this->_cache(__FUNCTION__, $parameters)) === false) { + $result = $this->_getVariables('hasObject' . ucfirst(ObjectAccessor::ACCESSOR_SETTER), $ordered); + $this->_cache(__FUNCTION__, $parameters, $result); + } + return $result; + } + + /** + * @param bool $ordered + * @return EncoderNodeVariable[] + */ + public function getObjectGetterVariables($ordered = true) { + $parameters = $ordered; + if (($result = $this->_cache(__FUNCTION__, $parameters)) === false) { + $result = $this->_getVariables('hasObject' . ucfirst(ObjectAccessor::ACCESSOR_GETTER), $ordered); + $this->_cache(__FUNCTION__, $parameters, $result); + } + return $result; + } + + /** + * @param string $methodNameHas + * @param bool $ordered + * @return EncoderNodeVariable[] + */ + protected function _getVariables($methodNameHas, $ordered = true) { + $orderedVariables = array(); + $unorderedVariables = array(); + foreach ($this->variables as $variable) { + if (!$variable->{$methodNameHas}()) { + // the variable does not have an object variable so continue the loop + continue; + } + $orderPosition = $ordered ? $variable->getOrder() : null; + if ($orderPosition !== null) { + if (array_key_exists($orderPosition, $orderedVariables)) { + throw new EncoderNodeVariableCollectionException(sprintf('Cannot order variables because position "%s" is being used more than once', $orderPosition)); + } + $orderedVariables[$orderPosition] = $variable; + } + else { + array_push($unorderedVariables, $variable); + } + } + // sort the ordered variables array + ksort($orderedVariables); + // merge all arrays and return the merged variables + return $ordered ? array_merge($orderedVariables, $unorderedVariables) : $unorderedVariables; + } + + + /** + * @param string $method The "has-variable" method name + * @param null $parameters + * @param bool $value + * @return bool + */ + protected function _cache($method, $parameters = null, $value = false) { + $parameters = is_null($parameters) ? '__default__' : (string) $parameters; + if ($value !== false) { + if (!isset($this->_cache[$method])) { + $this->_cache[$method] = array(); + } + $this->_cache[$method][$parameters] = $value; + return $value; + } + if (!(array_key_exists($method, $this->_cache) && array_key_exists($parameters, $this->_cache[$method]))) { + return false; + } + return $this->_cache[$method][$parameters]; + } + + /** * @param $dataArray * @param bool $throwErrorIfFails Set to true if you want it to throw an error if it fails * @return bool Returns true if all requirements are met */ - public function variablesAreValidWithData($dataArray, $throwErrorIfFails = false) { - $variables = $this->getVariables(); + public function objectVariablesAreValidWithData($dataArray, $throwErrorIfFails = false) { + $variables = $this->getObjectSetterVariables(false); $unique = array(); foreach ($dataArray as $data) { foreach ($variables as $variable) { $variableId = $variable->getId(); if ($variableId !== null && array_key_exists($variableId, $data)) { - if ($variable->mustBeUnique()) { + if ($variable->getObjectSetter()->mustBeUnique()) { if (!isset($unique[$variableId])) { $unique[$variableId] = array(); } $variableValue = $data[$variableId]; if (array_search($variableValue, $unique[$variableId]) !== false) { if ($throwErrorIfFails) { - throw new EncoderNodeVariableException(sprintf('Variable "%s" must be unique but value "%s" is given at least twice', $variableId, $variableValue)); + throw new EncoderNodeVariableCollectionException(sprintf('Variable "%s" must be unique but value "%s" is given at least twice', $variableId, $variableValue)); } else { return false; @@ -85,28 +240,4 @@ public function variablesAreValidWithData($dataArray, $throwErrorIfFails = false } return true; } - - public function getAlwaysExecutedVariables() { - if ($this->_cachedAlwaysExecutedVariables !== null) { - return $this->_cachedAlwaysExecutedVariables; - } - $variables = array(); - foreach ($this->getVariables() as $variable) { - if ($variable->alwaysExecute()) { - $variables[$variable->getId()] = $variable; - } - } - $this->_cachedAlwaysExecutedVariables = $variables; - return $variables; - } - - /** - * Overridden method so the returned data type corresponds with this class - * - * @param bool $order - * @return EncoderNodeVariable[] - */ - public function getVariables($order = true) { - return parent::getVariables($order); - } } \ No newline at end of file diff --git a/src/PE/Variables/Types/NodeAccessor.php b/src/PE/Variables/Types/NodeAccessor.php new file mode 100644 index 0000000..3e71a7d --- /dev/null +++ b/src/PE/Variables/Types/NodeAccessor.php @@ -0,0 +1,106 @@ +setParameters($parameters); + } + + protected function setParameters($parameters) { + if (!is_array($parameters)) { + $parameters = array(); + } + $this->parameters = $parameters; + } + public function getParameters() { + return $this->parameters; + } + + + /** + * Calls a certain node and provides any variables the method requires + * + * @param array $options Associated array based on all "SETTER_*" constants from ActionVariable. + * @return mixed Returns whatever the object returns + * + * @see ActionVariable All "SETTER_*" constants can be a key of the $parameters array + */ + public function apply($options) { + $parameters = $this->getParameters(); + + if (!count($parameters)) { + // if there are no custom parameters at least send the value of the variable + $parameters = array(NodeAccessor::VARIABLE_VALUE); + } + + // prepend the required node data as the first variable + array_unshift($parameters, NodeAccessor::VARIABLE_NODE_DATA); + + // using those parameters, call the node action method + return $this->_callNodeAction($options[NodeAccessor::VARIABLE_NODE], $this->getMethod(), $this->_gatherAccessorParameters($options, $parameters)); + } + + /** + * Gathers all required variables + * + * @param array $options Associated array based on all "SETTER_*" constants from ActionVariable. + * @param array $parameters All the options I would like to extract from the $options parameter + * @return array Returns an array with all required parameters extracted from the $parameters variable in the + * right order. + * @see ActionVariable All "SETTER_*" constants can be a key of the $parameters array + */ + protected function _gatherAccessorParameters($options, $parameters) { + $actionVariables = array(); + foreach ($parameters as $parameter) { + if (!array_key_exists($parameter, $options)) { + throw new VariableTypeException(sprintf('Parameter with id "%s" is not known', $parameter)); + } + array_push($actionVariables, $options[$parameter]); + } + return $actionVariables; + } + + /** + * Makes a call to the actual node method + * + * @param EncoderNode $node Node being used to make the call + * @param string $actionMethodName The method name from the node being called + * @param array $parameters All variables being set to the node in the order they are supplied + * @return mixed + */ + protected function _callNodeAction(EncoderNode $node, $actionMethodName, $parameters) { + return call_user_func_array(array($node, $actionMethodName), $parameters); + } +} \ No newline at end of file diff --git a/src/PE/Variables/Types/ObjectAccessor.php b/src/PE/Variables/Types/ObjectAccessor.php new file mode 100644 index 0000000..63b1eb7 --- /dev/null +++ b/src/PE/Variables/Types/ObjectAccessor.php @@ -0,0 +1,70 @@ +mustBeUnique = $bool; + } + return (bool) $this->mustBeUnique; + } + + /** + * @param string $str Spinal cased string + * @return string Camel cased string + */ + protected function camelCased($str) { + return ucfirst(Inflector::camelize($str, true, '-')); + } + + /** + * Applies parameters to a certain object method + * + * @param object $object The object you want to have called + * @param mixed $parameters The parameters this method should receive + * @return mixed Returns whatever the object returns + */ + protected function _apply($object, $parameters) { + $methodName = $this->getMethod(); + if (!method_exists($object, $methodName)) { + throw new VariableTypeException(sprintf('Method "%s" does not exist for class "%s" does not exist', $methodName, get_class($object))); + } + else { + return call_user_func_array(array($object, $methodName), $parameters); + } + } +} \ No newline at end of file diff --git a/src/PE/Variables/Types/ObjectGetter.php b/src/PE/Variables/Types/ObjectGetter.php new file mode 100644 index 0000000..f99ab19 --- /dev/null +++ b/src/PE/Variables/Types/ObjectGetter.php @@ -0,0 +1,32 @@ +camelCased($this->getVariable()->getId()); + } + + public function apply($object) { + return $this->_apply($object, array()); + } +} \ No newline at end of file diff --git a/src/PE/Variables/Types/ObjectSetter.php b/src/PE/Variables/Types/ObjectSetter.php new file mode 100644 index 0000000..59e8918 --- /dev/null +++ b/src/PE/Variables/Types/ObjectSetter.php @@ -0,0 +1,70 @@ +camelCased($this->getVariable()->getId()); + } + + public function apply($object, $value) { + return $this->_apply($object, array($this->processValue($value))); + } + + /** + * Processes a value based on the set data type of the variable + * @param $value + * @return mixed + */ + public function processValue($value) { + $type = $this->getVariable()->getType(); + if ($type !== null) { + switch ($type) { + case EncoderNodeVariable::TYPE_BOOL : + if (is_string($value)) { + return ($value === 'true' || $value === '1'); + } + else { + return (bool) $value; + } + break; + case EncoderNodeVariable::TYPE_ARRAY : + if (is_string($value)) { + return (array) json_decode($value); + } + else { + throw new VariableTypeException(sprintf('The set data type is array but the value cannot be processed')); + } + break; + case EncoderNodeVariable::TYPE_STRING : + return (string) $value; + break; + default : + throw new VariableTypeException(sprintf('Can\'t process value "%s" because the data type "%s" isn\'t recognized.', (string) $value, $type)); + } + } + return $value; + } +} \ No newline at end of file diff --git a/src/PE/Variables/Types/PostNodeGetter.php b/src/PE/Variables/Types/PostNodeGetter.php new file mode 100644 index 0000000..c70916d --- /dev/null +++ b/src/PE/Variables/Types/PostNodeGetter.php @@ -0,0 +1,17 @@ +method = $method; + } + + public function getMethod() { + return $this->method; + } + + /** + * Sets the Variable the type is connected to + * + * @param EncoderNodeVariable $variable + */ + public function setVariable($variable) { + $this->variable = $variable; + } + /** + * Gets the Variable the type is connected to + * + * @return EncoderNodeVariable + */ + public function getVariable() { + return $this->variable; + } + + /** + * This node variable is always executed even though there is not value set. This way you can force a value + * to be set manually + * + * @param null|bool $bool Set to true to enable the this variable to always be executed. Leave empty to retrieve the current value + * @return bool Default is false + */ + public function alwaysExecute($bool = null) { + if ($bool !== null && is_bool($bool)) { + $this->alwaysExecute = $bool; + } + return (bool) $this->alwaysExecute; + } +} \ No newline at end of file diff --git a/src/PE/Variables/Variable.php b/src/PE/Variables/Variable.php deleted file mode 100644 index bc9e417..0000000 --- a/src/PE/Variables/Variable.php +++ /dev/null @@ -1,203 +0,0 @@ -setId($id); - $this->parseOptions($options); - } - - /** - * Easy setup method for this class - * @param array $options - */ - public function parseOptions($options) { - $options = (array) $options; - foreach ($options as $option => $value) { - switch ($option) { - case 'method' : - $this->setSetterMethod($value); - $this->setGetterMethod($value); - break; - case 'setter' : - $this->setSetterMethod($value); - break; - case 'getter' : - $this->setGetterMethod($value); - break; - default : - $method = 'set' . ucfirst($option); - if (method_exists($this, $method)) { - $this->$method($value); - } - else if (method_exists($this, $option)) { - $this->$option($value); - } - break; - } - } - } - - /** - * @param string $id - * @return null|string - */ - public function setId($id) { - $this->id = $id; - return $id; - } - - /** - * @return string - */ - public function getId() { - return $this->id; - } - - - /** - * Method name of the corresponding node that sets the variable value - * @param string $setterMethodName - */ - public function setSetterMethod($setterMethodName) { - if ($setterMethodName !== null && (!$setterMethodName || empty($setterMethodName))) { - throw new VariableException(sprintf('A setter method for (%s) cannot be set because it has the wrong data type', $this->getId())); - } - $this->setterMethod = $setterMethodName; - } - /** - * @return string - */ - public function getSetterMethod() { - return $this->setterMethod; - } - - /** - * Method name of the corresponding node that gets the variable value - * @param string $getterMethodName - */ - public function setGetterMethod($getterMethodName) { - if ($getterMethodName !== null && (!$getterMethodName || empty($getterMethodName))) { - throw new VariableException(sprintf('A getter method for (%s) cannot be set because it has the wrong data type', $this->getId())); - } - $this->getterMethod = $getterMethodName; - } - /** - * @return string - */ - public function getGetterMethod() { - return $this->getterMethod; - } - - /** - * Sets the data type of the variable - * @param string $type - */ - public function setType($type) { - $this->type = $type; - } - /** - * @return string - */ - public function getType() { - return $this->type; - } - - /** - * Set the order the variable (when it is a collection) - * @param int $index - */ - public function setOrder($index) { - $this->order = $index; - } - /** - * @return int - */ - public function getOrder() { - return $this->order; - } - - /** - * Processes a value based on the set data type of the variable - * @param $value - * @return mixed - */ - public function processValue($value) { - $type = $this->getType(); - if ($type !== null) { - switch ($type) { - case self::TYPE_BOOL : - if (is_string($value)) { - return ($value === 'true' || $value === '1'); - } - else { - return (bool) $value; - } - break; - case self::TYPE_ARRAY : - if (is_string($value)) { - return (array) json_decode($value); - } - else { - throw new VariableException(sprintf('The set data type is array but the value cannot be processed')); - } - break; - case self::TYPE_STRING : - return (string) $value; - break; - default : - throw new VariableException(sprintf('Can\'t process value "%s" because the data type "%s" isn\'t recognized.', (string) $value, $type)); - } - } - return $value; - } -} \ No newline at end of file diff --git a/src/PE/Variables/VariableCollection.php b/src/PE/Variables/VariableCollection.php deleted file mode 100644 index 7705a28..0000000 --- a/src/PE/Variables/VariableCollection.php +++ /dev/null @@ -1,93 +0,0 @@ -variables = array(); - } - - public function processValue($name, $value) { - $variable = $this->getVariable($name); - if ($variable === null) { - return null; - } - return $variable->processValue($value); - } - - public function addVariable(Variable $variable) { - $id = $variable->getId(); - if (!$this->variableExists($id)) { - $this->variables[$id] = $variable; - } - return $variable; - } - public function alterVariable($variable, $options) { - $variable = $this->getVariable($variable); - if ($variable !== null) { - $variable->parseOptions($options); - return true; - } - return false; - } - - /** - * @param $variable - * @return Variable - */ - public function getVariable($variable) { - if (is_string($variable)) { - if ($object = $this->getVariableById($variable)) { - return $object; - } - } - else if (is_object($variable)) { - return $variable; - } - return null; - } - public function getVariableById($id) { - if ($this->variableExists($id)) { - return $this->variables[$id]; - } - return null; - } - - /** - * @param bool $order - * @return Variable[] - * @throws VariableCollectionException - */ - public function getVariables($order = true) { - if ($order === true) { - $orderedVariables = array(); - $unorderedVariables = array(); - foreach ($this->variables as $variable) { - $orderPosition = $variable->getOrder(); - if ($orderPosition !== null) { - if (array_key_exists($orderPosition, $orderedVariables)) { - throw new VariableCollectionException(sprintf('Cannot order variables because position "%s" is being used more than once', $orderPosition)); - } - $orderedVariables[$orderPosition] = $variable; - } - else { - array_push($unorderedVariables, $variable); - } - } - return array_merge($orderedVariables, $unorderedVariables); - } - return $this->variables; - } - - public function variableExists($id) { - return isset($this->variables[$id]); - } -} \ No newline at end of file diff --git a/tests/PE/Nodes/Erroneous/NoGetterMethodNode.php b/tests/PE/Nodes/Erroneous/NoGetterMethodNode.php index c61c1ee..3e8f374 100644 --- a/tests/PE/Nodes/Erroneous/NoGetterMethodNode.php +++ b/tests/PE/Nodes/Erroneous/NoGetterMethodNode.php @@ -2,6 +2,8 @@ namespace PE\Nodes\Erroneous; +use PE\Nodes\Children\NodeChildGetter; +use PE\Nodes\Children\NodeChildSetter; use PE\Nodes\EncoderNode; use PE\Nodes\EncoderNodeChild; @@ -10,10 +12,7 @@ class NoGetterMethodNode extends EncoderNode { function __construct() { parent::__construct('no-getter-methods', 'no-getter-method', '\\PE\\Samples\\Erroneous'); - $this->addChildNode(new EncoderNodeChild('things', array( - 'setter' => 'addThing', - 'getter' => 'getThings' - ))); + $this->addChildNode(new EncoderNodeChild('things', new NodeChildSetter('addThing'), new NodeChildGetter('getThings'))); } } \ No newline at end of file diff --git a/tests/PE/Nodes/Erroneous/NonArrayGetterMethodNode.php b/tests/PE/Nodes/Erroneous/NonArrayGetterMethodNode.php index b317cd8..dc4f0b8 100644 --- a/tests/PE/Nodes/Erroneous/NonArrayGetterMethodNode.php +++ b/tests/PE/Nodes/Erroneous/NonArrayGetterMethodNode.php @@ -2,6 +2,8 @@ namespace PE\Nodes\Erroneous; +use PE\Nodes\Children\NodeChildGetter; +use PE\Nodes\Children\NodeChildSetter; use PE\Nodes\EncoderNode; use PE\Nodes\EncoderNodeChild; @@ -10,9 +12,6 @@ class NonArrayGetterMethodNode extends EncoderNode { function __construct() { parent::__construct('non-array-getter-methods', 'non-array-getter-method', '\\PE\\Samples\\Erroneous'); - $this->addChildNode(new EncoderNodeChild('things', array( - 'setter' => 'addThing', - 'getter' => 'getThings' - ))); + $this->addChildNode(new EncoderNodeChild('things', new NodeChildSetter('addThing'), new NodeChildGetter('getThings'))); } } \ No newline at end of file diff --git a/tests/PE/Nodes/Farm/BuildingNode.php b/tests/PE/Nodes/Farm/BuildingNode.php index a86a2b5..ce76fba 100644 --- a/tests/PE/Nodes/Farm/BuildingNode.php +++ b/tests/PE/Nodes/Farm/BuildingNode.php @@ -6,6 +6,8 @@ use PE\Nodes\EncoderNode; use PE\Nodes\EncoderNodeVariable; use PE\Samples\Farm\Building; +use PE\Variables\Types\NodeAccessor; +use PE\Variables\Types\PostNodeGetter; class BuildingNode extends EncoderNode { @@ -13,14 +15,12 @@ function __construct($classPrepend = null, $nodeTypeName = null) { parent::__construct('buildings', 'building', $classPrepend !== null ? $classPrepend : '\\PE\\Samples\\Farm', $nodeTypeName); - $this->addVariable(new EncoderNodeVariable('type', array( - 'getterAction' => array( - 'type' => EncoderNodeVariable::ACTION_TYPE_NODE, - 'method' => 'getBuildingType', - 'variables' => array(ActionVariable::GETTER_OBJECT) - ), - 'alwaysExecute' => true + $type = $this->addVariable(new EncoderNodeVariable('type')); + + $typePostNodeGetter = $type->postNodeGetter(new PostNodeGetter('getBuildingType', array( + NodeAccessor::VARIABLE_OBJECT ))); + $typePostNodeGetter->alwaysExecute(true); } public function getBuildingType($nodeData, Building $building) { diff --git a/tests/PE/Nodes/Farm/Buildings/AnimalsBuildingNode.php b/tests/PE/Nodes/Farm/Buildings/AnimalsBuildingNode.php index dcf3b7f..0c84215 100644 --- a/tests/PE/Nodes/Farm/Buildings/AnimalsBuildingNode.php +++ b/tests/PE/Nodes/Farm/Buildings/AnimalsBuildingNode.php @@ -2,6 +2,8 @@ namespace PE\Nodes\Farm\Buildings; +use PE\Nodes\Children\NodeChildGetter; +use PE\Nodes\Children\NodeChildSetter; use PE\Nodes\EncoderNodeChild; class AnimalsBuildingNode extends CustomBuilding { @@ -9,10 +11,7 @@ class AnimalsBuildingNode extends CustomBuilding { function __construct($nodeTypeName) { parent::__construct($nodeTypeName); - $this->addChildNode(new EncoderNodeChild('animals', array( - 'setter' => 'addAnimal', - 'getter' => 'getAnimals' - ))); + $this->addChildNode(new EncoderNodeChild('animals', new NodeChildSetter('addAnimal'), new NodeChildGetter('getAnimals'))); } } \ No newline at end of file diff --git a/tests/PE/Nodes/Farm/FarmNode.php b/tests/PE/Nodes/Farm/FarmNode.php index 5efbfcb..0bdde6a 100644 --- a/tests/PE/Nodes/Farm/FarmNode.php +++ b/tests/PE/Nodes/Farm/FarmNode.php @@ -2,6 +2,8 @@ namespace PE\Nodes\Farm; +use PE\Nodes\Children\NodeChildGetter; +use PE\Nodes\Children\NodeChildSetter; use PE\Nodes\EncoderNode; use PE\Nodes\EncoderNodeChild; @@ -10,10 +12,7 @@ class FarmNode extends EncoderNode { function __construct() { parent::__construct('farms', 'farm', '\\PE\\Samples\\Farm'); - $this->addChildNode(new EncoderNodeChild('buildings', array( - 'setter' => 'addBuilding', - 'getter' => 'getBuildings' - ))); + $this->addChildNode(new EncoderNodeChild('buildings', new NodeChildSetter('addBuilding'), new NodeChildGetter('getBuildings'))); } } \ No newline at end of file diff --git a/tests/PE/Nodes/General/ThingsNode.php b/tests/PE/Nodes/General/ThingsNode.php index 20ea5b8..bb8db2d 100644 --- a/tests/PE/Nodes/General/ThingsNode.php +++ b/tests/PE/Nodes/General/ThingsNode.php @@ -2,6 +2,8 @@ namespace PE\Nodes\General; +use PE\Nodes\Children\NodeChildGetter; +use PE\Nodes\Children\NodeChildSetter; use PE\Nodes\EncoderNode; use PE\Nodes\EncoderNodeChild; @@ -10,10 +12,7 @@ class ThingsNode extends EncoderNode { function __construct() { parent::__construct('thingsContainer', 'thingContainer', '\\PE\\Samples\General'); - $this->addChildNode(new EncoderNodeChild('things', array( - 'setter' => 'addThing', - 'getter' => 'getThings' - ))); + $this->addChildNode(new EncoderNodeChild('things', new NodeChildSetter('addThing'), new NodeChildGetter('getThings'))); } } \ No newline at end of file diff --git a/tests/PE/Nodes/Specials/AccessorMethodActionTypeNodeNode.php b/tests/PE/Nodes/Specials/AccessorMethodActionTypeNodeNode.php index 0ecdd44..bbf27c2 100644 --- a/tests/PE/Nodes/Specials/AccessorMethodActionTypeNodeNode.php +++ b/tests/PE/Nodes/Specials/AccessorMethodActionTypeNodeNode.php @@ -5,6 +5,9 @@ use PE\Enums\ActionVariable; use PE\Nodes\EncoderNode; use PE\Nodes\EncoderNodeVariable; +use PE\Variables\Types\NodeAccessor; +use PE\Variables\Types\PostNodeGetter; +use PE\Variables\Types\PostNodeSetter; class AccessorMethodActionTypeNodeNode extends EncoderNode { @@ -13,18 +16,9 @@ function __construct() { $this->addVariable(new EncoderNodeVariable('special')); - $this->addVariable(new EncoderNodeVariable('node', array( - 'setterAction' => array( - 'type' => EncoderNodeVariable::ACTION_TYPE_NODE, - 'method' => 'addNodeToSpecial', - 'variables' => array(ActionVariable::SETTER_NAME) - ), - 'getterAction' => array( - 'type' => EncoderNodeVariable::ACTION_TYPE_NODE, - 'method' => 'getNodeFromSpecial', - 'variables' => array(ActionVariable::GETTER_NAME) - ) - ))); + $special = $this->addVariable(new EncoderNodeVariable('node', false)); + $special->postNodeSetter(new PostNodeSetter('addNodeToSpecial', array(NodeAccessor::VARIABLE_NAME))); + $special->postNodeGetter(new PostNodeGetter('getNodeFromSpecial', array(NodeAccessor::VARIABLE_NAME))); } public function addNodeToSpecial($data, $setterName) { diff --git a/tests/PE/Nodes/Specials/AddAfterDecodeChildRequiresNode.php b/tests/PE/Nodes/Specials/AddAfterDecodeChildRequiresNode.php index 9120cdf..d778ba9 100644 --- a/tests/PE/Nodes/Specials/AddAfterDecodeChildRequiresNode.php +++ b/tests/PE/Nodes/Specials/AddAfterDecodeChildRequiresNode.php @@ -7,19 +7,16 @@ use PE\Nodes\EncoderNodeChild; use PE\Nodes\EncoderNodeVariable; use PE\Samples\Specials\AddAfterDecodeParent; +use PE\Variables\Types\NodeAccessor; +use PE\Variables\Types\PostNodeSetter; class AddAfterDecodeChildRequiresNode extends EncoderNode { function __construct() { parent::__construct('add-after-decode-children-require', 'add-after-decode-child-require', '\\PE\\Samples\\Specials'); - $this->addVariable(new EncoderNodeVariable('name', array( - 'setterAction' => array( - 'type' => EncoderNodeChild::ACTION_TYPE_NODE, - 'method' => 'nodeSetName', - 'variables' => array(ActionVariable::SETTER_VALUE, ActionVariable::SETTER_PARENT) - ) - ))); + $name = $this->addVariable(new EncoderNodeVariable('name')); + $name->postNodeSetter(new PostNodeSetter('nodeSetName', array(NodeAccessor::VARIABLE_VALUE, NodeAccessor::VARIABLE_PARENT))); } public function nodeSetName($nodeData, $value, AddAfterDecodeParent $parent) { diff --git a/tests/PE/Nodes/Specials/AddAfterDecodeParentNode.php b/tests/PE/Nodes/Specials/AddAfterDecodeParentNode.php index 054c8e5..cf52a9b 100644 --- a/tests/PE/Nodes/Specials/AddAfterDecodeParentNode.php +++ b/tests/PE/Nodes/Specials/AddAfterDecodeParentNode.php @@ -2,6 +2,8 @@ namespace PE\Nodes\Specials; +use PE\Nodes\Children\NodeChildGetter; +use PE\Nodes\Children\NodeChildSetter; use PE\Nodes\EncoderNode; use PE\Nodes\EncoderNodeChild; use PE\Nodes\EncoderNodeVariable; @@ -13,16 +15,11 @@ function __construct($addAfterAttributes = true) { $this->addVariable(new EncoderNodeVariable('name')); - $this->addChildNode(new EncoderNodeChild('add-after-decode-child', array( - 'setter' => 'addChild', - 'getter' => 'getChildren', - 'setAfterChildren' => false, - 'setAfterAttributes' => $addAfterAttributes - ))); + $addAfterDecodeChildSetter = new NodeChildSetter('addChild'); + $addAfterDecodeChildSetter->setAfterChildren(false); + $addAfterDecodeChildSetter->setAfterAttributes($addAfterAttributes); + $this->addChildNode(new EncoderNodeChild('add-after-decode-child', $addAfterDecodeChildSetter, new NodeChildGetter('getChildren'))); - $this->addChildNode(new EncoderNodeChild('add-after-decode-children-require', array( - 'setter' => 'addChildRequires', - 'getter' => 'getChildrenRequires' - ))); + $this->addChildNode(new EncoderNodeChild('add-after-decode-children-require', new NodeChildSetter('addChildRequires'), new NodeChildGetter('getChildrenRequires'))); } } \ No newline at end of file diff --git a/tests/PE/Nodes/Specials/EncoderNodeVariableApplyToSetterNode.php b/tests/PE/Nodes/Specials/EncoderNodeVariableApplyToSetterNode.php index 11fe23d..e9d984d 100644 --- a/tests/PE/Nodes/Specials/EncoderNodeVariableApplyToSetterNode.php +++ b/tests/PE/Nodes/Specials/EncoderNodeVariableApplyToSetterNode.php @@ -7,73 +7,39 @@ use PE\Nodes\EncoderNodeVariable; use PE\Samples\General\Thing; use PE\Samples\Specials\EncoderNodeVariableApplyToSetter; +use PE\Variables\Types\NodeAccessor; +use PE\Variables\Types\ObjectSetter; +use PE\Variables\Types\PostNodeSetter; class EncoderNodeVariableApplyToSetterNode extends EncoderNode { function __construct() { parent::__construct('encoder-node-variable-apply-to-setters-node', 'encoder-node-variable-apply-to-setters-node', '\\PE\\Samples\\Specials'); - $this->addVariable(new EncoderNodeVariable('node-simple', array( - 'setterAction' => array( - 'type' => EncoderNodeVariable::ACTION_TYPE_NODE, - 'method' => 'nodeSimple', - 'variables' => array(ActionVariable::SETTER_NAME) - ) - ))); - - $this->addVariable(new EncoderNodeVariable('node-full', array( - 'setterAction' => array( - 'type' => EncoderNodeVariable::ACTION_TYPE_NODE, - 'method' => 'nodeFull', - 'variables' => array(ActionVariable::SETTER_NAME, ActionVariable::SETTER_VALUE, ActionVariable::SETTER_OBJECT, ActionVariable::SETTER_PARENT) - ) - ))); - - $this->addVariable(new EncoderNodeVariable('node-without-variables', array( - 'setterAction' => array( - 'type' => EncoderNodeVariable::ACTION_TYPE_NODE, - 'method' => 'nodeWithoutVariables' - ) - ))); - $this->addVariable(new EncoderNodeVariable('node-without-variables-empty', array( - 'setterAction' => array( - 'type' => EncoderNodeVariable::ACTION_TYPE_NODE, - 'method' => 'nodeWithoutVariables', - 'variables' => array() - ) - ))); - $this->addVariable(new EncoderNodeVariable('node-without-variables-null', array( - 'setterAction' => array( - 'type' => EncoderNodeVariable::ACTION_TYPE_NODE, - 'method' => 'nodeWithoutVariables', - 'variables' => array() - ) - ))); + $nodeSimple = $this->addVariable(new EncoderNodeVariable('node-simple')); + $nodeSimple->postNodeSetter(new PostNodeSetter('nodeSimple', array(NodeAccessor::VARIABLE_NAME))); - $this->addVariable(new EncoderNodeVariable('node-unknown-variable', array( - 'setterAction' => array( - 'type' => EncoderNodeVariable::ACTION_TYPE_NODE, - 'method' => 'nodeSimple', - 'variables' => array('unknown_variable') - ) + $nodeFull = $this->addVariable(new EncoderNodeVariable('node-full')); + $nodeFull->postNodeSetter(new PostNodeSetter('nodeFull', array( + NodeAccessor::VARIABLE_NAME, + NodeAccessor::VARIABLE_VALUE, + NodeAccessor::VARIABLE_OBJECT, + NodeAccessor::VARIABLE_PARENT ))); + $nodeWithoutVariables = $this->addVariable(new EncoderNodeVariable('node-without-variables')); + $nodeWithoutVariables->postNodeSetter(new PostNodeSetter('nodeWithoutVariables')); - $this->addVariable(new EncoderNodeVariable('var')); + $nodeWithoutVariablesEmpty = $this->addVariable(new EncoderNodeVariable('node-without-variables-empty')); + $nodeWithoutVariablesEmpty->postNodeSetter(new PostNodeSetter('nodeWithoutVariables', array())); - $this->addVariable(new EncoderNodeVariable('object-using-setter-action', array( - 'setterAction' => array( - 'method' => 'setVar' - ) - ))); + $nodeWithoutVariablesNull = $this->addVariable(new EncoderNodeVariable('node-without-variables-null')); + $nodeWithoutVariablesNull->postNodeSetter(new PostNodeSetter('nodeWithoutVariables', array())); - $this->addVariable(new EncoderNodeVariable('object-using-setter-method', array( - 'setter' => 'setVar' - ))); + $nodeUnknownVariable = $this->addVariable(new EncoderNodeVariable('node-unknown-variable')); + $nodeUnknownVariable->postNodeSetter(new PostNodeSetter('nodeSimple', array('unknown_variable'))); - $this->addVariable(new EncoderNodeVariable('object-using-unknown-setter-method', array( - 'setterMethod' => 'unknownMethod' - ))); + $this->addVariable(new EncoderNodeVariable('var')); } public function nodeSimple($nodeData, $setterName) { diff --git a/tests/PE/Nodes/Specials/NonArrayGetterMethodOnPurposeNode.php b/tests/PE/Nodes/Specials/NonArrayGetterMethodOnPurposeNode.php index 38d55a5..36ed73a 100644 --- a/tests/PE/Nodes/Specials/NonArrayGetterMethodOnPurposeNode.php +++ b/tests/PE/Nodes/Specials/NonArrayGetterMethodOnPurposeNode.php @@ -2,6 +2,8 @@ namespace PE\Nodes\Specials; +use PE\Nodes\Children\NodeChildGetter; +use PE\Nodes\Children\NodeChildSetter; use PE\Nodes\EncoderNode; use PE\Nodes\EncoderNodeChild; @@ -10,11 +12,7 @@ class NonArrayGetterMethodOnPurposeNode extends EncoderNode { function __construct() { parent::__construct('non-array-getter-methods-on-purpose', 'non-array-getter-method-on-purpose', '\\PE\\Samples\\Specials'); - $this->addChildNode(new EncoderNodeChild('things', array( - 'setter' => 'addThing', - 'getter' => 'getThing', - 'isArray' => false - ))); + $things = $this->addChildNode(new EncoderNodeChild('things', new NodeChildSetter('addThing'), new NodeChildGetter('getThing'))); + $things->isArray(false); } - } \ No newline at end of file diff --git a/tests/PE/Nodes/Specials/SingleChildNode.php b/tests/PE/Nodes/Specials/SingleChildNode.php index 6cf574b..0d36d5c 100644 --- a/tests/PE/Nodes/Specials/SingleChildNode.php +++ b/tests/PE/Nodes/Specials/SingleChildNode.php @@ -2,6 +2,8 @@ namespace PE\Nodes\Specials; +use PE\Nodes\Children\NodeChildGetter; +use PE\Nodes\Children\NodeChildSetter; use PE\Nodes\EncoderNode; use PE\Nodes\EncoderNodeChild; @@ -10,11 +12,8 @@ class SingleChildNode extends EncoderNode { function __construct() { parent::__construct('single-children', 'single-child', '\\PE\\Samples\\Specials'); - $this->addChildNode(new EncoderNodeChild('thing', array( - 'setter' => 'setThing', - 'getter' => 'getThing', - 'isArray' => false - ))); + $thing = $this->addChildNode(new EncoderNodeChild('thing', new NodeChildSetter('setThing'), new NodeChildGetter('getThing'))); + $thing->isArray(false); } } \ No newline at end of file diff --git a/tests/PE/Nodes/Specials/VariableTypesNode.php b/tests/PE/Nodes/Specials/VariableTypesNode.php new file mode 100644 index 0000000..b9018c9 --- /dev/null +++ b/tests/PE/Nodes/Specials/VariableTypesNode.php @@ -0,0 +1,118 @@ +addVariable(new EncoderNodeVariable('required')); + $required->setType(EncoderNodeVariable::TYPE_STRING); + $required->preNodeSetter(new PreNodeSetter('preNodeRequiredSetter', array( + NodeAccessor::VARIABLE_NODE, + NodeAccessor::VARIABLE_NAME, + NodeAccessor::VARIABLE_VALUE, + NodeAccessor::VARIABLE_PARENT + ))); + $required->postNodeSetter(new PostNodeSetter('postNodeRequiredSetter', array( + NodeAccessor::VARIABLE_NODE, + NodeAccessor::VARIABLE_NAME, + NodeAccessor::VARIABLE_VALUE, + NodeAccessor::VARIABLE_OBJECT, + NodeAccessor::VARIABLE_PARENT + ))); + + $required->preNodeGetter(new PreNodeGetter('preNodeRequiredGetter', array( + NodeAccessor::VARIABLE_NODE, + NodeAccessor::VARIABLE_NAME, + NodeAccessor::VARIABLE_OBJECT, + NodeAccessor::VARIABLE_PARENT + ))); + $required->postNodeGetter(new PostNodeGetter('postNodeRequiredGetter', array( + NodeAccessor::VARIABLE_NODE, + NodeAccessor::VARIABLE_NAME, + NodeAccessor::VARIABLE_VALUE, + NodeAccessor::VARIABLE_OBJECT, + NodeAccessor::VARIABLE_PARENT + ))); + + + $optional = $this->addVariable(new EncoderNodeVariable('optional')); + $optional->preNodeSetter(new PreNodeSetter('preNodeOptionalSetter', array( + NodeAccessor::VARIABLE_NODE, + NodeAccessor::VARIABLE_NAME, + NodeAccessor::VARIABLE_VALUE, + NodeAccessor::VARIABLE_PARENT + ))); + $optional->postNodeSetter(new PostNodeSetter('postNodeOptionalSetter', array( + NodeAccessor::VARIABLE_NODE, + NodeAccessor::VARIABLE_NAME, + NodeAccessor::VARIABLE_VALUE, + NodeAccessor::VARIABLE_OBJECT, + NodeAccessor::VARIABLE_PARENT + ))); + + $optional->preNodeGetter(new PreNodeGetter('preNodeOptionalGetter', array( + NodeAccessor::VARIABLE_NODE, + NodeAccessor::VARIABLE_NAME, + NodeAccessor::VARIABLE_OBJECT, + NodeAccessor::VARIABLE_PARENT + ))); + $optional->postNodeGetter(new PostNodeGetter('postNodeOptionalGetter', array( + NodeAccessor::VARIABLE_NODE, + NodeAccessor::VARIABLE_NAME, + NodeAccessor::VARIABLE_VALUE, + NodeAccessor::VARIABLE_OBJECT, + NodeAccessor::VARIABLE_PARENT + ))); + } + + public function preNodeRequiredSetter($nodeData, VariableTypesNode $variableTypesNode, $name, $value, $parent) { + $nodeData['required'] = $nodeData['required'] . ' | setter pre'; + return $nodeData; + } + public function postNodeRequiredSetter($nodeData, VariableTypesNode $variableTypesNode, $name, $value, VariableTypes $variableTypes, $parent) { + $nodeData['required'] = $nodeData['required'] . ' | setter post'; + return $nodeData; + } + + public function preNodeRequiredGetter($nodeData, VariableTypesNode $variableTypesNode, $name, VariableTypes $variableTypes, $parent) { + $variableTypes->setOptional($variableTypes->getOptional() . ' | required pre'); + $nodeData['pre-required'] = 'getter pre'; + return $nodeData; + } + public function postNodeRequiredGetter($nodeData, VariableTypesNode $variableTypesNode, $name, $value, VariableTypes $variableTypes, $parent) { + $nodeData['required'] = $nodeData['required'] . ' | getter post'; + return $nodeData; + } + + + public function preNodeOptionalSetter($nodeData, VariableTypesNode $variableTypesNode, $name, $value, $parent) { + $nodeData['optional'] = $nodeData['optional'] . ' | setter pre'; + return $nodeData; + } + public function postNodeOptionalSetter($nodeData, VariableTypesNode $variableTypesNode, $name, $value, VariableTypes $variableTypes, $parent) { + $nodeData['optional'] = $nodeData['optional'] . ' | setter post'; + return $nodeData; + } + + public function preNodeOptionalGetter($nodeData, VariableTypesNode $variableTypesNode, $name, VariableTypes $variableTypes, $parent) { + $variableTypes->setOptional($variableTypes->getOptional() . ' | optional pre'); + $nodeData['pre-optional'] = 'getter pre'; + return $nodeData; + } + public function postNodeOptionalGetter($nodeData, VariableTypesNode $variableTypesNode, $name, $value, VariableTypes $variableTypes, $parent) { + $nodeData['optional'] = $nodeData['optional'] . ' | getter post'; + return $nodeData; + } +} \ No newline at end of file diff --git a/tests/PE/Samples/Specials/VariableTypes.php b/tests/PE/Samples/Specials/VariableTypes.php new file mode 100644 index 0000000..721d6e7 --- /dev/null +++ b/tests/PE/Samples/Specials/VariableTypes.php @@ -0,0 +1,23 @@ +required = $required; + } + function getRequired() { + return $this->required; + } + + function setOptional($value) { + $this->optional = $value; + } + function getOptional() { + return $this->optional; + } +} \ No newline at end of file diff --git a/tests/PE/Tests/EncoderTest.php b/tests/PE/Tests/EncoderTest.php index d3d9e71..4e58e1c1 100644 --- a/tests/PE/Tests/EncoderTest.php +++ b/tests/PE/Tests/EncoderTest.php @@ -12,6 +12,7 @@ use PE\Samples\Specials\RequiredConstructorVariables; use PE\Samples\Specials\AccessorMethodActionTypeNode; use PE\Samples\Specials\SingleChild; +use PE\Samples\Specials\VariableTypes; class EncoderTest extends Samples { @@ -197,7 +198,7 @@ public function testDecodeObjectWithRequiredConstructorVariablesWhenOneOfTheVari )); } public function testDecodeObjectWithRequiredConstructorVariablesButOneRequiredVariableIsNotProperlySetup() { - $this->setExpectedException('\\PE\\Exceptions\\EncoderException', 'Variable "name" for "\PE\Samples\Specials\RequiredConstructorVariables" cannot process its value (awesomeType). Presumably because the NodeType does not recognize the variable'); + $this->setExpectedException('\\PE\\Exceptions\\EncoderException', 'Variable "name" for "\PE\Samples\Specials\RequiredConstructorVariables" is required but there is no EncoderNodeVariable available to retrieve the value for node "required-constructor-variables" (Node type: "required-constructors-variables") at index "0"'); $encoder = $this->encoder(); $this->addRequiredConstructorVariablesNode(false); @@ -238,6 +239,28 @@ public function testDecodeObjectWithOptionalVariables() { $this->assertEquals('other hello world', $obj->getOtherVariable()); } + public function testDecodeObjectAllVariableTypes() { + $this->addVariableTypesNode(); + $decoded = $this->encoder()->decode(array( + 'variable-type' => array( + 'required' => 'Hello world', + 'optional' => 'Hello other world' + ) + )); + + /** @var VariableTypes $obj */ + $obj = $decoded['variable-type']; + $this->assertEquals('Hello world | setter pre', $obj->getRequired()); + $this->assertEquals('Hello other world | setter pre | setter post', $obj->getOptional()); + + $encoded = $this->encoder()->encode($obj); + $encodedProcessed = $encoded['processed']; + $this->assertEquals('Hello world | setter pre | getter post', $encodedProcessed['variable-type']['required']); + $this->assertEquals('getter pre', $encodedProcessed['variable-type']['pre-required']); + $this->assertEquals('Hello other world | setter pre | setter post | required pre | optional pre | getter post', $encodedProcessed['variable-type']['optional']); + $this->assertEquals('getter pre', $encodedProcessed['variable-type']['pre-optional']); + } + public function testDecodeWithSetAfterChildrenFalse() { $this->addAddAfterDecodeNodes(); @@ -399,7 +422,7 @@ public function testEncodeWithoutGetterMethod() { $this->encoder()->encode($this->getNoGetterMethod()); } public function testEncodeWithoutVariableGetterMethod() { - $this->setExpectedException('\\PE\\Exceptions\\EncoderException', 'Getter method "getNonExistent" does not exist in object "PE\Samples\Erroneous\NoVariableGetterMethod" for node type "default" (PE\Nodes\Erroneous\NoVariableGetterMethodNode) and variable with id "nonExistent".'); + $this->setExpectedException('\\PE\\Exceptions\\VariableTypeException', 'Method "getNonExistent" does not exist for class "PE\Samples\Erroneous\NoVariableGetterMethod" does not exist'); $this->addVariableNoGetterMethodNode(); diff --git a/tests/PE/Tests/Nodes/Children/NodeChildGetterTest.php b/tests/PE/Tests/Nodes/Children/NodeChildGetterTest.php new file mode 100644 index 0000000..bc409fa --- /dev/null +++ b/tests/PE/Tests/Nodes/Children/NodeChildGetterTest.php @@ -0,0 +1,37 @@ +_peApp = new NodeChildGetter('method'); + } + + /** + * @return NodeChildGetter + */ + protected function nodeChildSetter() + { + return $this->_peApp; + } + + public function testConstructor() + { + $setter = new NodeChildGetter('test'); + $this->assertNotNull($setter); + $this->assertTrue($setter instanceof NodeChildGetter); + } + + public function testGetMethod() { + $childSetter = $this->nodeChildSetter(); + $this->assertEquals('method', $childSetter->getMethod()); + } +} +?> \ No newline at end of file diff --git a/tests/PE/Tests/Nodes/Children/NodeChildSetterTest.php b/tests/PE/Tests/Nodes/Children/NodeChildSetterTest.php new file mode 100644 index 0000000..639e8f3 --- /dev/null +++ b/tests/PE/Tests/Nodes/Children/NodeChildSetterTest.php @@ -0,0 +1,52 @@ +_peApp = new NodeChildSetter('method'); + } + + /** + * @return NodeChildSetter + */ + protected function nodeChildSetter() + { + return $this->_peApp; + } + + public function testConstructor() + { + $setter = new NodeChildSetter('test'); + $this->assertNotNull($setter); + $this->assertTrue($setter instanceof NodeChildSetter); + } + + public function testGetMethod() { + $childSetter = $this->nodeChildSetter(); + $this->assertEquals('method', $childSetter->getMethod()); + } + + public function testSetAfterChildren() { + $nodeChildSetter = $this->nodeChildSetter(); + + $this->assertTrue($nodeChildSetter->setAfterChildren()); + $this->assertFalse($nodeChildSetter->setAfterChildren(false)); + $this->assertTrue($nodeChildSetter->setAfterChildren(true)); + } + public function testSetAfterAttributes() { + $nodeChildSetter = $this->nodeChildSetter(); + + $this->assertTrue($nodeChildSetter->setAfterAttributes()); + $this->assertFalse($nodeChildSetter->setAfterAttributes(false)); + $this->assertTrue($nodeChildSetter->setAfterAttributes(true)); + } +} +?> \ No newline at end of file diff --git a/tests/PE/Tests/Nodes/EncoderNodeChildTest.php b/tests/PE/Tests/Nodes/EncoderNodeChildTest.php index 1c788d7..b68f217 100644 --- a/tests/PE/Tests/Nodes/EncoderNodeChildTest.php +++ b/tests/PE/Tests/Nodes/EncoderNodeChildTest.php @@ -1,6 +1,9 @@ assertNotNull($nodeChild); $this->assertTrue($nodeChild instanceof EncoderNodeChild); $this->assertEquals(self::DEFAULT_NODE_NAME, $nodeChild->getChildNodeName()); + $this->assertNull($nodeChild->getSetter()); + $this->assertNull($nodeChild->getGetter()); + + // with setter and getter + $setter = new NodeChildSetter('setterMethod'); + $getter = new NodeChildGetter('getterMethod'); + $nodeChild = $this->nodeChild('name', $setter, $getter); + $this->assertEquals($setter, $nodeChild->getSetter()); + $this->assertEquals($getter, $nodeChild->getGetter()); } public function testSetChildNodeName() { @@ -47,17 +60,12 @@ public function testSetChildNodeNameWithNull() { $nodeChild->setChildNodeName(null); } - public function testSetAfterChildren() { - $nodeChild = $this->nodeChild(); - $this->assertTrue($nodeChild->setAfterChildren()); - $this->assertFalse($nodeChild->setAfterChildren(false)); - $this->assertTrue($nodeChild->setAfterChildren(true)); - } - public function testSetAfterAttributes() { + public function testIsArray() { $nodeChild = $this->nodeChild(); - $this->assertTrue($nodeChild->setAfterAttributes()); - $this->assertFalse($nodeChild->setAfterAttributes(false)); - $this->assertTrue($nodeChild->setAfterAttributes(true)); + $this->assertTrue($nodeChild->isArray()); + $this->assertTrue($nodeChild->isArray('true')); + $this->assertFalse($nodeChild->isArray(false)); + $this->assertFalse($nodeChild->isArray()); } public function testAddChildrenToObject() { @@ -69,15 +77,14 @@ public function testAddChildrenToObject() { )); $this->assertEquals(array($house), $farm->getBuildings()); } - public function testAddChildrenToObjectWithoutMethod() { - $this->setExpectedException('\\PE\\Exceptions\\EncoderNodeChildException', 'Setter method (' . self::DEFAULT_NODE_NAME . ') for class "PE\Samples\General\Thing" does not exist'); - $nodeChild = $this->nodeChild(); + public function testAddChildrenToObjectWithNonExistentMethod() { + $this->setExpectedException('\\PE\\Exceptions\\EncoderNodeChildException', 'Setter method (children) for class "PE\Samples\General\Thing" does not exist'); + $nodeChild = $this->nodeChild(self::DEFAULT_NODE_NAME, new NodeChildSetter(null)); $nodeChild->addChildrenToObject($this->getThing(), array()); } public function testAddChildrenToObjectWhenMethodDoesNotExist() { - $this->setExpectedException('\\PE\\Exceptions\\EncoderNodeChildException', 'Trying to add children to "PE\Samples\General\Thing" with method "methodName", but this method does not exist'); - $nodeChild = $this->nodeChild(); - $nodeChild->setSetterMethod('methodName'); + $this->setExpectedException('\\PE\\Exceptions\\EncoderNodeChildException', 'Trying to add children to "PE\Samples\General\Thing" with method "unknown", but this method does not exist'); + $nodeChild = $this->nodeChild(self::DEFAULT_NODE_NAME, new NodeChildSetter('unknown')); $nodeChild->addChildrenToObject($this->getThing(), array()); } } \ No newline at end of file diff --git a/tests/PE/Tests/Nodes/EncoderNodeTest.php b/tests/PE/Tests/Nodes/EncoderNodeTest.php index dcf045a..61d0ab3 100644 --- a/tests/PE/Tests/Nodes/EncoderNodeTest.php +++ b/tests/PE/Tests/Nodes/EncoderNodeTest.php @@ -3,6 +3,8 @@ namespace PE\Tests\Nodes; use PE\Enums\ActionVariable; +use PE\Nodes\Children\NodeChildGetter; +use PE\Nodes\Children\NodeChildSetter; use PE\Nodes\EncoderNode; use PE\Nodes\EncoderNodeChild; use PE\Nodes\EncoderNodeVariable; @@ -151,6 +153,11 @@ public function testStaticAddNodeTypeWithoutNodeType() { EncoderNode::addNodeType($this->nodeType()); } + public function testGetDefaultType() { + $node = $this->node(); + $this->assertEquals('default', $node->getDefaultType()); + } + public function testOverwrittenDefaultType() { $hasDefaultTypeNode = $this->addHasDefaultTypeNode(); $this->addHasDefaultTypeTypeNode(); @@ -278,7 +285,7 @@ public function testGetNodeTypeName() { public function testChildNodeMethods() { $node = EncoderNode::addNode($this->node()); - $nodeChild = new EncoderNodeChild('node-child'); + $nodeChild = new EncoderNodeChild('node-child', new NodeChildSetter('setterMethod'), new NodeChildGetter('getterMethod')); $node->addChildNode($nodeChild); $this->assertTrue($node->childNodeExists('node-child')); @@ -303,61 +310,62 @@ public function testAddChildrenToObject() { - - - public function testLoadObjectWhenObjectFileNameReturnsNullToo() { - $this->setExpectedException('\\PE\\Exceptions\\EncoderNodeException', 'Object for loading cannot be null'); - $loaderNode = $this->addEncoderNodeLoaderNode(); + public function testLoadObject() { + $loaderNode = $this->addClassLoaderNode(true); $loaderNode->loadObject(); + $this->assertTrue(class_exists('\\PE\\Samples\\Loader\\ClassLoader')); } - public function testLoadObject() { + public function testLoadObjectWhenNodeDoesNotOverrideSubclass() { $this->setExpectedException('\\PE\\Exceptions\\EncoderNodeException', 'Must be overwritten by subclasses'); $loaderNode = $this->addEncoderNodeLoaderNode(false); $loaderNode->loadObject(); } + public function testLoadObjectWhenObjectFileNameReturnsNullToo() { + $this->setExpectedException('\\PE\\Exceptions\\EncoderNodeException', 'Object for loading cannot be null'); + $loaderNode = $this->addEncoderNodeLoaderNode(); + $loaderNode->loadObject(); + } + public function testVariableMethods() { - $node = EncoderNode::addNode($this->node());; + $node = EncoderNode::addNode($this->node()); $nodeVariable = new EncoderNodeVariable('node-variable'); $node->addVariable($nodeVariable); - $this->assertTrue($node->variableExists('node-variable')); - $this->assertFalse($node->variableExists('unknown')); + $collection = $node->getVariableCollection(); + + $this->assertTrue($collection->variableExists('node-variable')); + $this->assertFalse($collection->variableExists('unknown')); $this->assertEquals($nodeVariable, $node->getVariable('node-variable')); $this->assertNull($node->getVariable('unknown')); - $this->assertEquals($nodeVariable, $node->getVariableById('node-variable')); - $this->assertNull($node->getVariableById('unknown')); - - $this->assertEquals(array(), $node->getVariablesSetterActionByType('type')); - $this->assertEquals(array(), $node->getVariablesGetterActionByType('type')); - $this->assertEquals(array(), $node->getAlwaysExecutedVariables()); - - $this->assertEquals(array( - $nodeVariable - ), $node->getVariables()); + $this->assertEquals($nodeVariable, $collection->getVariableById('node-variable')); + $this->assertNull($collection->getVariableById('unknown')); } public function testApplyToVariable() { $node = $this->addThingNode(); $object = $this->getThing(); - $this->assertFalse($node->applyToVariable('unknown', array())); + $collection = $node->getVariableCollection(); + $objectSetter = $collection->getVariableById('thingVar')->getObjectSetter(); - $node->applyToVariable('thingVar', array( - ActionVariable::SETTER_OBJECT => $object, - ActionVariable::SETTER_VALUE => 'test' - )); + $objectSetter->apply($object, 'test'); $this->assertEquals('test', $object->getThingVar()); } + public function testGetObjectClassName() { + $node = $this->addThingNode(); + $this->assertEquals('\\PE\\Samples\\General\\Thing', $node->getObjectClassName()); + } + public function testGetObjectType() { $node = $this->addThingNode(); $this->assertEquals('test', $node->getObjectType(null, array( diff --git a/tests/PE/Tests/Nodes/EncoderNodeVariableCollectionTest.php b/tests/PE/Tests/Nodes/EncoderNodeVariableCollectionTest.php index b96c470..ca1ceda 100644 --- a/tests/PE/Tests/Nodes/EncoderNodeVariableCollectionTest.php +++ b/tests/PE/Tests/Nodes/EncoderNodeVariableCollectionTest.php @@ -5,6 +5,12 @@ use PE\Nodes\EncoderNodeVariable; use PE\Nodes\EncoderNodeVariableCollection; use PE\Tests\AbstractPETest; +use PE\Variables\Types\ObjectGetter; +use PE\Variables\Types\ObjectSetter; +use PE\Variables\Types\PostNodeGetter; +use PE\Variables\Types\PostNodeSetter; +use PE\Variables\Types\PreNodeGetter; +use PE\Variables\Types\PreNodeSetter; class EncoderNodeVariableCollectionTest extends AbstractPETest { @@ -28,82 +34,185 @@ public function testConstructor() $this->assertTrue($collection instanceof EncoderNodeVariableCollection); } - public function testGetVariablesSetterAndGetterActionByType() { + public function testProcessValue() { $collection = $this->variableCollection(); - $actionObject = array( - 'type' => EncoderNodeVariable::ACTION_TYPE_OBJECT, - 'method' => 'methodName', - ); - $actionNode = array( - 'type' => EncoderNodeVariable::ACTION_TYPE_NODE, - 'method' => 'methodName', - ); - $variable = $this->collectionAddVariable(new EncoderNodeVariable('var')); - $variable->setSetterAction($actionObject); - $variable->setGetterAction($actionObject); + $variable->setType(EncoderNodeVariable::TYPE_BOOL); + $variable2 = $this->collectionAddVariable(new EncoderNodeVariable('var2')); - $variable2->setSetterAction($actionNode); - $variable2->setGetterAction($actionNode); - $variable3 = $this->collectionAddVariable(new EncoderNodeVariable('var3')); - $variable3->setSetterAction($actionNode); - $variable3->setGetterAction($actionNode); + $variable2->setType(EncoderNodeVariable::TYPE_ARRAY); - // setter - $this->assertEquals(array('var' => $variable), $collection->getVariablesSetterActionByType(EncoderNodeVariable::ACTION_TYPE_OBJECT)); - $this->assertEquals(array('var2' => $variable2, 'var3' => $variable3), $collection->getVariablesSetterActionByType(EncoderNodeVariable::ACTION_TYPE_NODE)); + $varObjectSetter = $collection->getVariableById('var')->getObjectSetter(); + $this->assertEquals(true, $varObjectSetter->processValue('true')); - // getter - $this->assertEquals(array('var' => $variable), $collection->getVariablesGetterActionByType(EncoderNodeVariable::ACTION_TYPE_OBJECT)); - $this->assertEquals(array('var2' => $variable2, 'var3' => $variable3), $collection->getVariablesGetterActionByType(EncoderNodeVariable::ACTION_TYPE_NODE)); + $var2ObjectSetter = $collection->getVariableById('var2')->getObjectSetter(); + $this->assertEquals(array('key' => 'value'), $var2ObjectSetter->processValue('{"key":"value"}')); } - public function testAddVariableOldWay() { - $this->setExpectedException('PE\\Exceptions\\EncoderNodeVariableException', 'Use "addNodeVariable" to add variables'); - $this->variableCollection()->addVariable(new EncoderNodeVariable('var')); + public function testAddVariablesWithSameId() { + $this->setExpectedException('\\PE\\Exceptions\\EncoderNodeVariableCollectionException', 'Trying to add a EncoderNodeVariable but a variable with id "var" already exists'); + $this->collectionAddVariable(new EncoderNodeVariable('var')); + $this->collectionAddVariable(new EncoderNodeVariable('var')); } - public function testVariablesAreValidWithData() { + public function testGetVariable() { + $variable = $this->collectionAddVariableDefault(); + $collection = $this->variableCollection(); + + $this->assertEquals($variable, $collection->getVariable('var')); + $this->assertEquals($variable, $collection->getVariable($variable)); + $this->assertNull($collection->getVariable('doesNotExist')); + } + + public function testGetVariableById() { + $variable = $this->collectionAddVariableDefault(); + $collection = $this->variableCollection(); + + $this->assertEquals($variable, $collection->getVariableById('var')); + $this->assertNull($collection->getVariableById('doesNotExist')); + } + + public function testGetVariables() { + $variable = $this->collectionAddVariableDefault(); + + $variable2 = $this->collectionAddVariable(new EncoderNodeVariable('var2')); + $variable2->setType(EncoderNodeVariable::TYPE_ARRAY); + + $collection = $this->variableCollection(); + + $this->assertEquals(array('var' => $variable, 'var2' => $variable2), $collection->getVariables()); + } + + public function testGetVariablesSameIndex() { + $this->setExpectedException('PE\\Exceptions\\EncoderNodeVariableCollectionException', 'Cannot order variables because position "10" is being used more than once'); + + $variable = $this->collectionAddVariableDefault(); + $variable->setOrder(10); + + $variable2 = $this->collectionAddVariable(new EncoderNodeVariable('var2')); + $variable2->setOrder(10); + + $this->variableCollection()->getObjectSetterVariables(); + } + + public function testVariableExists() { + $this->collectionAddVariableDefault(); + $collection = $this->variableCollection(); + + $this->assertTrue($collection->variableExists('var')); + $this->assertFalse($collection->variableExists('doesNotExist')); + } + + + + public function testGetVariablesNodeSetterAndGetter() { $collection = $this->variableCollection(); $variable = $this->collectionAddVariable(new EncoderNodeVariable('var')); - $variable->mustBeUnique(true); + $variable->preNodeSetter(new PreNodeSetter('preNodeSetter')); + $variable->preNodeGetter(new PreNodeGetter('preNodeGetter')); + $variable->setOrder(3); + $variable2 = $this->collectionAddVariable(new EncoderNodeVariable('var2')); + $variable2->preNodeSetter(new PreNodeSetter('preNodeSetter2')); + $variable2->preNodeGetter(new PreNodeGetter('preNodeGetter2')); + $variable2->postNodeSetter(new PostNodeSetter('postNodeSetter2')); + $variable2->postNodeGetter(new PostNodeGetter('postNodeGetter2')); + $variable2->setOrder(2); + $variable3 = $this->collectionAddVariable(new EncoderNodeVariable('var3')); + $variable3->postNodeSetter(new PostNodeSetter('postNodeSetter3')); + $variable3->postNodeGetter(new PostNodeGetter('postNodeGetter3')); + $variable3->setOrder(1); + + // pre setter + $preSetters = $collection->getPreNodeSetterVariables(false); + $this->assertEquals(array($variable, $variable2), $preSetters); + + $preSettersSorted = $collection->getPreNodeSetterVariables(); + $this->assertEquals(array($variable2, $variable), $preSettersSorted); + + // pre getter + $preGetters = $collection->getPreNodeGetterVariables(false); + $this->assertEquals(array($variable, $variable2), $preGetters); + + $preGettersSorted = $collection->getPreNodeGetterVariables(); + $this->assertEquals(array($variable2, $variable), $preGettersSorted); - $this->assertTrue($collection->variablesAreValidWithData(array(array('var' => 'Test')))); - $this->assertFalse($collection->variablesAreValidWithData(array(array('var' => 'Test'), array('var' => 'Test')))); + + // post setter + $preSetters = $collection->getPostNodeSetterVariables(false); + $this->assertEquals(array($variable2, $variable3), $preSetters); + + $preSettersSorted = $collection->getPostNodeSetterVariables(); + $this->assertEquals(array($variable3, $variable2), $preSettersSorted); + + // post getter + $preGetters = $collection->getPostNodeGetterVariables(false); + $this->assertEquals(array($variable2, $variable3), $preGetters); + + $preGettersSorted = $collection->getPostNodeGetterVariables(); + $this->assertEquals(array($variable3, $variable2), $preGettersSorted); } - public function testVariablesAreNotValidWithData() { - $this->setExpectedException('PE\\Exceptions\\EncoderNodeVariableException', 'Variable "var" must be unique but value "Test" is given at least twice'); + public function testGetVariablesObjectSetterAndGetter() { $collection = $this->variableCollection(); $variable = $this->collectionAddVariable(new EncoderNodeVariable('var')); - $variable->mustBeUnique(true); + $variable->objectSetter(new ObjectSetter('objectSetter')); + $variable->objectGetter(new ObjectGetter('objectGetter')); + $variable->setOrder(2); + $variable2 = $this->collectionAddVariable(new EncoderNodeVariable('var2')); + $variable2->objectSetter(new ObjectSetter('objectSetter2')); + $variable2->objectGetter(new ObjectGetter('objectGetter2')); + $variable2->setOrder(1); + + // pre setter + $setters = $collection->getObjectSetterVariables(false); + $this->assertEquals(array($variable, $variable2), $setters); - $collection->variablesAreValidWithData(array(array('var' => 'Test'), array('var' => 'Test')), true); + $settersSorted = $collection->getObjectSetterVariables(); + $this->assertEquals(array($variable2, $variable), $settersSorted); + + // pre getter + $getters = $collection->getObjectGetterVariables(false); + $this->assertEquals(array($variable, $variable2), $getters); + + $gettersSorted = $collection->getObjectGetterVariables(); + $this->assertEquals(array($variable2, $variable), $gettersSorted); } - public function testGetAlwaysExecutedVariables() { + public function testVariablesAreValidWithData() { $collection = $this->variableCollection(); $variable = $this->collectionAddVariable(new EncoderNodeVariable('var')); - $variable->alwaysExecute(true); + $variable->getObjectSetter()->mustBeUnique(true); - $this->assertEquals(array('var' => $variable), $collection->getAlwaysExecutedVariables()); - // get from cache - $this->assertEquals(array('var' => $variable), $collection->getAlwaysExecutedVariables()); + $this->assertTrue($collection->objectVariablesAreValidWithData(array(array('var' => 'Test')))); + $this->assertFalse($collection->objectVariablesAreValidWithData(array(array('var' => 'Test'), array('var' => 'Test')))); + } - $this->collectionAddVariable(new EncoderNodeVariable('var2')); - $variable3 = $this->collectionAddVariable(new EncoderNodeVariable('var3')); - $variable3->alwaysExecute(true); + public function testVariablesAreNotValidWithData() { + $this->setExpectedException('PE\\Exceptions\\EncoderNodeVariableCollectionException', 'Variable "var" must be unique but value "Test" is given at least twice'); + $collection = $this->variableCollection(); - // cache has been reset because new variables have been added - $this->assertEquals(array('var' => $variable, 'var3' => $variable3), $collection->getAlwaysExecutedVariables()); + $variable = $this->collectionAddVariable(new EncoderNodeVariable('var')); + $variable->getObjectSetter()->mustBeUnique(true); + + $collection->objectVariablesAreValidWithData(array(array('var' => 'Test'), array('var' => 'Test')), true); } + /** + * @param null $variable + * @return EncoderNodeVariable + */ protected function collectionAddVariable($variable = null) { $collection = $this->variableCollection(); - return $collection->addNodeVariable($variable ? $variable : new EncoderNodeVariable('var')); + return $collection->addVariable($variable ? $variable : new EncoderNodeVariable('var')); + } + + protected function collectionAddVariableDefault() { + $variable = $this->collectionAddVariable(new EncoderNodeVariable('var')); + $variable->setType(EncoderNodeVariable::TYPE_BOOL); + return $variable; } } \ No newline at end of file diff --git a/tests/PE/Tests/Nodes/EncoderNodeVariableTest.php b/tests/PE/Tests/Nodes/EncoderNodeVariableTest.php index 08a3729..6b0472b 100644 --- a/tests/PE/Tests/Nodes/EncoderNodeVariableTest.php +++ b/tests/PE/Tests/Nodes/EncoderNodeVariableTest.php @@ -5,6 +5,13 @@ use PE\Enums\ActionVariable; use PE\Nodes\EncoderNodeVariable; use PE\Tests\Samples; +use PE\Variables\Types\NodeAccessor; +use PE\Variables\Types\ObjectGetter; +use PE\Variables\Types\ObjectSetter; +use PE\Variables\Types\PostNodeGetter; +use PE\Variables\Types\PostNodeSetter; +use PE\Variables\Types\PreNodeGetter; +use PE\Variables\Types\PreNodeSetter; class EncoderNodeVariableTest extends Samples { @@ -20,332 +27,119 @@ protected function setUp() protected function variable() { return $this->_peApp; } + /** + * @param $id + * @param bool $enableObjectAccessors + * @return EncoderNodeVariable + */ + protected function newVariable($id, $enableObjectAccessors = true) { + return new EncoderNodeVariable($id, $enableObjectAccessors); + } public function testConstructor() { $variable = new EncoderNodeVariable('var'); $this->assertNotNull($variable); $this->assertTrue($variable instanceof EncoderNodeVariable); - } - - public function testParseOptions() { - $variable = $this->variable(); - $variable->parseOptions(array( - 'setterAction' => 'setterMethodName', - 'getterAction' => 'getterMethodName', - 'unique' => true, - 'alwaysExecute' => true - )); - - // setter - $this->assertEquals('setVar', $variable->getSetterMethod()); - $this->assertEquals('setterMethodName', $variable->getSetterAction()); - $this->assertEquals(EncoderNodeVariable::ACTION_TYPE_OBJECT, $variable->getSetterActionType()); - $this->assertEquals('setterMethodName', $variable->getSetterActionMethod()); - - // getter - $this->assertEquals('getVar', $variable->getGetterMethod()); - $this->assertEquals('getterMethodName', $variable->getGetterAction()); - $this->assertEquals(EncoderNodeVariable::ACTION_TYPE_OBJECT, $variable->getGetterActionType()); - $this->assertEquals('getterMethodName', $variable->getGetterActionMethod()); - - // unique - $this->assertTrue($variable->mustBeUnique()); + $this->assertEquals('PE\\Variables\\Types\\ObjectSetter', get_class($variable->getObjectSetter())); + $this->assertEquals('PE\\Variables\\Types\\ObjectGetter', get_class($variable->getObjectGetter())); - // always execute - $this->assertTrue($variable->alwaysExecute()); + $variable = new EncoderNodeVariable('var', false); + $this->assertNull($variable->getObjectSetter()); + $this->assertNull($variable->getObjectGetter()); } - public function testMustBeUnique() { + public function testGetId() { $variable = $this->variable(); - - $this->assertFalse($variable->mustBeUnique()); - - $this->assertFalse($variable->mustBeUnique(false)); - $this->assertFalse($variable->mustBeUnique()); - $this->assertTrue($variable->mustBeUnique(true)); - $this->assertTrue($variable->mustBeUnique()); + $this->assertEquals('var', $variable->getId()); } - public function testAlwaysExecute() { + public function testSetType() { $variable = $this->variable(); - - $this->assertFalse($variable->alwaysExecute()); - - $this->assertFalse($variable->alwaysExecute(false)); - $this->assertFalse($variable->alwaysExecute()); - $this->assertTrue($variable->alwaysExecute(true)); - $this->assertTrue($variable->alwaysExecute()); + $variable->setType(EncoderNodeVariable::TYPE_ARRAY); + $this->assertEquals(EncoderNodeVariable::TYPE_ARRAY, $variable->getType()); + $variable->setType(EncoderNodeVariable::TYPE_STRING); + $this->assertEquals(EncoderNodeVariable::TYPE_STRING, $variable->getType()); + $variable->setType(EncoderNodeVariable::TYPE_BOOL); + $this->assertEquals(EncoderNodeVariable::TYPE_BOOL, $variable->getType()); + $variable->setType(null); + $this->assertNull($variable->getType()); } - public function testSetterAction() { - $variable = $this->variable(); - - $this->assertFalse($variable->hasSetterAction()); - - $variable->setSetterAction('methodName'); - $this->assertEquals('methodName', $variable->getSetterAction()); - - $this->assertTrue($variable->hasSetterAction()); - } - public function testSetterActionMethod() { + public function testGetType() { $variable = $this->variable(); - - $this->assertNull($variable->getSetterActionMethod()); - - $variable->setSetterAction('methodName'); - $this->assertEquals('methodName', $variable->getSetterActionMethod()); - - $variable->setSetterAction(array( - 'method' => 'methodNameArray' - )); - $this->assertEquals('methodNameArray', $variable->getSetterActionMethod()); - $this->assertEquals(EncoderNodeVariable::ACTION_TYPE_OBJECT, $variable->getSetterActionType()); - - $variable->setSetterAction(array( - 'method' => 'methodNameArray', - 'type' => EncoderNodeVariable::ACTION_TYPE_NODE - )); - $this->assertEquals('methodNameArray', $variable->getSetterActionMethod()); - $this->assertEquals(EncoderNodeVariable::ACTION_TYPE_NODE, $variable->getSetterActionType()); + $this->assertNull($variable->getType()); } - public function testGetterAction() { - $variable = $this->variable(); - - $this->assertFalse($variable->hasGetterAction()); - - $variable->setGetterAction('methodName'); - $this->assertEquals('methodName', $variable->getGetterAction()); - - $this->assertTrue($variable->hasGetterAction()); - } - public function testGetterActionWhenWrongDataType() { - $this->setExpectedException('\\PE\\Exceptions\\EncoderNodeVariableException', 'Either method must be a string or an array with a "method" key being a string'); - $this->variable()->setGetterAction(1); - } - public function testGetterActionWhenEmptyArray() { - $this->setExpectedException('\\PE\\Exceptions\\EncoderNodeVariableException', 'Either method must be a string or an array with a "method" key being a string'); - $this->variable()->setGetterAction(array()); - } - public function testGetterActionMethod() { + public function testOrder() { $variable = $this->variable(); - - $this->assertNull($variable->getGetterActionMethod()); - - $variable->setGetterAction('methodName'); - $this->assertEquals('methodName', $variable->getGetterActionMethod()); - - $variable->setGetterAction(array( - 'method' => 'methodNameArray' - )); - $this->assertEquals('methodNameArray', $variable->getGetterActionMethod()); - $this->assertEquals(EncoderNodeVariable::ACTION_TYPE_OBJECT, $variable->getGetterActionType()); - - $variable->setGetterAction(array( - 'method' => 'methodNameArray', - 'type' => EncoderNodeVariable::ACTION_TYPE_NODE - )); - $this->assertEquals('methodNameArray', $variable->getGetterActionMethod()); - $this->assertEquals(EncoderNodeVariable::ACTION_TYPE_NODE, $variable->getGetterActionType()); - } - - public function testCallNodeSetterAction() { - $node = $this->getAccessorMethodActionTypeNodeNode(); - $variable = $node->getVariable('node'); - - $this->assertEquals(array( - 'node' => 'hello world', - 'special' => 'hello world', - ), $variable->callNodeSetterAction($node, array( - ActionVariable::GETTER_NODE_DATA => array( - 'node' => 'hello world', - ), - ActionVariable::GETTER_NAME => 'node' - ))); - } - - public function testCallNodeSetterActionWithActionTypeNotNode() { - $node = $this->getAccessorMethodActionTypeNodeNode(); - $variable = $node->getVariable('node'); - $setterAction = $variable->getSetterAction(); - $setterAction['type'] = 'not-node'; - $variable->setSetterAction($setterAction); - - $this->assertNull($variable->callNodeSetterAction($node, array( - ActionVariable::GETTER_NODE_DATA => array( - 'node' => 'hello world', - ), - ActionVariable::GETTER_NAME => 'node' - ))); - } - - public function testCallNodeSetterActionWithMissingVariable() { - $this->setExpectedException('\\PE\\Exceptions\\EncoderNodeVariableException', 'Action variable "node_data" is not known'); - $node = $this->getAccessorMethodActionTypeNodeNode(); - $this->getAccessorMethodActionTypeNodeNode()->getVariable('node')->callNodeSetterAction($node, array()); - } - - public function testCallNodeSetterActionWithoutMethod() { - $this->setExpectedException('\\PE\\Exceptions\\EncoderNodeVariableException', 'Either method must be a string or an array with a "method" key being a string'); - $node = $this->getAccessorMethodActionTypeNodeNode(); - $variable = $node->getVariable('node'); - $setterAction = $variable->getSetterAction(); - unset($setterAction['method']); - $variable->setSetterAction($setterAction); - - $variable->callNodeSetterAction($node, array( - ActionVariable::GETTER_NODE_DATA => array( - 'node' => 'hello world', - ), - ActionVariable::GETTER_NAME => 'node' - )); - } - - public function testCallNodeGetterAction() { - $node = $this->getAccessorMethodActionTypeNodeNode(); - $variable = $node->getVariable('node'); - - $this->assertEquals(array( - 'node' => 'hello world', - 'special' => 'hello world getter', - ), $variable->callNodeGetterAction($node, array( - ActionVariable::GETTER_NODE_DATA => array( - 'node' => 'hello world', - ), - ActionVariable::GETTER_NAME => 'node' - ))); - } - - public function testCallNodeGetterActionWithActionTypeNotNode() { - $node = $this->getAccessorMethodActionTypeNodeNode(); - $variable = $node->getVariable('node'); - $setterAction = $variable->getGetterAction(); - $setterAction['type'] = 'not-node'; - $variable->setGetterAction($setterAction); - - $this->assertNull($variable->callNodeGetterAction($node, array( - ActionVariable::GETTER_NODE_DATA => array( - 'node' => 'hello world', - ), - ActionVariable::GETTER_NAME => 'node' - ))); - } - - - public function testApplyToSetterNodeSimple() { - $node = $this->getEncoderNodeVariableApplyToSetterNode(); - - $object = $this->getEncoderNodeVariableApplyToSetter(); - $var = $node->getVariableById('node-simple'); - - $this->assertEquals(array( - 'node' => 'test', - 'copied' => 'test', - ), $var->applyToSetter(array( - ActionVariable::SETTER_OBJECT => $object, - ActionVariable::SETTER_NODE_DATA => array( - 'node' => 'test' - ), - ActionVariable::SETTER_NODE => $node, - ActionVariable::SETTER_NAME => 'node', - ActionVariable::SETTER_VALUE => 'test' - ))); - - $this->assertNull($object->getVar()); - } - - public function testApplyToSetterNodeFull() { - $node = $this->getEncoderNodeVariableApplyToSetterNode(); - - $object = $this->getEncoderNodeVariableApplyToSetter(); - $parent = $this->getThing(); - $var = $node->getVariableById('node-full'); - - $this->assertEquals(array( - 'node' => 'test', - 'name' => 'node', - 'value' => 'test', - 'object' => $object, - 'parent' => $parent, - ), $var->applyToSetter(array( - ActionVariable::SETTER_OBJECT => $object, - ActionVariable::SETTER_PARENT => $parent, - ActionVariable::SETTER_NODE_DATA => array( - 'node' => 'test' - ), - ActionVariable::SETTER_NODE => $node, - ActionVariable::SETTER_NAME => 'node', - ActionVariable::SETTER_VALUE => 'test' - ))); - } - - public function testApplyToSetterNodeWithoutVariables() { - $this->_applyToSetterNodeWithoutVariables('node-without-variables'); - $this->_applyToSetterNodeWithoutVariables('node-without-variables-empty'); - $this->_applyToSetterNodeWithoutVariables('node-without-variables-null'); - } - protected function _applyToSetterNodeWithoutVariables($variable) - { - $node = $this->getEncoderNodeVariableApplyToSetterNode(); - - $object = $this->getEncoderNodeVariableApplyToSetter(); - $var = $node->getVariableById($variable); - - $this->assertEquals(array( - 'test' => 'altered', - ), $var->applyToSetter(array( - ActionVariable::SETTER_OBJECT => $object, - ActionVariable::SETTER_NODE_DATA => array( - 'test' => 'test' - ), - ActionVariable::SETTER_NODE => $node, - ActionVariable::SETTER_NAME => 'node', - ActionVariable::SETTER_VALUE => 'test' - ))); - - $this->assertNull($object->getVar()); - } - - public function testApplyToSetterNodeUnknownVariable() { - $this->setExpectedException('\\PE\\Exceptions\\EncoderNodeVariableException', 'Action variable id "unknown_variable" is not known'); - $node = $this->getEncoderNodeVariableApplyToSetterNode(); - - $object = $this->getEncoderNodeVariableApplyToSetter(); - $var = $node->getVariableById('node-unknown-variable'); - - $var->applyToSetter(array( - ActionVariable::SETTER_OBJECT => $object, - ActionVariable::SETTER_NODE_DATA => array( - 'node' => 'test' - ), - ActionVariable::SETTER_NODE => $node, - ActionVariable::SETTER_NAME => 'node', - ActionVariable::SETTER_VALUE => 'test' - )); - } - - public function testApplyToSetterObjectWithSetterMethod() { - $this->_applyToSetterObject('var'); - $this->_applyToSetterObject('object-using-setter-action'); - $this->_applyToSetterObject('object-using-setter-method'); - } - - public function testApplyToSetterObjectWithUnknownSetterMethod() { - $this->setExpectedException('\\PE\\Exceptions\\EncoderNodeVariableException', 'Method "unknownMethod" does not exist for class PE\Samples\Specials\EncoderNodeVariableApplyToSetter does not exist'); - $this->_applyToSetterObject('object-using-unknown-setter-method'); - } - - protected function _applyToSetterObject($variable) { - $node = $this->getEncoderNodeVariableApplyToSetterNode(); - - $object = $this->getEncoderNodeVariableApplyToSetter(); - $var = $node->getVariableById($variable); - - $this->assertTrue($var->applyToSetter(array( - ActionVariable::SETTER_OBJECT => $object, - ActionVariable::SETTER_VALUE => 'test' - ))); - $this->assertEquals('test', $object->getVar()); + $this->assertNull($variable->getOrder()); + $variable->setOrder(10); + $this->assertEquals(10, $variable->getOrder()); + } + + + public function testPreNodeSetter() { + $variable = $this->newVariable('var', false); + $this->assertNull($variable->getPreNodeSetter()); + $this->assertFalse($variable->hasPreNodeSetter()); + $nodeSetter = new PreNodeSetter('setterMethod'); + $variable->preNodeSetter($nodeSetter); + $this->assertEquals($nodeSetter, $variable->getPreNodeSetter()); + $this->assertTrue($variable->hasPreNodeSetter()); + $this->assertEquals($variable, $nodeSetter->getVariable()); + } + public function testPreNodeGetter() { + $variable = $this->newVariable('var', false); + $this->assertNull($variable->getPreNodeGetter()); + $this->assertFalse($variable->hasPreNodeGetter()); + $nodeGetter = new PreNodeGetter('getterMethod'); + $variable->preNodeGetter($nodeGetter); + $this->assertEquals($nodeGetter, $variable->getPreNodeGetter()); + $this->assertTrue($variable->hasPreNodeGetter()); + $this->assertEquals($variable, $nodeGetter->getVariable()); + } + + public function testPostNodeSetter() { + $variable = $this->newVariable('var', false); + $this->assertNull($variable->getPostNodeSetter()); + $this->assertFalse($variable->hasPostNodeSetter()); + $nodeSetter = new PostNodeSetter('setterMethod'); + $variable->postNodeSetter($nodeSetter); + $this->assertEquals($nodeSetter, $variable->getPostNodeSetter()); + $this->assertTrue($variable->hasPostNodeSetter()); + $this->assertEquals($variable, $nodeSetter->getVariable()); + } + public function testPostNodeGetter() { + $variable = $this->newVariable('var', false); + $this->assertNull($variable->getPostNodeGetter()); + $this->assertFalse($variable->hasPostNodeGetter()); + $nodeGetter = new PostNodeGetter('getterMethod'); + $variable->postNodeGetter($nodeGetter); + $this->assertEquals($nodeGetter, $variable->getPostNodeGetter()); + $this->assertTrue($variable->hasPostNodeGetter()); + $this->assertEquals($variable, $nodeGetter->getVariable()); + } + + public function testObjectSetter() { + $variable = $this->newVariable('var', false); + $this->assertNull($variable->getObjectSetter()); + $this->assertFalse($variable->hasObjectSetter()); + $objectSetter = new ObjectSetter('setterMethod'); + $variable->objectSetter($objectSetter); + $this->assertEquals($objectSetter, $variable->getObjectSetter()); + $this->assertTrue($variable->hasObjectSetter()); + $this->assertEquals($variable, $objectSetter->getVariable()); + } + + public function testObjectGetter() { + $variable = $this->newVariable('var', false); + $this->assertNull($variable->getObjectGetter()); + $this->assertFalse($variable->hasObjectGetter()); + $objectGetter = new ObjectGetter('setterMethod'); + $variable->objectGetter($objectGetter); + $this->assertEquals($objectGetter, $variable->getObjectGetter()); + $this->assertTrue($variable->hasObjectGetter()); + $this->assertEquals($variable, $objectGetter->getVariable()); } } \ No newline at end of file diff --git a/tests/PE/Tests/Samples.php b/tests/PE/Tests/Samples.php index ac56668..9693723 100644 --- a/tests/PE/Tests/Samples.php +++ b/tests/PE/Tests/Samples.php @@ -31,6 +31,7 @@ use PE\Nodes\Specials\OptionalVariablesNode; use PE\Nodes\Specials\RequiredConstructorVariablesNode; use PE\Nodes\Specials\SingleChildNode; +use PE\Nodes\Specials\VariableTypesNode; use PE\Samples\Erroneous\EncoderNodeLoader; use PE\Samples\Erroneous\NonArrayGetterMethod; use PE\Samples\Erroneous\NoVariableGetterMethod; @@ -52,6 +53,7 @@ use PE\Samples\Specials\AccessorMethodActionTypeNode; use PE\Samples\Specials\OptionalVariables; use PE\Samples\Specials\SingleChild; +use PE\Samples\Specials\VariableTypes; class Samples extends AbstractPETest { @@ -212,6 +214,13 @@ public function addOptionalVariablesNode() { return EncoderNode::addNode(new OptionalVariablesNode()); } + public function getVariableTypes($required) { + return new VariableTypes($required); + } + public function addVariableTypesNode() { + return EncoderNode::addNode(new VariableTypesNode()); + } + public function getHasDefaultType() { return new HasDefaultType(); diff --git a/tests/PE/Tests/Variables/Types/ObjectGetterTest.php b/tests/PE/Tests/Variables/Types/ObjectGetterTest.php new file mode 100644 index 0000000..1fb2877 --- /dev/null +++ b/tests/PE/Tests/Variables/Types/ObjectGetterTest.php @@ -0,0 +1,75 @@ +_peApp = new ObjectGetter(); + } + + /** + * @return ObjectGetter + */ + protected function objectGetter() { + return $this->_peApp; + } + + public function testConstructor() + { + $setter = new ObjectGetter('test'); + $this->assertNotNull($setter); + $this->assertTrue($setter instanceof ObjectGetter); + } + + public function testGetMethod() { + $objectSetter = new ObjectGetter('method'); + $this->assertEquals('method', $objectSetter->getMethod()); + + $objectSetter = new ObjectGetter(); + $objectSetter->setVariable(new EncoderNodeVariable('variableId')); + $this->assertEquals('getVariableId', $objectSetter->getMethod()); + } + + public function testEncodeWithoutVariableGetterMethod() { + $this->setExpectedException('\\PE\\Exceptions\\VariableTypeException', 'Method "getNonExistent" does not exist for class "PE\Tests\Variables\Types\ObjectGetterTestObject" does not exist'); + + $objectGetter = $this->objectGetter(); + $objectGetter->setVariable(new EncoderNodeVariable('non-existent')); + $objectGetter->apply(new ObjectGetterTestObject()); + } + + public function testMustBeUnique() { + $objectGetter = $this->objectGetter(); + + $this->assertFalse($objectGetter->mustBeUnique()); + + $this->assertFalse($objectGetter->mustBeUnique(false)); + $this->assertFalse($objectGetter->mustBeUnique()); + $this->assertTrue($objectGetter->mustBeUnique(true)); + $this->assertTrue($objectGetter->mustBeUnique()); + } + + public function testAlwaysExecute() { + $objectGetter = $this->objectGetter(); + + $this->assertFalse($objectGetter->alwaysExecute()); + + $this->assertFalse($objectGetter->alwaysExecute(false)); + $this->assertFalse($objectGetter->alwaysExecute()); + $this->assertTrue($objectGetter->alwaysExecute(true)); + $this->assertTrue($objectGetter->alwaysExecute()); + } +} + +class ObjectGetterTestObject { + +} +?> \ No newline at end of file diff --git a/tests/PE/Tests/Variables/Types/ObjectSetterTest.php b/tests/PE/Tests/Variables/Types/ObjectSetterTest.php new file mode 100644 index 0000000..c21d17e --- /dev/null +++ b/tests/PE/Tests/Variables/Types/ObjectSetterTest.php @@ -0,0 +1,131 @@ +_peApp = new ObjectSetter(); + } + + /** + * @return ObjectSetter + */ + protected function objectSetter() { + return $this->_peApp; + } + + protected function objectSetterWithVariable() { + $objectSetter = $this->objectSetter(); + $objectSetter->setVariable(new EncoderNodeVariable('var')); + return $objectSetter; + } + + public function testConstructor() + { + $setter = new ObjectSetter('test'); + $this->assertNotNull($setter); + $this->assertTrue($setter instanceof ObjectSetter); + } + + public function testGetMethod() { + $objectSetter = new ObjectSetter('method'); + $this->assertEquals('method', $objectSetter->getMethod()); + + $objectSetter = new ObjectSetter(); + $objectSetter->setVariable(new EncoderNodeVariable('variableId')); + $this->assertEquals('setVariableId', $objectSetter->getMethod()); + } + + public function testEncodeWithoutVariableGetterMethod() { + $this->setExpectedException('\\PE\\Exceptions\\VariableTypeException', 'Method "setNonExistent" does not exist for class "PE\Tests\Variables\Types\ObjectSetterTestObject'); + + $objectSetter = $this->objectSetter(); + $objectSetter->setVariable(new EncoderNodeVariable('non-existent')); + $objectSetter->apply(new ObjectSetterTestObject(), 'value'); + } + + public function testApplyToSetterObjectWithSetterMethod() { + $node = $this->getEncoderNodeVariableApplyToSetterNode(); + + $object = $this->getEncoderNodeVariableApplyToSetter(); + $collection = $node->getVariableCollection(); + $var = $collection->getVariableById('var'); + + $this->assertTrue($var->getObjectSetter()->apply($object, 'test')); + $this->assertEquals('test', $object->getVar()); + } + + public function testProcessValue() { + $objectSetter = $this->objectSetterWithVariable(); + $variable = $objectSetter->getVariable(); + $this->assertEquals('test', $objectSetter->processValue('test')); + + $variable->setType(EncoderNodeVariable::TYPE_BOOL); + $this->assertEquals(true, $objectSetter->processValue(1)); + $this->assertEquals(true, $objectSetter->processValue('1')); + $this->assertEquals(true, $objectSetter->processValue('true')); + $this->assertEquals(false, $objectSetter->processValue(0)); + $this->assertEquals(false, $objectSetter->processValue('0')); + $this->assertEquals(false, $objectSetter->processValue('false')); + $this->assertEquals(false, $objectSetter->processValue('abc')); + + $variable->setType(EncoderNodeVariable::TYPE_STRING); + $this->assertEquals('1', $objectSetter->processValue(1)); + $this->assertEquals('string', $objectSetter->processValue('string')); + + $variable->setType(EncoderNodeVariable::TYPE_ARRAY); + $this->assertEquals(array(), $objectSetter->processValue(json_encode(array()))); + $this->assertEquals(array('hello' => 'world'), $objectSetter->processValue(json_encode(array('hello' => 'world')))); + } + + public function testProcessValueArrayException() { + $this->setExpectedException('PE\\Exceptions\\VariableTypeException', 'The set data type is array but the value cannot be processed'); + $objectSetter = $this->objectSetterWithVariable(); + $variable = $objectSetter->getVariable(); + $variable->setType(EncoderNodeVariable::TYPE_ARRAY); + $objectSetter->processValue(array()); + } + public function testProcessValueUnknownTypeException() { + $this->setExpectedException('PE\\Exceptions\\VariableTypeException', 'Can\'t process value "string" because the data type "unknown" isn\'t recognized.'); + $objectSetter = $this->objectSetterWithVariable(); + $variable = $objectSetter->getVariable(); + $variable->setType('unknown'); + $objectSetter->processValue('string'); + } + + public function testMustBeUnique() { + $objectSetter = $this->objectSetter(); + + $this->assertFalse($objectSetter->mustBeUnique()); + + $this->assertFalse($objectSetter->mustBeUnique(false)); + $this->assertFalse($objectSetter->mustBeUnique()); + $this->assertTrue($objectSetter->mustBeUnique(true)); + $this->assertTrue($objectSetter->mustBeUnique()); + } + + public function testAlwaysExecute() { + $objectSetter = $this->objectSetter(); + + $this->assertFalse($objectSetter->alwaysExecute()); + + $this->assertFalse($objectSetter->alwaysExecute(false)); + $this->assertFalse($objectSetter->alwaysExecute()); + $this->assertTrue($objectSetter->alwaysExecute(true)); + $this->assertTrue($objectSetter->alwaysExecute()); + } +} + +class ObjectSetterTestObject { + +} +?> \ No newline at end of file diff --git a/tests/PE/Tests/Variables/Types/PostNodeGetterTest.php b/tests/PE/Tests/Variables/Types/PostNodeGetterTest.php new file mode 100644 index 0000000..8950482 --- /dev/null +++ b/tests/PE/Tests/Variables/Types/PostNodeGetterTest.php @@ -0,0 +1,48 @@ +_peApp = new PostNodeGetter('method'); + } + + /** + * @return PostNodeGetter + */ + protected function postNodeGetter() + { + return $this->_peApp; + } + + public function testConstructor() + { + $setter = new PostNodeGetter('method'); + $this->assertNotNull($setter); + $this->assertTrue($setter instanceof PostNodeGetter); + } + + public function testCallNodeGetterAction() { + $node = $this->getAccessorMethodActionTypeNodeNode(); + $variable = $node->getVariable('node'); + + $this->assertEquals(array( + 'node' => 'hello world', + 'special' => 'hello world getter', + ), $variable->getPostNodeGetter()->apply(array( + NodeAccessor::VARIABLE_NODE => $node, + NodeAccessor::VARIABLE_NODE_DATA => array( + 'node' => 'hello world', + ), + NodeAccessor::VARIABLE_NAME => 'node' + ))); + } +} \ No newline at end of file diff --git a/tests/PE/Tests/Variables/Types/PostNodeSetterTest.php b/tests/PE/Tests/Variables/Types/PostNodeSetterTest.php new file mode 100644 index 0000000..f99efe2 --- /dev/null +++ b/tests/PE/Tests/Variables/Types/PostNodeSetterTest.php @@ -0,0 +1,150 @@ +_peApp = new PostNodeSetter('method'); + } + + /** + * @return PostNodeSetter + */ + protected function postNodeSetter() + { + return $this->_peApp; + } + + public function testConstructor() + { + $setter = new PostNodeSetter('method'); + $this->assertNotNull($setter); + $this->assertTrue($setter instanceof PostNodeSetter); + } + + public function testCallNodeSetterAction() { + $node = $this->getAccessorMethodActionTypeNodeNode(); + $variable = $node->getVariable('node'); + + $this->assertEquals(array( + 'node' => 'hello world', + 'special' => 'hello world', + ), $variable->getPostNodeSetter()->apply(array( + NodeAccessor::VARIABLE_NODE => $node, + NodeAccessor::VARIABLE_NODE_DATA => array( + 'node' => 'hello world', + ), + NodeAccessor::VARIABLE_NAME => 'node' + ))); + } + + public function testCallNodeSetterActionWithMissingVariable() { + $this->setExpectedException('\\PE\\Exceptions\\VariableTypeException', 'Parameter with id "node_node_data" is not known'); + $node = $this->getAccessorMethodActionTypeNodeNode(); + $this->getAccessorMethodActionTypeNodeNode()->getVariable('node')->getPostNodeSetter()->apply(array(NodeAccessor::VARIABLE_NODE => $node)); + } + + public function testApplyToSetterNodeSimple() { + $node = $this->getEncoderNodeVariableApplyToSetterNode(); + + $object = $this->getEncoderNodeVariableApplyToSetter(); + $collection = $node->getVariableCollection(); + $var = $collection->getVariableById('node-simple'); + + $this->assertEquals(array( + 'node' => 'test', + 'copied' => 'test', + ), $var->getPostNodeSetter()->apply(array( + NodeAccessor::VARIABLE_OBJECT => $object, + NodeAccessor::VARIABLE_NODE_DATA => array( + 'node' => 'test' + ), + NodeAccessor::VARIABLE_NODE => $node, + NodeAccessor::VARIABLE_NAME => 'node', + NodeAccessor::VARIABLE_VALUE => 'test' + ))); + + $this->assertNull($object->getVar()); + } + + public function testApplyToSetterNodeFull() { + $node = $this->getEncoderNodeVariableApplyToSetterNode(); + + $object = $this->getEncoderNodeVariableApplyToSetter(); + $collection = $node->getVariableCollection(); + $var = $collection->getVariableById('node-full'); + + $parent = $this->getThing(); + + $this->assertEquals(array( + 'node' => 'test', + 'name' => 'node', + 'value' => 'test', + 'object' => $object, + 'parent' => $parent, + ), $var->getPostNodeSetter()->apply(array( + NodeAccessor::VARIABLE_OBJECT => $object, + NodeAccessor::VARIABLE_PARENT => $parent, + NodeAccessor::VARIABLE_NODE_DATA => array( + 'node' => 'test' + ), + NodeAccessor::VARIABLE_NODE => $node, + NodeAccessor::VARIABLE_NAME => 'node', + NodeAccessor::VARIABLE_VALUE => 'test' + ))); + } + + public function testApplyToSetterNodeWithoutVariables() { + $this->_applyToSetterNodeWithoutVariables('node-without-variables'); + $this->_applyToSetterNodeWithoutVariables('node-without-variables-empty'); + $this->_applyToSetterNodeWithoutVariables('node-without-variables-null'); + } + protected function _applyToSetterNodeWithoutVariables($variable) + { + $node = $this->getEncoderNodeVariableApplyToSetterNode(); + + $object = $this->getEncoderNodeVariableApplyToSetter(); + $collection = $node->getVariableCollection(); + $var = $collection->getVariableById($variable); + + $this->assertEquals(array( + 'test' => 'altered', + ), $var->getPostNodeSetter()->apply(array( + NodeAccessor::VARIABLE_OBJECT => $object, + NodeAccessor::VARIABLE_NODE_DATA => array( + 'test' => 'test' + ), + NodeAccessor::VARIABLE_NODE => $node, + NodeAccessor::VARIABLE_NAME => 'node', + NodeAccessor::VARIABLE_VALUE => 'test' + ))); + + $this->assertNull($object->getVar()); + } + + public function testApplyToSetterNodeUnknownVariable() { + $this->setExpectedException('\\PE\\Exceptions\\VariableTypeException', 'Parameter with id "unknown_variable" is not known'); + $node = $this->getEncoderNodeVariableApplyToSetterNode(); + + $object = $this->getEncoderNodeVariableApplyToSetter(); + $collection = $node->getVariableCollection(); + $var = $collection->getVariableById('node-unknown-variable'); + + $var->getPostNodeSetter()->apply(array( + NodeAccessor::VARIABLE_OBJECT => $object, + NodeAccessor::VARIABLE_NODE_DATA => array( + 'node' => 'test' + ), + NodeAccessor::VARIABLE_NODE => $node, + NodeAccessor::VARIABLE_NAME => 'node', + NodeAccessor::VARIABLE_VALUE => 'test' + )); + } +} \ No newline at end of file diff --git a/tests/PE/Tests/Variables/VariableCollectionTest.php b/tests/PE/Tests/Variables/VariableCollectionTest.php deleted file mode 100644 index f74c111..0000000 --- a/tests/PE/Tests/Variables/VariableCollectionTest.php +++ /dev/null @@ -1,133 +0,0 @@ -_peApp = new VariableCollection(); - } - - /** - * @return VariableCollection - */ - protected function variableCollection() { - return $this->_peApp; - } - - public function testConstructor() - { - $collection = new VariableCollection(); - $this->assertNotNull($collection); - $this->assertTrue($collection instanceof VariableCollection); - } - - public function testProcessValue() { - $collection = $this->variableCollection(); - - $variable = $this->collectionAddVariable(new Variable(null, 'var')); - $variable->setId('var'); - $variable->setType(Variable::TYPE_BOOL); - - $variable2 = $this->collectionAddVariable(new Variable(null, 'var2')); - $variable2->setId('var2'); - $variable2->setType(Variable::TYPE_ARRAY); - - $this->assertEquals(true, $collection->processValue('var', 'true')); - $this->assertEquals(array('key' => 'value'), $collection->processValue('var2', '{"key":"value"}')); - - $this->assertNull($collection->processValue('nonExistingVariable', 'doesNotMatter')); - } - - public function testAlterVariable() { - $variable = $this->collectionAddVariableDefault(); - $collection = $this->variableCollection(); - - $this->assertNull($variable->getGetterMethod()); - - $collection->alterVariable('var', array('getter' => 'newMethod')); - $this->assertEquals('newMethod', $variable->getGetterMethod()); - - $this->assertFalse($collection->alterVariable('doesNotExist', array())); - } - - public function testGetVariable() { - $variable = $this->collectionAddVariableDefault(); - $collection = $this->variableCollection(); - - $this->assertEquals($variable, $collection->getVariable('var')); - $this->assertEquals($variable, $collection->getVariable($variable)); - $this->assertNull($collection->getVariable('doesNotExist')); - } - - public function testGetVariableById() { - $variable = $this->collectionAddVariableDefault(); - $collection = $this->variableCollection(); - - $this->assertEquals($variable, $collection->getVariableById('var')); - $this->assertNull($collection->getVariableById('doesNotExist')); - } - - public function testGetVariables() { - $variable = $this->collectionAddVariableDefault(); - - $variable2 = $this->collectionAddVariable(new Variable(null, 'var2')); - $variable2->setType(Variable::TYPE_ARRAY); - - $variable3 = $this->collectionAddVariable(new Variable(null, 'var3')); - $variable3->setType(Variable::TYPE_ARRAY); - - $collection = $this->variableCollection(); - - $this->assertEquals(array('var' => $variable, 'var2' => $variable2, 'var3' => $variable3), $collection->getVariables(false)); - $this->assertEquals(array($variable, $variable2, $variable3), $collection->getVariables()); - - $variable2->setOrder(10); - $this->assertEquals(array($variable2, $variable, $variable3), $collection->getVariables()); - - $variable3->setOrder(15); - $this->assertEquals(array($variable2, $variable3, $variable), $collection->getVariables()); - - $variable->setOrder(5); - $this->assertEquals(array($variable, $variable2, $variable3), $collection->getVariables()); - } - - public function testGetVariablesSameIndex() { - $this->setExpectedException('PE\\Exceptions\\VariableCollectionException', 'Cannot order variables because position "10" is being used more than once'); - - $variable = $this->collectionAddVariableDefault(); - $variable->setOrder(10); - - $variable2 = $this->collectionAddVariable(new Variable(null, 'var2')); - $variable2->setOrder(10); - - $this->variableCollection()->getVariables(); - } - - public function testVariableExists() { - $this->collectionAddVariableDefault(); - $collection = $this->variableCollection(); - - $this->assertTrue($collection->variableExists('var')); - $this->assertFalse($collection->variableExists('doesNotExist')); - } - - - - protected function collectionAddVariable($variable = null) { - $collection = $this->variableCollection(); - return $collection->addVariable($variable ? $variable : new Variable()); - } - - protected function collectionAddVariableDefault() { - $variable = $this->collectionAddVariable(new Variable(null, 'var')); - $variable->setType(Variable::TYPE_BOOL); - return $variable; - } -} \ No newline at end of file diff --git a/tests/PE/Tests/Variables/VariableTest.php b/tests/PE/Tests/Variables/VariableTest.php deleted file mode 100644 index 359c8ee..0000000 --- a/tests/PE/Tests/Variables/VariableTest.php +++ /dev/null @@ -1,143 +0,0 @@ -_peApp = new Variable(); - } - - /** - * @return Variable - */ - protected function variable() { - return $this->_peApp; - } - - public function testConstructor() - { - $variable = new Variable(); - $this->assertNotNull($variable); - $this->assertTrue($variable instanceof Variable); - } - - public function testParseOptionsMethodCombined() { - $variable = $this->variable(); - $variable->parseOptions(array( - 'method' => 'methodName' - )); - $this->assertEquals('methodName', $variable->getSetterMethod()); - $this->assertEquals('methodName', $variable->getGetterMethod()); - } - public function testParseOptionsSetterGetter() { - $variable = $this->variable(); - $variable->parseOptions(array( - 'setter' => 'setterMethodName', - 'getter' => 'getterMethodName', - )); - $this->assertEquals('setterMethodName', $variable->getSetterMethod()); - $this->assertEquals('getterMethodName', $variable->getGetterMethod()); - } - public function testParseOptionsDefaultSetExists() { - $variable = $this->variable(); - $variable->parseOptions(array( - 'type' => Variable::TYPE_ARRAY, - )); - $this->assertEquals(Variable::TYPE_ARRAY, $variable->getType()); - } - - public function testSetSetterMethod() { - $variable = $this->variable(); - $this->assertNull($variable->getSetterMethod()); - $variable->setSetterMethod('setterName'); - $this->assertEquals('setterName', $variable->getSetterMethod()); - $variable->setSetterMethod(null); - $this->assertNull($variable->getSetterMethod()); - } - public function testSetSetterMethodNoValue() { - $this->setExpectedException('PE\\Exceptions\\VariableException', 'A setter method for (id) cannot be set because it has the wrong data type'); - $variable = $this->variable(); - $variable->setId('id'); - $variable->setSetterMethod(''); - } - - public function testSetGetterMethod() { - $variable = $this->variable(); - $this->assertNull($variable->getGetterMethod()); - $variable->setGetterMethod('getterName'); - $this->assertEquals('getterName', $variable->getGetterMethod()); - $variable->setGetterMethod(null); - $this->assertNull($variable->getGetterMethod()); - } - public function testSetGetterMethodNoValue() { - $this->setExpectedException('PE\\Exceptions\\VariableException', 'A getter method for (id) cannot be set because it has the wrong data type'); - $variable = $this->variable(); - $variable->setId('id'); - $variable->setGetterMethod(''); - } - - public function testSetType() { - $variable = $this->variable(); - $variable->setType(Variable::TYPE_ARRAY); - $this->assertEquals(Variable::TYPE_ARRAY, $variable->getType()); - $variable->setType(Variable::TYPE_STRING); - $this->assertEquals(Variable::TYPE_STRING, $variable->getType()); - $variable->setType(Variable::TYPE_BOOL); - $this->assertEquals(Variable::TYPE_BOOL, $variable->getType()); - $variable->setType(null); - $this->assertNull($variable->getType()); - } - - public function testGetType() { - $variable = $this->variable(); - $this->assertNull($variable->getType()); - } - - public function testOrder() { - $variable = $this->variable(); - $this->assertNull($variable->getOrder()); - $variable->setOrder(10); - $this->assertEquals(10, $variable->getOrder()); - } - - public function testProcessValue() { - $variable = $this->variable(); - $this->assertEquals('test', $variable->processValue('test')); - - $variable->setType(Variable::TYPE_BOOL); - $this->assertEquals(true, $variable->processValue(1)); - $this->assertEquals(true, $variable->processValue('1')); - $this->assertEquals(true, $variable->processValue('true')); - $this->assertEquals(false, $variable->processValue(0)); - $this->assertEquals(false, $variable->processValue('0')); - $this->assertEquals(false, $variable->processValue('false')); - $this->assertEquals(false, $variable->processValue('abc')); - - $variable->setType(Variable::TYPE_STRING); - $this->assertEquals('1', $variable->processValue(1)); - $this->assertEquals('string', $variable->processValue('string')); - - $variable->setType(Variable::TYPE_ARRAY); - $this->assertEquals(array(), $variable->processValue(json_encode(array()))); - $this->assertEquals(array('hello' => 'world'), $variable->processValue(json_encode(array('hello' => 'world')))); - } - - public function testProcessValueArrayException() { - $this->setExpectedException('PE\\Exceptions\\VariableException', 'The set data type is array but the value cannot be processed'); - $variable = $this->variable(); - $variable->setType(Variable::TYPE_ARRAY); - $variable->processValue(array()); - } - public function testProcessValueUnknownTypeException() { - $this->setExpectedException('PE\\Exceptions\\VariableException', 'Can\'t process value "string" because the data type "unknown" isn\'t recognized.'); - $variable = $this->variable(); - $variable->setType('unknown'); - $variable->processValue('string'); - } -} \ No newline at end of file