From 0a2e3750c88be2843cd4267ceb494c0f152dc56a Mon Sep 17 00:00:00 2001 From: Dave Ross Date: Fri, 16 Mar 2018 11:30:00 -0400 Subject: [PATCH] Checking in the plugin scaffold from project-scaffolds --- composer.json | 21 +++++ includes/classes/.gitkeep | 0 includes/functions/core.php | 74 ++++++++++++++++ package-lock.json | 3 + package.json | 19 ++++ phpunit.xml | 21 +++++ plugin.php | 34 +++++++ readme.txt | 36 ++++++++ script.js | 6 ++ style.css | 6 ++ tests/bootstrap.php | 31 +++++++ tests/phpunit/test-tools/Core_Tests.php | 113 ++++++++++++++++++++++++ tests/phpunit/test-tools/TestCase.php | 75 ++++++++++++++++ 13 files changed, 439 insertions(+) create mode 100644 composer.json create mode 100644 includes/classes/.gitkeep create mode 100644 includes/functions/core.php create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 phpunit.xml create mode 100644 plugin.php create mode 100644 readme.txt create mode 100644 script.js create mode 100644 style.css create mode 100644 tests/bootstrap.php create mode 100644 tests/phpunit/test-tools/Core_Tests.php create mode 100644 tests/phpunit/test-tools/TestCase.php diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..c33055a --- /dev/null +++ b/composer.json @@ -0,0 +1,21 @@ +{ + "name": "10up/tenup-plugin-scaffold", + "description": "Project Description", + "authors": [ + { + "name": "Author", + "email": "email@10up.com" + } + ], + "require": { + "php": ">=7.0" + }, + "autoload": { + "psr-4": { + "TenUpThemeScaffold\\": "includes/classes/" + } + }, + "require-dev": { + "10up/wp_mock": "dev-dev" + } +} diff --git a/includes/classes/.gitkeep b/includes/classes/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/includes/functions/core.php b/includes/functions/core.php new file mode 100644 index 0000000..c2f1b24 --- /dev/null +++ b/includes/functions/core.php @@ -0,0 +1,74 @@ +_loaded' ); +} + +/** + * Registers the default textdomain. + * + * @uses apply_filters() + * @uses get_locale() + * @uses load_textdomain() + * @uses load_plugin_textdomain() + * @uses plugin_basename() + * + * @return void + */ +function i18n() { + $locale = apply_filters( 'plugin_locale', get_locale(), '<%= funcPrefix %>' ); + load_textdomain( '<%= funcPrefix %>', WP_LANG_DIR . '/<%= funcPrefix %>/<%= funcPrefix %>-' . $locale . '.mo' ); + load_plugin_textdomain( '<%= funcPrefix %>', false, plugin_basename( <%= funcPrefix.toUpperCase() %>_PATH ) . '/languages/' ); +} + +/** + * Initializes the plugin and fires an action other plugins can hook into. + * + * @uses do_action() + * + * @return void + */ +function init() { + do_action( '<%= funcPrefix %>_init' ); +} + +/** + * Activate the plugin + * + * @uses init() + * @uses flush_rewrite_rules() + * + * @return void + */ +function activate() { + // First load the init scripts in case any rewrite functionality is being loaded + init(); + flush_rewrite_rules(); +} + +/** + * Deactivate the plugin + * + * Uninstall routines should be in uninstall.php + * + * @return void + */ +function deactivate() { + +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..48e341a --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3 @@ +{ + "lockfileVersion": 1 +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..6416101 --- /dev/null +++ b/package.json @@ -0,0 +1,19 @@ +{ + "name": "tenup-plugin-scaffold", + "version": "1.0.0", + "description": "Project Description", + "main": "index.js", + "author": { + "name": "10up", + "email": "info@10up.com", + "url": "https://10up.com", + "role": "developer" + }, + "scripts": { + "test": "phpunit" + }, + "repository": { + "type": "git", + "url": "https://project-git-repo.tld" + } +} diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..2e1d540 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,21 @@ + + + + ./tests/phpunit + + + + + ./includes + + + + + + + + diff --git a/plugin.php b/plugin.php new file mode 100644 index 0000000..148c303 --- /dev/null +++ b/plugin.php @@ -0,0 +1,34 @@ + + * Plugin URI: <%= projectHome %> + * Description: <%= description %> + * Version: 0.1.0 + * Author: <%= authorName %> + * Author URI: <%= authorUrl %> + * Text Domain: <%= funcPrefix %> + * Domain Path: /languages + */ + +/** + * Built using yo wp-make:plugin + * Copyright (c) 2015 10up, LLC + * https://github.com/10up/generator-wp-make + */ + +// Useful global constants +define( '<%= funcPrefix.toUpperCase() %>_VERSION', '0.1.0' ); +define( '<%= funcPrefix.toUpperCase() %>_URL', plugin_dir_url( __FILE__ ) ); +define( '<%= funcPrefix.toUpperCase() %>_PATH', dirname( __FILE__ ) . '/' ); +define( '<%= funcPrefix.toUpperCase() %>_INC', <%= funcPrefix.toUpperCase() %>_PATH . 'includes/' ); + +// Include files +require_once <%= funcPrefix.toUpperCase() %>_INC . 'functions/core.php'; + + +// Activation/Deactivation +register_activation_hook( __FILE__, '\TenUp\<%= namespace %>\Core\activate' ); +register_deactivation_hook( __FILE__, '\TenUp\<%= namespace %>\Core\deactivate' ); + +// Bootstrap +TenUp\<%= namespace %>\Core\setup(); diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000..f2d6b8c --- /dev/null +++ b/readme.txt @@ -0,0 +1,36 @@ +=== <%= projectTitle %> === +Contributors: <%= authorName %> +Donate link: <%= authorUrl %> +Tags: +Requires at least: 4.9 +Tested up to: 4.9 +Stable tag: 0.1.0 + +<%= description %> + +== Description == + + + +== Installation == + += Manual Installation = + +1. Upload the entire `/<%= basename %>` directory to the `/wp-content/plugins/` directory. +2. Activate <%= projectTitle %> through the 'Plugins' menu in WordPress. + +== Frequently Asked Questions == + + +== Screenshots == + + +== Changelog == + += 0.1.0 = +* First release + +== Upgrade Notice == + += 0.1.0 = +First Release diff --git a/script.js b/script.js new file mode 100644 index 0000000..a466d0d --- /dev/null +++ b/script.js @@ -0,0 +1,6 @@ +/** + * <%= projectTitle %> + * <%= projectHome %> + * + * Copyright (c) <%= new Date().getFullYear() %> <%= authorName %> + */ diff --git a/style.css b/style.css new file mode 100644 index 0000000..a466d0d --- /dev/null +++ b/style.css @@ -0,0 +1,6 @@ +/** + * <%= projectTitle %> + * <%= projectHome %> + * + * Copyright (c) <%= new Date().getFullYear() %> <%= authorName %> + */ diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 0000000..9773ea3 --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,31 @@ +_DIR' ) ) { + define( '<%= funcPrefix.toUpperCase() %>_DIR', __DIR__ . '/' ); +} + +// Place any additional bootstrapping requirements here for PHP Unit. +if ( ! defined( 'WP_LANG_DIR' ) ) { + define( 'WP_LANG_DIR', 'lang_dir' ); +} +if ( ! defined( '<%= funcPrefix.toUpperCase() %>_PATH' ) ) { + define( '<%= funcPrefix.toUpperCase() %>_PATH', 'path' ); +} + +if ( ! file_exists( __DIR__ . '/../vendor/autoload.php' ) ) { + throw new PHPUnit_Framework_Exception( + 'ERROR' . PHP_EOL . PHP_EOL . + 'You must use Composer to install the test suite\'s dependencies!' . PHP_EOL + ); +} + +require_once __DIR__ . '/../vendor/autoload.php'; + +require_once __DIR__ . '/../tests/phpunit/test-tools/TestCase.php'; + +WP_Mock::setUsePatchwork( true ); +WP_Mock::bootstrap(); +WP_Mock::tearDown(); diff --git a/tests/phpunit/test-tools/Core_Tests.php b/tests/phpunit/test-tools/Core_Tests.php new file mode 100644 index 0000000..2073094 --- /dev/null +++ b/tests/phpunit/test-tools/Core_Tests.php @@ -0,0 +1,113 @@ +\Core; + +/** + * This is a very basic test case to get things started. You should probably rename this and make + * it work for your project. You can use all the tools provided by WP Mock and Mockery to create + * your tests. Coverage is calculated against your includes/ folder, so try to keep all of your + * functional code self contained in there. + * + * References: + * - http://phpunit.de/manual/current/en/index.html + * - https://github.com/padraic/mockery + * - https://github.com/10up/wp_mock + */ + +use TenUp\<%= namespace %> as Base; + +class Core_Tests extends Base\TestCase { + + protected $testFiles = [ + 'functions/core.php' + ]; + + /** + * Test load method. + */ + public function test_setup() { + // Setup + \WP_Mock::expectActionAdded( 'init', 'TenUp\<%= namespace %>\Core\i18n' ); + \WP_Mock::expectActionAdded( 'init', 'TenUp\<%= namespace %>\Core\init' ); + \WP_Mock::expectAction( '<%= funcPrefix %>_loaded' ); + + // Act + setup(); + + // Verify + $this->assertConditionsMet(); + } + + /** + * Test internationalization integration. + */ + public function test_i18n() { + // Setup + \WP_Mock::wpFunction( 'get_locale', array( + 'times' => 1, + 'args' => array(), + 'return' => 'en_US', + ) ); + \WP_Mock::onFilter( 'plugin_locale' )->with( 'en_US', '<%= funcPrefix %>' )->reply( 'en_US' ); + \WP_Mock::wpFunction( 'load_textdomain', array( + 'times' => 1, + 'args' => array( '<%= funcPrefix %>', 'lang_dir/<%= funcPrefix %>/<%= funcPrefix %>-en_US.mo' ), + ) ); + \WP_Mock::wpFunction( 'plugin_basename', array( + 'times' => 1, + 'args' => array( 'path' ), + 'return' => 'path', + ) ); + \WP_Mock::wpFunction( 'load_plugin_textdomain', array( + 'times' => 1, + 'args' => array( '<%= funcPrefix %>', false, 'path/languages/' ), + ) ); + + // Act + i18n(); + + // Verify + $this->assertConditionsMet(); + } + + /** + * Test initialization method. + */ + public function test_init() { + // Setup + \WP_Mock::expectAction( '<%= funcPrefix %>_init' ); + + // Act + init(); + + // Verify + $this->assertConditionsMet(); + } + + /** + * Test activation routine. + */ + public function test_activate() { + // Setup + \WP_Mock::wpFunction( 'flush_rewrite_rules', array( + 'times' => 1 + ) ); + + // Act + activate(); + + // Verify + $this->assertConditionsMet(); + } + + /** + * Test deactivation routine. + */ + public function test_deactivate() { + // Setup + + // Act + deactivate(); + + // Verify + } +} \ No newline at end of file diff --git a/tests/phpunit/test-tools/TestCase.php b/tests/phpunit/test-tools/TestCase.php new file mode 100644 index 0000000..b607a01 --- /dev/null +++ b/tests/phpunit/test-tools/TestCase.php @@ -0,0 +1,75 @@ +; + +use PHPUnit_Framework_TestResult; +use Text_Template; +use WP_Mock; +use WP_Mock\Tools\TestCase as BaseTestCase; + +class TestCase extends BaseTestCase { + public function run( \PHPUnit\Framework\TestResult $result = null ) { + $this->setPreserveGlobalState( false ); + return parent::run( $result ); + } + + protected $testFiles = array(); + + public function setUp() { + if ( ! empty( $this->testFiles ) ) { + foreach ( $this->testFiles as $file ) { + if ( file_exists( PROJECT . $file ) ) { + require_once( PROJECT . $file ); + } + } + } + + parent::setUp(); + } + + public function assertActionsCalled() { + $actions_not_added = $expected_actions = 0; + try { + WP_Mock::assertActionsCalled(); + } catch ( \Exception $e ) { + $actions_not_added = 1; + $expected_actions = $e->getMessage(); + } + $this->assertEmpty( $actions_not_added, $expected_actions ); + } + + public function ns( $function ) { + if ( ! is_string( $function ) || false !== strpos( $function, '\\' ) ) { + return $function; + } + + $thisClassName = trim( get_class( $this ), '\\' ); + + if ( ! strpos( $thisClassName, '\\' ) ) { + return $function; + } + + // $thisNamespace is constructed by exploding the current class name on + // namespace separators, running array_slice on that array starting at 0 + // and ending one element from the end (chops the class name off) and + // imploding that using namespace separators as the glue. + $thisNamespace = implode( '\\', array_slice( explode( '\\', $thisClassName ), 0, - 1 ) ); + + return "$thisNamespace\\$function"; + } + + /** + * Define constants after requires/includes + * + * See http://kpayne.me/2012/07/02/phpunit-process-isolation-and-constant-already-defined/ + * for more details + * + * @param \Text_Template $template + */ + public function prepareTemplate( \Text_Template $template ) { + $template->setVar( [ + 'globals' => '$GLOBALS[\'__PHPUNIT_BOOTSTRAP\'] = \'' . $GLOBALS['__PHPUNIT_BOOTSTRAP'] . '\';', + ] ); + parent::prepareTemplate( $template ); + } +} \ No newline at end of file