[Question] Module class made `final`, Codeception docs seem to indicate `extends`
(apologies if the title is too convoluted!)
So, one of the changes introduced between 1.1.10 & 1.1.11 is that the Module class is made final. See src/Codeception/Module/Yii2.php, line 168/169.
Craft CMS is a CMS that is built on Yii2. For its testing API it uses Codeception and this Codeception yii2 module. Amongst others it extends this module: https://github.com/craftcms/cms/blob/5.x/src/test/Craft.php#L65
And of course extending a final class is not possible, so our test suites now throw an error:
Fatal error: Class craft\test\Craft cannot extend final class Codeception\Module\Yii2 in /app/vendor/craftcms/cms/src/test/Craft.php on line 65
The documentation of Codeception 5 mentions the following when it comes to extending a Module: https://codeception.com/docs/ModulesAndHelpers#Extending-a-Module. So I think this means that the Codeception\Module\Yii2 class should not be final.
I'm submitting this more as a question, because I might be missing the context for which the change to final was made.
I've just tagged new release un-finalizing it.
Just tested with the newest version and as expected the test suite runs again, thank you!
@qrazi
I'm reopening this issue for the next major release. I've looked at the craft implementation of the subclass and I'm wondering if the same could not be achieved via composition?
Opening up class internals for extension by 3rd party code is really bad for our maintainability and makes it harder to reason about the (supposedly) internal state of our module.
@qrazi, just a heads up i'm releasing v2; this will reintroduce this issue for you.
I'm doing this because finalizing is a major release and we could always unfinalize it in a minor one.
I checked the composer.json for CraftCMS and it should not lead to problems since you're using "codeception/module-yii2": "^1.1.9", which won't match 2.
Makes total sense to me, thanks!
Now the extending of a (this) module does not work anymore as described in the general documentation: https://codeception.com/docs/ModulesAndHelpers#Extending-a-Module:
If accessing modules doesn’t provide enough flexibility, you can extend a module inside a Helper class:
namespace Tests\Support\Helper;
class MyExtendedSelenium extends \Codeception\Module\WebDriver
{
}
So, is this a case where Codeception Modules decide for themselves how they can be extended? So, I / someone should make PR for the documentation on Codeception?
So, is this a case where Codeception Modules decide for themselves how they can be extended? So, I / someone should make PR for the documentation on Codeception?
I think so yes.
But I'd still like to make sure that your specific case can actually be solved using composition; or if it requires other changes to the Yii2 module.
Closing this, create a new issue if you need help / guidance on using composition to offer your own functionality in the module.
@SamMousa - Can you please add some clear documentation linked to the readme section with few real-world examples to explain this composition method. Linking to relevant (now absolute) craft docs also will help.
Can you please add some clear documentation linked to the readme section with few real-world examples to explain this composition method.
What do you mean? There's plenty of articles on composition vs inheritance freely available online.
Linking to relevant (now absolute) craft docs also will help.
What are craft docs?
@samuelrajan747 I think this would require opening an issue on the Craft CMS repo actually, not anything in this repo. I'm not sure I have the time soon, but I was planning on doing so - accompanied by a PR. They are will know what the change to this module means as well, I'm sure.