diff --git a/src/Styles/AbstractStyle.php b/src/Styles/AbstractStyle.php index 918a6f9..fbe056c 100644 --- a/src/Styles/AbstractStyle.php +++ b/src/Styles/AbstractStyle.php @@ -4,7 +4,6 @@ namespace Respect\Data\Styles; -use function preg_match; use function preg_quote; use function preg_replace; use function preg_replace_callback; @@ -27,34 +26,4 @@ protected function separatorToCamelCase(string $name, string $separator = '_'): $name, ); } - - protected function pluralToSingular(string $name): string - { - $replacements = [ - '/^(.+)ies$/' => '$1y', - '/^(.+)s$/' => '$1', - ]; - foreach ($replacements as $key => $value) { - if (preg_match($key, $name)) { - return (string) preg_replace($key, $value, $name); - } - } - - return $name; - } - - protected function singularToPlural(string $name): string - { - $replacements = [ - '/^(.+)y$/' => '$1ies', - '/^(.+)([^s])$/' => '$1$2s', - ]; - foreach ($replacements as $key => $value) { - if (preg_match($key, $name)) { - return (string) preg_replace($key, $value, $name); - } - } - - return $name; - } } diff --git a/src/Styles/CakePHP.php b/src/Styles/CakePHP.php deleted file mode 100644 index 54ffbf2..0000000 --- a/src/Styles/CakePHP.php +++ /dev/null @@ -1,49 +0,0 @@ -camelCaseToSeparator($name, '_'))); - $pieces[] = $this->singularToPlural(array_pop($pieces)); - - return implode('_', $pieces); - } - - public function remoteIdentifier(string $name): string - { - return $this->pluralToSingular($name) . '_id'; - } - - public function remoteFromIdentifier(string $name): string|null - { - return $this->isRemoteIdentifier($name) ? $this->singularToPlural(substr($name, 0, -3)) : null; - } - - public function styledName(string $name): string - { - $pieces = explode('_', $name); - $pieces[] = $this->pluralToSingular(array_pop($pieces)); - - return ucfirst($this->separatorToCamelCase(implode('_', $pieces), '_')); - } - - public function composed(string $left, string $right): string - { - $pieces = explode('_', $right); - $pieces[] = $this->singularToPlural(array_pop($pieces)); - - return $left . '_' . implode('_', $pieces); - } -} diff --git a/src/Styles/NorthWind.php b/src/Styles/NorthWind.php deleted file mode 100644 index e7c3982..0000000 --- a/src/Styles/NorthWind.php +++ /dev/null @@ -1,67 +0,0 @@ -pluralToSingular($left) . $right; - } - - public function identifier(string $name): string - { - return $this->pluralToSingular($name) . 'ID'; - } - - public function remoteIdentifier(string $name): string - { - return $this->pluralToSingular($name) . 'ID'; - } - - public function isRemoteIdentifier(string $name): bool - { - return strlen($name) - 2 === strripos($name, 'ID'); - } - - public function remoteFromIdentifier(string $name): string|null - { - return $this->isRemoteIdentifier($name) ? $this->singularToPlural(substr($name, 0, -2)) : null; - } - - public function relationProperty(string $field): string|null - { - return $this->isRemoteIdentifier($field) ? substr($field, 0, -2) : null; - } - - public function isRelationProperty(string $name): bool - { - return !$this->isRemoteIdentifier($name) && $this->isRemoteIdentifier($name . 'ID'); - } -} diff --git a/src/Styles/Plural.php b/src/Styles/Plural.php index 603ed15..5ebde4a 100644 --- a/src/Styles/Plural.php +++ b/src/Styles/Plural.php @@ -7,6 +7,8 @@ use function array_map; use function explode; use function implode; +use function preg_match; +use function preg_replace; use function strtolower; use function substr; use function ucfirst; @@ -52,4 +54,34 @@ public function composed(string $left, string $right): string { return $this->singularToPlural($left) . '_' . $this->singularToPlural($right); } + + private function pluralToSingular(string $name): string + { + $replacements = [ + '/^(.+)ies$/' => '$1y', + '/^(.+)s$/' => '$1', + ]; + foreach ($replacements as $key => $value) { + if (preg_match($key, $name)) { + return (string) preg_replace($key, $value, $name); + } + } + + return $name; + } + + private function singularToPlural(string $name): string + { + $replacements = [ + '/^(.+)y$/' => '$1ies', + '/^(.+)([^s])$/' => '$1$2s', + ]; + foreach ($replacements as $key => $value) { + if (preg_match($key, $name)) { + return (string) preg_replace($key, $value, $name); + } + } + + return $name; + } } diff --git a/src/Styles/Sakila.php b/src/Styles/Sakila.php deleted file mode 100644 index d780cfe..0000000 --- a/src/Styles/Sakila.php +++ /dev/null @@ -1,13 +0,0 @@ -remoteIdentifier($name); - } -} diff --git a/tests/AbstractMapperTest.php b/tests/AbstractMapperTest.php index 9802c47..8b0f426 100644 --- a/tests/AbstractMapperTest.php +++ b/tests/AbstractMapperTest.php @@ -10,7 +10,7 @@ use ReflectionObject; use Respect\Data\Collections\Collection; use Respect\Data\Hydrators\Nested; -use Respect\Data\Styles\CakePHP; +use Respect\Data\Styles\Plural; use Respect\Data\Styles\Standard; use SplObjectStorage; @@ -92,7 +92,7 @@ public function getStyleShouldReturnSameInstanceOnSubsequentCalls(): void #[Test] public function styleShouldComeFromEntityFactory(): void { - $style = new CakePHP(); + $style = new Plural(); $mapper = new class (new Nested(new EntityFactory(style: $style))) extends AbstractMapper { public function flush(): void { diff --git a/tests/EntityFactoryTest.php b/tests/EntityFactoryTest.php index 1ae02f6..239b180 100644 --- a/tests/EntityFactoryTest.php +++ b/tests/EntityFactoryTest.php @@ -129,7 +129,7 @@ public function createAndCopySkipsUninitializedSourceProperties(): void #[Test] public function getStyleReturnsConfiguredStyle(): void { - $style = new Styles\CakePHP(); + $style = new Styles\Plural(); $factory = new EntityFactory(style: $style); $this->assertSame($style, $factory->style); } diff --git a/tests/Styles/AbstractStyleTest.php b/tests/Styles/AbstractStyleTest.php index a589a97..059b98a 100644 --- a/tests/Styles/AbstractStyleTest.php +++ b/tests/Styles/AbstractStyleTest.php @@ -74,18 +74,6 @@ public function isRelationProperty(string $name): bool }; } - /** @return array */ - public static function singularPluralProvider(): array - { - return [ - ['post', 'posts'], - ['comment', 'comments'], - ['category', 'categories'], - ['tag', 'tags'], - ['entity', 'entities'], - ]; - } - /** @return array */ public static function camelCaseToSeparatorProvider(): array { @@ -96,16 +84,6 @@ public static function camelCaseToSeparatorProvider(): array ]; } - #[DataProvider('singularPluralProvider')] - public function testPluralToSingularAndViceVersa(string $singular, string $plural): void - { - $pluralToSingular = new ReflectionMethod($this->style, 'pluralToSingular'); - $this->assertEquals($singular, $pluralToSingular->invoke($this->style, $plural)); - - $singularToPlural = new ReflectionMethod($this->style, 'singularToPlural'); - $this->assertEquals($plural, $singularToPlural->invoke($this->style, $singular)); - } - #[DataProvider('camelCaseToSeparatorProvider')] public function testCamelCaseToSeparatorAndViceVersa( string $separator, @@ -124,16 +102,4 @@ public function testCamelCaseToSeparatorAndViceVersa( $separatorToCamelCaseMethod->invoke($this->style, $separated, $separator), ); } - - public function testPluralToSingularReturnsUnchangedWhenNoMatch(): void - { - $method = new ReflectionMethod($this->style, 'pluralToSingular'); - $this->assertEquals('fox', $method->invoke($this->style, 'fox')); - } - - public function testSingularToPluralReturnsUnchangedWhenNoMatch(): void - { - $method = new ReflectionMethod($this->style, 'singularToPlural'); - $this->assertEquals('news', $method->invoke($this->style, 'news')); - } } diff --git a/tests/Styles/CakePHP/Author.php b/tests/Styles/CakePHP/Author.php deleted file mode 100644 index 1e90a4a..0000000 --- a/tests/Styles/CakePHP/Author.php +++ /dev/null @@ -1,12 +0,0 @@ -style = new CakePHP(); - $this->mapper = new InMemoryMapper(new Nested(new EntityFactory( - style: $this->style, - entityNamespace: __NAMESPACE__ . '\\', - ))); - - $this->mapper->seed('posts', [ - ['id' => 5, 'title' => 'Post Title', 'text' => 'Post Text', 'author_id' => 1], - ]); - $this->mapper->seed('authors', [ - ['id' => 1, 'name' => 'Author 1'], - ]); - $this->mapper->seed('comments', [ - ['id' => 7, 'post_id' => 5, 'text' => 'Comment Text'], - ['id' => 8, 'post_id' => 4, 'text' => 'Comment Text 2'], - ]); - $this->mapper->seed('categories', [ - ['id' => 2, 'name' => 'Sample Category', 'category_id' => null], - ['id' => 3, 'name' => 'NONON', 'category_id' => null], - ]); - $this->mapper->seed('post_categories', [ - ['id' => 66, 'post_id' => 5, 'category_id' => 2], - ]); - } - - #[Test] - public function fetchAndPersistRoundTrip(): void - { - $entity = $this->mapper->fetch($this->mapper->posts()); - $this->assertIsObject($entity); - $this->assertEquals('Post Title', $this->mapper->entityFactory->get($entity, 'title')); - } -} diff --git a/tests/Styles/CakePHP/Category.php b/tests/Styles/CakePHP/Category.php deleted file mode 100644 index fb8fcb1..0000000 --- a/tests/Styles/CakePHP/Category.php +++ /dev/null @@ -1,14 +0,0 @@ -style = new CakePHP(); - } - - /** @return array> */ - public static function tableEntityProvider(): array - { - return [ - ['posts', 'Post'], - ['comments', 'Comment'], - ['categories', 'Category'], - ['post_categories', 'PostCategory'], - ['post_tags', 'PostTag'], - ]; - } - - /** @return array> */ - public static function manyToManyTableProvider(): array - { - return [ - ['post', 'category', 'post_categories'], - ['user', 'group', 'user_groups'], - ['group', 'profile', 'group_profiles'], - ]; - } - - /** @return array> */ - public static function columnsPropertyProvider(): array - { - return [ - ['id'], - ['text'], - ['name'], - ['content'], - ['created'], - ]; - } - - /** @return array> */ - public static function foreignProvider(): array - { - return [ - ['posts', 'post_id'], - ['authors', 'author_id'], - ['tags', 'tag_id'], - ['users', 'user_id'], - ]; - } - - #[DataProvider('tableEntityProvider')] - public function testTableAndEntitiesMethods(string $table, string $entity): void - { - $this->assertEquals($entity, $this->style->styledName($table)); - $this->assertEquals($table, $this->style->realName($entity)); - $this->assertEquals('id', $this->style->identifier($table)); - } - - #[DataProvider('columnsPropertyProvider')] - public function testColumnsAndPropertiesMethods(string $column): void - { - $this->assertEquals($column, $this->style->styledProperty($column)); - $this->assertEquals($column, $this->style->realProperty($column)); - $this->assertFalse($this->style->isRemoteIdentifier($column)); - $this->assertNull($this->style->remoteFromIdentifier($column)); - } - - #[DataProvider('manyToManyTableProvider')] - public function testTableFromLeftRightTable(string $left, string $right, string $table): void - { - $this->assertEquals($table, $this->style->composed($left, $right)); - } - - #[DataProvider('foreignProvider')] - public function testForeign(string $table, string $foreign): void - { - $this->assertTrue($this->style->isRemoteIdentifier($foreign)); - $this->assertEquals($table, $this->style->remoteFromIdentifier($foreign)); - $this->assertEquals($foreign, $this->style->remoteIdentifier($table)); - } -} diff --git a/tests/Styles/NorthWind/Authors.php b/tests/Styles/NorthWind/Authors.php deleted file mode 100644 index bbea1d9..0000000 --- a/tests/Styles/NorthWind/Authors.php +++ /dev/null @@ -1,12 +0,0 @@ -style = new NorthWind(); - $this->mapper = new InMemoryMapper(new Nested(new EntityFactory( - style: $this->style, - entityNamespace: __NAMESPACE__ . '\\', - ))); - - $this->mapper->seed('Posts', [ - ['PostID' => 5, 'Title' => 'Post Title', 'Text' => 'Post Text', 'AuthorID' => 1], - ]); - $this->mapper->seed('Authors', [ - ['AuthorID' => 1, 'Name' => 'Author 1'], - ]); - $this->mapper->seed('Comments', [ - ['CommentID' => 7, 'PostID' => 5, 'Text' => 'Comment Text'], - ['CommentID' => 8, 'PostID' => 4, 'Text' => 'Comment Text 2'], - ]); - $this->mapper->seed('Categories', [ - ['CategoryID' => 2, 'Name' => 'Sample Category', 'Description' => 'Category description'], - ['CategoryID' => 3, 'Name' => 'NONON', 'Description' => null], - ]); - $this->mapper->seed('PostCategories', [ - ['PostCategoryID' => 66, 'PostID' => 5, 'CategoryID' => 2], - ]); - } - - #[Test] - public function fetchAndPersistRoundTrip(): void - { - $entity = $this->mapper->fetch($this->mapper->Posts()); - $this->assertIsObject($entity); - $this->assertEquals('Post Title', $this->mapper->entityFactory->get($entity, 'Title')); - } -} diff --git a/tests/Styles/NorthWind/PostCategories.php b/tests/Styles/NorthWind/PostCategories.php deleted file mode 100644 index 14f6b1b..0000000 --- a/tests/Styles/NorthWind/PostCategories.php +++ /dev/null @@ -1,14 +0,0 @@ -style = new NorthWind(); - } - - /** @return array> */ - public static function tableEntityProvider(): array - { - return [ - ['Posts', 'Posts'], - ['Comments', 'Comments'], - ['Categories', 'Categories'], - ['PostCategories', 'PostCategories'], - ['PostTags', 'PostTags'], - ]; - } - - /** @return array> */ - public static function manyToManyTableProvider(): array - { - return [ - ['Posts', 'Categories', 'PostCategories'], - ['Users', 'Groups', 'UserGroups'], - ['Groups', 'Profiles', 'GroupProfiles'], - ]; - } - - /** @return array> */ - public static function columnsPropertyProvider(): array - { - return [ - ['Text'], - ['Name'], - ['Content'], - ['Created'], - ['Updated'], - ]; - } - - /** @return array> */ - public static function keyProvider(): array - { - return [ - ['Posts', 'PostID'], - ['Authors', 'AuthorID'], - ['Tags', 'TagID'], - ['Users', 'UserID'], - ]; - } - - #[DataProvider('tableEntityProvider')] - public function testTableAndEntitiesMethods(string $table, string $entity): void - { - $this->assertEquals($entity, $this->style->styledName($table)); - $this->assertEquals($table, $this->style->realName($entity)); - } - - #[DataProvider('columnsPropertyProvider')] - public function testColumnsAndPropertiesMethods(string $column): void - { - $this->assertEquals($column, $this->style->styledProperty($column)); - $this->assertEquals($column, $this->style->realProperty($column)); - $this->assertFalse($this->style->isRemoteIdentifier($column)); - $this->assertNull($this->style->remoteFromIdentifier($column)); - } - - #[DataProvider('manyToManyTableProvider')] - public function testTableFromLeftRightTable(string $left, string $right, string $table): void - { - $this->assertEquals($table, $this->style->composed($left, $right)); - } - - #[DataProvider('keyProvider')] - public function testKeys(string $table, string $foreign): void - { - $this->assertTrue($this->style->isRemoteIdentifier($foreign)); - $this->assertEquals($table, $this->style->remoteFromIdentifier($foreign)); - $this->assertEquals($foreign, $this->style->identifier($table)); - $this->assertEquals($foreign, $this->style->remoteIdentifier($table)); - } - - /** @return array> */ - public static function relationProvider(): array - { - return [ - ['Post', 'PostID'], - ['Author', 'AuthorID'], - ['Tag', 'TagID'], - ['User', 'UserID'], - ]; - } - - #[DataProvider('relationProvider')] - public function testRelationProperty(string $relation, string $foreign): void - { - $this->assertEquals($relation, $this->style->relationProperty($foreign)); - $this->assertNull($this->style->relationProperty($relation)); - } - - #[DataProvider('relationProvider')] - public function testIsRelationProperty(string $relation, string $foreign): void - { - $this->assertTrue($this->style->isRelationProperty($relation)); - $this->assertFalse($this->style->isRelationProperty($foreign)); - } - - #[DataProvider('relationProvider')] - public function testForeignKeyIsNotRelationProperty(string $relation, string $foreign): void - { - $this->assertFalse($this->style->isRelationProperty($foreign)); - } -} diff --git a/tests/Styles/Sakila/Author.php b/tests/Styles/Sakila/Author.php deleted file mode 100644 index 992f833..0000000 --- a/tests/Styles/Sakila/Author.php +++ /dev/null @@ -1,12 +0,0 @@ -style = new Sakila(); - $this->mapper = new InMemoryMapper(new Nested(new EntityFactory( - style: $this->style, - entityNamespace: __NAMESPACE__ . '\\', - ))); - - $this->mapper->seed('post', [ - ['post_id' => 5, 'title' => 'Post Title', 'text' => 'Post Text', 'author_id' => 1], - ]); - $this->mapper->seed('author', [ - ['author_id' => 1, 'name' => 'Author 1'], - ]); - $this->mapper->seed('comment', [ - ['comment_id' => 7, 'post_id' => 5, 'text' => 'Comment Text'], - ['comment_id' => 8, 'post_id' => 4, 'text' => 'Comment Text 2'], - ]); - $this->mapper->seed('category', [ - ['category_id' => 2, 'name' => 'Sample Category', 'content' => null], - ['category_id' => 3, 'name' => 'NONON', 'content' => null], - ]); - $this->mapper->seed('post_category', [ - ['post_category_id' => 66, 'post_id' => 5, 'category_id' => 2], - ]); - } - - #[Test] - public function fetchAndPersistRoundTrip(): void - { - $entity = $this->mapper->fetch($this->mapper->post()); - $this->assertIsObject($entity); - $this->assertEquals('Post Title', $this->mapper->entityFactory->get($entity, 'title')); - } -} diff --git a/tests/Styles/SakilaTest.php b/tests/Styles/SakilaTest.php deleted file mode 100644 index 7df68a9..0000000 --- a/tests/Styles/SakilaTest.php +++ /dev/null @@ -1,96 +0,0 @@ -style = new Sakila(); - } - - /** @return array> */ - public static function tableEntityProvider(): array - { - return [ - ['post', 'Post'], - ['comment', 'Comment'], - ['category', 'Category'], - ['post_category', 'PostCategory'], - ['post_tag', 'PostTag'], - ]; - } - - /** @return array> */ - public static function manyToManyTableProvider(): array - { - return [ - ['post', 'category', 'post_category'], - ['user', 'group', 'user_group'], - ['group', 'profile', 'group_profile'], - ]; - } - - /** @return array> */ - public static function columnsPropertyProvider(): array - { - return [ - ['id'], - ['text'], - ['name'], - ['content'], - ['created'], - ]; - } - - /** @return array> */ - public static function keyProvider(): array - { - return [ - ['post', 'post_id'], - ['author', 'author_id'], - ['tag', 'tag_id'], - ['user', 'user_id'], - ]; - } - - #[DataProvider('tableEntityProvider')] - public function testTableAndEntitiesMethods(string $table, string $entity): void - { - $this->assertEquals($entity, $this->style->styledName($table)); - $this->assertEquals($table, $this->style->realName($entity)); - } - - #[DataProvider('columnsPropertyProvider')] - public function testColumnsAndPropertiesMethods(string $column): void - { - $this->assertEquals($column, $this->style->styledProperty($column)); - $this->assertEquals($column, $this->style->realProperty($column)); - $this->assertFalse($this->style->isRemoteIdentifier($column)); - $this->assertNull($this->style->remoteFromIdentifier($column)); - } - - #[DataProvider('manyToManyTableProvider')] - public function testTableFromLeftRightTable(string $left, string $right, string $table): void - { - $this->assertEquals($table, $this->style->composed($left, $right)); - } - - #[DataProvider('keyProvider')] - public function testForeign(string $table, string $key): void - { - $this->assertTrue($this->style->isRemoteIdentifier($key)); - $this->assertEquals($table, $this->style->remoteFromIdentifier($key)); - $this->assertEquals($key, $this->style->identifier($table)); - $this->assertEquals($key, $this->style->remoteIdentifier($table)); - } -}