Loading core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItem.php +44 −1 Original line number Diff line number Diff line Loading @@ -72,7 +72,50 @@ public function getConstraints() { */ public static function generateSampleValue(FieldDefinitionInterface $field_definition) { $random = new Random(); $values['value'] = $random->word(mt_rand(1, $field_definition->getSetting('max_length'))); $max_length = $field_definition->getSetting('max_length'); // When the maximum length is less than 15, generate a random word instead // of sentences. if ($max_length <= 15) { $values['value'] = ucfirst($random->word($max_length)); return $values; } // The minimum length is either 10% of the maximum length, or 15 characters // long, whichever is greater. $min_length = max(ceil($max_length * 0.10), 15); // The random value is generated multiple times to create a slight // preference towards values that are closer to the minimum length of the // string. For values larger than 255 (which is the default maximum value), // the bias towards minimum length is increased. This is because the default // maximum length of 255 is often used for fields that include shorter // values (i.e. title). $length = mt_rand($min_length, mt_rand($min_length, $max_length >= 255 ? mt_rand($min_length, $max_length) : $max_length)); $string = $random->sentences(1); while (mb_strlen($string) < $length) { $string .= " {$random->sentences(1)}"; } // If the length of the generated string is longer than the maximum length, // re-create the string word by word to reduce the chances of the string // ending middle of a word. if (mb_strlen($string) > $max_length) { $words = explode(' ', $string); $string = array_reduce($words, function ($current, $item) use ($length) { return mb_strlen($current) > $length ? $current : "$current$item "; }, ''); } // Normalize the string to be shorter than the maximum length. $normalized_value = rtrim(mb_substr($string, 0, $max_length - 1), ' .'); // Ensure that the string ends with a full stop if there are multiple // sentences. $values['value'] = $normalized_value . (str_contains($normalized_value, '.') ? '.' : ''); return $values; } Loading core/modules/workspaces/tests/src/Functional/EntityResource/WorkspaceJsonAnonTest.php +19 −0 Original line number Diff line number Diff line Loading @@ -28,4 +28,23 @@ class WorkspaceJsonAnonTest extends WorkspaceResourceTestBase { */ protected $defaultTheme = 'stark'; /** * {@inheritdoc} */ protected function getModifiedEntityForPostTesting(): array { $values = parent::getModifiedEntityForPostTesting(); // The ID field for a workspace uses a string field, with a validation // constraint that applies a regex pattern that prevents whitespace. // \Drupal\Core\Field\Plugin\Field\FieldType\StringItem::generateSampleValue // used in the parent implementation of ::getModifiedEntityForPostTesting // can generate whitespace, so we use the same regex pattern here to ensure // the generated value is valid for the sake of the test. // // @see \Drupal\Core\Field\Plugin\Field\FieldType\StringItem::generateSampleValue // @see \Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase::getModifiedEntityForPostTesting // @see \Drupal\workspaces\Entity\Workspace::baseFieldDefinitions $values['id'] = preg_replace('/[^a-z0-9_]/', '', $values['id']); return $values; } } core/tests/Drupal/Tests/Core/Field/StringItemTest.php 0 → 100644 +50 −0 Original line number Diff line number Diff line <?php namespace Drupal\Tests\Core\Field; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\Plugin\Field\FieldType\StringItem; use Drupal\Tests\UnitTestCase; /** * Defines a test for the StringItem field-type. * * @group Field * @coversDefaultClass \Drupal\Core\Field\Plugin\Field\FieldType\StringItem */ class StringItemTest extends UnitTestCase { /** * Tests generating sample values. * * @param int $max_length * Maximum field length. * * @covers ::generateSampleValue * @dataProvider providerMaxLength */ public function testGenerateSampleValue(int $max_length): void { $definition = $this->prophesize(FieldDefinitionInterface::class); $definition->getSetting('max_length')->willReturn($max_length); $sample_value = StringItem::generateSampleValue($definition->reveal()); $this->assertLessThanOrEqual($max_length, mb_strlen($sample_value['value'])); } /** * Data provider for maximum-lengths. * * @return array * Test cases. */ public function providerMaxLength(): array { return [ '32' => [32], '255' => [255], '500' => [500], '15' => [15], '4' => [4], '64' => [64], ]; } } Loading
core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItem.php +44 −1 Original line number Diff line number Diff line Loading @@ -72,7 +72,50 @@ public function getConstraints() { */ public static function generateSampleValue(FieldDefinitionInterface $field_definition) { $random = new Random(); $values['value'] = $random->word(mt_rand(1, $field_definition->getSetting('max_length'))); $max_length = $field_definition->getSetting('max_length'); // When the maximum length is less than 15, generate a random word instead // of sentences. if ($max_length <= 15) { $values['value'] = ucfirst($random->word($max_length)); return $values; } // The minimum length is either 10% of the maximum length, or 15 characters // long, whichever is greater. $min_length = max(ceil($max_length * 0.10), 15); // The random value is generated multiple times to create a slight // preference towards values that are closer to the minimum length of the // string. For values larger than 255 (which is the default maximum value), // the bias towards minimum length is increased. This is because the default // maximum length of 255 is often used for fields that include shorter // values (i.e. title). $length = mt_rand($min_length, mt_rand($min_length, $max_length >= 255 ? mt_rand($min_length, $max_length) : $max_length)); $string = $random->sentences(1); while (mb_strlen($string) < $length) { $string .= " {$random->sentences(1)}"; } // If the length of the generated string is longer than the maximum length, // re-create the string word by word to reduce the chances of the string // ending middle of a word. if (mb_strlen($string) > $max_length) { $words = explode(' ', $string); $string = array_reduce($words, function ($current, $item) use ($length) { return mb_strlen($current) > $length ? $current : "$current$item "; }, ''); } // Normalize the string to be shorter than the maximum length. $normalized_value = rtrim(mb_substr($string, 0, $max_length - 1), ' .'); // Ensure that the string ends with a full stop if there are multiple // sentences. $values['value'] = $normalized_value . (str_contains($normalized_value, '.') ? '.' : ''); return $values; } Loading
core/modules/workspaces/tests/src/Functional/EntityResource/WorkspaceJsonAnonTest.php +19 −0 Original line number Diff line number Diff line Loading @@ -28,4 +28,23 @@ class WorkspaceJsonAnonTest extends WorkspaceResourceTestBase { */ protected $defaultTheme = 'stark'; /** * {@inheritdoc} */ protected function getModifiedEntityForPostTesting(): array { $values = parent::getModifiedEntityForPostTesting(); // The ID field for a workspace uses a string field, with a validation // constraint that applies a regex pattern that prevents whitespace. // \Drupal\Core\Field\Plugin\Field\FieldType\StringItem::generateSampleValue // used in the parent implementation of ::getModifiedEntityForPostTesting // can generate whitespace, so we use the same regex pattern here to ensure // the generated value is valid for the sake of the test. // // @see \Drupal\Core\Field\Plugin\Field\FieldType\StringItem::generateSampleValue // @see \Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase::getModifiedEntityForPostTesting // @see \Drupal\workspaces\Entity\Workspace::baseFieldDefinitions $values['id'] = preg_replace('/[^a-z0-9_]/', '', $values['id']); return $values; } }
core/tests/Drupal/Tests/Core/Field/StringItemTest.php 0 → 100644 +50 −0 Original line number Diff line number Diff line <?php namespace Drupal\Tests\Core\Field; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\Plugin\Field\FieldType\StringItem; use Drupal\Tests\UnitTestCase; /** * Defines a test for the StringItem field-type. * * @group Field * @coversDefaultClass \Drupal\Core\Field\Plugin\Field\FieldType\StringItem */ class StringItemTest extends UnitTestCase { /** * Tests generating sample values. * * @param int $max_length * Maximum field length. * * @covers ::generateSampleValue * @dataProvider providerMaxLength */ public function testGenerateSampleValue(int $max_length): void { $definition = $this->prophesize(FieldDefinitionInterface::class); $definition->getSetting('max_length')->willReturn($max_length); $sample_value = StringItem::generateSampleValue($definition->reveal()); $this->assertLessThanOrEqual($max_length, mb_strlen($sample_value['value'])); } /** * Data provider for maximum-lengths. * * @return array * Test cases. */ public function providerMaxLength(): array { return [ '32' => [32], '255' => [255], '500' => [500], '15' => [15], '4' => [4], '64' => [64], ]; } }