diff --git a/.gitattributes b/.gitattributes
index bbdd753cf..912ac1990 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -5,22 +5,23 @@
# https://www.reddit.com/r/PHP/comments/2jzp6k/i_dont_need_your_tests_in_my_production
# https://blog.madewithlove.be/post/gitattributes/
#
-/.cache export-ignore
-/.github export-ignore
-/config export-ignore
-/svn-assets export-ignore
-/tests export-ignore
-.babelrc export-ignore
-.editorconfig export-ignore
-.gitattributes export-ignore
-.gitignore export-ignore
-.phpcs.xml.dist export-ignore
-CHANGELOG export-ignore
-Gruntfile.js export-ignore
-LICENSE export-ignore
-package.json export-ignore
-phpunit.xml.dist export-ignore
-README.md export-ignore
+/.cache export-ignore
+/.github export-ignore
+/config export-ignore
+/svn-assets export-ignore
+/tests export-ignore
+.babelrc export-ignore
+.editorconfig export-ignore
+.gitattributes export-ignore
+.gitignore export-ignore
+.phpcs.xml.dist export-ignore
+CHANGELOG export-ignore
+Gruntfile.js export-ignore
+LICENSE export-ignore
+package.json export-ignore
+phpunit.xml.dist export-ignore
+phpunit-wp.xml.dist export-ignore
+README.md export-ignore
#
# Auto detect text files and perform LF normalization
diff --git a/.github/workflows/cs.yml b/.github/workflows/cs.yml
index 6738b8b40..e44fdd010 100644
--- a/.github/workflows/cs.yml
+++ b/.github/workflows/cs.yml
@@ -19,6 +19,7 @@ on:
- 'LICENSE'
- 'package.json'
- 'phpunit.xml.dist'
+ - 'phpunit-wp.xml.dist'
- 'yarn.lock'
- '.github/dependabot.yml'
- '.github/workflows/deploy.yml'
@@ -42,6 +43,7 @@ on:
- 'LICENSE'
- 'package.json'
- 'phpunit.xml.dist'
+ - 'phpunit-wp.xml.dist'
- 'yarn.lock'
- '.github/dependabot.yml'
- '.github/workflows/deploy.yml'
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index cc0795188..0a8c524a3 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -25,6 +25,7 @@ on:
- '.phpcs.xml.dist'
- 'phpcs.xml.dist'
- 'phpunit.xml.dist'
+ - 'phpunit-wp.xml.dist'
- 'yarn.lock'
- '.github/dependabot.yml'
- '.github/workflows/cs.yml'
@@ -50,6 +51,7 @@ on:
- '.phpcs.xml.dist'
- 'phpcs.xml.dist'
- 'phpunit.xml.dist'
+ - 'phpunit-wp.xml.dist'
- 'yarn.lock'
- '.github/dependabot.yml'
- '.github/workflows/cs.yml'
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index c8b0d8830..c43949388 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -30,6 +30,7 @@ on:
- '.github/workflows/deploy.yml'
- '.github/workflows/lint.yml'
- 'config/**'
+ - '!config/scripts/install-wp-tests.sh'
- 'css/**'
- 'js/**'
pull_request:
@@ -54,6 +55,7 @@ on:
- '.github/workflows/deploy.yml'
- '.github/workflows/lint.yml'
- 'config/**'
+ - '!config/scripts/install-wp-tests.sh'
- 'css/**'
- 'js/**'
# Allow manually triggering the workflow.
@@ -131,6 +133,130 @@ jobs:
COVERALLS_FLAG_NAME: php-${{ matrix.php_version }}
run: php-coveralls -v -x build/logs/clover.xml
+ integration-test:
+ runs-on: ubuntu-latest
+
+ strategy:
+ matrix:
+ include:
+ - php_version: "7.2"
+ wp_version: "6.2"
+ multisite: true
+ coverage: true
+
+ - php_version: "7.3"
+ wp_version: "trunk"
+ multisite: true
+ coverage: false
+
+ - php_version: "7.4"
+ wp_version: "latest"
+ multisite: false
+ coverage: false
+
+ - php_version: "8.0"
+ wp_version: "6.2"
+ multisite: false
+ coverage: false
+
+ - php_version: "8.1"
+ wp_version: "latest"
+ multisite: true
+ coverage: false
+
+ - php_version: "8.2"
+ wp_version: "6.3"
+ multisite: true
+ coverage: true
+
+ name: "Integration Test: PHP ${{ matrix.php_version }} | WP ${{ matrix.wp_version }}${{ matrix.multisite == true && ' (+ ms)' || '' }}"
+
+ # Allow builds to fail on as-of-yet unreleased WordPress versions.
+ continue-on-error: ${{ matrix.wp_version == 'trunk' }}
+
+ services:
+ mysql:
+ # Use MySQL 5.6 for PHP 7.2, use MySQL 5.7 for PHP 7.3 < 7.4, otherwise MySQL 8.0.
+ # Also see: https://core.trac.wordpress.org/ticket/52496
+ image: mysql:${{ ( matrix.php_version == '7.2' && '5.6' ) || ( matrix.php_version < '7.4' && '5.7' ) || '8.0' }}
+ env:
+ MYSQL_ALLOW_EMPTY_PASSWORD: false
+ ports:
+ - 3306:3306
+ options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=10s --health-retries=10
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v3
+
+ - name: Install PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php_version }}
+ ini-values: zend.assertions=1, error_reporting=-1, display_errors=On
+ coverage: ${{ matrix.coverage == true && 'xdebug' || 'none' }}
+
+ # Install dependencies and handle caching in one go.
+ # @link https://github.com/marketplace/actions/install-composer-dependencies
+ - name: Install Composer dependencies
+ uses: ramsey/composer-install@v2
+ with:
+ # Bust the cache at least once a month - output format: YYYY-MM.
+ custom-cache-suffix: $(date -u "+%Y-%m")
+
+ - name: Install WP
+ shell: bash
+ run: config/scripts/install-wp-tests.sh wordpress_test root '' 127.0.0.1:3306 ${{ matrix.wp_version }}
+
+ - name: Run integration tests - single site
+ if: ${{ matrix.coverage == false }}
+ run: composer integration-test
+
+ - name: Run integration tests - multisite
+ if: ${{ matrix.multisite == true && matrix.coverage == false }}
+ run: composer integration-test
+ env:
+ WP_MULTISITE: 1
+
+ - name: Run integration tests with code coverage - single site
+ if: ${{ matrix.coverage == true }}
+ run: composer integration-coverage
+
+ - name: Run integration tests with code coverage - multisite
+ if: ${{ matrix.multisite == true && matrix.coverage == true }}
+ run: composer integration-coverage -- --coverage-clover build/logs/clover-integration-ms.xml
+ env:
+ WP_MULTISITE: 1
+
+ # PHP Coveralls doesn't fully support PHP 8.x yet, so switch the PHP version.
+ - name: Switch to PHP 7.4
+ if: ${{ success() && matrix.coverage == true && startsWith( matrix.php_version, '8' ) }}
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: 7.4
+ coverage: none
+
+ # Global install is used to prevent a conflict with the local composer.lock in PHP 8.0+.
+ - name: Install Coveralls
+ if: ${{ success() && matrix.coverage == true }}
+ run: composer global require php-coveralls/php-coveralls:"^2.5.3" --no-interaction
+
+ - name: Upload coverage results to Coveralls
+ if: ${{ success() && matrix.coverage == true }}
+ env:
+ COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_TOKEN }}
+ COVERALLS_PARALLEL: true
+ COVERALLS_FLAG_NAME: intgr-php-${{ matrix.php_version }}-wp-${{ matrix.wp_version }}
+ run: php-coveralls -v -x build/logs/clover-integration.xml
+
+ - name: Upload coverage results to Coveralls - multisite
+ if: ${{ success() && matrix.multisite == true && matrix.coverage == true }}
+ env:
+ COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_TOKEN }}
+ COVERALLS_PARALLEL: true
+ COVERALLS_FLAG_NAME: intgr-php-${{ matrix.php_version }}-wp-${{ matrix.wp_version }}-ms
+ run: php-coveralls -v -x build/logs/clover-integration-ms.xml
+
coveralls-finish:
needs: unit
runs-on: ubuntu-latest
diff --git a/.gitignore b/.gitignore
index 909d53deb..0ea5601bf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -54,6 +54,8 @@ composer.lock
phpcs.xml
.cache/phpcs.cache
phpunit.xml
+phpunit-integration.xml
+phpunit-wp.xml
.phpunit.result.cache
############
diff --git a/.phpcs.xml.dist b/.phpcs.xml.dist
index 9cb8f12f3..cde1e5400 100644
--- a/.phpcs.xml.dist
+++ b/.phpcs.xml.dist
@@ -108,7 +108,7 @@
-
+
/tests/*\.php$
@@ -118,7 +118,7 @@
/tests/*
-
+
/tests/*
diff --git a/composer.json b/composer.json
index 9468caf69..3bc1623d7 100644
--- a/composer.json
+++ b/composer.json
@@ -56,6 +56,12 @@
],
"coverage": [
"@php ./vendor/phpunit/phpunit/phpunit"
+ ],
+ "integration-test": [
+ "@php ./vendor/phpunit/phpunit/phpunit -c phpunit-wp.xml.dist --no-coverage"
+ ],
+ "integration-coverage": [
+ "@php ./vendor/phpunit/phpunit/phpunit -c phpunit-wp.xml.dist"
]
},
"config": {
diff --git a/config/scripts/install-wp-tests.sh b/config/scripts/install-wp-tests.sh
new file mode 100755
index 000000000..8c0004eee
--- /dev/null
+++ b/config/scripts/install-wp-tests.sh
@@ -0,0 +1,189 @@
+#!/usr/bin/env bash
+
+########################################################################
+# Script to download and install WordPress for use in automated testing.
+#
+# Source: https://github.com/wp-cli/scaffold-command/blob/main/templates/install-wp-tests.sh
+# Last updated based on commit https://github.com/wp-cli/scaffold-command/commit/503ac569875d3665a0b28b9a5b7e8d136112b6d6
+# dated December 15 2022.
+########################################################################
+
+if [ $# -lt 3 ]; then
+ echo "usage: $0 [db-host] [wp-version] [skip-database-creation]"
+ exit 1
+fi
+
+DB_NAME=$1
+DB_USER=$2
+DB_PASS=$3
+DB_HOST=${4-localhost}
+WP_VERSION=${5-latest}
+SKIP_DB_CREATE=${6-false}
+
+TMPDIR=${TMPDIR-/tmp}
+TMPDIR=$(echo $TMPDIR | sed -e "s/\/$//")
+WP_TESTS_DIR=${WP_TESTS_DIR-$TMPDIR/wordpress-tests-lib}
+WP_CORE_DIR=${WP_CORE_DIR-$TMPDIR/wordpress}
+
+download() {
+ if [ `which curl` ]; then
+ curl -s "$1" > "$2";
+ elif [ `which wget` ]; then
+ wget -nv -O "$2" "$1"
+ fi
+}
+
+if [[ $WP_VERSION =~ ^[0-9]+\.[0-9]+\-(beta|RC)[0-9]+$ ]]; then
+ WP_BRANCH=${WP_VERSION%\-*}
+ WP_TESTS_TAG="branches/$WP_BRANCH"
+
+elif [[ $WP_VERSION =~ ^[0-9]+\.[0-9]+$ ]]; then
+ WP_TESTS_TAG="branches/$WP_VERSION"
+elif [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0-9]+ ]]; then
+ if [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0] ]]; then
+ # version x.x.0 means the first release of the major version, so strip off the .0 and download version x.x
+ WP_TESTS_TAG="tags/${WP_VERSION%??}"
+ else
+ WP_TESTS_TAG="tags/$WP_VERSION"
+ fi
+elif [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then
+ WP_TESTS_TAG="trunk"
+else
+ # http serves a single offer, whereas https serves multiple. we only want one
+ download http://api.wordpress.org/core/version-check/1.7/ /tmp/wp-latest.json
+ grep '[0-9]+\.[0-9]+(\.[0-9]+)?' /tmp/wp-latest.json
+ LATEST_VERSION=$(grep -o '"version":"[^"]*' /tmp/wp-latest.json | sed 's/"version":"//')
+ if [[ -z "$LATEST_VERSION" ]]; then
+ echo "Latest WordPress version could not be found"
+ exit 1
+ fi
+ WP_TESTS_TAG="tags/$LATEST_VERSION"
+fi
+set -ex
+
+install_wp() {
+
+ if [ -d $WP_CORE_DIR ]; then
+ return;
+ fi
+
+ mkdir -p $WP_CORE_DIR
+
+ if [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then
+ mkdir -p $TMPDIR/wordpress-trunk
+ rm -rf $TMPDIR/wordpress-trunk/*
+ svn export --quiet https://core.svn.wordpress.org/trunk $TMPDIR/wordpress-trunk/wordpress
+ mv $TMPDIR/wordpress-trunk/wordpress/* $WP_CORE_DIR
+ else
+ if [ $WP_VERSION == 'latest' ]; then
+ local ARCHIVE_NAME='latest'
+ elif [[ $WP_VERSION =~ [0-9]+\.[0-9]+ ]]; then
+ # https serves multiple offers, whereas http serves single.
+ download https://api.wordpress.org/core/version-check/1.7/ $TMPDIR/wp-latest.json
+ if [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0] ]]; then
+ # version x.x.0 means the first release of the major version, so strip off the .0 and download version x.x
+ LATEST_VERSION=${WP_VERSION%??}
+ else
+ # otherwise, scan the releases and get the most up to date minor version of the major release
+ local VERSION_ESCAPED=`echo $WP_VERSION | sed 's/\./\\\\./g'`
+ LATEST_VERSION=$(grep -o '"version":"'$VERSION_ESCAPED'[^"]*' $TMPDIR/wp-latest.json | sed 's/"version":"//' | head -1)
+ fi
+ if [[ -z "$LATEST_VERSION" ]]; then
+ local ARCHIVE_NAME="wordpress-$WP_VERSION"
+ else
+ local ARCHIVE_NAME="wordpress-$LATEST_VERSION"
+ fi
+ else
+ local ARCHIVE_NAME="wordpress-$WP_VERSION"
+ fi
+ download https://wordpress.org/${ARCHIVE_NAME}.tar.gz $TMPDIR/wordpress.tar.gz
+ tar --strip-components=1 -zxmf $TMPDIR/wordpress.tar.gz -C $WP_CORE_DIR
+ fi
+
+ download https://raw.githubusercontent.com/markoheijnen/wp-mysqli/master/db.php $WP_CORE_DIR/wp-content/db.php
+}
+
+install_test_suite() {
+ # portable in-place argument for both GNU sed and Mac OSX sed
+ if [[ $(uname -s) == 'Darwin' ]]; then
+ local ioption='-i.bak'
+ else
+ local ioption='-i'
+ fi
+
+ # set up testing suite if it doesn't yet exist
+ if [ ! -d $WP_TESTS_DIR ]; then
+ # set up testing suite
+ mkdir -p $WP_TESTS_DIR
+ rm -rf $WP_TESTS_DIR/{includes,data}
+ svn export --quiet --ignore-externals https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes
+ svn export --quiet --ignore-externals https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/data/ $WP_TESTS_DIR/data
+ fi
+
+ if [ ! -f wp-tests-config.php ]; then
+ download https://develop.svn.wordpress.org/${WP_TESTS_TAG}/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php
+ # remove all forward slashes in the end
+ WP_CORE_DIR=$(echo $WP_CORE_DIR | sed "s:/\+$::")
+ sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR/':" "$WP_TESTS_DIR"/wp-tests-config.php
+ sed $ioption "s:__DIR__ . '/src/':'$WP_CORE_DIR/':" "$WP_TESTS_DIR"/wp-tests-config.php
+ sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php
+ sed $ioption "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php
+ sed $ioption "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR"/wp-tests-config.php
+ sed $ioption "s|localhost|${DB_HOST}|" "$WP_TESTS_DIR"/wp-tests-config.php
+ fi
+
+}
+
+recreate_db() {
+ shopt -s nocasematch
+ if [[ $1 =~ ^(y|yes)$ ]]
+ then
+ mysqladmin drop $DB_NAME -f --user="$DB_USER" --password="$DB_PASS"$EXTRA
+ create_db
+ echo "Recreated the database ($DB_NAME)."
+ else
+ echo "Leaving the existing database ($DB_NAME) in place."
+ fi
+ shopt -u nocasematch
+}
+
+create_db() {
+ mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA
+}
+
+install_db() {
+
+ if [ ${SKIP_DB_CREATE} = "true" ]; then
+ return 0
+ fi
+
+ # parse DB_HOST for port or socket references
+ local PARTS=(${DB_HOST//\:/ })
+ local DB_HOSTNAME=${PARTS[0]};
+ local DB_SOCK_OR_PORT=${PARTS[1]};
+ local EXTRA=""
+
+ if ! [ -z $DB_HOSTNAME ] ; then
+ if [ $(echo $DB_SOCK_OR_PORT | grep -e '^[0-9]\{1,\}$') ]; then
+ EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp"
+ elif ! [ -z $DB_SOCK_OR_PORT ] ; then
+ EXTRA=" --socket=$DB_SOCK_OR_PORT"
+ elif ! [ -z $DB_HOSTNAME ] ; then
+ EXTRA=" --host=$DB_HOSTNAME --protocol=tcp"
+ fi
+ fi
+
+ # create database
+ if [ $(mysql --user="$DB_USER" --password="$DB_PASS"$EXTRA --execute='show databases;' | grep ^$DB_NAME$) ]
+ then
+ echo "Reinstalling will delete the existing test database ($DB_NAME)"
+ read -p 'Are you sure you want to proceed? [y/N]: ' DELETE_EXISTING_DB
+ recreate_db $DELETE_EXISTING_DB
+ else
+ create_db
+ fi
+}
+
+install_wp
+install_test_suite
+install_db
diff --git a/phpunit-wp.xml.dist b/phpunit-wp.xml.dist
new file mode 100644
index 000000000..3c3a0d933
--- /dev/null
+++ b/phpunit-wp.xml.dist
@@ -0,0 +1,43 @@
+
+
+
+
+ ./tests/wp
+
+
+
+
+
+ ./admin-functions.php
+ ./common-functions.php
+ ./duplicate-post.php
+ ./options.php
+ ./compat
+ ./src
+
+
+
+
+
+
+
+
+
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 2c132cba2..2a4179710 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -4,7 +4,7 @@
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/8.5/phpunit.xsd"
backupGlobals="false"
backupStaticAttributes="false"
- bootstrap="tests/bootstrap.php"
+ bootstrap="tests/unit/bootstrap.php"
colors="true"
convertDeprecationsToExceptions="true"
convertErrorsToExceptions="true"
@@ -20,7 +20,7 @@
>
- ./tests/
+ ./tests/unit
diff --git a/tests/admin/options-form-generator-test.php b/tests/unit/admin/options-form-generator-test.php
similarity index 99%
rename from tests/admin/options-form-generator-test.php
rename to tests/unit/admin/options-form-generator-test.php
index 297e64660..81b90aa65 100644
--- a/tests/admin/options-form-generator-test.php
+++ b/tests/unit/admin/options-form-generator-test.php
@@ -1,6 +1,6 @@
instance = new Post_Duplicator();
+ }
+
+ /**
+ * Tests whether the admin page is generated correctly.
+ *
+ * @covers ::create_duplicate
+ * @covers ::get_default_options
+ * @covers ::generate_copy_title
+ * @covers ::generate_copy_status
+ * @covers ::generate_copy_author
+ * @covers ::set_modified
+ */
+ public function test_create_duplicate() {
+
+ $post = $this->factory->post->create_and_get();
+
+ $id = $this->instance->create_duplicate( $post, [ 'copy_date' => true ] );
+
+ $this->assertIsInt( $id );
+ }
+}