diff --git a/composer.json b/composer.json index e52b08ca4..18b9568c4 100644 --- a/composer.json +++ b/composer.json @@ -30,5 +30,10 @@ "psr-4": { "WordPress\\Plugin_Check\\": "includes/" } + }, + "autoload-dev": { + "psr-4": { + "WordPress\\Plugin_Check\\Test_Data\\": "tests/testdata" + } } } diff --git a/includes/Checker/Checks.php b/includes/Checker/Checks.php new file mode 100644 index 000000000..7219269df --- /dev/null +++ b/includes/Checker/Checks.php @@ -0,0 +1,123 @@ +check_context = new Check_Context( $plugin_main_file ); + } + + /** + * Runs checks against the plugin. + * + * @since n.e.x.t + * + * @param array $checks An array of Check objects to run. + * @return Check_Result Object containing all check results. + * + * @throws Exception Thrown when check fails with critical error. + */ + public function run_checks( array $checks ) { + $result = new Check_Result( $this->check_context ); + $all_checks = $this->get_checks(); + + // Create an array of Check objects to run based on the check names passed. + $checks_to_run = array_filter( + $checks, + function( $check ) use ( $all_checks ) { + return in_array( $check, $all_checks, true ); + } + ); + + // Run the checks. + array_walk( + $checks_to_run, + function( Check $check ) use ( $result ) { + $this->run_check_with_result( $check, $result ); + } + ); + + return $result; + } + + /** + * Runs a given check with the given result object to amend. + * + * @since n.e.x.t + * + * @param Check $check The check to run. + * @param Check_Result $result The result object to amend. + * + * @throws Exception Thrown when check fails with critical error. + */ + protected function run_check_with_result( Check $check, Check_Result $result ) { + // If $check implements Preparation interface, ensure the preparation and clean up is run. + if ( $check instanceof Preparation ) { + $cleanup = $check->prepare(); + + try { + $check->run( $result ); + } catch ( Exception $e ) { + // Run clean up in case of any exception thrown from check. + $cleanup(); + throw $e; + } + + $cleanup(); + return; + } + + // Otherwise, just run the check. + $check->run( $result ); + } + + /** + * Gets the available plugin check classes. + * + * @since n.e.x.t + * + * @return array List of plugin check class instances implementing the Check interface. + */ + public function get_checks() { + // TODO: Add checks once implemented. + $checks = array(); + + /** + * Filters the available plugin check classes. + * + * @since n.e.x.t + * + * @param array $checks List of plugin check class instances implementing the Check interface. + */ + return apply_filters( 'wp_plugin_check_checks', $checks ); + } +} diff --git a/tests/Checker/Checks_Tests.php b/tests/Checker/Checks_Tests.php new file mode 100644 index 000000000..fd14b7702 --- /dev/null +++ b/tests/Checker/Checks_Tests.php @@ -0,0 +1,87 @@ +checks = new Checks( 'test-plugin/test-plugin.php' ); + } + + public function test_get_checks_returns_array_of_expected_checks() { + $expected = array( + new WordPress\Plugin_Check\Test_Data\Empty_Check(), + new WordPress\Plugin_Check\Test_Data\Error_Check(), + ); + + add_filter( + 'wp_plugin_check_checks', + function( $checks ) use ( $expected ) { + return $expected; + } + ); + + $checks = $this->checks->get_checks(); + + $this->assertIsArray( $checks ); + $this->assertSame( $expected, $checks ); + } + + public function test_run_checks() { + $all_checks = array( + new WordPress\Plugin_Check\Test_Data\Empty_Check(), + new WordPress\Plugin_Check\Test_Data\Error_Check(), + ); + + $checks_to_run = array( + $all_checks[0], + ); + + add_filter( + 'wp_plugin_check_checks', + function( $checks ) use ( $all_checks ) { + return $all_checks; + } + ); + + $results = $this->checks->run_checks( $checks_to_run ); + + $this->assertInstanceOf( Check_Result::class, $results ); + $this->assertEmpty( $results->get_warnings() ); + $this->assertEmpty( $results->get_errors() ); + } + + public function test_run_checks_with_error() { + $all_checks = array( + new WordPress\Plugin_Check\Test_Data\Empty_Check(), + new WordPress\Plugin_Check\Test_Data\Error_Check(), + ); + + $checks_to_run = array( + $all_checks[1], + ); + + add_filter( + 'wp_plugin_check_checks', + function( $checks ) use ( $all_checks ) { + return $all_checks; + } + ); + + $results = $this->checks->run_checks( $checks_to_run ); + + $this->assertEmpty( $results->get_warnings() ); + $this->assertNotEmpty( $results->get_errors() ); + } +} diff --git a/tests/testdata/Checks/Empty_Check.php b/tests/testdata/Checks/Empty_Check.php new file mode 100644 index 000000000..dcbbc2524 --- /dev/null +++ b/tests/testdata/Checks/Empty_Check.php @@ -0,0 +1,12 @@ +add_message( + true, + 'Error message', + array( + 'code' => 'check_error', + 'file' => 'error-file.php', + 'line' => 10, + 'column' => 5, + ) + ); + } +}