substrakt/faktory

WordPress测试驱动开发工厂。

v1.0.2 2023-11-14 14:11 UTC

This package is auto-updated.

Last update: 2024-09-14 16:18:58 UTC


README

Faktory是一个用于为WordPress创建固定数据的库。它可以用来创建文章、页面、自定义文章类型和术语。它在测试驱动开发期间生成固定数据时特别有用。

Faktory附带页面、文章、术语和自定义文章类型的工厂定义。你可以通过创建相应的PHP文件并包含默认属性来定义自己的工厂。

为了创建伪数据,Faktory使用了Rando-PHP

创建工厂

$f = Faktory::create(string $factory = "page", array|object $args = []);

参数

factory

要创建的工厂的名称。大小写必须与工厂文件名的大小写匹配。这是为了避免与Linux等大小写敏感的文件系统发生问题。内置的工厂文件都是小写的。

  • page (默认)
  • post

args

一个数组,用于覆盖默认值。页面和文章工厂的数组传递给wp_insert_post以保存文章到数据库。

$args = [
    "comment_count"     => "",
    "comment_status"    => "",
    "ID"                => 0,
    "meta_input"        => [],
    "menu_order"        => 0,
    "ping_status"       => "",
    "post_author"       => "",
    "post_content"      => "",
    "post_date_gmt"     => $date,
    "post_date"         => $date,
    "post_excerpt"      => "",
    "post_modified_gmt" => $date,
    "post_modified"     => $date,
    "post_name"         => "",
    "post_parent"       => 0,
    "post_password"     => "",
    "post_status"       => "publish",
    "post_title"        => Randomize::chars()->generate(),
    "post_type"         => "page",
    "tax_input"         => [],
];

注意:创建新工厂时,post_type字段将设置为post。插入项的ID将更新以匹配数据库中相应行的ID。

返回值

将返回一个Faktory\Page对象。

示例

创建页面工厂

$f = Faktory::create("page");

创建页面工厂并设置一些属性

$f = Faktory::create("page", ["post_title" => "About me", "post_name" => "about"]);

创建术语工厂

可以使用相同的Faktory::create方法创建术语固定数据。默认工厂是页面,因此请确保第一个参数设置为术语。

args

一个数组,用于覆盖默认值。该数组作为$args参数传递给wp_insert_term以保存术语到数据库。

$args = [
    "alias_of"    => "",
    "description" => "",
    "name"        => Randomize::chars()->generate(),
    "parent"      => 0,
    "slug"        => "",
    "taxonomy"    => "category",
];

返回值

将返回一个Faktory\Term对象。

示例

创建分类术语

$f = Faktory::create("term", ["name" => "Programming"]);

创建标签术语

$f = Faktory::create("term", ["name" => "TDD", "taxonomy" => "post_tag"]);

创建名为“genre”的自定义分类的术语

$f = Faktory::create("term", ["name" => "Computer Science", "taxonomy" => "genre"]);

使用其他工厂使用术语

$term = Faktory::create("term", ["name" => "Programming"]);
$page = Faktory::create("page", [
    "tax_input" => [
        "category" => [$term->ID]
    ]
]);

根据WordPress文档,如果分类是分层的,术语列表必须是一个术语ID数组或逗号分隔的ID字符串。如果分类是非分层的,术语列表可以是一个包含术语名称或别名的数组,或一个逗号分隔的名称或别名字符串。这是因为,在分层分类中,子术语可以具有不同的父术语的相同名称,因此唯一连接它们的方法是使用ID。默认为空。

使用tax_input与对数组中每个自定义分类调用wp_set_post_terms()等效。如果当前用户没有处理分类的能力,则必须使用wp_set_object_terms()

将测试运行的测试用户的用户设置为管理员将允许使用tax_input。以下示例来自Substrakt测试套件的引导文件。

(function() {
    $userId = 1;
    if (empty(get_users())) {
        $userId = wp_create_user('admin', 'password');
    }
    $user = new \WP_User($userId);
    $user->set_role('administrator');
    \wp_set_current_user($userId);
})();

创建不保存的工厂

如果您想创建一个工厂但不想将其保存到数据库中,则可以使用new方法代替create方法。new方法接受与create方法相同的参数。

$f = Faktory::new("page");

如果您最终想要保存Faktory,则可以调用save方法。

$f = Faktory::new("page");
...
$f->save();

将返回的Faktory传递给一个类

Faktory::createFaktory::new将返回一个对象。此对象模拟WordPress帖子对象或术语对象。您可能会发现自己经常将创建的固定值作为参数传递给另一个类。这正是as方法可以派上用场的地方。

$f = Faktory::create("page")->as("TheClassIWant");
# is equal to
$f = new TheClassIWant(Faktory::create("page"));

创建自己的工厂

在您希望的位置添加一个名为factories的目录。在此目录中,您将放置所有自定义工厂文件。如果您创建了一个名为post.php、page.php或term.php的文件,它将覆盖Faktory使用的默认工厂。这是完全可以接受的。

然后您需要使用addDirs方法将目录注册到Faktory中。这应该在您打算使用Faktory之前在引导文件中完成。

示例

Faktory::addDirs([
    "the/full/path/to/your/factories/dir"
]);

您的工厂需要返回一个数据数组。返回的数据取决于要插入数据库的数据类型。目前,Faktory支持帖子类型和术语。要通知Faktory要创建的对象的类型,请使用您的返回数组上的类属性。例如,请参阅默认工厂

类属性

工厂上定义的类属性决定了将返回哪个Faktory对象。目前这可以是Faktory\PostFaktory\PageFaktory\Term。如果没有类属性,则返回一个Faktory\Page

[
...,
"class" => "\Faktory\Page",
];

Faktory\PageFaktory\Post对象在名称上相同,它们的存在是为了帮助区分两种帖子类型。如果您正在创建术语工厂,那么指定术语类将非常重要。

[
...,
"class" => "\Faktory\Term",
];

每个类都有一个save方法,负责在使用了Faktory::create时将数据插入数据库。

默认工厂

页面

# faktory/factories/page.php
$date = date("Y-m-d H:i:s");
return [
    "comment_count"     => "",
    "comment_status"    => "",
    "ID"                => 0,
    "meta_input"        => [],
    "menu_order"        => 0,
    "ping_status"       => "",
    "post_author"       => "",
    "post_content"      => "",
    "post_date_gmt"     => $date,
    "post_date"         => $date,
    "post_excerpt"      => "",
    "post_modified_gmt" => $date,
    "post_modified"     => $date,
    "post_name"         => "",
    "post_parent"       => 0,
    "post_password"     => "",
    "post_status"       => "publish",
    "post_title"        => Randomize::chars()->generate(),
    "post_type"         => "page",
    "tax_input"         => [],
    "class"             => "\Faktory\Page",
];

帖子

# faktory/factories/post.php
$date = date("Y-m-d H:i:s");
return [
    "comment_count"     => "",
    "comment_status"    => "",
    "ID"                => 0,
    "meta_input"        => [],
    "menu_order"        => 0,
    "ping_status"       => "",
    "post_author"       => "",
    "post_content"      => "",
    "post_date_gmt"     => $date,
    "post_date"         => $date,
    "post_excerpt"      => "",
    "post_modified_gmt" => $date,
    "post_modified"     => $date,
    "post_name"         => "",
    "post_parent"       => 0,
    "post_password"     => "",
    "post_status"       => "publish",
    "post_title"        => Randomize::chars()->generate(),
    "post_type"         => "post",
    "tax_input"         => [],
    "class"             => "\Faktory\Post",
];

术语

# faktory/factories/term.php
return [
    "count"            => 0,
    "description"      => "",
    "name"             => Randomize::chars()->generate(),
    "parent"           => 0,
    "post_author"      => "",
    "slug"             => "",
    "taxonomy"         => "category",
    "term_group"       => 0,
    "term_id"          => 0,
    "term_taxonomy_id" => 0,
    "class"            => "\Faktory\Term",
];

简写属性

对于是帖子类型的工厂(即帖子、页面等),可以使用简写作为数组键。以下是显示简写属性将被转换为什么的映射。

Faktory::new("page", ["title" => "Foo", "content" => "Foo bar baz"]);

简写键

以下是一个所有简写键及其映射到的完整键名的列表。

$map = [
    "author"         => "post_author",
    "name"           => "post_name",
    "type"           => "post_type",
    "title"          => "post_title",
    "date"           => "post_date",
    "date_gmt"       => "post_date_gmt",
    "content"        => "post_content",
    "excerpt"        => "post_excerpt",
    "status"         => "post_status",
    "password"       => "post_password",
    "parent"         => "post_parent",
    "modified"       => "post_modified",
    "modified_gmt"   => "post_modified_gmt",
    "meta"           => "meta_input",
];

未定义的工厂

创建未定义的工厂将基于page创建工厂,但将帖子类型设置为请求的类型。

示例

$fixture = Faktory::create('foobar');
$fixture->post_type #=> 'foobar'

这允许您轻松地创建自定义帖子类型的固定值,而无需在工厂目录中创建相应的文件。

高级自定义字段

目前,通过meta_input参数提供对高级自定义字段的支持。

$fixture = Faktory::create('page', [
    'meta_input' => [
        'masthead_image__color'  => '#000',
        '_masthead_image__color' => 'field_5be99d501d261',
    ]
]);

请注意,字段引用(field_5be99d501d261)对于原始值类型不是必需的,但如果您希望ACF返回与其存储不同的值类型,则它是必需的。例如,ACF为post_object字段存储整数,但返回WP_Post实例。

如果您在测试中需要做大量的meta_input工作,请考虑将其移到工厂文件中。

贡献

我们非常希望您帮助Faktory,任何贡献都不会太小。我们特别欢迎那些希望做出第一个开源贡献的人的pull requests。

从Faktory进行Fork并创建一个包含您更改或功能的pull request。当然,如果更改是针对代码的,您还需要包含一些测试。

pull request的想法

  • 用户工厂
  • 附件工厂。WordPress将附件存储为帖子,但需要额外的数据才能使其作为附件工作。
  • 可选返回原生 WP_PostWP_Term 对象,而不是 Faktory 的对象。
  • 文档。永远都不可能有足够的示例。

我们大致遵循 PSR-1PSR-2 编码标准,但我们可能会合并看起来足够接近的任何代码。

许可证

Faktory 在 BSD 3-Clause 许可证 下授权。

Faktory 的发展由 Substrakt 赞助。