<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[49115] trunk: General: Introduce the ability to merge multiple `WP_Error` objects into one another, and to store more than one item of data for an error.</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { white-space: pre-line; overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="https://core.trac.wordpress.org/changeset/49115">49115</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"https://core.trac.wordpress.org/changeset/49115","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>johnbillion</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2020-10-09 22:20:50 +0000 (Fri, 09 Oct 2020)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>General: Introduce the ability to merge multiple `WP_Error` objects into one another, and to store more than one item of data for an error.

This allows multiple errors to be instantiated independently but collected into one without having to manually combine their properties.

Props rmccue, dlh, TimothyBlynJacobs

Fixes <a href="https://core.trac.wordpress.org/ticket/38777">#38777</a></pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcwpincludesclasswperrorphp">trunk/src/wp-includes/class-wp-error.php</a></li>
<li><a href="#trunktestsphpunittestsgeneralwpErrorphp">trunk/tests/phpunit/tests/general/wpError.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcwpincludesclasswperrorphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/class-wp-error.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/class-wp-error.php  2020-10-09 16:05:37 UTC (rev 49114)
+++ trunk/src/wp-includes/class-wp-error.php    2020-10-09 22:20:50 UTC (rev 49115)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2,8 +2,6 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px">  * WordPress Error API.
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * Contains the WP_Error class and the is_wp_error() function.
- *
</del><span class="cx" style="display: block; padding: 0 10px">  * @package WordPress
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -27,7 +25,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">        public $errors = array();
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-         * Stores the list of data for error codes.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  * Stores the most-recently added data for each error code.
</ins><span class="cx" style="display: block; padding: 0 10px">          *
</span><span class="cx" style="display: block; padding: 0 10px">         * @since 2.1.0
</span><span class="cx" style="display: block; padding: 0 10px">         * @var array
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -35,8 +33,16 @@
</span><span class="cx" style="display: block; padding: 0 10px">        public $error_data = array();
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-         * Initialize the error.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  * Stores previously added data added for error codes, oldest-to-newest by code.
</ins><span class="cx" style="display: block; padding: 0 10px">          *
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         * @since 5.6.0
+        * @var array[]
+        */
+       protected $additional_data = array();
+
+       /**
+        * Initializes the error.
+        *
</ins><span class="cx" style="display: block; padding: 0 10px">          * If `$code` is empty, the other parameters will be ignored.
</span><span class="cx" style="display: block; padding: 0 10px">         * When `$code` is not empty, `$message` will be used even if
</span><span class="cx" style="display: block; padding: 0 10px">         * it is empty. The `$data` parameter will be used only if it
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -60,7 +66,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-         * Retrieve all error codes.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  * Retrieves all error codes.
</ins><span class="cx" style="display: block; padding: 0 10px">          *
</span><span class="cx" style="display: block; padding: 0 10px">         * @since 2.1.0
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -75,7 +81,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-         * Retrieve first error code available.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  * Retrieves the first error code available.
</ins><span class="cx" style="display: block; padding: 0 10px">          *
</span><span class="cx" style="display: block; padding: 0 10px">         * @since 2.1.0
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -92,12 +98,12 @@
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-         * Retrieve all error messages or error messages matching code.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  * Retrieves all error messages, or the error messages for the given error code.
</ins><span class="cx" style="display: block; padding: 0 10px">          *
</span><span class="cx" style="display: block; padding: 0 10px">         * @since 2.1.0
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="cx" style="display: block; padding: 0 10px">         * @param string|int $code Optional. Retrieve messages matching code, if exists.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-         * @return array Error strings on success, or empty array on failure (if using code parameter).
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  * @return array Error strings on success, or empty array if there are none.
</ins><span class="cx" style="display: block; padding: 0 10px">          */
</span><span class="cx" style="display: block; padding: 0 10px">        public function get_error_messages( $code = '' ) {
</span><span class="cx" style="display: block; padding: 0 10px">                // Return all messages if no code specified.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -118,7 +124,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-         * Get single error message.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  * Gets a single error message.
</ins><span class="cx" style="display: block; padding: 0 10px">          *
</span><span class="cx" style="display: block; padding: 0 10px">         * This will get the first message available for the code. If no code is
</span><span class="cx" style="display: block; padding: 0 10px">         * given then the first code available will be used.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -126,7 +132,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * @since 2.1.0
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="cx" style="display: block; padding: 0 10px">         * @param string|int $code Optional. Error code to retrieve message.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-         * @return string
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  * @return string The error message.
</ins><span class="cx" style="display: block; padding: 0 10px">          */
</span><span class="cx" style="display: block; padding: 0 10px">        public function get_error_message( $code = '' ) {
</span><span class="cx" style="display: block; padding: 0 10px">                if ( empty( $code ) ) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -140,7 +146,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-         * Retrieve error data for error code.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  * Retrieves the most-recently added error data for an error code.
</ins><span class="cx" style="display: block; padding: 0 10px">          *
</span><span class="cx" style="display: block; padding: 0 10px">         * @since 2.1.0
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -158,11 +164,11 @@
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-         * Verify if the instance contains errors.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  * Verifies if the instance contains errors.
</ins><span class="cx" style="display: block; padding: 0 10px">          *
</span><span class="cx" style="display: block; padding: 0 10px">         * @since 5.1.0
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-         * @return bool
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  * @return bool If the instance contains errors.
</ins><span class="cx" style="display: block; padding: 0 10px">          */
</span><span class="cx" style="display: block; padding: 0 10px">        public function has_errors() {
</span><span class="cx" style="display: block; padding: 0 10px">                if ( ! empty( $this->errors ) ) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -201,11 +207,10 @@
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-         * Add data for error code.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  * Adds data to an error with the given code.
</ins><span class="cx" style="display: block; padding: 0 10px">          *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-         * The error code can only contain one error data.
-        *
</del><span class="cx" style="display: block; padding: 0 10px">          * @since 2.1.0
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         * @since 5.6.0 Errors can now contain more than one item of error data. {@see WP_Error::$additional_data}.
</ins><span class="cx" style="display: block; padding: 0 10px">          *
</span><span class="cx" style="display: block; padding: 0 10px">         * @param mixed      $data Error data.
</span><span class="cx" style="display: block; padding: 0 10px">         * @param string|int $code Error code.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -215,10 +220,40 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        $code = $this->get_error_code();
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                if ( isset( $this->error_data[ $code ] ) ) {
+                       $this->additional_data[ $code ][] = $this->error_data[ $code ];
+               }
+
</ins><span class="cx" style="display: block; padding: 0 10px">                 $this->error_data[ $code ] = $data;
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         * Retrieves all error data for an error code in the order in which the data was added.
+        *
+        * @since 5.6.0
+        *
+        * @param string|int $code Error code.
+        * @return mixed[] Array of error data, if it exists.
+        */
+       public function get_all_error_data( $code = '' ) {
+               if ( empty( $code ) ) {
+                       $code = $this->get_error_code();
+               }
+
+               $data = array();
+
+               if ( isset( $this->additional_data[ $code ] ) ) {
+                       $data = $this->additional_data[ $code ];
+               }
+
+               if ( isset( $this->error_data[ $code ] ) ) {
+                       $data[] = $this->error_data[ $code ];
+               }
+
+               return $data;
+       }
+
+       /**
</ins><span class="cx" style="display: block; padding: 0 10px">          * Removes the specified error.
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="cx" style="display: block; padding: 0 10px">         * This function removes all error messages associated with the specified
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -231,5 +266,48 @@
</span><span class="cx" style="display: block; padding: 0 10px">        public function remove( $code ) {
</span><span class="cx" style="display: block; padding: 0 10px">                unset( $this->errors[ $code ] );
</span><span class="cx" style="display: block; padding: 0 10px">                unset( $this->error_data[ $code ] );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                unset( $this->additional_data[ $code ] );
</ins><span class="cx" style="display: block; padding: 0 10px">         }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+       /**
+        * Merges the errors in the given error object into this one.
+        *
+        * @since 5.6.0
+        *
+        * @param WP_Error $error Error object to merge.
+        */
+       public function merge_from( WP_Error $error ) {
+               static::copy_errors( $error, $this );
+       }
+
+       /**
+        * Exports the errors in this object into the given one.
+        *
+        * @since 5.6.0
+        *
+        * @param WP_Error $error Error object to export into.
+        */
+       public function export_to( WP_Error $error ) {
+               static::copy_errors( $this, $error );
+       }
+
+       /**
+        * Copies errors from one WP_Error instance to another.
+        *
+        * @since 5.6.0
+        *
+        * @param WP_Error $from From.
+        * @param WP_Error $to   To.
+        */
+       protected static function copy_errors( WP_Error $from, WP_Error $to ) {
+               foreach ( $from->get_error_codes() as $code ) {
+                       foreach ( $from->get_error_messages( $code ) as $error_message ) {
+                               $to->add( $code, $error_message );
+                       }
+
+                       foreach ( $from->get_all_error_data( $code ) as $data ) {
+                               $to->add_data( $data, $code );
+                       }
+               }
+       }
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre></div>
<a id="trunktestsphpunittestsgeneralwpErrorphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tests/phpunit/tests/general/wpError.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/general/wpError.php     2020-10-09 16:05:37 UTC (rev 49114)
+++ trunk/tests/phpunit/tests/general/wpError.php       2020-10-09 22:20:50 UTC (rev 49115)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -376,6 +376,58 @@
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         * @covers ::get_all_error_data
+        */
+       public function test_get_all_error_data_with_code_and_no_errors_should_evaluate_as_empty_array() {
+               $this->assertSame( array(), $this->wp_error->get_all_error_data( 'code' ) );
+       }
+
+       /**
+        * @covers ::get_all_error_data
+        */
+       public function test_get_all_error_data_with_code_and_one_error_with_no_data_should_evaluate_as_empty_array() {
+               $this->wp_error->add( 'code', 'message' );
+
+               $this->assertSame( array(), $this->wp_error->get_all_error_data( 'code' ) );
+       }
+
+       /**
+        * @covers ::get_all_error_data
+        */
+       public function test_get_all_error_data_with_code_and_one_error_with_data_should_return_that_data() {
+               $expected = array( 'data-key' => 'data-value' );
+               $this->wp_error->add( 'code', 'message', $expected );
+
+               $actual = $this->wp_error->get_all_error_data( 'code' );
+               $this->assertCount( 1, $actual );
+               $this->assertSameSetsWithIndex( $expected, $actual[0] );
+       }
+
+       /**
+        * @covers ::get_all_error_data
+        */
+       public function test_get_all_error_data_with_code_and_multiple_errors_same_code_should_return_all_data() {
+               $this->wp_error->add( 'code', 'message', 'data' );
+               $this->wp_error->add( 'code', 'message2', 'data2' );
+               $this->wp_error->add( 'code2', 'message3', 'data3' );
+
+               $this->assertSame( array( 'data', 'data2' ), $this->wp_error->get_all_error_data( 'code' ) );
+       }
+
+       /**
+        * @covers ::get_all_error_data
+        */
+       public function test_get_all_error_data_should_handle_manipulation_of_error_data_property() {
+               $this->wp_error->add_data( 'data1', 'code' );
+               $this->wp_error->add_data( 'data2', 'code' );
+
+               $this->wp_error->error_data['code'] = 'dataX';
+
+               $this->assertSame( 'dataX', $this->wp_error->get_error_data( 'code' ) );
+               $this->assertSame( array( 'data1', 'dataX' ), $this->wp_error->get_all_error_data( 'code' ) );
+       }
+
+       /**
</ins><span class="cx" style="display: block; padding: 0 10px">          * @covers ::has_errors
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public function test_has_errors_with_no_errors_returns_false() {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -712,10 +764,68 @@
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public function test_remove_should_remove_the_error_data_associated_with_the_given_code() {
</span><span class="cx" style="display: block; padding: 0 10px">                $this->wp_error->add( 'code', 'message', 'data' );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                $this->wp_error->add( 'code', 'message', 'data2' );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                $this->wp_error->remove( 'code' );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                $this->assertEmpty( $this->wp_error->error_data );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                $this->assertEmpty( $this->wp_error->get_error_data( 'code' ) );
+               $this->assertEmpty( $this->wp_error->get_all_error_data( 'code' ) );
</ins><span class="cx" style="display: block; padding: 0 10px">         }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        /**
+        * @covers ::merge_from()
+        */
+       public function test_merge_from_should_copy_other_error_into_instance() {
+               $this->wp_error->add( 'code1', 'message1', 'data1' );
+
+               $other = new WP_Error( 'code1', 'message2', 'data2' );
+               $other->add( 'code2', 'message3' );
+               $this->wp_error->merge_from( $other );
+
+               $this->assertSame( array( 'message1', 'message2' ), $this->wp_error->get_error_messages( 'code1' ) );
+               $this->assertSame( 'data2', $this->wp_error->get_error_data( 'code1' ) );
+               $this->assertSame( array( 'data1', 'data2' ), $this->wp_error->get_all_error_data( 'code1' ) );
+               $this->assertSame( 'message3', $this->wp_error->get_error_message( 'code2' ) );
+       }
+
+       /**
+        * @covers ::merge_from()
+        */
+       public function test_merge_from_with_no_errors_should_not_add_to_instance() {
+               $other = new WP_Error();
+
+               $this->wp_error->merge_from( $other );
+
+               $this->assertFalse( $this->wp_error->has_errors() );
+       }
+
+       /**
+        * @covers ::export_to()
+        */
+       public function test_export_to_should_copy_instance_into_other_error() {
+               $other = new WP_Error();
+               $other->add( 'code1', 'message1', 'data1' );
+
+               $this->wp_error->add( 'code1', 'message2', 'data2' );
+               $this->wp_error->add( 'code2', 'message3' );
+
+               $this->wp_error->export_to( $other );
+
+               $this->assertSame( array( 'message1', 'message2' ), $other->get_error_messages( 'code1' ) );
+               $this->assertSame( 'data2', $other->get_error_data( 'code1' ) );
+               $this->assertSame( array( 'data1', 'data2' ), $other->get_all_error_data( 'code1' ) );
+               $this->assertSame( 'message3', $other->get_error_message( 'code2' ) );
+       }
+
+       /**
+        * @covers ::export_to()
+        */
+       public function test_export_to_with_no_errors_should_not_add_to_other_error() {
+               $other = new WP_Error();
+
+               $this->wp_error->export_to( $other );
+
+               $this->assertFalse( $other->has_errors() );
+       }
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre>
</div>
</div>

</body>
</html>