/**
  * @test
  */
 public function conversionExtractsWholeExtensionMetadataWithRelations()
 {
     $input = array('modules' => array(0 => array('value' => array('name' => 'Blog', 'objectsettings' => array('description' => 'A blog object', 'aggregateRoot' => FALSE, 'type' => 'Entity'), 'propertyGroup' => array('properties' => array(0 => array('propertyName' => 'name', 'propertyType' => 'String'), 1 => array('propertyName' => 'description', 'propertyType' => 'String'))), 'relationGroup' => array('relations' => array(0 => array('relationName' => 'posts', 'relationType' => 'zeroToMany', 'propertyIsExcludeField' => 1))))), 1 => array('value' => array('name' => 'Post', 'objectsettings' => array('description' => 'A blog post', 'aggregateRoot' => FALSE, 'type' => 'Entity'), 'propertyGroup' => array('properties' => array()), 'relationGroup' => array('relations' => array(0 => array('relationName' => 'comments', 'relationType' => 'zeroToMany', 'propertyIsExcludeField' => 1))))), 2 => array('value' => array('name' => 'Comment', 'objectsettings' => array('description' => '', 'aggregateRoot' => FALSE, 'type' => 'Entity'), 'propertyGroup' => array('properties' => array()), 'relationGroup' => array('relations' => array())))), 'properties' => array('description' => 'Some description', 'extensionKey' => $this->extensionKey, 'name' => 'My ext name', 'emConf' => array('state' => 'beta')), 'wires' => array(0 => array('tgt' => array('moduleId' => 1, 'terminal' => 'SOURCES'), 'src' => array('moduleId' => 0, 'terminal' => 'relationWire_0')), 1 => array('tgt' => array('moduleId' => 2, 'terminal' => 'SOURCES'), 'src' => array('moduleId' => 1, 'terminal' => 'relationWire_0'))));
     $extension = new Tx_ExtensionBuilder_Domain_Model_Extension();
     $extension->setName('My ext name');
     $extension->setState(Tx_ExtensionBuilder_Domain_Model_Extension::STATE_BETA);
     $extension->setExtensionKey($this->extensionKey);
     $extension->setDescription('Some description');
     $extension->setExtensionDir('');
     $blog = new Tx_ExtensionBuilder_Domain_Model_DomainObject();
     $blog->setName('Blog');
     $blog->setDescription('A blog object');
     $blog->setEntity(TRUE);
     $blog->setAggregateRoot(FALSE);
     $property = new Tx_ExtensionBuilder_Domain_Model_DomainObject_StringProperty('name');
     $blog->addProperty($property);
     $property = new Tx_ExtensionBuilder_Domain_Model_DomainObject_StringProperty('description');
     $blog->addProperty($property);
     $extension->addDomainObject($blog);
     $post = new Tx_ExtensionBuilder_Domain_Model_DomainObject();
     $post->setName('Post');
     $post->setDescription('A blog post');
     $post->setEntity(TRUE);
     $post->setAggregateRoot(FALSE);
     $extension->addDomainObject($post);
     $comment = new Tx_ExtensionBuilder_Domain_Model_DomainObject();
     $comment->setName('Comment');
     $comment->setDescription('');
     $comment->setEntity(TRUE);
     $comment->setAggregateRoot(FALSE);
     $extension->addDomainObject($comment);
     $relation = new Tx_ExtensionBuilder_Domain_Model_DomainObject_Relation_ZeroToManyRelation('posts');
     $relation->setForeignModel($post);
     $relation->setExcludeField(1);
     $blog->addProperty($relation);
     $relation = new Tx_ExtensionBuilder_Domain_Model_DomainObject_Relation_ZeroToManyRelation('comments');
     $relation->setForeignModel($comment);
     $relation->setExcludeField(1);
     $post->addProperty($relation);
     $actualExtension = $this->extensionSchemaBuilder->build($input);
     $this->assertEquals($extension->getDomainObjects(), $actualExtension->getDomainObjects(), 'The extensions differ');
 }
 /**
  * Write a simple model class for a non aggregate root domain object with zero to many relation
  *
  * @depends checkRequirements
  * @test
  */
 function writeModelClassWithZeroToManyRelation()
 {
     $modelName = 'ModelCgt4';
     $relatedModelName = 'relatedModel';
     $propertyName = 'relNames';
     $domainObject = $this->buildDomainObject($modelName);
     $relatedDomainObject = $this->buildDomainObject($relatedModelName);
     $relation = new Tx_ExtensionBuilder_Domain_Model_DomainObject_Relation_ZeroToManyRelation($propertyName);
     $relation->setForeignModel($relatedDomainObject);
     $domainObject->addProperty($relation);
     $classFileContent = $this->codeGenerator->generateDomainObjectCode($domainObject, $this->extension);
     $modelClassDir = 'Classes/Domain/Model/';
     $result = t3lib_div::mkdir_deep($this->extension->getExtensionDir(), $modelClassDir);
     $absModelClassDir = $this->extension->getExtensionDir() . $modelClassDir;
     $this->assertTrue(is_dir($absModelClassDir), 'Directory ' . $absModelClassDir . ' was not created');
     $modelClassPath = $absModelClassDir . $domainObject->getName() . '.php';
     t3lib_div::writeFile($modelClassPath, $classFileContent);
     $this->assertFileExists($modelClassPath, 'File was not generated: ' . $modelClassPath);
     $className = $domainObject->getClassName();
     include $modelClassPath;
     $this->assertTrue(class_exists($className), 'Class was not generated:' . $className);
     $reflection = new Tx_ExtensionBuilder_Reflection_ClassReflection($className);
     $this->assertTrue($reflection->hasMethod('add' . ucfirst(Tx_ExtensionBuilder_Utility_Inflector::singularize($propertyName))), 'Add method was not generated');
     $this->assertTrue($reflection->hasMethod('remove' . ucfirst(Tx_ExtensionBuilder_Utility_Inflector::singularize($propertyName))), 'Remove method was not generated');
     $this->assertTrue($reflection->hasMethod('get' . ucfirst($propertyName)), 'Getter was not generated');
     $this->assertTrue($reflection->hasMethod('set' . ucfirst($propertyName)), 'Setter was not generated');
     //checking methods
     $setterMethod = $reflection->getMethod('set' . ucfirst($propertyName));
     $this->assertTrue($setterMethod->isTaggedWith('param'), 'No param tag set for setter method');
     $paramTagValues = $setterMethod->getTagValues('param');
     $this->assertTrue(strpos($paramTagValues[0], 'Tx_Extbase_Persistence_ObjectStorage<' . $relatedDomainObject->getClassName()) === 0, 'Wrong param tag:' . $paramTagValues[0]);
     $parameters = $setterMethod->getParameters();
     $this->assertTrue(count($parameters) == 1, 'Wrong parameter count in setter method');
     $parameter = current($parameters);
     $this->assertTrue($parameter->getName() == $propertyName, 'Wrong parameter name in setter method');
     $this->assertTrue($parameter->getTypeHint() == 'Tx_Extbase_Persistence_ObjectStorage', 'Wrong type hint for setter parameter:' . $parameter->getTypeHint());
     $addMethod = $reflection->getMethod('add' . ucfirst(Tx_ExtensionBuilder_Utility_Inflector::singularize($propertyName)));
     $this->assertTrue($addMethod->isTaggedWith('param'), 'No param tag set for setter method');
     $paramTagValues = $addMethod->getTagValues('param');
     $this->assertTrue(strpos($paramTagValues[0], $relatedDomainObject->getClassName()) === 0, 'Wrong param tag:' . $paramTagValues[0]);
     $parameters = $addMethod->getParameters();
     $this->assertTrue(count($parameters) == 1, 'Wrong parameter count in add method');
     $parameter = current($parameters);
     $this->assertTrue($parameter->getName() == Tx_ExtensionBuilder_Utility_Inflector::singularize($propertyName), 'Wrong parameter name in add method');
     $this->assertTrue($parameter->getTypeHint() == $relatedDomainObject->getClassName(), 'Wrong type hint for add method parameter:' . $parameter->getTypeHint());
     $removeMethod = $reflection->getMethod('remove' . ucfirst(Tx_ExtensionBuilder_Utility_Inflector::singularize($propertyName)));
     $this->assertTrue($removeMethod->isTaggedWith('param'), 'No param tag set for remove method');
     $paramTagValues = $removeMethod->getTagValues('param');
     $this->assertTrue(strpos($paramTagValues[0], $relatedDomainObject->getClassName()) === 0, 'Wrong param tag:' . $paramTagValues[0]);
     $parameters = $removeMethod->getParameters();
     $this->assertTrue(count($parameters) == 1, 'Wrong parameter count in remove method');
     $parameter = current($parameters);
     $this->assertTrue($parameter->getName() == Tx_ExtensionBuilder_Utility_Inflector::singularize($propertyName) . 'ToRemove', 'Wrong parameter name in remove method');
     $this->assertTrue($parameter->getTypeHint() == $relatedDomainObject->getClassName(), 'Wrong type hint for remove method parameter:' . $parameter->getTypeHint());
 }