Skip to content

Commit

Permalink
Ensure factories can be used with data providers (#462)
Browse files Browse the repository at this point in the history
* Overhauling the generics of factories to return the proper type

* Adding a global constant to make testing easier

* Include some functionality from core

* Ensure that post factories work in data providers

* Switch to get_comment_delimited_block_content() to compile blocks

* Ensure that a new line is added before/after content
  • Loading branch information
srtfisher committed Nov 14, 2023
1 parent ae06416 commit 5c37b70
Show file tree
Hide file tree
Showing 24 changed files with 172 additions and 76 deletions.
1 change: 1 addition & 0 deletions phpcs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
<exclude name="PHPCompatibility.FunctionUse.ArgumentFunctionsReportCurrentValue.NeedsInspection" />
<exclude name="PHPCompatibility.FunctionUse.ArgumentFunctionsReportCurrentValue.Changed" />
<exclude name="Squiz.Commenting.FunctionComment.IncorrectTypeHint" />
<exclude name="Generic.Commenting.DocComment.MissingShort" />
</rule>

<rule ref="Generic.Arrays.DisallowLongArraySyntax" />
Expand Down
2 changes: 1 addition & 1 deletion src/mantle/database/class-factory-service-provider.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ function ( $app, $parameters ) {
$locale = config( 'app.faker_locale', Factory::DEFAULT_LOCALE );

if ( ! isset( static::$fakers[ $locale ] ) ) {
static::$fakers[ $locale ] = Factory::create();
static::$fakers[ $locale ] = Factory::create( $locale );

static::$fakers[ $locale ]->addProvider(
new Faker_Provider( static::$fakers[ $locale ] )
Expand Down
9 changes: 6 additions & 3 deletions src/mantle/database/factory/class-attachment-factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
namespace Mantle\Database\Factory;

use Closure;
use Faker\Generator;
use Mantle\Contracts\Database\Core_Object;
use Mantle\Database\Model\Attachment;
use RuntimeException;
Expand All @@ -19,15 +18,19 @@
/**
* Attachment Factory
*
* @template TObject of \Mantle\Database\Model\Attachment
* @template TModel of \Mantle\Database\Model\Attachment
* @template TObject of \WP_Post
* @template TReturnValue
*
* @extends Factory<TModel, TObject, TReturnValue>
*/
class Attachment_Factory extends Post_Factory {
use Concerns\Generates_Images;

/**
* Model to use when creating objects.
*
* @var class-string
* @var class-string<TModel>
*/
protected string $model = Attachment::class;

Expand Down
8 changes: 6 additions & 2 deletions src/mantle/database/factory/class-blog-factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,17 @@
/**
* Blog Factory
*
* @template TObject of \Mantle\Database\Model\Site
* @template TModel of \Mantle\Database\Model\Site
* @template TObject of \WP_Site
* @template TReturnValue
*
* @extends Factory<TModel, TObject, TReturnValue>
*/
class Blog_Factory extends Factory {
/**
* Model to use when creating objects.
*
* @var class-string
* @var class-string<TModel>
*/
protected string $model = Site::class;

Expand Down
6 changes: 5 additions & 1 deletion src/mantle/database/factory/class-comment-factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@
/**
* Term Factory
*
* @template TObject of \Mantle\Database\Model\Comment
* @template TModel of \Mantle\Database\Model\Comment
* @template TObject of \WP_Comment
* @template TReturnValue
*
* @extends Factory<TModel, TObject, TReturnValue>
*/
class Comment_Factory extends Factory {
/**
Expand Down
65 changes: 46 additions & 19 deletions src/mantle/database/factory/class-factory-container.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@

namespace Mantle\Database\Factory;

use Faker\Generator;
use Mantle\Contracts\Container;
use Mantle\Faker\Faker_Provider;

/**
* Collect all the Database Factories for IDE Support
Expand All @@ -21,79 +23,81 @@ class Factory_Container {
/**
* Attachment Factory
*
* @var Attachment_Factory<\WP_Post|\Mantle\Database\Model\Attachment>
* @var Attachment_Factory<\Mantle\Database\Model\Attachment, \WP_Post, \WP_Post>
*/
public $attachment;
public Attachment_Factory $attachment;

/**
* Blog Factory
*
* @var Blog_Factory<\WP_Site|\Mantle\Database\Model\Site>
* @var Blog_Factory<\Mantle\Database\Model\Site, \WP_Site, \WP_Site>
*/
public $blog;
public Blog_Factory $blog;

/**
* Category Factory
*
* @var Term_Factory<\WP_Term|\Mantle\Database\Model\Term>
* @var Term_Factory<\Mantle\Database\Model\Term, \WP_Term, \WP_Term>
*/
public $category;
public Term_Factory $category;

/**
* Comment Factory
*
* @var Comment_Factory<\WP_Comment>
* @var Comment_Factory<\Mantle\Database\Model\Comment, \WP_Comment, \WP_Comment>
*/
public $comment;
public Comment_Factory $comment;

/**
* Network Factory
*
* @var Network_Factory<\WP_Network>
* @var Network_Factory<null, \WP_Network>
*/
public $network;
public Network_Factory $network;

/**
* Page Factory
*
* @var Post_Factory<\WP_Post|\Mantle\Database\Model\Post>
* @var Post_Factory<\Mantle\Database\Model\Post, \WP_Post, \WP_Post>
*/
public $page;

/**
* Post Factory
*
* @var Post_Factory<\WP_Post|\Mantle\Database\Model\Post>
* @var Post_Factory<\Mantle\Database\Model\Post, \WP_Post, \WP_Post>
*/
public $post;
public Post_Factory $post;

/**
* Tag Factory
*
* @var Term_Factory<\WP_Term|\Mantle\Database\Model\Term>
* @var Term_Factory<\Mantle\Database\Model\Term, \WP_Term, \WP_Term>
*/
public $tag;
public Term_Factory $tag;

/**
* Term Factory (alias for Tag Factory).
*
* @var Term_Factory<\WP_Term|\Mantle\Database\Model\Term>
* @var Term_Factory<\Mantle\Database\Model\Term, \WP_Term, \WP_Term>
*/
public $term;
public Term_Factory $term;

/**
* User Factory
*
* @var User_Factory<\WP_User|\Mantle\Database\Model\User>
* @var User_Factory<\Mantle\Database\Model\User, \WP_User, \WP_User>
*/
public $user;
public User_Factory $user;

/**
* Constructor.
*
* @param Container $container Container instance.
*/
public function __construct( Container $container ) {
$this->setup_faker( $container );

$this->attachment = $container->make( Attachment_Factory::class );
$this->category = $container->make( Term_Factory::class, [ 'taxonomy' => 'category' ] );
$this->comment = $container->make( Comment_Factory::class );
Expand All @@ -108,4 +112,27 @@ public function __construct( Container $container ) {
$this->network = $container->make( Network_Factory::class );
}
}

/**
* Set up the Faker instance in the container.
*
* Primarily used when faker/factory is called from a data provider and the
* application hasn't been setup yet.
*
* @param Container $container Container instance.
*/
protected function setup_faker( Container $container ): void {
$container->singleton_if(
Generator::class,
function () {
$generator = \Faker\Factory::create();

$generator->unique();

$generator->addProvider( new Faker_Provider( $generator ) );

return $generator;
},
);
}
}
20 changes: 12 additions & 8 deletions src/mantle/database/factory/class-factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@
/**
* Base Factory
*
* @template TObject of \Mantle\Database\Model\Model
* @template TModel of \Mantle\Database\Model\Model
* @template TObject
* @template TReturnValue
*
* @method \Mantle\Database\Factory\Fluent_Factory<TObject> count(int $count)
* @method \Mantle\Database\Factory\Fluent_Factory<TModel, TObject, TReturnValue> count(int $count)
*/
abstract class Factory {
use Concerns\Resolves_Factories,
Expand Down Expand Up @@ -74,7 +76,7 @@ abstract public function definition(): array;
* Retrieves an object by ID.
*
* @param int $object_id The object ID.
* @return mixed
* @return TModel|TObject|null
*/
abstract public function get_object_by_id( int $object_id );

Expand All @@ -91,7 +93,7 @@ public function create( array $args = [] ): mixed {
/**
* Generate models from the factory.
*
* @return static
* @return static<TModel, TObject, TModel>
*/
public function as_models() {
return tap(
Expand All @@ -103,7 +105,7 @@ public function as_models() {
/**
* Generate core WordPress objects from the factory.
*
* @return static
* @return static<TModel, TObject, TObject>
*/
public function as_objects() {
return tap(
Expand Down Expand Up @@ -145,8 +147,10 @@ public function without_middleware() {
*
* @throws \InvalidArgumentException If the model does not extend from the base model class.
*
* @param class-string<TObject> $model The model to use.
* @return static
* @template TNewModel of \Mantle\Database\Model\Model
*
* @param class-string<TNewModel> $model The model to use.
* @return static<TNewModel, TObject, TReturnValue>
*/
public function with_model( string $model ) {
// Validate that model extends from the base model class.
Expand Down Expand Up @@ -210,7 +214,7 @@ public function create_many( int $count, array $args = [] ) {
* Creates an object and returns its object.
*
* @param array $args Optional. The arguments for the object to create. Default is empty array.
* @return TObject The created object.
* @return TReturnValue The created object.
*/
public function create_and_get( array $args = [] ) {
return $this->get_object_by_id( $this->create( $args ) );
Expand Down
12 changes: 8 additions & 4 deletions src/mantle/database/factory/class-fluent-factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@
* Extends upon the factory that is included with Mantle (one that is designed
* to mirror WordPress) and builds upon it to provide a fluent interface.
*
* @template TObject of \Mantle\Database\Model\Model
* @template TModel of \Mantle\Database\Model\Model
* @template TObject
* @template TReturnValue
*
* @extends Factory<TModel, TObject, TReturnValue>
*/
class Fluent_Factory extends Factory {
/**
Expand Down Expand Up @@ -57,7 +61,7 @@ public function count( int $count ): static {
* Create one or multiple objects and return the IDs.
*
* @param array $args Arguments to pass to the factory.
* @return \Mantle\Support\Collection<int, mixed>|mixed
* @return \Mantle\Support\Collection<int, TReturnValue>|mixed
*/
public function create( array $args = [] ): mixed {
if ( 1 === $this->count ) {
Expand All @@ -71,7 +75,7 @@ public function create( array $args = [] ): mixed {
* Create one or multiple objects and return the objects.
*
* @param array $args Arguments to pass to the factory.
* @return \Mantle\Support\Collection<int, TObject>|TObject
* @return \Mantle\Support\Collection<int, TReturnValue>|TReturnValue
*/
public function create_and_get( array $args = [] ): mixed {
if ( 1 === $this->count ) {
Expand All @@ -98,7 +102,7 @@ public function definition(): array {
* Retrieves an object by ID.
*
* @param mixed $object_id The object ID.
* @return TObject
* @return TReturnValue
*/
public function get_object_by_id( mixed $object_id ): mixed {
return $this->factory->get_object_by_id( $object_id );
Expand Down
8 changes: 5 additions & 3 deletions src/mantle/database/factory/class-network-factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@

namespace Mantle\Database\Factory;

use Faker\Generator;

/**
* Network Factory
*
* @template TObject
* @template TModel
* @template TObject of \WP_Network
* @template TReturnValue
*
* @extends Factory<TModel, TObject, TReturnValue>
*/
class Network_Factory extends Factory {
/**
Expand Down
11 changes: 8 additions & 3 deletions src/mantle/database/factory/class-post-factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,19 @@
/**
* Post Factory
*
* @template TObject of \Mantle\Database\Model\Post
* @template TModel of \Mantle\Database\Model\Post
* @template TObject
* @template TReturnValue
*
* @extends Factory<TModel, TObject, TReturnValue>
*/
class Post_Factory extends Factory {
use Concerns\With_Meta;

/**
* Model to use when creating objects.
*
* @var class-string
* @var class-string<TModel>
*/
protected string $model = Post::class;

Expand All @@ -44,7 +48,7 @@ public function __construct( Generator $faker, public string $post_type = 'post'
/**
* Create a new factory instance to create posts with a set of terms.
*
* @param array<int, \WP_Term|int|string>|\WP_Term|int|string ...$terms Terms to assign to the post.
* @param array<int|string, \WP_Term|int|string|array<string, mixed>>|\WP_Term|int|string ...$terms Terms to assign to the post.
* @return static
*/
public function with_terms( ...$terms ): static {
Expand Down Expand Up @@ -172,6 +176,7 @@ public function create_ordered_set(
*
* @param int $object_id The object ID.
* @return Post|WP_Post|null
* @phpstan-return TModel|TObject|null
*/
public function get_object_by_id( int $object_id ) {
return $this->as_models
Expand Down
Loading

0 comments on commit 5c37b70

Please sign in to comment.