Skip to content
This repository

Mapping test improvements #144

Merged
merged 37 commits into from almost 2 years ago

6 participants

Craig Marvelley Lukas Kahwe Smith Don't Add Me To Your Organization a.k.a The Travis Bot David Buchmann Christophe Coevoet Benjamin Eberlei
Craig Marvelley

As discussed at the Symfony Live hackday, I've improved the test coverage of the XML and YAML mapping drivers and fixed a couple of bugs relating to the types of the mapped fields as stored in the CR in the process. There's still much that needs to be covered relating to the more advanced mapped properties, and I'm aiming to complete that in the coming days, but I'll open this PR now just in case you want these changes earlier.

Relates to http://www.doctrine-project.org/jira/browse/PHPCR-42

added some commits June 09, 2012
Craig Marvelley Moved utility method to abstract test class for use in other driver t…
…ests
ba511e6
Craig Marvelley Removed utility class b92b6b2
Craig Marvelley Added XmlDriverTest a197b02
Craig Marvelley Made testLoadMetadataForNonDocumentThrowsException and testGetAllClas…
…sNamesIsIdempotent tests abstract
0120fd5
Craig Marvelley Maintain mapping exception data when rethrowing exception 97c90b6
Craig Marvelley Added CmsAddress XML mapping file fe8050a
Craig Marvelley Made testGetAllClassNamesReturnsAlreadyLoadedClassesIfAppropriate an …
…abstract mapping test
1b0ed9c
Craig Marvelley Made testGetAllClassNamesReturnsOnlyTheAppropriateClasses an abstract…
… mapping test
84c4c14
Craig Marvelley Relocated method for visibility f1f6ec7
Craig Marvelley Made loadDriverForCMSDocuments an abstract method in the base class c42d5d0
Craig Marvelley Added YamlMappingTest which extends the AbstractMappingDriverTest class 3e46d76
Craig Marvelley Use a specific class for the testing of property methods. Fixed bug w…
…ith type mapping of decimal fields in XML and YAML mapping drivers
5ea8cd3
Craig Marvelley Use 'field' rather than 'property' to make tests less ambiguous 381ce08
Craig Marvelley Ensure types are correct, and unsupported field types map to their al…
…iases
514205d
Craig Marvelley Added tests for Nodename mapping to abstract driver class e06ef56
Craig Marvelley Added tests for ParentDocument mapping to abstract driver class 766ef00
Craig Marvelley Removed redundant files 40aae5a
Craig Marvelley Refactored abstract test class to remove repitition 3bbd585
Craig Marvelley Added tests for Child mapping to abstract driver class 82e6dc8
Craig Marvelley Added tests for Children mapping to abstract driver class fec02f4
Craig Marvelley Throw an exception if the fieldName of a children field is blank 41039a4
Craig Marvelley Removed redundant tests fb0cce4
Craig Marvelley Removed unused file b6bf172
Craig Marvelley Singularized Models directory for consistency 5e9c90c
Craig Marvelley Added tests for specifying a Repository strategy to abstract driver c…
…lass
35b9990
lib/Doctrine/ODM/PHPCR/Mapping/ClassMetadata.php
@@ -581,9 +581,13 @@ protected function validateAndCompleteReferrersMapping($mapping)
581 581
 
582 582
     protected function validateAndCompleteFieldMapping($mapping, $isField = true)
583 583
     {
584  
-        if (!isset($mapping['fieldName'])) {
  584
+        if (!isset($mapping['fieldName']) || empty($mapping['fieldName'])) {
3
Lukas Kahwe Smith Collaborator
lsmith77 added a note June 11, 2012

this makes !isset() redundant .. but did you really mean to also ignore 0 ?

Originally blank strings were being accepted here, and I assume that's not a valid case. Maybe strlen($mapping['fieldName']) === 0 is better? I'm not really sure what the valid cases are to be honest.

Lukas Kahwe Smith Collaborator
lsmith77 added a note June 11, 2012

yeah .. 0 probably also doesn't make sense .. so i am fine if you just remove the !isset() part since its redundant now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/Doctrine/ODM/PHPCR/Mapping/Driver/XmlDriver.php
@@ -50,7 +50,14 @@ public function __construct($locator, $fileExtension = self::DEFAULT_FILE_EXTENS
50 50
      */
51 51
     public function loadMetadataForClass($className, ClassMetadata $class)
52 52
     {
53  
-        $xmlRoot = $this->getElement($className);
  53
+        try {
  54
+            $xmlRoot = $this->getElement($className);
  55
+        }
  56
+        catch(\Doctrine\Common\Persistence\Mapping\MappingException $e) {
2
Lukas Kahwe Smith Collaborator
lsmith77 added a note June 11, 2012

missing a space after catch

Lukas Kahwe Smith Collaborator
lsmith77 added a note June 11, 2012

oh and we usually try to add a use statement to avoid fully qualified names inside the class code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/Doctrine/ODM/PHPCR/Mapping/Driver/YamlDriver.php
@@ -50,7 +50,14 @@ public function __construct($locator, $fileExtension = self::DEFAULT_FILE_EXTENS
50 50
      */
51 51
     public function loadMetadataForClass($className, ClassMetadata $class)
52 52
     {
53  
-        $element = $this->getElement($className);
  53
+        try {
  54
+            $element = $this->getElement($className);
  55
+        }
  56
+        catch(\Doctrine\Common\Persistence\Mapping\MappingException $e) {
1
Lukas Kahwe Smith Collaborator
lsmith77 added a note June 11, 2012

see above notes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/Doctrine/ODM/PHPCR/Mapping/Driver/YamlDriver.php
@@ -84,7 +91,18 @@ public function loadMetadataForClass($className, ClassMetadata $class)
84 91
             }
85 92
         }
86 93
         if (isset($element['id'])) {
87  
-            $mapping = array('fieldName' => $element['id'], 'id' => true);
  94
+            if(is_array($element['id'])) {
1
Lukas Kahwe Smith Collaborator
lsmith77 added a note June 11, 2012

here again a few CS issues with missing spaces and code that should be on the same line as the closing curly bracket

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Lukas Kahwe Smith
Collaborator

thx for working on this!

Craig Marvelley

No worries, glad to help. I'll address the comments you raised, thanks for the review :)

lib/Doctrine/ODM/PHPCR/Mapping/Driver/XmlDriver.php
@@ -50,7 +50,14 @@ public function __construct($locator, $fileExtension = self::DEFAULT_FILE_EXTENS
50 50
      */
51 51
     public function loadMetadataForClass($className, ClassMetadata $class)
52 52
     {
53  
-        $xmlRoot = $this->getElement($className);
  53
+        try {
  54
+            $xmlRoot = $this->getElement($className);
  55
+        }
  56
+        catch(\Doctrine\Common\Persistence\Mapping\MappingException $e) {
  57
+            // Convert Exception type for consistency with other drivers
  58
+            throw new MappingException($e->getMessage(), $e->getCode(), $e->getPrevious());
8
Christophe Coevoet
stof added a note June 11, 2012

IMO, you should keep the common MappingException as previous exception instead of stripping it

OK.. I added it because the AnnotationDriver throws the specific exception, whereas the XML and YAML drivers throw the common one. I thought it'd be more consistent and easier to test if they all threw the same type, but happy to go with the consensus.

Christophe Coevoet
stof added a note June 11, 2012

I was just talking about what you put as previous exception here. But anyway, throwing the common exception is a better idea IMO (or making the MappingException extend the common one) so that some code can catch the common one if it wants to work for any Doctrine project

Ah, I misunderstood. Yep - ATM Doctrine\ODM\PHPCR\Mapping\MappingException and Doctrine\Common\Persistence\Mapping\MappingException are not related. Was trying to prevent calling code having to be aware of the driver implementation, which spoils the pattern.

David Buchmann Collaborator
dbu added a note June 12, 2012

is there any good reason to have a phpcr specific MappingException? i would assume that it is just that at the time of writing, the exception was not yet moved into the doctrine common but copied for each odm and the orm.

@stof i see the orm still has its own MappingException https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/Mapping/MappingException.php and it extends from ORMException rather than the common MappingException - is that subject to change? is the exception concept to have a specific tree for each of the backends or should we push that all into common and eliminate the impl specific exceptions? (unless there is some additional info to track in an exception, where you would extend the common exception rather than some sort of base implemenation exception)

Christophe Coevoet
stof added a note June 12, 2012

Improving the ORM exceptions is in the roadmap. Currently, they all extend from the ORMException class, which should probably be changed to an interface instead to be able to extend from other exceptions too

David Buchmann Collaborator
dbu added a note June 12, 2012

@stof is there a jira issue or something describing what you want to do? i guess we should do the same with phpcr-odm. i created http://www.doctrine-project.org/jira/browse/PHPCR-71 to track this further - i think we should not block this pull request by it. having the same behaviour over all 3 mappers is definitively better than having diverging behaviour.

Christophe Coevoet
stof added a note June 12, 2012

not sure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/Doctrine/ODM/PHPCR/Mapping/Driver/YamlDriver.php
@@ -84,7 +91,18 @@ public function loadMetadataForClass($className, ClassMetadata $class)
84 91
             }
85 92
         }
86 93
         if (isset($element['id'])) {
87  
-            $mapping = array('fieldName' => $element['id'], 'id' => true);
  94
+            if(is_array($element['id'])) {
  95
+                if(!isset($element['id']['fieldName'])) {
  96
+                    throw new MappingException("Missing fieldName property for id field");
  97
+                }
  98
+                else {
2
Christophe Coevoet
stof added a note June 11, 2012

else should be on the same line than the closing curly brace of the corresponding if

Christophe Coevoet
stof added a note June 11, 2012

btw, you don't need to use else in this place as the if leaves the function because of the exception

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Don't Add Me To Your Organization a.k.a The Travis Bot

This pull request passes (merged bd15c45 into dbd116e).

Don't Add Me To Your Organization a.k.a The Travis Bot

This pull request passes (merged 55bc9fc into 50b4ee1).

lib/Doctrine/ODM/PHPCR/Mapping/ClassMetadata.php
@@ -920,6 +924,10 @@ public function mapField(array $mapping)
920 924
         if ($mapping['type'] === 'int') {
921 925
             $mapping['type'] = 'long';
922 926
         }
  927
+        
1
Lukas Kahwe Smith Collaborator
lsmith77 added a note June 13, 2012

should be an elseif .. ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Don't Add Me To Your Organization a.k.a The Travis Bot

This pull request fails (merged f30153b into 50b4ee1).

Don't Add Me To Your Organization a.k.a The Travis Bot

This pull request fails (merged 516f928 into 50b4ee1).

David Buchmann
Collaborator
dbu commented June 14, 2012

is this failure a bug that is reveiled by the changes to the tests or a bug in one of the code cleanups?

Doctrine\Tests\ODM\PHPCR\Mapping\AnnotationDriverTest::testLoadMappedSuperclassTypeMapping
Undefined property: Doctrine\ODM\PHPCR\Mapping\Annotations\MappedSuperclass::$nodeType

/home/vagrant/builds/doctrine/phpcr-odm/lib/Doctrine/ODM/PHPCR/Mapping/Driver/AnnotationDriver.php:87
/home/vagrant/builds/doctrine/phpcr-odm/tests/Doctrine/Tests/ODM/PHPCR/Mapping/AbstractMappingDriverTest.php:31
/home/vagrant/builds/doctrine/phpcr-odm/tests/Doctrine/Tests/ODM/PHPCR/Mapping/AbstractMappingDriverTest.php:399
/home/vagrant/.phpenv/versions/5.3.13/bin/phpunit:46

apart from that i think we should merge now and do further things in a separate pull request, otherwise it becomes to big.

Christophe Coevoet
stof commented June 14, 2012

from what I see in the code, it is an existing bug which was not spotted by the testsuite previously but is now covered. And it is indeed right: the nodeType property is defined in Document but not in MappedSuperclass`` whereas it will still try to access it for mapped superclasses (other properties will fail too): https://github.com/craigmarvelley/phpcr-odm/blob/516f92848bb7bb38eb74c2aed0562e0fafe8f35e/lib/Doctrine/ODM/PHPCR/Mapping/Driver/AnnotationDriver.php#L58

Craig Marvelley

Sorry, only now seeing the failing test - what's the best approach to take here? Extend Document and MappedSuperclass from an abstract parent, and move those properties there?

Craig Marvelley

I couldn't find any docs on MappedSuperclass so wasn't sure it made sense for that and Document to extend a common parent, so I've followed Doctrine ORM's lead, and like Doctrine\ORM\Mapping\Entity and Doctrine\ORM\Mapping\MappedSuperclass I've kept them apart and just replicated the common properties for now.

Don't Add Me To Your Organization a.k.a The Travis Bot

This pull request passes (merged 4162a4d into 50b4ee1).

David Buchmann dbu merged commit 96e876b into from June 14, 2012
David Buchmann dbu closed this June 14, 2012
David Buchmann
Collaborator
dbu commented July 18, 2012

hi @craigmarvelley

bringing this up again, as i started to write the phpcr-odm documentation and stumbled over the mapped super class. as far as i can see, this is just a cludge for the inflexibilty of an ORM data store. this is how i currently document the feature:

https://github.com/doctrine/phpcr-odm-documentation/blob/master/en/reference/inheritance-mapping.rst

i think we can just ditch the explicit mapped superclass thing, it makes no sense for phpcr-odm. if somebody explicitly never wants to store the super class, he can just make it an abstract class in the php sense. does that make sense?

/cc @lsmith77

Lukas Kahwe Smith
Collaborator

we need to discuss this with the other ODM devs @beberlei, @jmikola, @jwage, @odino

Craig Marvelley

Handling it with abstract classes makes sense to me. Is the intention of the MappedSuperclass annotation to just let you specify a single class in the inheritance chain from which additional annotations will be parsed, rather than recursing through all ancestors? Is that the functionality that we're after here?

I started implementing some more unit tests to achieve mapping driver parity here: https://github.com/craigmarvelley/phpcr-odm/tree/more-mapping-code-coverage, can roll any other changes into that work if necessary. Also just started paternity leave though, so you may have to bear with me time-wise :)

Benjamin Eberlei
Owner

@dbu how on this abstract class is the person going to define mapping information in annotatinos? That is what the Mapped superclass is for. If no annotation document or MSC is found, no parsing of metadata is done.

David Buchmann
Collaborator
dbu commented July 19, 2012

@beberlei so the xml/yml mapping drivers will not look at the class and check if its parent class has mappings too?
as we do not have the limitations on extending document classes with the odm, we need something more flexible where the parent class does not need to know it is going to be extended... in the orm the superclass thing is for the parent class, right? we would rather need to have something like (yml) inheritMappings: My\Super\Class to make the loader get the metadata from that parent and merge them in.

  • note to self: we should load the meta data through the loader, so the parent class can have the mappings defined in a different way than the extending class.
David Buchmann
Collaborator
dbu commented July 19, 2012

aaah. i did not really read. are you saying that i use this to make doctrine understand that my class which is just extending a mapped class without adding any mappings of its own should get the mappings of the super class when i use xml/yml mapping?

Benjamin Eberlei
Owner

you are thinking about this wrong. This has nothing to do with xm/yml.

Mapped superclasses are abstract base classes, which can be reused in any persistent document. These persistent document classes inherit all mapped properties of the mapped superclass. This is not a limitation of the persistence storatge, but of single inheritance languages such as PHP.

David Buchmann
Collaborator
dbu commented July 19, 2012

ok, so it is about mapping inheritance not following class inheritance? what happens with class inheritance, is it usually ignored unless you explicitly map the class as superclass? or is the MSC just overwriting mapping inheritance following the class inheritance that would normally happen?

David Buchmann
Collaborator
dbu commented July 23, 2012

i created http://www.doctrine-project.org/jira/browse/PHPCR-75 to further track this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 37 unique commits by 2 authors.

Jun 09, 2012
Craig Marvelley Moved utility method to abstract test class for use in other driver t…
…ests
ba511e6
Craig Marvelley Removed utility class b92b6b2
Craig Marvelley Added XmlDriverTest a197b02
Craig Marvelley Made testLoadMetadataForNonDocumentThrowsException and testGetAllClas…
…sNamesIsIdempotent tests abstract
0120fd5
Craig Marvelley Maintain mapping exception data when rethrowing exception 97c90b6
Craig Marvelley Added CmsAddress XML mapping file fe8050a
Craig Marvelley Made testGetAllClassNamesReturnsAlreadyLoadedClassesIfAppropriate an …
…abstract mapping test
1b0ed9c
Craig Marvelley Made testGetAllClassNamesReturnsOnlyTheAppropriateClasses an abstract…
… mapping test
84c4c14
Craig Marvelley Relocated method for visibility f1f6ec7
Craig Marvelley Made loadDriverForCMSDocuments an abstract method in the base class c42d5d0
Craig Marvelley Added YamlMappingTest which extends the AbstractMappingDriverTest class 3e46d76
Craig Marvelley Use a specific class for the testing of property methods. Fixed bug w…
…ith type mapping of decimal fields in XML and YAML mapping drivers
5ea8cd3
Craig Marvelley Use 'field' rather than 'property' to make tests less ambiguous 381ce08
Craig Marvelley Ensure types are correct, and unsupported field types map to their al…
…iases
514205d
Craig Marvelley Added tests for Nodename mapping to abstract driver class e06ef56
Craig Marvelley Added tests for ParentDocument mapping to abstract driver class 766ef00
Craig Marvelley Removed redundant files 40aae5a
Craig Marvelley Refactored abstract test class to remove repitition 3bbd585
Craig Marvelley Added tests for Child mapping to abstract driver class 82e6dc8
Craig Marvelley Added tests for Children mapping to abstract driver class fec02f4
Craig Marvelley Throw an exception if the fieldName of a children field is blank 41039a4
Craig Marvelley Removed redundant tests fb0cce4
Craig Marvelley Removed unused file b6bf172
Craig Marvelley Singularized Models directory for consistency 5e9c90c
Jun 10, 2012
Craig Marvelley Added tests for specifying a Repository strategy to abstract driver c…
…lass
35b9990
Jun 12, 2012
Craig Marvelley Removed unnecessary isset() 1c5bbd9
Craig Marvelley Maintain exception stack 9d594c1
Craig Marvelley CS fixes, removed redundant else 6207513
Craig Marvelley Explicitly use default YAML properties b1adc86
Craig Marvelley CS fixes bd15c45
Jun 13, 2012
Craig Marvelley Merge remote-tracking branch 'original/master' into mapping-test-impr…
…ovements
55bc9fc
Craig Marvelley Added tests for setting versionable annotation metadata d747570
Craig Marvelley Added tests for setting NodeType and MappedSuperclass annotation meta…
…data
1a4e99b
Craig Marvelley Added tests for setting Node annotation metadata f30153b
Craig Marvelley Use an elseif when checking field mapping type 516f928
Craig Marvelley XML and YAML drivers load ReferenceMany metadata mappings be92b27
Jun 15, 2012
Craig Marvelley Added missing properties to MappedSuperclass annotation 4162a4d
Something went wrong with that request. Please try again.