post = new WP_UnitTest_Factory_For_Post( $this ); $this->attachment = new WP_UnitTest_Factory_For_Attachment( $this ); $this->comment = new WP_UnitTest_Factory_For_Comment( $this ); $this->user = new WP_UnitTest_Factory_For_User( $this ); $this->term = new WP_UnitTest_Factory_For_Term( $this ); $this->category = new WP_UnitTest_Factory_For_Term( $this, 'category' ); $this->tag = new WP_UnitTest_Factory_For_Term( $this, 'post_tag' ); if ( is_multisite() ) $this->blog = new WP_UnitTest_Factory_For_Blog( $this ); } } class WP_UnitTest_Factory_For_Post extends WP_UnitTest_Factory_For_Thing { function __construct( $factory = null ) { parent::__construct( $factory ); $this->default_generation_definitions = array( 'post_status' => 'publish', 'post_title' => new WP_UnitTest_Generator_Sequence( 'Post title %s' ), 'post_content' => new WP_UnitTest_Generator_Sequence( 'Post content %s' ), 'post_excerpt' => new WP_UnitTest_Generator_Sequence( 'Post excerpt %s' ), 'post_type' => 'post' ); } function create_object( $args ) { return wp_insert_post( $args ); } function update_object( $post_id, $fields ) { $fields['ID'] = $post_id; return wp_update_post( $fields ); } function get_object_by_id( $post_id ) { return get_post( $post_id ); } } class WP_UnitTest_Factory_For_Attachment extends WP_UnitTest_Factory_For_Post { function create_object( $file, $parent = 0, $args = array() ) { return wp_insert_attachment( $args, $file, $parent ); } } class WP_UnitTest_Factory_For_User extends WP_UnitTest_Factory_For_Thing { function __construct( $factory = null ) { parent::__construct( $factory ); $this->default_generation_definitions = array( 'user_login' => new WP_UnitTest_Generator_Sequence( 'User %s' ), 'user_pass' => 'password', 'user_email' => new WP_UnitTest_Generator_Sequence( 'user_%s@example.org' ), ); } function create_object( $args ) { return wp_insert_user( $args ); } function update_object( $user_id, $fields ) { $fields['ID'] = $user_id; return wp_update_user( $fields ); } function get_object_by_id( $user_id ) { return new WP_User( $user_id ); } } class WP_UnitTest_Factory_For_Comment extends WP_UnitTest_Factory_For_Thing { function __construct( $factory = null ) { parent::__construct( $factory ); $this->default_generation_definitions = array( 'comment_author' => new WP_UnitTest_Generator_Sequence( 'Commenter %s' ), 'comment_author_url' => new WP_UnitTest_Generator_Sequence( 'http://example.com/%s/' ), 'comment_approved' => 1, ); } function create_object( $args ) { return wp_insert_comment( $this->addslashes_deep( $args ) ); } function update_object( $comment_id, $fields ) { $fields['comment_ID'] = $comment_id; return wp_update_comment( $this->addslashes_deep( $fields ) ); } function create_post_comments( $post_id, $count = 1, $args = array(), $generation_definitions = null ) { $args['comment_post_ID'] = $post_id; return $this->create_many( $count, $args, $generation_definitions ); } function get_object_by_id( $comment_id ) { return get_comment( $comment_id ); } } class WP_UnitTest_Factory_For_Blog extends WP_UnitTest_Factory_For_Thing { function __construct( $factory = null ) { global $current_site, $base; parent::__construct( $factory ); $this->default_generation_definitions = array( 'domain' => $current_site->domain, 'path' => new WP_UnitTest_Generator_Sequence( $base . 'testpath%s' ), 'title' => new WP_UnitTest_Generator_Sequence( 'Site %s' ), 'site_id' => $current_site->id, ); } function create_object( $args ) { $meta = isset( $args['meta'] ) ? $args['meta'] : array(); $user_id = isset( $args['user_id'] ) ? $args['user_id'] : get_current_user_id(); return wpmu_create_blog( $args['domain'], $args['path'], $args['title'], $user_id, $meta, $args['site_id'] ); } function update_object( $blog_id, $fields ) {} function get_object_by_id( $blog_id ) { return get_blog_details( $blog_id, false ); } } class WP_UnitTest_Factory_For_Term extends WP_UnitTest_Factory_For_Thing { private $taxonomy; const DEFAULT_TAXONOMY = 'post_tag'; function __construct( $factory = null, $taxonomy = null ) { parent::__construct( $factory ); $this->taxonomy = $taxonomy ? $taxonomy : self::DEFAULT_TAXONOMY; $this->default_generation_definitions = array( 'name' => new WP_UnitTest_Generator_Sequence( 'Term %s' ), 'taxonomy' => $this->taxonomy, 'description' => new WP_UnitTest_Generator_Sequence( 'Term description %s' ), ); } function create_object( $args ) { $args = array_merge( array( 'taxonomy' => $this->taxonomy ), $args ); $term_id_pair = wp_insert_term( $args['name'], $args['taxonomy'], $args ); if ( is_wp_error( $term_id_pair ) ) return $term_id_pair; return $term_id_pair['term_id']; } function update_object( $term, $fields ) { $fields = array_merge( array( 'taxonomy' => $this->taxonomy ), $fields ); if ( is_object( $term ) ) $taxonomy = $term->taxonomy; $term_id_pair = wp_update_term( $term, $taxonomy, $fields ); return $term_id_pair['term_id']; } function add_post_terms( $post_id, $terms, $taxonomy, $append = true ) { return wp_set_post_terms( $post_id, $terms, $taxonomy, $append ); } function get_object_by_id( $term_id ) { return get_term( $term_id, $this->taxonomy ); } } abstract class WP_UnitTest_Factory_For_Thing { var $default_generation_definitions; var $factory; /** * Creates a new factory, which will create objects of a specific Thing * * @param object $factory Global factory that can be used to create other objects on the system * @param array $default_generation_definitions Defines what default values should the properties of the object have. The default values * can be generators -- an object with next() method. There are some default generators: {@link WP_UnitTest_Generator_Sequence}, * {@link WP_UnitTest_Generator_Locale_Name}, {@link WP_UnitTest_Factory_Callback_After_Create}. */ function __construct( $factory, $default_generation_definitions = array() ) { $this->factory = $factory; $this->default_generation_definitions = $default_generation_definitions; } abstract function create_object( $args ); abstract function update_object( $object, $fields ); function create( $args = array(), $generation_definitions = null ) { if ( is_null( $generation_definitions ) ) $generation_definitions = $this->default_generation_definitions; $generated_args = $this->generate_args( $args, $generation_definitions, $callbacks ); $created = $this->create_object( $generated_args ); if ( !$created || is_wp_error( $created ) ) return $created; if ( $callbacks ) { $updated_fields = $this->apply_callbacks( $callbacks, $created ); $save_result = $this->update_object( $created, $updated_fields ); if ( !$save_result || is_wp_error( $save_result ) ) return $save_result; } return $created; } function create_and_get( $args = array(), $generation_definitions = null ) { $object_id = $this->create( $args, $generation_definitions ); return $this->get_object_by_id( $object_id ); } abstract function get_object_by_id( $object_id ); function create_many( $count, $args = array(), $generation_definitions = null ) { $results = array(); for ( $i = 0; $i < $count; $i++ ) { $results[] = $this->create( $args, $generation_definitions ); } return $results; } function generate_args( $args = array(), $generation_definitions = null, &$callbacks = null ) { $callbacks = array(); if ( is_null( $generation_definitions ) ) $generation_definitions = $this->default_generation_definitions; foreach( array_keys( $generation_definitions ) as $field_name ) { if ( !isset( $args[$field_name] ) ) { $generator = $generation_definitions[$field_name]; if ( is_scalar( $generator ) ) $args[$field_name] = $generator; elseif ( is_object( $generator ) && method_exists( $generator, 'call' ) ) { $callbacks[$field_name] = $generator; } elseif ( is_object( $generator ) ) $args[$field_name] = $generator->next(); else return new WP_Error( 'invalid_argument', 'Factory default value should be either a scalar or an generator object.' ); } } return $args; } function apply_callbacks( $callbacks, $created ) { $updated_fields = array(); foreach( $callbacks as $field_name => $generator ) { $updated_fields[$field_name] = $generator->call( $created ); } return $updated_fields; } function callback( $function ) { return new WP_UnitTest_Factory_Callback_After_Create( $function ); } function addslashes_deep($value) { if ( is_array( $value ) ) { $value = array_map( array( $this, 'addslashes_deep' ), $value ); } elseif ( is_object( $value ) ) { $vars = get_object_vars( $value ); foreach ($vars as $key=>$data) { $value->{$key} = $this->addslashes_deep( $data ); } } elseif ( is_string( $value ) ) { $value = addslashes( $value ); } return $value; } } class WP_UnitTest_Generator_Sequence { var $next; var $template_string; function __construct( $template_string = '%s', $start = 1 ) { $this->next = $start; $this->template_string = $template_string; } function next() { $generated = sprintf( $this->template_string , $this->next ); $this->next++; return $generated; } } class WP_UnitTest_Factory_Callback_After_Create { var $callback; function __construct( $callback ) { $this->callback = $callback; } function call( $object ) { return call_user_func( $this->callback, $object ); } }