Problem/Motivation
https://qa.drupal.org/pifr/test/995283
The Template Assertions patch adds this assertion just prior to the return.
assert('$value instanceof \\Drupal\\Core\\Template\\AttributeValueBase', 'invalidReturn');
This is based on and enforces the following existing PHP docs line.
* @return \Drupal\Core\Template\AttributeValueBase
* An AttributeValueBase representation of the attribute's value.
Two exceptions each are raised for these tests.
Drupal\action\Tests\ConfigurationTest
Drupal\search\Tests\SearchConfigSettingsFormTest
The assertion code is not wrong unless the PHP docs code is wrong. Either the code is defective or the documentation is wrong. I don't know which.
Proposed resolution
Three possible, depending on the actual problem.
- Fix the underlying code so that an instance of AttributeValueBase is returned as indicated in the PHP Docs
- Update the documentation line to match what the function actually is supposed to return and modify the assertion to match the new PHP documentation.
- There is a bug in the tests involved that must be updated.
Remaining tasks
One of the above must be followed up on.
User interface changes
None anticipated.
API changes
None anticipated.
Comments
Comment #1
Aki Tendo commentedOk, upon running a local test I discovered that a TranslationWrapper was passed in as the value argument. Let's look at the function since it's fairly short...
If we pass an object to this function then, without the assertion, it will be returned without conversion. Is this the correct behavior.
If yes, the assertion must be changed to allow this.
If no, the code must be changed to forbid it and all calling code debugged.
Or, is the intent that an object's string expression be returned as an AttributeString? If so another branch to the conditional is called for.
That last one is the one I'll try for patching this.
Comment #2
Aki Tendo commentedAdded a conditional to force an object that has a magic __toString method to cast itself as a string. This satisfies both the two failed tests and the assertion added for the Template Assertions patch. This patch will be added to it's parent so that the parent can pass testing.
Comment #4
Aki Tendo commentedIt would help if I'd apply against core.
Comment #5
Aki Tendo commentedComment #6
dawehnerI'm curious wehther we can add a test?
Afaik we have a unit test for that already:
core/tests/Drupal/Tests/Core/Template/AttributeTest.phpComment #7
Aki Tendo commentedProbably should add a test to the code that is directly affected - then again in a sense the assertion is itself a test of sorts. I'll look into adding a test tomorrow.
Comment #8
Aki Tendo commentedWell, here's the problem...
That test only checks if arrays get converted. It checks no other types and doesn't check invalids. I'll go ahead an add that logic, but I need to get the assert statement in at this point to check to make sure it gets thrown when invalid objects are supplied. The only thing that can do that is outside code, which indicates a bug in that code, so assert is the correct handle here, not an exception.
Comment #9
Aki Tendo commentedK, multiple new tests added to make sure what I understand the code should be returned is being returned. Also a test to see if the assertion gets thrown.
No interdiff since the first patch was only 3 lines.
Comment #10
Aki Tendo commentedComment #11
yesct commented[cross posted with #10, (and then copied the summary instead of my comment).
maybe #10 had a more informative tests only patch?]
Thanks for adding tests.
Fixed some coding standard nits:
We usually say what we are testing without numbering things. (So if we change the order or insert another test case, we do not have to make unrelated changes changing the numbering. ... unless the order actually matters.
"Lines containing comments (including docblocks) must wrap as close to 80 characters as possible without going over"
https://www.drupal.org/node/1354#drupal
in line comments are all // even if they are a block of multiple lines.
"even for multiple lines, repeat the // single-line comment"
https://www.drupal.org/node/1354#inline
tests are sometimes do not follow standards as strictly... but
one line summaries should start with 3rd person verbs.
"Use a third person verb to start the summary of a class, interface, or method. For example: "Represents a ..." or "Provides..."."
https://www.drupal.org/node/1354#classes
https://www.drupal.org/node/608152#indenting
some empty lines here...
=====
other than those nits,
I wonder if we can do a tests only patch to show the test additions/changes will catch the problem nicely.
maybe not, though since the fix in core/lib/Drupal/Core/Template/Attribute.php
adds an assert there...
Comment #14
yesct commentedWell at least we can see the how the test fails are different including or excluding that assert. :)
Comment #15
yesct commentedSo do we know enough to clarify the issue summary now?
Comment #16
Aki Tendo commentedI'm not sure. The point of the assertion is to enforce the PHPDocs comment - that the function only returns objects of a certain type. It has proven that in at least 4 cases in the existing code that isn't happening. I don't know what is more disruptive - enforcing the PHP docs statement or dropping the assert - but I do know the long term health of the code is best served by enforcing the PHP docs or changing them to match the actual behavior.
Something else that isn't tested for - Numbers of all types. Reading the code flow they will currently drop through and be returned unmodified. Why where they overlooked? Are they even legal inputs? Are they legal only for certain attributes - I know you can't have a class name that is merely a number, nor an ID, and they can't start with a number either. Is it the responsibility of this class to make that check?
Assuming they are legal, do we create a new AttributeValue container for them, or cast them to string and let the AttributeString class work with them?
Comment #17
Aki Tendo commentedThis morning I started doing a lot more hardening shuffling, so this is no longer a simple issue but does go hand in hand with assertions. Closing this ticket to merge back to the Template Assertions ticket.