Hydrate/extract changes value when there are consecutive underscores
Opened this issue · 1 comments
kirkmadera commented
Bug Report
Q | A |
---|---|
Version(s) | 4.15.0 |
Summary
Current behavior
Extract/hydrate should be symmetrical. Extracting, then hydrating any value should produce the original value. This fails when there are consecutive underscores.
How to reproduce
$namingStrategy = new UnderscoreNamingStrategy();
$value = 'usb_a__out_usb_a_out';
var_dump($namingStrategy->hydrate($value));
var_dump($namingStrategy->extract($namingStrategy->hydrate($value)));
string(15) "usbA_outUsbAOut"
string(19) "usb_a_out_usb_a_out"
Expected behavior
I would expect the second output to equal the original string.
kirkmadera commented
Here is a simplified version of this class that does not have this issue.
$namingStrategy = new class implements NamingStrategyInterface
{
/**
* Converts camel case to snake case.
*
* @param string $name The name in camel case.
* @param null|object $object The original object for context (unused).
* @return string The name converted to snake case.
*/
public function extract(string $name, ?object $object = null): string
{
return strtolower(preg_replace('/[A-Z]/', '_$0', lcfirst($name)));
}
/**
* Converts snake case to camel case.
*
* @param string $name The name in snake case.
* @param null|mixed[] $data The original data for context (unused).
* @return string The name converted to camel case.
*/
public function hydrate(string $name, ?array $data = null): string
{
return lcfirst(preg_replace_callback('/(_[a-z])/', static function ($match) {
return strtoupper($match[1][1]);
}, $name));
}
};
$value = 'usb_a__out_usb_a_out';
var_dump($namingStrategy->hydrate($value));
var_dump($namingStrategy->extract($namingStrategy->hydrate($value)));
die(__METHOD__);
string(15) "usbA_OutUsbAOut"
string(19) "usb_a__out_usb_a_out"