diff --git a/.gitattributes b/.gitattributes
index 11b011cb..67ca9531 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -6,12 +6,10 @@ includes/ui/* linguist-language=HTML+PHP
/.github export-ignore
/.wordpress-org export-ignore
/bin export-ignore
-/docker export-ignore
.editorconfig export-ignore
.gitattributes export-ignore
.gitignore export-ignore
composer.json export-ignore
-docker-compose.yml export-ignore
phpcs.xml export-ignore
phpunit.xml.dist export-ignore
-readme.txt export-ignore
+readme.txt export-ignore
\ No newline at end of file
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index a48749d6..6755b345 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -1,11 +1,12 @@
name: Run Tests
on:
- push:
- pull_request:
+ push: null
+ pull_request: null
jobs:
- single-instance:
+
+ instance:
name: Testing (PHP ${{ matrix.php }}; Instance ${{ matrix.redis }})
runs-on: ubuntu-latest
timeout-minutes: 5
@@ -36,14 +37,11 @@ jobs:
--health-timeout 5s
--health-retries 5
-
strategy:
fail-fast: false
matrix:
- php: [ '7.1', '7.2', '7.3', '7.4', '8.0', '8.1' ]
- composer: [ 'composer' ]
- redis: [ '4.0.14', '5.0.12', '6.2.6' ]
- wordpress: [ 'latest' ]
+ php: ['7.2', '7.3', '7.4', '8.0', '8.1']
+ redis: ['3.2.12', '6.2.6', '7.0.3']
steps:
- name: Checkout
@@ -54,12 +52,12 @@ jobs:
with:
php-version: ${{ matrix.php }}
extensions: msgpack, igbinary, redis-5.3.7
- tools: ${{ matrix.composer }}
- name: Set up WordPress and WordPress Test Library
uses: sjinks/setup-wordpress-test-library@master
with:
- version: ${{ matrix.wordpress }}
+ version: latest
+ cache_prefix: redis-cache-${{ github.ref }}
- name: Install PHP Dependencies
uses: ramsey/composer-install@v2
@@ -71,7 +69,7 @@ jobs:
- name: Run test suite
run: ./vendor/bin/phpunit
- cluster-instance:
+ cluster:
name: Testing (PHP ${{ matrix.php }}; Cluster ${{ matrix.redis }})
runs-on: ubuntu-latest
timeout-minutes: 5
@@ -93,7 +91,7 @@ jobs:
MYSQL_DATABASE: wordpress_test
redis:
- image: grokzen/redis-cluster
+ image: grokzen/redis-cluster:${{ matrix.redis }}
ports:
- '6379-6384:6379-6384'
options: >-
@@ -112,10 +110,8 @@ jobs:
strategy:
fail-fast: false
matrix:
- php: [ '7.1', '7.2', '7.3', '7.4', '8.0', '8.1' ]
- composer: [ 'composer' ]
- redis: [ '5.0.12', '6.2.1' ]
- wordpress: [ 'latest' ]
+ php: ['7.2', '7.3', '7.4', '8.0', '8.1']
+ redis: ['5.0.12', '6.2.1']
steps:
- name: Checkout
@@ -126,12 +122,12 @@ jobs:
with:
php-version: ${{ matrix.php }}
extensions: msgpack, igbinary, redis-5.3.7
- tools: ${{ matrix.composer }}
- name: Set up WordPress and WordPress Test Library
uses: sjinks/setup-wordpress-test-library@master
with:
- version: ${{ matrix.wordpress }}
+ version: latest
+ cache_prefix: redis-cache-${{ github.ref }}
- name: Install PHP Dependencies
uses: ramsey/composer-install@v2
diff --git a/.gitignore b/.gitignore
index 044b8dad..42d892af 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,9 @@
+/.wp-test
+/.phpunit.cache
/docker/apf.php
/php-tools
/vendor
/reports
+.phpunit.result.cache
composer.lock
+config.sh
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 76be648e..96e40d5a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
# Changelog
+## 2.1.1
+
+- Bumped PHP requirement to 7.2
+- Renamed `WP_REDIS_DIR` to `WP_REDIS_PLUGIN_DIR`
+- Fixed rare fatal error in diagnostics
+- Allow Predis v1.1 Composer installs
+- Support using `WP_REDIS_CLUSTER` string
+
## 2.1.0
- Bumped PHP requirement to 7.0
diff --git a/README.md b/README.md
index 0825d88f..9c574409 100644
--- a/README.md
+++ b/README.md
@@ -48,4 +48,4 @@ To see a list of all available WP-CLI commands, please see the [WP CLI commands
### Development
-Head over to the [Docker Development wiki page](https://github.com/rhubarbgroup/redis-cache/wiki/Docker-Development) to spin up various Redis setups.
+Head over to the [Local development wiki page](https://github.com/rhubarbgroup/redis-cache/wiki/Local-Development) for more information.
diff --git a/bin/includes/flags-arguments.sh b/bin/includes/flags-arguments.sh
deleted file mode 100644
index ae29e636..00000000
--- a/bin/includes/flags-arguments.sh
+++ /dev/null
@@ -1,43 +0,0 @@
-#/usr/bin/env bash
-#
-# Get command arguments
-# Reference: https://stackoverflow.com/questions/7069682/how-to-get-arguments-with-flags-in-bash
-#
-
-for i in ${@}; do
- arguments[$index]=$i;
- prev_index="$(expr $index - 1)";
-
- # this if block does something akin to "where $i contains ="
- # "%=*" here strips out everything from the = to the end of the argument leaving only the label
- if [[ $i == *"="* ]]; then
- argument_label=${i%=*}
- else
- argument_label=${arguments[$prev_index]}
- fi
-
- # first argument and no label detected: must be mode then
- if [[ 1 == $index && -z $argument_label ]]; then
- argument_label="-m"
- fi
-
- if [[ -n $argument_label ]]; then
- # this if block only evaluates to true if the argument label exists in the variables array
- if [[ -n ${variables[$argument_label]} ]]; then
- # dynamically creating variables names using declare
- # "#$argument_label=" here strips out the label leaving only the value
- if [[ $i == *"="* ]]; then
- declare ${variables[$argument_label]}=${i#$argument_label=}
- else
- declare ${variables[$argument_label]}=${arguments[$index]}
- fi
- else
- # if the argument was not found store it in order
- options+=(${arguments[$index]})
- fi
- else
- echo "unrecognized $1"
- fi
-
- index=index+1;
-done;
diff --git a/bin/includes/flags-declares.sh b/bin/includes/flags-declares.sh
deleted file mode 100644
index 6611faed..00000000
--- a/bin/includes/flags-declares.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!busr/bin/env bash
-#
-# Needed for argument extraction
-#
-declare -A arguments=();
-declare -A variables=();
-declare options=();
-declare -i index=1;
diff --git a/bin/includes/functions.sh b/bin/includes/functions.sh
deleted file mode 100644
index c9206ae2..00000000
--- a/bin/includes/functions.sh
+++ /dev/null
@@ -1,108 +0,0 @@
-#!/usr/bin/env bash
-#
-# Utility functions
-#
-
-_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
-BASE_DIR="$( dirname $( dirname "$_DIR" ))"
-SRC_DIR="$BASE_DIR"
-DOCKER_DIR="$BASE_DIR/docker"
-
-# Shorthand function for docker-compose with the right yml file
-compose() {
- docker-compose \
- -f "$BASE_DIR/docker-compose.yml" \
- "${@:1}"
-}
-
-# Starts all containers and scales them accordingly
-start() {
- compose \
- up -d \
- --scale redis-master="${1:-0}" \
- --scale redis-slave="${2:-0}" \
- --scale redis-sentinel="${3:-0}" \
- "${@:4}"
-}
-
-# Stops all containers
-stop() {
- compose down "${@}"
-}
-
-container_info() {
- docker ps -a --no-trunc \
- --format '{{ .ID }}\t{{ .Names }}\t{{ .State }}\tp:{{ .Label "com.docker.compose.project" }}' \
- | grep 'p:redis-cache' \
- | grep "$1"
-}
-
-# Modifies the auto-prepend-file
-apf() {
- echo "APF-Constant $@"
- ESCAPE='s/[]\/$*.^[]/\\&/g'
- # --reset
- if [[ '--reset' == "$1" ]]; then
- apf WP_REDIS_HOST --remove
- apf WP_REDIS_CLIENT --remove
- apf WP_REDIS_SERVERS --remove
- apf WP_REDIS_SENTINEL --remove
- apf WP_REDIS_SHARDS --remove
- apf WP_REDIS_CLUSTER --remove
- return
- fi
- FILE="$DOCKER_DIR/apf.php"
- # Test if apf.php exists or if it is empty
- if [[ ! -f "$FILE" || ! -s "$FILE" ]]; then
- cp "$DOCKER_DIR/apf-template.php" "$FILE"
- fi
- TMP1=$(mktemp)
- CONST=$(echo "'$1'" | sed "$ESCAPE")
- sed -n "/$CONST/!p" "$FILE" > "$TMP1"
- if [[ '--remove' != "$2" ]]; then
- TMP2=$(mktemp)
- if [ -n "$3" ]; then
- VALUE="["
- for var in "${@:2}"; do
- VALUE="$VALUE'$var',"
- done
- VALUE="$VALUE]"
- else
- VALUE="'$2'"
- fi
- VALUE=$(echo "$VALUE" | sed "$ESCAPE")
- INSAFTER=$(echo "// constant-definition end" | sed "$ESCAPE")
- # Add constructed line before the insertion indicator end comment
- REPL=$(printf ' %s => %s,' "$CONST" "$VALUE")
- sed 's/^[ ]*'"$INSAFTER"'.*$/'"$REPL"'\'$'\n&/g' \
- "$TMP1" > "$TMP2"
- mv "$TMP2" "$TMP1"
- fi
- mv "$TMP1" "$FILE"
-}
-
-# Retrieves the IP of a docker container using its name and optionally its index
-dcip() {
- declare -i counter=1
- declare -i max_counter=25
- container_name="$1_${2:-1}"
- while [ $counter -le $max_counter ]; do
- container_state=$(container_info $container_name | awk '{print $3}')
- if [ "running" = $container_state ]; then
- break
- fi
- sleep 0.1s
- ((counter++))
- done
- if [ $counter -lt $max_counter ]; then
- echo $(compose exec --index="${2:-1}" "$1" hostname -i) | tr -d '\r'
- else
- echo "$container_name"
- fi
-}
-
-# Restarts apache in the wordpress container
-restart_apache() {
- echo "Restarting Apache"
- compose exec wordpress apachectl restart
-}
diff --git a/bin/run-tests.sh b/bin/run-tests.sh
deleted file mode 100644
index cdd3e183..00000000
--- a/bin/run-tests.sh
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/usr/bin/env bash
-#
-# Utility script to run phpunit unit tests
-#
-
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
-
-# Argument definitions
-. "$DIR/includes/flags-declares.sh"
-variables["-m"]="mode";
-variables["--mode"]="mode";
-variables["-f"]="force";
-variables["--force"]="force";
-
-# Load libraries
-. "$DIR/includes/functions.sh"
-. "$DIR/includes/flags-arguments.sh"
-
-TESTSUITE=${mode-all}
-ARG_TESTSUITE=""
-CONTAINER_ID=$(container_info wordpress | awk '{print $1}')
-XDEBUG_FILTER_PATH="/tmp/xdebug-filter.php"
-
-[ "all" != $TESTSUITE ] && ARG_TESTSUITE="--testsuite $TESTSUITE"
-
-# Create reports directory if missing.
-[ ! -d "$BASE_DIR/reports" ] && mkdir -p "$BASE_DIR/reports"
-
-# Try to create xdebug filter file.
-docker-compose exec wordpress test -f "$XDEBUG_FILTER_PATH"
-if [ $? -eq 1 ] || [ ! -n $force ]; then
- compose exec wordpress rm -rf "$XDEBUG_FILTER_PATH"
- compose exec wordpress phpunit -c "/redis-cache/phpunit.xml.dist" --dump-xdebug-filter "$XDEBUG_FILTER_PATH"
-fi
-
-# Use to provided object-cache.php instead of the one in `wp-content`
-if compose exec wordpress test -f "/opt/bitnami/wordpress/wp-content/object-cache.php"; then
- echo "Object cache already installed - saving object-cache.php"
- compose exec wordpress cp "/opt/bitnami/wordpress/wp-content/object-cache.php" "/opt/bitnami/wordpress/wp-content/_object-cache.php"
-fi
-echo "Forcing WordPress to use the object-cache.php in the plugin's include directory"
-compose exec wordpress bash -c 'echo " "/opt/bitnami/wordpress/wp-content/object-cache.php"'
-
-# Execute phpunit tests in the container.
-compose exec wordpress \
- phpunit -c "/redis-cache/phpunit.xml.dist" --prepend "$XDEBUG_FILTER_PATH" $ARG_TESTSUITE
-
-# Retrieve code coverage report.
-docker cp $CONTAINER_ID:/tmp/codecov "$BASE_DIR/reports"
-
-# Reset to the object-cache.php found before
-if compose exec wordpress test -f "/opt/bitnami/wordpress/wp-content/_object-cache.php"; then
- echo "Resetting to installed object-cache.php"
- compose exec wordpress cp "/opt/bitnami/wordpress/wp-content/_object-cache.php" "/opt/bitnami/wordpress/wp-content/object-cache.php"
- compose exec wordpress rm "/opt/bitnami/wordpress/wp-content/_object-cache.php"
-else
- echo "Resetting using object-cache.php"
- compose exec wordpress rm "/opt/bitnami/wordpress/wp-content/object-cache.php"
-fi
\ No newline at end of file
diff --git a/bin/setup-test.sh b/bin/setup-test.sh
new file mode 100755
index 00000000..a64c911a
--- /dev/null
+++ b/bin/setup-test.sh
@@ -0,0 +1,48 @@
+#! /usr/bin/env sh
+
+set -e
+
+WP_DEV_GIT=https://github.com/WordPress/wordpress-develop
+WP_TESTS_DIR=.wp-test
+
+if [ -a config.sh ]
+then
+ echo " - Sourcing your test environment variables"
+ source "config.sh"
+fi
+
+GIT_BRANCH=${GIT_BRANCH:=trunk}
+
+if [[ ! -d $WP_TESTS_DIR ]]; then
+ echo " - Cloning wordpress develop"
+ git clone --depth 1 --quiet --branch $GIT_BRANCH $WP_DEV_GIT $WP_TESTS_DIR
+fi
+
+
+echo " - Creating the config file"
+cp $WP_TESTS_DIR/wp-tests-config-sample.php $WP_TESTS_DIR/wp-tests-config.php
+
+
+
+
+# portable in-place argument for both GNU sed and Mac OSX sed
+if [[ $(uname -s) == 'Darwin' ]]; then
+ ioption='-i.bak'
+else
+ ioption='-i'
+fi
+
+DB_HOST=${DB_HOST:=127.0.0.1}
+DB_PASS=${DB_PASS:=""}
+DB_NAME=${DB_NAME:="wp_tests"}
+DB_USER=${DB_USER:="root"}
+
+echo " - Setting up the database connection values"
+
+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
+
+
+echo " - We are done ✅ \n"
\ No newline at end of file
diff --git a/bin/start-env.sh b/bin/start-env.sh
deleted file mode 100644
index 2a566ba7..00000000
--- a/bin/start-env.sh
+++ /dev/null
@@ -1,88 +0,0 @@
-#!/usr/bin/env bash
-#
-# Utility script to manage the docker dev environments
-#
-# Documentation:
-# https://github.com/rhubarbgroup/redis-cache/wiki/Docker-Development
-#
-
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
-
-# Argument definitions
-. "$DIR/includes/flags-declares.sh"
-variables["-m"]="mode";
-variables["--mode"]="mode";
-variables["-c"]="client";
-variables["--client"]="client";
-
-# Load libraries
-. "$DIR/includes/functions.sh"
-. "$DIR/includes/flags-arguments.sh"
-
-case ${mode-default} in
-
- "default"|"-"|"simple"|"up"|"start")
- start 1 0 0 "${options[@]}"
- apf --reset
- apf WP_REDIS_CLIENT "${client-phpredis}"
- apf WP_REDIS_HOST redis-master
- restart_apache
- ;;
-
- "replication"|"repl")
- start 1 3 0 "${options[@]}"
- apf --reset
- apf WP_REDIS_CLIENT "${client-phpredis}"
- apf WP_REDIS_SERVERS \
- tcp://$(dcip redis-master):6379?alias=master \
- tcp://$(dcip redis-slave 1):6379?alias=slave-01 \
- tcp://$(dcip redis-slave 2):6379?alias=slave-02 \
- tcp://$(dcip redis-slave 3):6379?alias=slave-03
- restart_apache
- ;;
-
- "sentinel"|"sent")
- start 1 5 3 "${options[@]}"
- apf --reset
- apf WP_REDIS_CLIENT "${client-predis}"
- apf WP_REDIS_SENTINEL master
- apf WP_REDIS_SERVERS \
- tcp://$(dcip redis-sentinel 1):26379 \
- tcp://$(dcip redis-sentinel 2):26379 \
- tcp://$(dcip redis-sentinel 3):26379
- restart_apache
- ;;
-
- "shard"|"sharding")
- start 3 0 0 "${options[@]}"
- apf --reset
- apf WP_REDIS_CLIENT "${client-predis}"
- apf WP_REDIS_SHARDS \
- tcp://$(dcip redis-master 1):6379?alias=shard-01 \
- tcp://$(dcip redis-master 2):6379?alias=shard-02 \
- tcp://$(dcip redis-master 3):6379?alias=shard-03
- restart_apache
- ;;
-
- "cluster"|"clustering")
- start 3 0 0 "${options[@]}"
- apf WP_REDIS_CLIENT "${client-predis}"
- apf WP_REDIS_CLUSTER \
- tcp://$(dcip redis-master 1):6379?alias=node-01 \
- tcp://$(dcip redis-master 2):6379?alias=node-02 \
- tcp://$(dcip redis-master 3):6379?alias=node-03
- restart_apache
- ;;
-
- "stop"|"down")
- stop "${options[@]}"
- apf --reset
- apf WP_REDIS_CLIENT "${client-phpredis}"
- apf WP_REDIS_HOST redis-master
- ;;
-
- *) echo "unrecognized command $mode"
- exit
- ;;
-
-esac
diff --git a/composer.json b/composer.json
index 90dd43d7..5564c69c 100644
--- a/composer.json
+++ b/composer.json
@@ -19,18 +19,26 @@
"wordpress"
],
"require": {
- "php": "^7.0 || ^8.0",
+ "php": "^7.2 || ^8.0",
"composer/installers": "~1.0 || ~2.0",
"mnsami/composer-custom-directory-installer": "^2.0",
- "predis/predis": "^2.0",
+ "predis/predis": "^1.1 || ^2.0",
"colinmollenhour/credis": "^1.12.1"
},
"require-dev": {
"wp-coding-standards/wpcs": "^2.3",
"phpcompatibility/phpcompatibility-wp": "^2.1",
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
- "phpunit/phpunit": "^7.0 || ^8.0"
+ "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
+ "yoast/wp-test-utils": "^1.0",
+ "dms/phpunit-arraysubset-asserts": "^0.4.0"
},
+ "autoload-dev": {
+ "psr-4": {
+ "Rhubarb\\RedisCache\\": "includes/",
+ "Tests\\": "tests/"
+ }
+ },
"extra": {
"installer-paths": {
"dependencies/predis/predis": ["predis/predis"],
diff --git a/docker-compose.yml b/docker-compose.yml
deleted file mode 100644
index a0909095..00000000
--- a/docker-compose.yml
+++ /dev/null
@@ -1,53 +0,0 @@
-version: '3.5'
-services:
- mariadb:
- image: 'bitnami/mariadb:10.3'
- volumes:
- - 'mariadb_data:/bitnami/mariadb'
- environment:
- MARIADB_USER: bn_wordpress
- MARIADB_DATABASE: bitnami_wordpress
- ALLOW_EMPTY_PASSWORD: "yes"
- wordpress:
- build: docker/wordpress
- ports:
- - '80:8080'
- - '443:8443'
- volumes:
- - 'wordpress_data:/bitnami/wordpress'
- - '.:/redis-cache:ro'
- depends_on:
- - mariadb
- - redis-master
- environment:
- WORDPRESS_DATABASE_HOST: mariadb
- WORDPRESS_DATABASE_PORT_NUMBER: 3306
- WORDPRESS_DATABASE_USER: bn_wordpress
- WORDPRESS_DATABASE_NAME: bitnami_wordpress
- ALLOW_EMPTY_PASSWORD: "yes"
- WORDPRESS_USERNAME: wordpress
- WORDPRESS_PASSWORD: wordpress
- WORDPRESS_BLOG_NAME: Redis Cache Dev
- WORDPRESS_PLUGINS: query-monitor
- redis-master:
- build: docker/redis
- ports:
- - '6379:6379'
- redis-slave:
- build: docker/redis
- command: 'redis-server --slaveof redis-master 6379'
- depends_on:
- - redis-master
- redis-sentinel:
- build: docker/redis-sentinel
- depends_on:
- - redis-master
- environment:
- MASTER_NAME: master
- QUORUM: 2
- MASTER: redis-master
-volumes:
- mariadb_data:
- driver: local
- wordpress_data:
- driver: local
diff --git a/docker/apf-template.php b/docker/apf-template.php
deleted file mode 100644
index 64bf307c..00000000
--- a/docker/apf-template.php
+++ /dev/null
@@ -1,13 +0,0 @@
- 'redis-master',
- // constant-definition end
-];
-
-foreach ( $constants as $constant => $value ) {
- if ( ! defined( $constant ) ) {
- define( $constant, $value );
- }
-}
diff --git a/docker/redis-sentinel/Dockerfile b/docker/redis-sentinel/Dockerfile
deleted file mode 100644
index 0353f2e8..00000000
--- a/docker/redis-sentinel/Dockerfile
+++ /dev/null
@@ -1,12 +0,0 @@
-FROM redis:alpine
-
-RUN apk add --no-cache \
- curl \
- bash
-
-ADD docker-entrypoint.sh /
-RUN chmod +x /docker-entrypoint.sh
-
-EXPOSE 26379
-
-ENTRYPOINT ["/docker-entrypoint.sh"]
diff --git a/docker/redis-sentinel/docker-entrypoint.sh b/docker/redis-sentinel/docker-entrypoint.sh
deleted file mode 100644
index fa8329f8..00000000
--- a/docker/redis-sentinel/docker-entrypoint.sh
+++ /dev/null
@@ -1,87 +0,0 @@
-#!/usr/bin/env bash
-
-set -e
-
-SENTINEL_CONFIGURATION_FILE=/etc/sentinel.conf
-
-if [ "$AWS_IP_DISCOVERY" ]; then
- ANNOUNCE_IP=`curl http://169.254.169.254/latest/meta-data/local-ipv4`
-fi
-
-DEFAULT_REDIS_PORT=6379
-: ${REDIS_PORT:=$DEFAULT_REDIS_PORT}
-: ${SENTINEL_PORT:=26379}
-
-# Backward compatibility fix previously existed DEFAULT_PORT
-if [ "$DEFAULT_PORT" ] && [ "$REDIS_PORT" -eq $DEFAULT_REDIS_PORT ]; then
- REDIS_PORT=$DEFAULT_PORT
-fi
-
-: ${QUORUM:=2}
-: ${DOWN_AFTER:=30000}
-: ${FAILOVER_TIMEOUT:=180000}
-: ${PARALLEL_SYNCS:=1}
-
-parse_addr () {
- local _retvar=$1
- IFS=':' read -ra ADDR <<< "$2"
-
- if [ "${ADDR[1]}" = "" ]; then
- ADDR[1]=$REDIS_PORT
- fi
-
- eval $_retvar='("${ADDR[@]}")'
-}
-
-print_slave () {
- local -a ADDR
- parse_addr ADDR $1
- echo "sentinel known-slave $MASTER_NAME ${ADDR[0]} ${ADDR[1]}" >> $SENTINEL_CONFIGURATION_FILE
-}
-
-print_master () {
- local -a ADDR
- parse_addr ADDR $1
- echo "sentinel monitor $MASTER_NAME ${ADDR[0]} ${ADDR[1]} $QUORUM" >> $SENTINEL_CONFIGURATION_FILE
-}
-
-echo "port $SENTINEL_PORT" > $SENTINEL_CONFIGURATION_FILE
-echo "sentinel resolve-hostnames yes" > $SENTINEL_CONFIGURATION_FILE
-
-if [ "$ANNOUNCE_IP" ]; then
- echo "sentinel announce-ip $ANNOUNCE_IP" >> $SENTINEL_CONFIGURATION_FILE
-fi
-
-if [ "$ANNOUNCE_PORT" ]; then
- echo "sentinel announce-port $ANNOUNCE_PORT" >> $SENTINEL_CONFIGURATION_FILE
-fi
-
-if [ "$MASTER_NAME" ]; then
- print_master $MASTER
- echo "sentinel down-after-milliseconds $MASTER_NAME $DOWN_AFTER" >> $SENTINEL_CONFIGURATION_FILE
- echo "sentinel failover-timeout $MASTER_NAME $FAILOVER_TIMEOUT" >> $SENTINEL_CONFIGURATION_FILE
- echo "sentinel parallel-syncs $MASTER_NAME $PARALLEL_SYNCS" >> $SENTINEL_CONFIGURATION_FILE
-
- if [ "$NOTIFICATION_SCRIPT" ]; then
- echo "sentinel notification-script $MASTER_NAME $NOTIFICATION_SCRIPT" >> $SENTINEL_CONFIGURATION_FILE
- fi
-
- if [ "$CLIENT_RECONFIG_SCRIPT" ]; then
- echo "sentinel client-reconfig-script $MASTER_NAME $CLIENT_RECONFIG_SCRIPT" >> $SENTINEL_CONFIGURATION_FILE
- fi
-
- if [ "$AUTH_PASS" ]; then
- echo "sentinel auth-pass $MASTER_NAME $AUTH_PASS" >> $SENTINEL_CONFIGURATION_FILE
- fi
-
- if [ "$SLAVES" ]; then
- for SLAVE in $(echo $SLAVES | tr ";" "\n")
- do
- if [ "$SLAVE" ]; then
- print_slave $SLAVE
- fi
- done
- fi
-fi
-
-exec redis-server $SENTINEL_CONFIGURATION_FILE --sentinel
diff --git a/docker/redis/Dockerfile b/docker/redis/Dockerfile
deleted file mode 100644
index 058f6b22..00000000
--- a/docker/redis/Dockerfile
+++ /dev/null
@@ -1 +0,0 @@
-FROM redis:alpine
diff --git a/docker/wordpress/Dockerfile b/docker/wordpress/Dockerfile
deleted file mode 100644
index 434dea29..00000000
--- a/docker/wordpress/Dockerfile
+++ /dev/null
@@ -1,28 +0,0 @@
-FROM bitnami/wordpress:5
-
-# Required to perform privileged actions
-USER 0
-
-# install apt packages
-RUN install_packages php-pear autoconf build-essential lsyncd subversion vim
-# Use development config
-ENV PHP_DEV_CONF_FILE "/opt/bitnami/php/etc/php.ini-development"
-RUN ln -sf "$PHP_DEV_CONF_FILE" /opt/bitnami/php/lib/php.ini
-RUN pear config-set php_ini /opt/bitnami/php/lib/php.ini
-# install xdebug using pecl
-RUN pecl install xdebug
-# install redis using pecl
-RUN pecl install redis
-# allow dependency execution
-ENV PATH /redis-cache/bin:/redis-cache/vendor/bin:$PATH
-
-ADD ./app-entrypoint-custom.sh /
-RUN chmod +x /app-entrypoint-custom.sh
-
-# Revert to the original non-root user
-USER 1001
-
-RUN rm -r /opt/bitnami/wordpress/wp-content/plugins/*
-
-ENTRYPOINT [ "/app-entrypoint-custom.sh" ]
-CMD [ "/opt/bitnami/scripts/apache/run.sh" ]
diff --git a/docker/wordpress/app-entrypoint-custom.sh b/docker/wordpress/app-entrypoint-custom.sh
deleted file mode 100644
index 4fad4c0e..00000000
--- a/docker/wordpress/app-entrypoint-custom.sh
+++ /dev/null
@@ -1,138 +0,0 @@
-#!/usr/bin/env bash
-set -e
-
-#
-# Initial part copied from
-# https://github.com/bitnami/bitnami-docker-wordpress/blob/a0affeb00b7087bcfb81e85e1982a9419ad401c9/5/debian-10/rootfs/opt/bitnami/scripts/wordpress/entrypoint.sh
-#
-
-# shellcheck disable=SC1091
-
-set -o errexit
-set -o nounset
-set -o pipefail
-# set -o xtrace # Uncomment this line for debugging purpose
-
-# Load WordPress environment
-. /opt/bitnami/scripts/wordpress-env.sh
-
-# Load libraries
-. /opt/bitnami/scripts/libbitnami.sh
-. /opt/bitnami/scripts/liblog.sh
-. /opt/bitnami/scripts/libwebserver.sh
-
-print_welcome_page
-
-if [[ "$1" = "/opt/bitnami/scripts/$(web_server_type)/run.sh" || "$1" = "/opt/bitnami/scripts/nginx-php-fpm/run.sh" ]]; then
- info "** Starting WordPress setup **"
- /opt/bitnami/scripts/"$(web_server_type)"/setup.sh
- /opt/bitnami/scripts/php/setup.sh
- /opt/bitnami/scripts/mysql-client/setup.sh
- /opt/bitnami/scripts/wordpress/setup.sh
- /post-init.sh
- info "** WordPress setup finished! **"
-fi
-
-###
-# Custom actions
-###
-
-# Load libraries
-. /opt/bitnami/scripts/libfs.sh
-. /opt/bitnami/scripts/libphp.sh
-. /opt/bitnami/scripts/libapache.sh
-. /opt/bitnami/scripts/libwordpress.sh
-# Load environments
-. /opt/bitnami/scripts/php-env.sh
-. /opt/bitnami/scripts/apache-env.sh
-
-PLUGIN_SOURCE_DIR="/redis-cache"
-PLUGIN_TARGET_DIR="/opt/bitnami/wordpress/wp-content/plugins/redis-cache"
-APF_FILE_PATH="/redis-cache/docker/apf.php"
-WP_TESTS_DIR="$WORDPRESS_BASE_DIR/tests-lib"
-WP_VERSION=$(wp core version)
-
-# Reference: `install-wp-tests.sh`
-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"
-fi
-
-## Symlink generation
-info "Creating plugin symlink"
-if [ ! -L "$PLUGIN_TARGET_DIR" ]; then
- ln -s "$PLUGIN_SOURCE_DIR" "$PLUGIN_TARGET_DIR"
-fi
-
-## Set APF file
-if [ -f "$APF_FILE_PATH" ]; then
- php_conf_set auto_prepend_file "$APF_FILE_PATH" "$PHP_DEV_CONF_FILE"
- info "Set PHP auto prepend file ($PHP_DEV_CONF_FILE)"
-else
- error "Unable to set PHP auto prepend file"
- ls -lah $(dirname "$APF_FILE_PATH") | grep $(basename "$APF_FILE_PATH")
-fi
-
-## Set xdebug config
-php_conf_set xdebug.mode coverage "$PHP_DEV_CONF_FILE"
-
-## Download WP test suite
-## Reference: https://github.com/wp-cli/scaffold-command/blob/402542fada9c17d45ffa644da1f82661c07643fd/templates/install-wp-tests.sh
-if [ ! -d "$WP_TESTS_DIR" ]; then
- info "Downloading WP testing suite using svn"
- mkdir -p "$WP_TESTS_DIR"
- svn co --quiet "https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/" "$WP_TESTS_DIR/includes"
- svn co --quiet "https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/data/" "$WP_TESTS_DIR/data"
-fi
-
-if [ ! -f "$WP_TESTS_DIR/wp-tests-config.php" ]; then
- info "Creating test config"
- curl --silent "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 "$WORDPRESS_BASE_DIR" | sed "s:/\+$::")
- sed -i "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR/':" "$WP_TESTS_DIR/wp-tests-config.php"
- sed -i "s/youremptytestdbnamehere/$WORDPRESS_DATABASE_NAME/" "$WP_TESTS_DIR/wp-tests-config.php"
- sed -i "s/yourusernamehere/$WORDPRESS_DATABASE_USER/" "$WP_TESTS_DIR/wp-tests-config.php"
- sed -i "s/yourpasswordhere//" "$WP_TESTS_DIR/wp-tests-config.php"
- sed -i "s|localhost|${WORDPRESS_DATABASE_HOST}|" "$WP_TESTS_DIR/wp-tests-config.php"
-fi
-
-## Create phpinfo file
-info "Creating info.php file displaying phpinfo"
-echo " "$WORDPRESS_BASE_DIR/info.php"
-
-## Set development constants
-info "Setting wp-config.php development constants"
-is_file_writable "$WORDPRESS_CONF_FILE" || chmod +w "$WORDPRESS_CONF_FILE"
-
-wordpress_conf_set WP_DEBUG true yes
-wordpress_conf_set SCRIPT_DEBUG true yes
-wordpress_conf_set WP_ENVIRONMENT_TYPE "local"
-
-wordpress_conf_set DISALLOW_FILE_EDIT true yes
-wordpress_conf_set CONCATENATE_SCRIPTS false yes
-
-is_file_writable "$WORDPRESS_CONF_FILE" && chmod -w "$WORDPRESS_CONF_FILE"
-
-## Activates the newly copied plugin
-info "Activating plugin and enabling dropin"
-wp_execute plugin activate redis-cache
-wp_execute redis update-dropin
-wp_execute redis enable
-
-# fixes httpd already running error
-apache_stop
-# Needed for bitnami image - needs to be the last command!
-echo ""
-exec "$@"
diff --git a/includes/class-plugin.php b/includes/class-plugin.php
index fed3665d..db618922 100644
--- a/includes/class-plugin.php
+++ b/includes/class-plugin.php
@@ -281,7 +281,7 @@ public function enqueue_admin_styles() {
return;
}
- wp_enqueue_style( 'redis-cache', WP_REDIS_DIR . '/assets/css/admin.css', null, WP_REDIS_VERSION );
+ wp_enqueue_style( 'redis-cache', WP_REDIS_PLUGIN_DIR . '/assets/css/admin.css', null, WP_REDIS_VERSION );
}
/**
diff --git a/includes/diagnostics.php b/includes/diagnostics.php
index 4dc889f0..2cd8f937 100644
--- a/includes/diagnostics.php
+++ b/includes/diagnostics.php
@@ -119,22 +119,22 @@
if ( $dropin && ! $disabled ) {
$info['Global Groups'] = wp_json_encode(
- array_values( $wp_object_cache->global_groups ),
+ array_values( $wp_object_cache->global_groups ?? [] ),
JSON_PRETTY_PRINT
);
$info['Ignored Groups'] = wp_json_encode(
- array_values( $wp_object_cache->ignored_groups ),
+ array_values( $wp_object_cache->ignored_groups ?? [] ),
JSON_PRETTY_PRINT
);
$info['Unflushable Groups'] = wp_json_encode(
- array_values( $wp_object_cache->unflushable_groups ),
+ array_values( $wp_object_cache->unflushable_groups ?? [] ),
JSON_PRETTY_PRINT
);
$info['Groups Types'] = wp_json_encode(
- $wp_object_cache->group_type,
+ $wp_object_cache->group_type ?? null,
JSON_PRETTY_PRINT
);
}
diff --git a/includes/object-cache.php b/includes/object-cache.php
index 8b027a9a..1f96e13f 100644
--- a/includes/object-cache.php
+++ b/includes/object-cache.php
@@ -3,12 +3,12 @@
* Plugin Name: Redis Object Cache Drop-In
* Plugin URI: https://wordpress.org/plugins/redis-cache/
* Description: A persistent object cache backend powered by Redis. Supports Predis, PhpRedis, Relay, replication, sentinels, clustering and WP-CLI.
- * Version: 2.1.0
+ * Version: 2.1.1
* Author: Till Krüss
* Author URI: https://objectcache.pro
* License: GPLv3
* License URI: http://www.gnu.org/licenses/gpl-3.0.html
- * Requires PHP: 7.0
+ * Requires PHP: 7.2
*
* @package Rhubarb\RedisCache
*/
@@ -686,18 +686,22 @@ protected function connect_using_phpredis( $parameters ) {
$this->diagnostics[ 'shards' ] = WP_REDIS_SHARDS;
} elseif ( defined( 'WP_REDIS_CLUSTER' ) ) {
- $args = [
- 'cluster' => $this->build_cluster_connection_array(),
- 'timeout' => $parameters['timeout'],
- 'read_timeout' => $parameters['read_timeout'],
- 'persistent' => $parameters['persistent'],
- ];
+ if ( is_string( WP_REDIS_CLUSTER ) ) {
+ $this->redis = new RedisCluster( WP_REDIS_CLUSTER );
+ } else {
+ $args = [
+ 'cluster' => $this->build_cluster_connection_array(),
+ 'timeout' => $parameters['timeout'],
+ 'read_timeout' => $parameters['read_timeout'],
+ 'persistent' => $parameters['persistent'],
+ ];
- if ( isset( $parameters['password'] ) && version_compare( $version, '4.3.0', '>=' ) ) {
- $args['password'] = $parameters['password'];
- }
+ if ( isset( $parameters['password'] ) && version_compare( $version, '4.3.0', '>=' ) ) {
+ $args['password'] = $parameters['password'];
+ }
- $this->redis = new RedisCluster( null, ...array_values( $args ) );
+ $this->redis = new RedisCluster( null, ...array_values( $args ) );
+ }
$this->diagnostics += $args;
} else {
diff --git a/includes/ui/settings.php b/includes/ui/settings.php
index 4679b714..53df4d02 100644
--- a/includes/ui/settings.php
+++ b/includes/ui/settings.php
@@ -98,7 +98,7 @@ class="classes() ); ?>"
- =' ); ?>
+ =' ); ?>
=' ); ?>
@@ -122,7 +122,7 @@ class="classes() ); ?>"
diff --git a/languages/redis-cache.pot b/languages/redis-cache.pot
index aa17af2c..cf3def5d 100644
--- a/languages/redis-cache.pot
+++ b/languages/redis-cache.pot
@@ -2,14 +2,14 @@
# This file is distributed under the GPLv3.
msgid ""
msgstr ""
-"Project-Id-Version: Redis Object Cache 2.1.0\n"
+"Project-Id-Version: Redis Object Cache 2.1.1\n"
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/redis-cache\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"POT-Creation-Date: 2022-07-13T16:42:49+00:00\n"
+"POT-Creation-Date: 2022-07-18T16:28:07+00:00\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"X-Generator: WP-CLI 2.6.0\n"
"X-Domain: redis-cache\n"
@@ -358,7 +358,7 @@ msgstr ""
#. translators: %s = PHP Version.
#: includes/ui/settings.php:125
-msgid "The current version of PHP (%s) is too old. PHP 7.0 or newer is required."
+msgid "The current version of PHP (%s) is too old. PHP 7.2 or newer is required."
msgstr ""
#: includes/ui/settings.php:134
diff --git a/phpcs.xml b/phpcs.xml
index 116ce838..1b2b4250 100644
--- a/phpcs.xml
+++ b/phpcs.xml
@@ -9,7 +9,6 @@
.
/vendor/
/dependencies/
- /docker/
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 94a8f49c..7e9a1504 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -1,33 +1,35 @@
-
-
-
-
-
-
-
-
-
-
- includes
- redis-cache.php
-
-
-
-
- ./tests/phpunit/main
-
-
- ./tests/phpunit/cache
-
-
- ./tests/phpunit/meta
-
-
+
+
+
+
+
+ ./tests/Feature
+
+
+
+
+
+ includes
+
+
+
+
+
+
+
+
diff --git a/readme.txt b/readme.txt
index ee43160a..8f4da93b 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,11 +1,11 @@
=== Redis Object Cache ===
Contributors: tillkruess
Donate link: https://github.com/sponsors/tillkruss
-Tags: redis, predis, phpredis, credis, pecl, relay, caching, cache, object cache, performance, replication, clustering, keydb
+Tags: redis, predis, phpredis, credis, relay, caching, cache, object cache, performance, replication, clustering, keydb
Requires at least: 3.3
Tested up to: 6.0
-Requires PHP: 5.6
-Stable tag: 2.1.0
+Requires PHP: 7.2
+Stable tag: 2.1.1
License: GPLv3
License URI: http://www.gnu.org/licenses/gpl-3.0.html
@@ -83,6 +83,14 @@ To see a list of all available WP-CLI commands, please see the [WP CLI commands
== Changelog ==
+= 2.1.1 =
+
+- Bumped PHP requirement to 7.2
+- Renamed `WP_REDIS_DIR` to `WP_REDIS_PLUGIN_DIR`
+- Fixed rare fatal error in diagnostics
+- Allow Predis v1.1 Composer installs
+- Support using `WP_REDIS_CLUSTER` string
+
= 2.1.0 =
- Bumped PHP requirement to 7.0
@@ -564,6 +572,6 @@ Since Predis isn't maintained any longer, it's highly recommended to switch over
== Upgrade Notice ==
-= 2.1.0 =
+= 2.1.1 =
-Bumped PHP requirement to 7.0, updated Predis to v2.0 and deprecated Credis and HHVM clients.
+Bumped PHP requirement to 7.2, updated Predis to v2.0 and deprecated Credis and HHVM clients.
diff --git a/redis-cache.php b/redis-cache.php
index fb1d0fbf..657e8204 100644
--- a/redis-cache.php
+++ b/redis-cache.php
@@ -3,11 +3,11 @@
* Plugin Name: Redis Object Cache
* Plugin URI: https://wordpress.org/plugins/redis-cache/
* Description: A persistent object cache backend powered by Redis. Supports Predis, PhpRedis, Relay, replication, sentinels, clustering and WP-CLI.
- * Version: 2.1.0
+ * Version: 2.1.1
* Text Domain: redis-cache
* Domain Path: /languages
* Network: true
- * Requires PHP: 7.0
+ * Requires PHP: 7.2
* Author: Till Krüss
* Author URI: https://objectcache.pro
* GitHub Plugin URI: https://github.com/rhubarbgroup/redis-cache
@@ -22,7 +22,7 @@
define( 'WP_REDIS_FILE', __FILE__ );
define( 'WP_REDIS_PLUGIN_PATH', __DIR__ );
define( 'WP_REDIS_BASENAME', plugin_basename( WP_REDIS_FILE ) );
-define( 'WP_REDIS_DIR', plugin_dir_url( WP_REDIS_FILE ) );
+define( 'WP_REDIS_PLUGIN_DIR', plugin_dir_url( WP_REDIS_FILE ) );
$meta = get_file_data( WP_REDIS_FILE, [ 'Version' => 'Version' ] );
diff --git a/tests/Feature/CacheTest.php b/tests/Feature/CacheTest.php
new file mode 100644
index 00000000..129a8d00
--- /dev/null
+++ b/tests/Feature/CacheTest.php
@@ -0,0 +1,358 @@
+assertFalse($this->cache->get('test_miss'));
+ }
+
+ public function testAddGet(): void
+ {
+ $key = __FUNCTION__;
+ $val = 'val';
+
+ $this->cache->add($key, $val);
+ $this->assertSame($val, $this->cache->get($key));
+ }
+
+ public function testAddGet0(): void
+ {
+ $key = __FUNCTION__;
+ $val = 0;
+
+ // You can store zero in the cache.
+ $this->assertTrue($this->cache->add($key, $val));
+ $this->assertSame($val, $this->cache->get($key));
+ }
+
+ /**
+ * @ticket 20004
+ */
+ public function testAddGetNull(): void
+ {
+ $key = __FUNCTION__;
+ $val = null;
+
+ // You can store `null` in the cache.
+ $this->assertTrue($this->cache->add($key, $val));
+ $this->assertSame($val, $this->cache->get($key));
+ }
+
+ /**
+ * @ticket 20004
+ */
+ public function testAddGetFalse(): void
+ {
+ $key = __FUNCTION__;
+ $val = false;
+
+ // You can store `false` in the cache.
+ $this->assertTrue($this->cache->add($key, $val));
+ $this->assertSame($val, $this->cache->get($key));
+ }
+
+ public function testAdd(): void
+ {
+ $key = __FUNCTION__;
+ $val1 = 'val1';
+ $val2 = 'val2';
+
+ // Add $key to the cache.
+ $this->assertTrue($this->cache->add($key, $val1));
+ $this->assertSame($val1, $this->cache->get($key));
+ // $key is in the cache, so reject new calls to add().
+ $this->assertFalse($this->cache->add($key, $val2));
+ $this->assertSame($val1, $this->cache->get($key));
+ }
+
+ public function testReplace(): void
+ {
+ $key = __FUNCTION__;
+ $val = 'val1';
+ $val2 = 'val2';
+
+ // memcached rejects replace() if the key does not exist.
+ $this->assertFalse($this->cache->replace($key, $val));
+ $this->assertFalse($this->cache->get($key));
+ $this->assertTrue($this->cache->add($key, $val));
+ $this->assertSame($val, $this->cache->get($key));
+ $this->assertTrue($this->cache->replace($key, $val2));
+ $this->assertSame($val2, $this->cache->get($key));
+ }
+
+ public function testSet(): void
+ {
+ $key = __FUNCTION__;
+ $val1 = 'val1';
+ $val2 = 'val2';
+
+ // memcached accepts set() if the key does not exist.
+ $this->assertTrue($this->cache->set($key, $val1));
+ $this->assertSame($val1, $this->cache->get($key));
+ // Second set() with same key should be allowed.
+ $this->assertTrue($this->cache->set($key, $val2));
+ $this->assertSame($val2, $this->cache->get($key));
+ }
+
+ public function testFlush(): void
+ {
+ global $_wp_using_ext_object_cache;
+
+ if ($_wp_using_ext_object_cache) {
+ $this->markTestSkipped('This test requires that an external object cache is not in use.');
+ }
+
+ $key = __FUNCTION__;
+ $val = 'val';
+
+ $this->cache->add($key, $val);
+ // Item is visible to both cache objects.
+ $this->assertSame($val, $this->cache->get($key));
+ $this->cache->flush();
+ // If there is no value get returns false.
+ $this->assertFalse($this->cache->get($key));
+ }
+
+ // Make sure objects are cloned going to and from the cache.
+ public function testObjectRefs(): void
+ {
+ $key = __FUNCTION__.'_1';
+ $object_a = new \stdClass();
+ $object_a->foo = 'alpha';
+ $this->cache->set($key, $object_a);
+ $object_a->foo = 'bravo';
+ $object_b = $this->cache->get($key);
+ $this->assertSame('alpha', $object_b->foo);
+ $object_b->foo = 'charlie';
+ $this->assertSame('bravo', $object_a->foo);
+
+ $key = __FUNCTION__.'_2';
+ $object_a = new \stdClass();
+ $object_a->foo = 'alpha';
+ $this->cache->add($key, $object_a);
+ $object_a->foo = 'bravo';
+ $object_b = $this->cache->get($key);
+ $this->assertSame('alpha', $object_b->foo);
+ $object_b->foo = 'charlie';
+ $this->assertSame('bravo', $object_a->foo);
+ }
+
+ public function testIncr(): void
+ {
+ $key = __FUNCTION__;
+
+ $this->assertFalse($this->cache->incr($key));
+
+ $this->cache->set($key, 0);
+ $this->cache->incr($key);
+ $this->assertSame(1, $this->cache->get($key));
+
+ $this->cache->incr($key, 2);
+ $this->assertSame(3, $this->cache->get($key));
+ }
+
+ public function testWpCacheIncr(): void
+ {
+ $key = __FUNCTION__;
+
+ $this->assertFalse(wp_cache_incr($key));
+
+ wp_cache_set($key, 0);
+ wp_cache_incr($key);
+ $this->assertSame(1, wp_cache_get($key));
+
+ wp_cache_incr($key, 2);
+ $this->assertSame(3, wp_cache_get($key));
+ }
+
+ public function testDecr(): void
+ {
+ $key = __FUNCTION__;
+
+ $this->assertFalse($this->cache->decr($key));
+
+ $this->cache->set($key, 0);
+ $this->cache->decr($key);
+ $this->assertSame(0, $this->cache->get($key));
+
+ $this->cache->set($key, 3);
+ $this->cache->decr($key);
+ $this->assertSame(2, $this->cache->get($key));
+
+ $this->cache->decr($key, 2);
+ $this->assertSame(0, $this->cache->get($key));
+ }
+
+ /**
+ * @ticket 21327
+ */
+ public function testWpCacheDecr(): void
+ {
+ $key = __FUNCTION__;
+
+ $this->assertFalse(wp_cache_decr($key));
+
+ wp_cache_set($key, 0);
+ wp_cache_decr($key);
+ $this->assertSame(0, wp_cache_get($key));
+
+ wp_cache_set($key, 3);
+ wp_cache_decr($key);
+ $this->assertSame(2, wp_cache_get($key));
+
+ wp_cache_decr($key, 2);
+ $this->assertSame(0, wp_cache_get($key));
+ }
+
+ public function testDelete(): void
+ {
+ $key = __FUNCTION__;
+ $val = 'val';
+
+ // Verify set.
+ $this->assertTrue($this->cache->set($key, $val));
+ $this->assertSame($val, $this->cache->get($key));
+
+ // Verify successful delete.
+ $this->assertTrue($this->cache->delete($key));
+ $this->assertFalse($this->cache->get($key));
+
+ $this->assertFalse($this->cache->delete($key, 'default'));
+ }
+
+ public function testWpCacheDelete(): void
+ {
+ $key = __FUNCTION__;
+ $val = 'val';
+
+ // Verify set.
+ $this->assertTrue(wp_cache_set($key, $val));
+ $this->assertSame($val, wp_cache_get($key));
+
+ // Verify successful delete.
+ $this->assertTrue(wp_cache_delete($key));
+ $this->assertFalse(wp_cache_get($key));
+
+ // wp_cache_delete() does not have a $force method.
+ // Delete returns (bool) true when key is not set and $force is true.
+ // $this->assertTrue( wp_cache_delete( $key, 'default', true ) );
+
+ $this->assertFalse(wp_cache_delete($key, 'default'));
+ }
+
+ public function testSwitchToBlog(): void
+ {
+ if (!method_exists($this->cache, 'switch_to_blog')) {
+ $this->markTestSkipped('This test requires a switch_to_blog() method on the cache object.');
+ }
+
+ $key = __FUNCTION__;
+ $val = 'val1';
+ $val2 = 'val2';
+
+ if (!is_multisite()) {
+ // Single site ignores switch_to_blog().
+ $this->assertTrue($this->cache->set($key, $val));
+ $this->assertSame($val, $this->cache->get($key));
+ $this->cache->switch_to_blog(999);
+ $this->assertSame($val, $this->cache->get($key));
+ $this->assertTrue($this->cache->set($key, $val2));
+ $this->assertSame($val2, $this->cache->get($key));
+ $this->cache->switch_to_blog(get_current_blog_id());
+ $this->assertSame($val2, $this->cache->get($key));
+ } else {
+ // Multisite should have separate per-blog caches.
+ $this->assertTrue($this->cache->set($key, $val));
+ $this->assertSame($val, $this->cache->get($key));
+ $this->cache->switch_to_blog(999);
+ $this->assertFalse($this->cache->get($key));
+ $this->assertTrue($this->cache->set($key, $val2));
+ $this->assertSame($val2, $this->cache->get($key));
+ $this->cache->switch_to_blog(get_current_blog_id());
+ $this->assertSame($val, $this->cache->get($key));
+ $this->cache->switch_to_blog(999);
+ $this->assertSame($val2, $this->cache->get($key));
+ $this->cache->switch_to_blog(get_current_blog_id());
+ $this->assertSame($val, $this->cache->get($key));
+ }
+
+ // Global group.
+ $this->assertTrue($this->cache->set($key, $val, 'global-cache-test'));
+ $this->assertSame($val, $this->cache->get($key, 'global-cache-test'));
+ $this->cache->switch_to_blog(999);
+ $this->assertSame($val, $this->cache->get($key, 'global-cache-test'));
+ $this->assertTrue($this->cache->set($key, $val2, 'global-cache-test'));
+ $this->assertSame($val2, $this->cache->get($key, 'global-cache-test'));
+ $this->cache->switch_to_blog(get_current_blog_id());
+ $this->assertSame($val2, $this->cache->get($key, 'global-cache-test'));
+ }
+
+ public function testWpCacheInit(): void
+ {
+ $new_blank_cache_object = new \WP_Object_Cache();
+ wp_cache_init();
+
+ global $wp_object_cache;
+
+ if (wp_using_ext_object_cache()) {
+ // External caches will contain property values that contain non-matching resource IDs.
+ $this->assertInstanceOf('WP_Object_Cache', $wp_object_cache);
+ } else {
+ $this->assertEquals($wp_object_cache, $new_blank_cache_object);
+ }
+ }
+
+ public function testWpCacheReplace(): void
+ {
+ $key = 'my-key';
+ $val1 = 'first-val';
+ $val2 = 'second-val';
+
+ $fake_key = 'my-fake-key';
+
+ // Save the first value to cache and verify.
+ wp_cache_set($key, $val1);
+ $this->assertSame($val1, wp_cache_get($key));
+
+ // Replace the value and verify.
+ wp_cache_replace($key, $val2);
+ $this->assertSame($val2, wp_cache_get($key));
+
+ // Non-existent key should fail.
+ $this->assertFalse(wp_cache_replace($fake_key, $val1));
+
+ // Make sure $fake_key is not stored.
+ $this->assertFalse(wp_cache_get($fake_key));
+ }
+
+ /**
+ * @ticket 20875
+ */
+ public function testGetMultiple(): void
+ {
+ wp_cache_set('foo1', 'bar', 'group1');
+ wp_cache_set('foo2', 'bar', 'group1');
+ wp_cache_set('foo1', 'bar', 'group2');
+
+ $found = wp_cache_get_multiple(['foo1', 'foo2', 'foo3'], 'group1');
+
+ $expected = [
+ 'foo1' => 'bar',
+ 'foo2' => 'bar',
+ 'foo3' => false,
+ ];
+
+ $this->assertSame($expected, $found);
+ }
+}
diff --git a/tests/Feature/PluginMetaTest.php b/tests/Feature/PluginMetaTest.php
new file mode 100644
index 00000000..6cecebca
--- /dev/null
+++ b/tests/Feature/PluginMetaTest.php
@@ -0,0 +1,166 @@
+assertNotNull($this->pluginHeaders(), 'Main plugin file not found');
+ }
+
+ public function testReadmeIncluded(): void
+ {
+ $this->assertNotNull($this->readmeHeaders(), 'Readme not found');
+ }
+
+ public function testDropInIncluded(): void
+ {
+ $this->assertNotNull($this->dropinHeaders(), 'Drop-in not found');
+ }
+
+ /**
+ * @depends testReadmeIncluded
+ * @depends testMainPluginFileIncluded
+ */
+ public function testReadmeStableTagIsUpToDate(): void
+ {
+ $readme_data = $this->readmeHeaders();
+ $plugin_data = $this->pluginHeaders();
+
+ $this->assertEquals(
+ $readme_data['StableTag'],
+ $plugin_data['Version'],
+ 'Version information between main plugin file and readme is not up to date'
+ );
+ }
+
+ /**
+ * @depends testDropInIncluded
+ * @depends testMainPluginFileIncluded
+ */
+ public function testDropInVersionIsUpToDate(): void
+ {
+ $dropin_data = $this->dropinHeaders();
+ $dropin_data['Name'] = trim(preg_replace('/Drop-?In/i', '', $dropin_data['Name']));
+ $plugin_data = $this->pluginHeaders();
+
+ $this->assertArraySubset(
+ $dropin_data,
+ $plugin_data,
+ true,
+ 'Dropin file headers do not match main plugin file headers'
+ );
+ }
+
+ /**
+ * Retrieves an absolute path from the plugin's base directory.
+ *
+ * @param string $relative_path The relative path to change to an absolute one
+ */
+ protected function basepath(string $relative_path): ?string
+ {
+ $basepath = dirname(dirname(__DIR__));
+ $path = realpath(trailingslashit($basepath).$relative_path);
+
+ return $path ?: null;
+ }
+
+ /**
+ * Retrieves file data (headers) from a specific file if the file is readable.
+ *
+ * @param string $path The path of the file
+ * @param array $headers Headers to find. Format: ['key_index'=>'Header in File']
+ *
+ * @return null|array
+ */
+ protected function fileHeaders(string $path, array $headers): ?array
+ {
+ static $data;
+ if (!isset($data[$path])) {
+ $data[$path] = is_readable($path)
+ ? $this->fileData($path, $headers)
+ : null;
+ }
+
+ return $data[$path];
+ }
+
+ /**
+ * Retrieves file data (headers) from a specific file.
+ *
+ * @param string $path The path of the file
+ * @param array $headers Headers to find. Format: ['key_index'=>'Header in File']
+ *
+ * @return array
+ */
+ protected function fileData(string $path, array $headers): array
+ {
+ static $data;
+ if (!isset($data[$path])) {
+ $data[$path] = get_file_data($path, $headers);
+ }
+
+ return $data[$path];
+ }
+
+ protected function readmeHeaders(): ?array
+ {
+ return $this->fileHeaders(
+ $this->basepath(self::README_PATH),
+ [
+ 'TestedUpTo' => 'Tested up to',
+ 'StableTag' => 'Stable tag',
+ ]
+ );
+ }
+
+ protected function dropinHeaders(): ?array
+ {
+ return $this->fileHeaders(
+ $this->basepath(self::DROPIN_PATH),
+ [
+ 'Name' => 'Plugin Name',
+ 'PluginURI' => 'Plugin URI',
+ 'Version' => 'Version',
+ 'Description' => 'Description',
+ 'Author' => 'Author',
+ 'AuthorURI' => 'Author URI',
+ 'License' => 'License',
+ 'LicenseURI' => 'License URI',
+ ]
+ );
+ }
+
+ protected function pluginHeaders(): ?array
+ {
+ return $this->fileHeaders(
+ $this->basepath(self::PLUGIN_PATH),
+ [
+ 'Name' => 'Plugin Name',
+ 'PluginURI' => 'Plugin URI',
+ 'Version' => 'Version',
+ 'Description' => 'Description',
+ 'Author' => 'Author',
+ 'AuthorURI' => 'Author URI',
+ 'License' => 'License',
+ 'LicenseURI' => 'License URI',
+ ]
+ );
+ }
+}
diff --git a/tests/Feature/PluginTest.php b/tests/Feature/PluginTest.php
new file mode 100644
index 00000000..15e7d032
--- /dev/null
+++ b/tests/Feature/PluginTest.php
@@ -0,0 +1,108 @@
+redis_cache()->object_cache_dropin_exists());
+ }
+
+ public function testObjectCacheDropinExistsFailure(): void
+ {
+ $target_file = WP_CONTENT_DIR.'/object-cache.php';
+ $backup_file = WP_CONTENT_DIR.'/object-cache.foo.php';
+
+ if (copy($target_file, $backup_file)) {
+ unlink($target_file);
+ }
+
+ self::assertFalse($this->redis_cache()->object_cache_dropin_exists());
+
+ if (copy($backup_file, $target_file)) {
+ unlink($backup_file);
+ }
+ }
+
+ /**
+ * @depends testObjectCacheDropinExists
+ */
+ public function testValidateObjectCacheDropin(): void
+ {
+ self::assertTrue($this->redis_cache()->validate_object_cache_dropin());
+ }
+
+ /**
+ * @depends testObjectCacheDropinExists
+ */
+ public function testValidateObjectCacheDropinFilter(): void
+ {
+ $test = 0;
+
+ add_filter(
+ 'redis_cache_validate_dropin',
+ function ($is_valid) use (&$test) {
+ ++$test;
+
+ return $is_valid;
+ }
+ );
+
+ $this->redis_cache()->validate_object_cache_dropin();
+
+ // Test if the filter was executed exactly one time.
+ self::assertEquals(1, $test);
+ }
+
+ /**
+ * @depends testObjectCacheDropinExists
+ */
+ public function testObjectCacheDropinOutdated(): void
+ {
+ self::assertFalse($this->redis_cache()->object_cache_dropin_outdated());
+ }
+
+ /**
+ * Retrieves the plugin's instance.
+ *
+ * @return null|Rhubarb\RedisCache\Plugin
+ */
+ protected function redis_cache(): ?Plugin
+ {
+ return redis_object_cache();
+ }
+}
diff --git a/tests/TestCase.php b/tests/TestCase.php
new file mode 100644
index 00000000..8ce229e7
--- /dev/null
+++ b/tests/TestCase.php
@@ -0,0 +1,57 @@
+cache = $this->init_cache();
+ }
+
+ public function tear_down()
+ {
+ // Your own additional tear down.
+ parent::tear_down();
+ }
+
+ protected function init_cache()
+ {
+ global $wp_object_cache;
+
+ $cache_class = get_class($wp_object_cache);
+ $cache = new $cache_class();
+ $cache->add_global_groups([
+ 'global-cache-test',
+ 'users',
+ 'userlogins',
+ 'usermeta',
+ 'user_meta',
+ 'useremail',
+ 'userslugs',
+ 'site-transient',
+ 'site-options',
+ 'blog-lookup',
+ 'blog-details',
+ 'rss',
+ 'global-posts',
+ 'blog-id-cache',
+ 'networks',
+ 'sites',
+ 'site-details',
+ ]);
+
+ return $cache;
+ }
+}
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
new file mode 100644
index 00000000..c34bce67
--- /dev/null
+++ b/tests/bootstrap.php
@@ -0,0 +1,45 @@
+ ['redis-cache/redis-cache.php'],
+];
+
+require_once dirname(__DIR__).'/vendor/yoast/wp-test-utils/src/WPIntegration/bootstrap-functions.php';
+
+/*
+ * Bootstrap WordPress. This will also load the Composer autoload file, the PHPUnit Polyfills
+ * and the custom autoloader for the TestCase and the mock object classes.
+ */
+WPIntegration\bootstrap_it();
+
+if (!defined('WP_PLUGIN_DIR') || false === file_exists(WP_PLUGIN_DIR.'/redis-cache/redis-cache.php')) {
+ echo PHP_EOL, 'ERROR: Please check whether the WP_PLUGIN_DIR environment variable is set and set to the correct value. The integration test suite won\'t be able to run without it.', PHP_EOL;
+
+ exit(1);
+}
+
+require_once __DIR__.'/../redis-cache.php';
diff --git a/tests/phpstan/boostrap.php b/tests/phpstan/boostrap.php
deleted file mode 100644
index 5512980c..00000000
--- a/tests/phpstan/boostrap.php
+++ /dev/null
@@ -1,20 +0,0 @@
- \true, 'QueryMonitor' => \true, 'W3_Db' => \true, 'Debug_Bar_PHP' => \true, 'WP_Hook' => \true);
- protected static $ignore_method = array();
- protected static $ignore_func = array('include_once' => \true, 'require_once' => \true, 'include' => \true, 'require' => \true, 'call_user_func_array' => \true, 'call_user_func' => \true, 'trigger_error' => \true, '_doing_it_wrong' => \true, '_deprecated_argument' => \true, '_deprecated_file' => \true, '_deprecated_function' => \true, 'dbDelta' => \true);
- protected static $show_args = array('do_action' => 1, 'apply_filters' => 1, 'do_action_ref_array' => 1, 'apply_filters_ref_array' => 1, 'get_template_part' => 2, 'get_extended_template_part' => 2, 'load_template' => 'dir', 'dynamic_sidebar' => 1, 'get_header' => 1, 'get_sidebar' => 1, 'get_footer' => 1, 'class_exists' => 2, 'current_user_can' => 3, 'user_can' => 4, 'current_user_can_for_blog' => 4, 'author_can' => 4);
- protected static $filtered = \false;
- protected $trace = \null;
- protected $filtered_trace = \null;
- protected $calling_line = 0;
- protected $calling_file = '';
- public function __construct(array $args = array(), array $trace = \null)
- {
- }
- public function get_stack()
- {
- }
- public function get_caller()
- {
- }
- public function get_component()
- {
- }
- public static function get_frame_component(array $frame)
- {
- }
- public function get_trace()
- {
- }
- public function get_display_trace()
- {
- }
- public function get_filtered_trace()
- {
- }
- public function ignore($num)
- {
- }
- public function ignore_current_filter()
- {
- }
- public function filter_trace(array $frame)
- {
- }
-}
-abstract class QM_Dispatcher
-{
- /**
- * Outputter instances.
- *
- * @var QM_Output[] Array of outputters.
- */
- protected $outputters = array();
- /**
- * Query Monitor plugin instance.
- *
- * @var QM_Plugin Plugin instance.
- */
- protected $qm;
- public function __construct(\QM_Plugin $qm)
- {
- }
- public abstract function is_active();
- public final function should_dispatch()
- {
- }
- /**
- * Processes and fetches the outputters for this dispatcher.
- *
- * @param string $outputter_id The outputter ID.
- * @return QM_Output[] Array of outputters.
- */
- public function get_outputters($outputter_id)
- {
- }
- public function init()
- {
- }
- protected function before_output()
- {
- }
- protected function after_output()
- {
- }
- public static function user_can_view()
- {
- }
- public static function user_verified()
- {
- }
- public static function editor_cookie()
- {
- }
- public static function verify_cookie($value)
- {
- }
-}
-/**
- * Timer that collects timing and memory usage.
- *
- * @package query-monitor
- */
-class QM_Timer
-{
- protected $start = \null;
- protected $end = \null;
- protected $trace = \null;
- protected $laps = array();
- public function start(array $data = \null)
- {
- }
- public function stop(array $data = \null)
- {
- }
- public function lap(array $data = \null, $name = \null)
- {
- }
- public function get_laps()
- {
- }
- public function get_time()
- {
- }
- public function get_memory()
- {
- }
- public function get_start_time()
- {
- }
- public function get_start_memory()
- {
- }
- public function get_end_time()
- {
- }
- public function get_end_memory()
- {
- }
- public function get_trace()
- {
- }
- public function end(array $data = \null)
- {
- }
-}
-abstract class QM_Plugin
-{
- private $plugin = array();
- public static $minimum_php_version = '5.3.6';
- /**
- * Class constructor
- */
- protected function __construct($file)
- {
- }
- /**
- * Returns the URL for for a file/dir within this plugin.
- *
- * @param string $file The path within this plugin, e.g. '/js/clever-fx.js'
- * @return string URL
- */
- public final function plugin_url($file = '')
- {
- }
- /**
- * Returns the filesystem path for a file/dir within this plugin.
- *
- * @param string $file The path within this plugin, e.g. '/js/clever-fx.js'
- * @return string Filesystem path
- */
- public final function plugin_path($file = '')
- {
- }
- /**
- * Returns a version number for the given plugin file.
- *
- * @param string $file The path within this plugin, e.g. '/js/clever-fx.js'
- * @return string Version
- */
- public final function plugin_ver($file)
- {
- }
- /**
- * Returns the current plugin's basename, eg. 'my_plugin/my_plugin.php'.
- *
- * @return string Basename
- */
- public final function plugin_base()
- {
- }
- /**
- * Populates and returns the current plugin info.
- */
- private final function _plugin($item, $file = '')
- {
- }
- public static function php_version_met()
- {
- }
- public static function php_version_nope()
- {
- }
-}
-/**
- * Plugin activation handler.
- *
- * @package query-monitor
- */
-class QM_Activation extends \QM_Plugin
-{
- protected function __construct($file)
- {
- }
- public function activate($sitewide = \false)
- {
- }
- public function deactivate()
- {
- }
- public function filter_active_plugins($plugins)
- {
- }
- public function filter_active_sitewide_plugins($plugins)
- {
- }
- public function php_notice()
- {
- }
- public static function init($file = \null)
- {
- }
-}
-/**
- * A convenience class for wrapping certain user-facing functionality.
- *
- * @package query-monitor
- */
-class QM
-{
- public static function emergency($message, array $context = array())
- {
- }
- public static function alert($message, array $context = array())
- {
- }
- public static function critical($message, array $context = array())
- {
- }
- public static function error($message, array $context = array())
- {
- }
- public static function warning($message, array $context = array())
- {
- }
- public static function notice($message, array $context = array())
- {
- }
- public static function info($message, array $context = array())
- {
- }
- public static function debug($message, array $context = array())
- {
- }
- public static function log($level, $message, array $context = array())
- {
- }
-}
-/**
- * Mock 'Debug Bar' plugin class.
- *
- * @package query-monitor
- */
-class Debug_Bar
-{
- public $panels = array();
- public function __construct()
- {
- }
- public function enqueue()
- {
- }
- public function init_panels()
- {
- }
- public function ensure_ajaxurl()
- {
- }
- public function Debug_Bar()
- {
- }
-}
-class QM_Collectors implements \IteratorAggregate
-{
- private $items = array();
- private $processed = \false;
- public function getIterator()
- {
- }
- public static function add(\QM_Collector $collector)
- {
- }
- /**
- * Fetches a collector instance.
- *
- * @param string $id The collector ID.
- * @return QM_Collector|null The collector object.
- */
- public static function get($id)
- {
- }
- public static function init()
- {
- }
- public function process()
- {
- }
-}
-abstract class QM_Collector
-{
- protected $timer;
- protected $data = array('types' => array(), 'component_times' => array());
- protected static $hide_qm = \null;
- public $concerned_actions = array();
- public $concerned_filters = array();
- public $concerned_constants = array();
- public $tracked_hooks = array();
- public function __construct()
- {
- }
- public final function id()
- {
- }
- protected function log_type($type)
- {
- }
- protected function maybe_log_dupe($sql, $i)
- {
- }
- protected function log_component($component, $ltime, $type)
- {
- }
- public static function timer_stop_float()
- {
- }
- public static function format_bool_constant($constant)
- {
- }
- public final function get_data()
- {
- }
- public final function set_id($id)
- {
- }
- public final function process_concerns()
- {
- }
- public function filter_concerns($concerns)
- {
- }
- public static function format_user(\WP_User $user_object)
- {
- }
- public static function enabled()
- {
- }
- public static function hide_qm()
- {
- }
- public function filter_remove_qm(array $item)
- {
- }
- public function process()
- {
- }
- public function post_process()
- {
- }
- public function tear_down()
- {
- }
- public function get_timer()
- {
- }
- public function set_timer(\QM_Timer $timer)
- {
- }
- public function get_concerned_actions()
- {
- }
- public function get_concerned_filters()
- {
- }
- public function get_concerned_options()
- {
- }
- public function get_concerned_constants()
- {
- }
-}
-/**
- * Plugin CLI command.
- *
- * @package query-monitor
- */
-class QM_CLI extends \QM_Plugin
-{
- protected function __construct($file)
- {
- }
- /**
- * Enable QM by creating the symlink for db.php
- */
- public function enable()
- {
- }
- public static function init($file = \null)
- {
- }
-}
-/**
- * The main Query Monitor plugin class.
- *
- * @package query-monitor
- */
-class QueryMonitor extends \QM_Plugin
-{
- protected function __construct($file)
- {
- }
- public function filter_plugin_action_links(array $actions)
- {
- }
- /**
- * Filter a user's capabilities so they can be altered at runtime.
- *
- * This is used to:
- * - Grant the 'view_query_monitor' capability to the user if they have the ability to manage options.
- *
- * This does not get called for Super Admins.
- *
- * @param bool[] $user_caps Array of key/value pairs where keys represent a capability name and boolean values
- * represent whether the user has that capability.
- * @param string[] $required_caps Required primitive capabilities for the requested capability.
- * @param array $args {
- * Arguments that accompany the requested capability check.
- *
- * @type string $0 Requested capability.
- * @type int $1 Concerned user ID.
- * @type mixed ...$2 Optional second and further parameters.
- * }
- * @param WP_User $user Concerned user object.
- * @return bool[] Concerned user's capabilities.
- */
- public function filter_user_has_cap(array $user_caps, array $required_caps, array $args, \WP_User $user)
- {
- }
- public function action_plugins_loaded()
- {
- }
- public function action_init()
- {
- }
- public static function symlink_warning()
- {
- }
- /**
- * Registers the Query Monitor user capability group for the Members plugin.
- *
- * @link https://wordpress.org/plugins/members/
- */
- public function action_register_members_groups()
- {
- }
- /**
- * Registers the View Query Monitor user capability for the Members plugin.
- *
- * @link https://wordpress.org/plugins/members/
- */
- public function action_register_members_caps()
- {
- }
- /**
- * Registers the Query Monitor user capability group for the User Role Editor plugin.
- *
- * @link https://wordpress.org/plugins/user-role-editor/
- *
- * @param array[] $groups Array of existing groups.
- * @return array[] Updated array of groups.
- */
- public function filter_ure_groups(array $groups)
- {
- }
- /**
- * Registers the View Query Monitor user capability for the User Role Editor plugin.
- *
- * @link https://wordpress.org/plugins/user-role-editor/
- *
- * @param array[] $caps Array of existing capabilities.
- * @return array[] Updated array of capabilities.
- */
- public function filter_ure_caps(array $caps)
- {
- }
- public static function init($file = \null)
- {
- }
-}
-class QM_Util
-{
- protected static $file_components = array();
- protected static $file_dirs = array();
- protected static $abspath = \null;
- protected static $contentpath = \null;
- protected static $sort_field = \null;
- private function __construct()
- {
- }
- public static function convert_hr_to_bytes($size)
- {
- }
- public static function standard_dir($dir, $path_replace = \null)
- {
- }
- public static function normalize_path($path)
- {
- }
- public static function get_file_dirs()
- {
- }
- public static function get_file_component($file)
- {
- }
- public static function populate_callback(array $callback)
- {
- }
- public static function is_ajax()
- {
- }
- public static function is_async()
- {
- }
- public static function get_admins()
- {
- }
- public static function is_multi_network()
- {
- }
- public static function get_client_version($client)
- {
- }
- public static function get_query_type($sql)
- {
- }
- public static function display_variable($value)
- {
- }
- /**
- * Shortens a fully qualified name to reduce the length of the names of long namespaced symbols.
- *
- * This initialises portions that do not form the first or last portion of the name. For example:
- *
- * Inpsyde\Wonolog\HookListener\HookListenersRegistry->hook_callback()
- *
- * becomes:
- *
- * Inpsyde\W\H\HookListenersRegistry->hook_callback()
- *
- * @param string $fqn A fully qualified name.
- * @return string A shortened version of the name.
- */
- public static function shorten_fqn($fqn)
- {
- }
- /**
- * Helper function for JSON encoding data and formatting it in a consistent and compatible manner.
- *
- * @param mixed $data The data to be JSON encoded.
- * @return string The JSON encoded data.
- */
- public static function json_format($data)
- {
- }
- public static function is_stringy($data)
- {
- }
- public static function sort(array &$array, $field)
- {
- }
- public static function rsort(array &$array, $field)
- {
- }
- private static function _rsort($a, $b)
- {
- }
- private static function _sort($a, $b)
- {
- }
-}
-/**
- * Abstract output class for HTML pages.
- *
- * @package query-monitor
- */
-abstract class QM_Output_Html extends \QM_Output
-{
- protected static $file_link_format = \null;
- protected $current_id = \null;
- protected $current_name = \null;
- public function name()
- {
- }
- public function admin_menu(array $menu)
- {
- }
- public function get_output()
- {
- }
- protected function before_tabular_output($id = \null, $name = \null)
- {
- }
- protected function after_tabular_output()
- {
- }
- protected function before_non_tabular_output($id = \null, $name = \null)
- {
- }
- protected function after_non_tabular_output()
- {
- }
- protected function output_concerns()
- {
- }
- protected function before_debug_bar_output($id = \null, $name = \null)
- {
- }
- protected function after_debug_bar_output()
- {
- }
- protected function build_notice($notice)
- {
- }
- public static function output_inner($vars)
- {
- }
- /**
- * Returns the table filter controls. Safe for output.
- *
- * @param string $name The name for the `data-` attributes that get filtered by this control.
- * @param string[] $values Option values for this control.
- * @param string $label Label text for the filter control.
- * @param array $args {
- * @type string $highlight The name for the `data-` attributes that get highlighted by this control.
- * @type array $prepend Associative array of options to prepend to the list of values.
- * @type array $append Associative array of options to append to the list of values.
- * }
- * @return string Markup for the table filter controls.
- */
- protected function build_filter($name, array $values, $label, $args = array())
- {
- }
- /**
- * Returns the column sorter controls. Safe for output.
- *
- * @param string $heading Heading text for the column. Optional.
- * @return string Markup for the column sorter controls.
- */
- protected function build_sorter($heading = '')
- {
- }
- /**
- * Returns a toggle control. Safe for output.
- *
- * @return string Markup for the column sorter controls.
- */
- protected static function build_toggler()
- {
- }
- protected function menu(array $args)
- {
- }
- /**
- * Returns the given SQL string in a nicely presented format. Safe for output.
- *
- * @param string $sql An SQL query string.
- * @return string The SQL formatted with markup.
- */
- public static function format_sql($sql)
- {
- }
- /**
- * Returns the given URL in a nicely presented format. Safe for output.
- *
- * @param string $url A URL.
- * @return string The URL formatted with markup.
- */
- public static function format_url($url)
- {
- }
- /**
- * Returns a file path, name, and line number, or a clickable link to the file. Safe for output.
- *
- * @link https://querymonitor.com/blog/2019/02/clickable-stack-traces-and-function-names-in-query-monitor/
- *
- * @param string $text The display text, such as a function name or file name.
- * @param string $file The full file path and name.
- * @param int $line Optional. A line number, if appropriate.
- * @param bool $is_filename Optional. Is the text a plain file name? Default false.
- * @return string The fully formatted file link or file name, safe for output.
- */
- public static function output_filename($text, $file, $line = 0, $is_filename = \false)
- {
- }
- /**
- * Provides a protocol URL for edit links in QM stack traces for various editors.
- *
- * @param string $editor the chosen code editor
- * @param string $default_format a format to use if no editor is found
- *
- * @return string a protocol URL format
- */
- public static function get_editor_file_link_format($editor, $default_format)
- {
- }
- public static function get_file_link_format()
- {
- }
- public static function get_file_path_map()
- {
- }
- public static function has_clickable_links()
- {
- }
-}
-/**
- * Abstract output class for HTTP headers.
- *
- * @package query-monitor
- */
-abstract class QM_Output_Headers extends \QM_Output
-{
- public function output()
- {
- }
-}
-/**
- * HTTP redirects output for HTTP headers.
- *
- * @package query-monitor
- */
-class QM_Output_Headers_Redirects extends \QM_Output_Headers
-{
- /**
- * Collector instance.
- *
- * @var QM_Collector_Redirects Collector.
- */
- protected $collector;
- public function get_output()
- {
- }
-}
-/**
- * General overview output for HTTP headers.
- *
- * @package query-monitor
- */
-class QM_Output_Headers_Overview extends \QM_Output_Headers
-{
- /**
- * Collector instance.
- *
- * @var QM_Collector_Overview Collector.
- */
- protected $collector;
- public function get_output()
- {
- }
-}
-/**
- * PHP error output for HTTP headers.
- *
- * @package query-monitor
- */
-class QM_Output_Headers_PHP_Errors extends \QM_Output_Headers
-{
- /**
- * Collector instance.
- *
- * @var QM_Collector_PHP_Errors Collector.
- */
- protected $collector;
- public function get_output()
- {
- }
-}
-/**
- * General overview output for HTML pages.
- *
- * @package query-monitor
- */
-class QM_Output_Html_Overview extends \QM_Output_Html
-{
- /**
- * Collector instance.
- *
- * @var QM_Collector_Overview Collector.
- */
- protected $collector;
- public function __construct(\QM_Collector $collector)
- {
- }
- public function name()
- {
- }
- public function output()
- {
- }
- public function admin_title(array $existing)
- {
- }
-}
-/**
- * Request data output for HTML pages.
- *
- * @package query-monitor
- */
-class QM_Output_Html_Request extends \QM_Output_Html
-{
- /**
- * Collector instance.
- *
- * @var QM_Collector_Request Collector.
- */
- protected $collector;
- public function __construct(\QM_Collector $collector)
- {
- }
- public function name()
- {
- }
- public function output()
- {
- }
- public function admin_menu(array $menu)
- {
- }
-}
-/**
- * Database query output for HTML pages.
- *
- * @package query-monitor
- */
-class QM_Output_Html_DB_Queries extends \QM_Output_Html
-{
- /**
- * Collector instance.
- *
- * @var QM_Collector_DB_Queries Collector.
- */
- protected $collector;
- public $query_row = 0;
- public function __construct(\QM_Collector $collector)
- {
- }
- public function name()
- {
- }
- public function output()
- {
- }
- protected function output_empty_queries()
- {
- }
- protected function output_error_queries(array $errors)
- {
- }
- protected function output_expensive_queries(array $expensive)
- {
- }
- protected function output_queries($name, \stdClass $db, array $data)
- {
- }
- protected function output_query_row(array $row, array $cols)
- {
- }
- public function admin_title(array $existing)
- {
- }
- public function admin_class(array $class)
- {
- }
- public function admin_menu(array $menu)
- {
- }
- public function panel_menu(array $menu)
- {
- }
-}
-/**
- * Language and locale output for HTML pages.
- *
- * @package query-monitor
- */
-class QM_Output_Html_Languages extends \QM_Output_Html
-{
- /**
- * Collector instance.
- *
- * @var QM_Collector_Languages Collector.
- */
- protected $collector;
- public function __construct(\QM_Collector $collector)
- {
- }
- public function name()
- {
- }
- public function output()
- {
- }
- public function admin_menu(array $menu)
- {
- }
-}
-/**
- * Template and theme output for HTML pages.
- *
- * @package query-monitor
- */
-class QM_Output_Html_Theme extends \QM_Output_Html
-{
- /**
- * Collector instance.
- *
- * @var QM_Collector_Theme Collector.
- */
- protected $collector;
- public function __construct(\QM_Collector $collector)
- {
- }
- public function name()
- {
- }
- public function output()
- {
- }
- public function admin_menu(array $menu)
- {
- }
- public function panel_menu(array $menu)
- {
- }
-}
-/**
- * PHP error output for HTML pages.
- *
- * @package query-monitor
- */
-class QM_Output_Html_PHP_Errors extends \QM_Output_Html
-{
- /**
- * Collector instance.
- *
- * @var QM_Collector_PHP_Errors Collector.
- */
- protected $collector;
- public function __construct(\QM_Collector $collector)
- {
- }
- public function name()
- {
- }
- public function output()
- {
- }
- public function admin_class(array $class)
- {
- }
- public function admin_menu(array $menu)
- {
- }
- public function panel_menu(array $menu)
- {
- }
-}
-/**
- * Database query calling function output for HTML pages.
- *
- * @package query-monitor
- */
-class QM_Output_Html_DB_Callers extends \QM_Output_Html
-{
- /**
- * Collector instance.
- *
- * @var QM_Collector_DB_Callers Collector.
- */
- protected $collector;
- public function __construct(\QM_Collector $collector)
- {
- }
- public function name()
- {
- }
- public function output()
- {
- }
- public function panel_menu(array $menu)
- {
- }
-}
-/**
- * Duplicate database query output for HTML pages.
- *
- * @package query-monitor
- */
-class QM_Output_Html_DB_Dupes extends \QM_Output_Html
-{
- /**
- * Collector instance.
- *
- * @var QM_Collector_DB_Dupes Collector.
- */
- protected $collector;
- public function __construct(\QM_Collector $collector)
- {
- }
- public function name()
- {
- }
- public function output()
- {
- }
- public function admin_menu(array $menu)
- {
- }
- public function panel_menu(array $menu)
- {
- }
-}
-/**
- * Template conditionals output for HTML pages.
- *
- * @package query-monitor
- */
-class QM_Output_Html_Conditionals extends \QM_Output_Html
-{
- /**
- * Collector instance.
- *
- * @var QM_Collector_Conditionals Collector.
- */
- protected $collector;
- public function __construct(\QM_Collector $collector)
- {
- }
- public function name()
- {
- }
- public function output()
- {
- }
- public function admin_menu(array $menu)
- {
- }
- public function panel_menu(array $menu)
- {
- }
-}
-/**
- * Scripts and styles output for HTML pages.
- *
- * @package query-monitor
- */
-abstract class QM_Output_Html_Assets extends \QM_Output_Html
-{
- /**
- * Collector instance.
- *
- * @var QM_Collector_Assets Collector.
- */
- protected $collector;
- public function __construct(\QM_Collector $collector)
- {
- }
- public abstract function get_type_labels();
- public function output()
- {
- }
- protected function dependency_row($handle, array $asset, $label)
- {
- }
- public function _prefix_type($val)
- {
- }
- public function admin_class(array $class)
- {
- }
- public function admin_menu(array $menu)
- {
- }
-}
-/**
- * Enqueued scripts output for HTML pages.
- *
- * @package query-monitor
- */
-class QM_Output_Html_Assets_Scripts extends \QM_Output_Html_Assets
-{
- /**
- * Collector instance.
- *
- * @var QM_Collector_Assets_Scripts Collector.
- */
- protected $collector;
- public function name()
- {
- }
- public function get_type_labels()
- {
- }
-}
-/**
- * Timing and profiling output for HTML pages.
- *
- * @package query-monitor
- */
-class QM_Output_Html_Timing extends \QM_Output_Html
-{
- /**
- * Collector instance.
- *
- * @var QM_Collector_Timing Collector.
- */
- protected $collector;
- public function __construct(\QM_Collector $collector)
- {
- }
- public function name()
- {
- }
- public function output()
- {
- }
- public function admin_menu(array $menu)
- {
- }
-}
-/**
- * Database query calling component output for HTML pages.
- *
- * @package query-monitor
- */
-class QM_Output_Html_DB_Components extends \QM_Output_Html
-{
- /**
- * Collector instance.
- *
- * @var QM_Collector_DB_Components Collector.
- */
- protected $collector;
- public function __construct(\QM_Collector $collector)
- {
- }
- public function name()
- {
- }
- public function output()
- {
- }
- public function panel_menu(array $menu)
- {
- }
-}
-/**
- * Admin screen output for HTML pages.
- *
- * @package query-monitor
- */
-class QM_Output_Html_Admin extends \QM_Output_Html
-{
- /**
- * Collector instance.
- *
- * @var QM_Collector_Admin Collector.
- */
- protected $collector;
- public function __construct(\QM_Collector $collector)
- {
- }
- public function name()
- {
- }
- public function output()
- {
- }
-}
-/**
- * Block editor data output for HTML pages.
- *
- * @package query-monitor
- */
-class QM_Output_Html_Block_Editor extends \QM_Output_Html
-{
- /**
- * Collector instance.
- *
- * @var QM_Collector_Block_Editor Collector.
- */
- protected $collector;
- public function __construct(\QM_Collector $collector)
- {
- }
- public function name()
- {
- }
- public function output()
- {
- }
- protected static function render_block($i, array $block, array $data)
- {
- }
- public function admin_menu(array $menu)
- {
- }
-}
-/**
- * User capability checks output for HTML pages.
- *
- * @package query-monitor
- */
-class QM_Output_Html_Caps extends \QM_Output_Html
-{
- /**
- * Collector instance.
- *
- * @var QM_Collector_Caps Collector.
- */
- protected $collector;
- public function __construct(\QM_Collector $collector)
- {
- }
- public function name()
- {
- }
- public function output()
- {
- }
- public function admin_menu(array $menu)
- {
- }
-}
-/**
- * HTTP API request output for HTML pages.
- *
- * @package query-monitor
- */
-class QM_Output_Html_HTTP extends \QM_Output_Html
-{
- /**
- * Collector instance.
- *
- * @var QM_Collector_HTTP Collector.
- */
- protected $collector;
- public function __construct(\QM_Collector $collector)
- {
- }
- public function name()
- {
- }
- public function output()
- {
- }
- public function admin_class(array $class)
- {
- }
- public function admin_menu(array $menu)
- {
- }
-}
-/**
- * Enqueued styles output for HTML pages.
- *
- * @package query-monitor
- */
-class QM_Output_Html_Assets_Styles extends \QM_Output_Html_Assets
-{
- /**
- * Collector instance.
- *
- * @var QM_Collector_Assets_Styles Collector.
- */
- protected $collector;
- public function name()
- {
- }
- public function get_type_labels()
- {
- }
-}
-/**
- * 'Debug Bar' output for HTML pages.
- *
- * @package query-monitor
- */
-class QM_Output_Html_Debug_Bar extends \QM_Output_Html
-{
- /**
- * Collector instance.
- *
- * @var QM_Collector_Debug_Bar Collector.
- */
- protected $collector;
- public function __construct(\QM_Collector $collector)
- {
- }
- public function name()
- {
- }
- public function output()
- {
- }
-}
-/**
- * Hooks and actions output for HTML pages.
- *
- * @package query-monitor
- */
-class QM_Output_Html_Hooks extends \QM_Output_Html
-{
- /**
- * Collector instance.
- *
- * @var QM_Collector_Hooks Collector.
- */
- protected $collector;
- public function __construct(\QM_Collector $collector)
- {
- }
- public function name()
- {
- }
- public function output()
- {
- }
- public static function output_hook_table(array $hooks)
- {
- }
-}
-/**
- * Environment data output for HTML pages.
- *
- * @package query-monitor
- */
-class QM_Output_Html_Environment extends \QM_Output_Html
-{
- /**
- * Collector instance.
- *
- * @var QM_Collector_Environment Collector.
- */
- protected $collector;
- public function __construct(\QM_Collector $collector)
- {
- }
- public function name()
- {
- }
- public function output()
- {
- }
-}
-/**
- * Request and response headers output for HTML pages.
- *
- * @package query-monitor
- */
-class QM_Output_Html_Headers extends \QM_Output_Html
-{
- /**
- * Collector instance.
- *
- * @var QM_Collector_Raw_Request Collector.
- */
- protected $collector;
- public function __construct(\QM_Collector $collector)
- {
- }
- /**
- * Collector name.
- *
- * This is unused.
- *
- * @return string
- */
- public function name()
- {
- }
- public function output()
- {
- }
- public function output_request()
- {
- }
- public function output_response()
- {
- }
- protected function output_header_table(array $headers, $title)
- {
- }
- public function panel_menu(array $menu)
- {
- }
-}
-/**
- * PSR-3 compatible logging output for HTML pages.
- *
- * @package query-monitor
- */
-class QM_Output_Html_Logger extends \QM_Output_Html
-{
- /**
- * Collector instance.
- *
- * @var QM_Collector_Logger Collector.
- */
- protected $collector;
- public function __construct(\QM_Collector $collector)
- {
- }
- public function name()
- {
- }
- public function output()
- {
- }
- public function admin_class(array $class)
- {
- }
- public function admin_menu(array $menu)
- {
- }
-}
-/**
- * Transient storage output for HTML pages.
- *
- * @package query-monitor
- */
-class QM_Output_Html_Transients extends \QM_Output_Html
-{
- /**
- * Collector instance.
- *
- * @var QM_Collector_Transients Collector.
- */
- protected $collector;
- public function __construct(\QM_Collector $collector)
- {
- }
- public function name()
- {
- }
- public function output()
- {
- }
- public function admin_menu(array $menu)
- {
- }
-}
\ No newline at end of file
diff --git a/tests/phpunit/bootstrap.php b/tests/phpunit/bootstrap.php
deleted file mode 100644
index d3aa634d..00000000
--- a/tests/phpunit/bootstrap.php
+++ /dev/null
@@ -1,58 +0,0 @@
- [
- 'redis-cache/redis-cache.php',
- ],
-];
-
-if ( getenv('GH_REDIS_CLUSTER') ) {
- define('WP_REDIS_CLUSTER', [
- 'tcp://127.0.0.1:6379',
- 'tcp://127.0.0.1:6380',
- 'tcp://127.0.0.1:6381',
- 'tcp://127.0.0.1:6382',
- 'tcp://127.0.0.1:6383',
- 'tcp://127.0.0.1:6384',
- ]);
-}
-
-$_tests_dir = getenv('WP_TESTS_DIR');
-
-if ( ! getenv('WP_TESTS_DIR') ) {
- $_tests_dir = '/opt/bitnami/wordpress/tests-lib';
-}
-
-$base_dir = dirname( dirname( __DIR__ ) );
-
-// Give access to tests_add_filter() function.
-require_once $_tests_dir . '/includes/functions.php';
-
-/**
- * Manually load the plugin being tested.
- */
-tests_add_filter(
- 'muplugins_loaded',
- function() use ( $base_dir ) {
- require $base_dir . '/redis-cache.php';
- }
-);
-
-// Start up the WP testing environment.
-require_once $_tests_dir . '/includes/bootstrap.php';
-
-// Adds composer.
-require_once $base_dir . '/vendor/autoload.php';
-
-require_once __DIR__ . '/class-roc-unit-test-case.php';
-
-// Installs object cache
-copy(
- ROC_Unit_Test_Case::basepath( 'includes/object-cache.php' ),
- WP_CONTENT_DIR . '/object-cache.php'
-);
diff --git a/tests/phpunit/cache/class-cache-test.php b/tests/phpunit/cache/class-cache-test.php
deleted file mode 100644
index 54b10fc1..00000000
--- a/tests/phpunit/cache/class-cache-test.php
+++ /dev/null
@@ -1,352 +0,0 @@
-cache =& $this->init_cache();
- }
-
- function tearDown(): void {
- $this->flush_cache();
- parent::tearDown();
- }
-
- function &init_cache() {
- global $wp_object_cache;
- $cache_class = get_class( $wp_object_cache );
- $cache = new $cache_class();
- $cache->add_global_groups( array( 'global-cache-test', 'users', 'userlogins', 'usermeta', 'user_meta', 'useremail', 'userslugs', 'site-transient', 'site-options', 'blog-lookup', 'blog-details', 'rss', 'global-posts', 'blog-id-cache', 'networks', 'sites', 'site-details' ) );
- return $cache;
- }
-
- function test_miss(): void {
- $this->assertFalse( $this->cache->get( 'test_miss' ) );
- }
-
- function test_add_get(): void {
- $key = __FUNCTION__;
- $val = 'val';
-
- $this->cache->add( $key, $val );
- $this->assertSame( $val, $this->cache->get( $key ) );
- }
-
- function test_add_get_0(): void {
- $key = __FUNCTION__;
- $val = 0;
-
- // You can store zero in the cache.
- $this->assertTrue( $this->cache->add( $key, $val ) );
- $this->assertSame( $val, $this->cache->get( $key ) );
- }
-
- /**
- * @ticket 20004
- */
- function test_add_get_null(): void {
- $key = __FUNCTION__;
- $val = null;
-
- // You can store `null` in the cache.
- $this->assertTrue( $this->cache->add( $key, $val ) );
- $this->assertSame( $val, $this->cache->get( $key ) );
- }
-
- /**
- * @ticket 20004
- */
- function test_add_get_false(): void {
- $key = __FUNCTION__;
- $val = false;
-
- // You can store `false` in the cache.
- $this->assertTrue( $this->cache->add( $key, $val ) );
- $this->assertSame( $val, $this->cache->get( $key ) );
- }
-
- function test_add(): void {
- $key = __FUNCTION__;
- $val1 = 'val1';
- $val2 = 'val2';
-
- // Add $key to the cache.
- $this->assertTrue( $this->cache->add( $key, $val1 ) );
- $this->assertSame( $val1, $this->cache->get( $key ) );
- // $key is in the cache, so reject new calls to add().
- $this->assertFalse( $this->cache->add( $key, $val2 ) );
- $this->assertSame( $val1, $this->cache->get( $key ) );
- }
-
- function test_replace(): void {
- $key = __FUNCTION__;
- $val = 'val1';
- $val2 = 'val2';
-
- // memcached rejects replace() if the key does not exist.
- $this->assertFalse( $this->cache->replace( $key, $val ) );
- $this->assertFalse( $this->cache->get( $key ) );
- $this->assertTrue( $this->cache->add( $key, $val ) );
- $this->assertSame( $val, $this->cache->get( $key ) );
- $this->assertTrue( $this->cache->replace( $key, $val2 ) );
- $this->assertSame( $val2, $this->cache->get( $key ) );
- }
-
- function test_set(): void {
- $key = __FUNCTION__;
- $val1 = 'val1';
- $val2 = 'val2';
-
- // memcached accepts set() if the key does not exist.
- $this->assertTrue( $this->cache->set( $key, $val1 ) );
- $this->assertSame( $val1, $this->cache->get( $key ) );
- // Second set() with same key should be allowed.
- $this->assertTrue( $this->cache->set( $key, $val2 ) );
- $this->assertSame( $val2, $this->cache->get( $key ) );
- }
-
- function test_flush(): void {
- global $_wp_using_ext_object_cache;
-
- if ( $_wp_using_ext_object_cache ) {
- $this->markTestSkipped( 'This test requires that an external object cache is not in use.' );
- }
-
- $key = __FUNCTION__;
- $val = 'val';
-
- $this->cache->add( $key, $val );
- // Item is visible to both cache objects.
- $this->assertSame( $val, $this->cache->get( $key ) );
- $this->cache->flush();
- // If there is no value get returns false.
- $this->assertFalse( $this->cache->get( $key ) );
- }
-
- // Make sure objects are cloned going to and from the cache.
- function test_object_refs(): void {
- $key = __FUNCTION__ . '_1';
- $object_a = new stdClass;
- $object_a->foo = 'alpha';
- $this->cache->set( $key, $object_a );
- $object_a->foo = 'bravo';
- $object_b = $this->cache->get( $key );
- $this->assertSame( 'alpha', $object_b->foo );
- $object_b->foo = 'charlie';
- $this->assertSame( 'bravo', $object_a->foo );
-
- $key = __FUNCTION__ . '_2';
- $object_a = new stdClass;
- $object_a->foo = 'alpha';
- $this->cache->add( $key, $object_a );
- $object_a->foo = 'bravo';
- $object_b = $this->cache->get( $key );
- $this->assertSame( 'alpha', $object_b->foo );
- $object_b->foo = 'charlie';
- $this->assertSame( 'bravo', $object_a->foo );
- }
-
- function test_incr(): void {
- $key = __FUNCTION__;
-
- $this->assertFalse( $this->cache->incr( $key ) );
-
- $this->cache->set( $key, 0 );
- $this->cache->incr( $key );
- $this->assertSame( 1, $this->cache->get( $key ) );
-
- $this->cache->incr( $key, 2 );
- $this->assertSame( 3, $this->cache->get( $key ) );
- }
-
- function test_wp_cache_incr(): void {
- $key = __FUNCTION__;
-
- $this->assertFalse( wp_cache_incr( $key ) );
-
- wp_cache_set( $key, 0 );
- wp_cache_incr( $key );
- $this->assertSame( 1, wp_cache_get( $key ) );
-
- wp_cache_incr( $key, 2 );
- $this->assertSame( 3, wp_cache_get( $key ) );
- }
-
- function test_decr(): void {
- $key = __FUNCTION__;
-
- $this->assertFalse( $this->cache->decr( $key ) );
-
- $this->cache->set( $key, 0 );
- $this->cache->decr( $key );
- $this->assertSame( 0, $this->cache->get( $key ) );
-
- $this->cache->set( $key, 3 );
- $this->cache->decr( $key );
- $this->assertSame( 2, $this->cache->get( $key ) );
-
- $this->cache->decr( $key, 2 );
- $this->assertSame( 0, $this->cache->get( $key ) );
- }
-
- /**
- * @ticket 21327
- */
- function test_wp_cache_decr(): void {
- $key = __FUNCTION__;
-
- $this->assertFalse( wp_cache_decr( $key ) );
-
- wp_cache_set( $key, 0 );
- wp_cache_decr( $key );
- $this->assertSame( 0, wp_cache_get( $key ) );
-
- wp_cache_set( $key, 3 );
- wp_cache_decr( $key );
- $this->assertSame( 2, wp_cache_get( $key ) );
-
- wp_cache_decr( $key, 2 );
- $this->assertSame( 0, wp_cache_get( $key ) );
- }
-
- function test_delete(): void {
- $key = __FUNCTION__;
- $val = 'val';
-
- // Verify set.
- $this->assertTrue( $this->cache->set( $key, $val ) );
- $this->assertSame( $val, $this->cache->get( $key ) );
-
- // Verify successful delete.
- $this->assertTrue( $this->cache->delete( $key ) );
- $this->assertFalse( $this->cache->get( $key ) );
-
- $this->assertFalse( $this->cache->delete( $key, 'default' ) );
- }
-
- function test_wp_cache_delete(): void {
- $key = __FUNCTION__;
- $val = 'val';
-
- // Verify set.
- $this->assertTrue( wp_cache_set( $key, $val ) );
- $this->assertSame( $val, wp_cache_get( $key ) );
-
- // Verify successful delete.
- $this->assertTrue( wp_cache_delete( $key ) );
- $this->assertFalse( wp_cache_get( $key ) );
-
- // wp_cache_delete() does not have a $force method.
- // Delete returns (bool) true when key is not set and $force is true.
- // $this->assertTrue( wp_cache_delete( $key, 'default', true ) );
-
- $this->assertFalse( wp_cache_delete( $key, 'default' ) );
- }
-
- function test_switch_to_blog(): void {
- if ( ! method_exists( $this->cache, 'switch_to_blog' ) ) {
- $this->markTestSkipped( 'This test requires a switch_to_blog() method on the cache object.' );
- }
-
- $key = __FUNCTION__;
- $val = 'val1';
- $val2 = 'val2';
-
- if ( ! is_multisite() ) {
- // Single site ignores switch_to_blog().
- $this->assertTrue( $this->cache->set( $key, $val ) );
- $this->assertSame( $val, $this->cache->get( $key ) );
- $this->cache->switch_to_blog( 999 );
- $this->assertSame( $val, $this->cache->get( $key ) );
- $this->assertTrue( $this->cache->set( $key, $val2 ) );
- $this->assertSame( $val2, $this->cache->get( $key ) );
- $this->cache->switch_to_blog( get_current_blog_id() );
- $this->assertSame( $val2, $this->cache->get( $key ) );
- } else {
- // Multisite should have separate per-blog caches.
- $this->assertTrue( $this->cache->set( $key, $val ) );
- $this->assertSame( $val, $this->cache->get( $key ) );
- $this->cache->switch_to_blog( 999 );
- $this->assertFalse( $this->cache->get( $key ) );
- $this->assertTrue( $this->cache->set( $key, $val2 ) );
- $this->assertSame( $val2, $this->cache->get( $key ) );
- $this->cache->switch_to_blog( get_current_blog_id() );
- $this->assertSame( $val, $this->cache->get( $key ) );
- $this->cache->switch_to_blog( 999 );
- $this->assertSame( $val2, $this->cache->get( $key ) );
- $this->cache->switch_to_blog( get_current_blog_id() );
- $this->assertSame( $val, $this->cache->get( $key ) );
- }
-
- // Global group.
- $this->assertTrue( $this->cache->set( $key, $val, 'global-cache-test' ) );
- $this->assertSame( $val, $this->cache->get( $key, 'global-cache-test' ) );
- $this->cache->switch_to_blog( 999 );
- $this->assertSame( $val, $this->cache->get( $key, 'global-cache-test' ) );
- $this->assertTrue( $this->cache->set( $key, $val2, 'global-cache-test' ) );
- $this->assertSame( $val2, $this->cache->get( $key, 'global-cache-test' ) );
- $this->cache->switch_to_blog( get_current_blog_id() );
- $this->assertSame( $val2, $this->cache->get( $key, 'global-cache-test' ) );
- }
-
- function test_wp_cache_init(): void {
- $new_blank_cache_object = new WP_Object_Cache();
- wp_cache_init();
-
- global $wp_object_cache;
-
- if ( wp_using_ext_object_cache() ) {
- // External caches will contain property values that contain non-matching resource IDs.
- $this->assertInstanceOf( 'WP_Object_Cache', $wp_object_cache );
- } else {
- $this->assertEquals( $wp_object_cache, $new_blank_cache_object );
- }
- }
-
- function test_wp_cache_replace(): void {
- $key = 'my-key';
- $val1 = 'first-val';
- $val2 = 'second-val';
-
- $fake_key = 'my-fake-key';
-
- // Save the first value to cache and verify.
- wp_cache_set( $key, $val1 );
- $this->assertSame( $val1, wp_cache_get( $key ) );
-
- // Replace the value and verify.
- wp_cache_replace( $key, $val2 );
- $this->assertSame( $val2, wp_cache_get( $key ) );
-
- // Non-existent key should fail.
- $this->assertFalse( wp_cache_replace( $fake_key, $val1 ) );
-
- // Make sure $fake_key is not stored.
- $this->assertFalse( wp_cache_get( $fake_key ) );
- }
-
- /**
- * @ticket 20875
- */
- public function test_get_multiple(): void {
- wp_cache_set( 'foo1', 'bar', 'group1' );
- wp_cache_set( 'foo2', 'bar', 'group1' );
- wp_cache_set( 'foo1', 'bar', 'group2' );
-
- $found = wp_cache_get_multiple( array( 'foo1', 'foo2', 'foo3' ), 'group1' );
-
- $expected = array(
- 'foo1' => 'bar',
- 'foo2' => 'bar',
- 'foo3' => false,
- );
-
- $this->assertSame( $expected, $found );
- }
-}
diff --git a/tests/phpunit/class-roc-unit-test-case.php b/tests/phpunit/class-roc-unit-test-case.php
deleted file mode 100644
index d7b0dbed..00000000
--- a/tests/phpunit/class-roc-unit-test-case.php
+++ /dev/null
@@ -1,73 +0,0 @@
-redis_cache ) ) {
- $this->redis_cache = redis_object_cache();
- }
- return $this->redis_cache;
- }
-
- /**
- * Retrieves an absolute path from the plugin's base directory
- *
- * @param string $relative_path The relative path to change to an absolute one
- * @return null|string
- */
- public static function basepath( string $relative_path ) : ?string {
- $basepath = dirname( dirname( __DIR__ ) );
- $path = realpath( trailingslashit( $basepath ) . $relative_path );
- return $path ?: null;
- }
-
- /**
- * Retrieves file data (headers) from a specific file
- *
- * @param string $path The path of the file
- * @param array $headers Headers to find. Format: ['key_index'=>'Header in File']
- * @return array
- */
- protected static function fileData( string $path, array $headers ) : array {
- static $data;
- if ( ! isset( $data[ $path ] ) ) {
- $data[ $path ] = get_file_data( $path, $headers );
- }
- return $data[ $path ];
- }
-
- /**
- * Retrieves file data (headers) from a specific file if the file is readable
- *
- * @param string $path The path of the file
- * @param array $headers Headers to find. Format: ['key_index'=>'Header in File']
- * @return null|array
- */
- protected static function fileHeaders( string $path, array $headers ) : ?array {
- static $data;
- if ( ! isset( $data[ $path ] ) ) {
- $data[ $path ] = is_readable( $path )
- ? self::fileData( $path, $headers )
- : null;
- }
-
- return $data[ $path ];
- }
-
-}
diff --git a/tests/phpunit/main/class-plugin-test.php b/tests/phpunit/main/class-plugin-test.php
deleted file mode 100644
index 1f1cd448..00000000
--- a/tests/phpunit/main/class-plugin-test.php
+++ /dev/null
@@ -1,72 +0,0 @@
-redis_cache()->object_cache_dropin_exists() );
- }
-
- public function test_object_cache_dropin_exists_failure() : void {
- $target_file = WP_CONTENT_DIR . '/object-cache.php';
- $backup_file = WP_CONTENT_DIR . '/object-cache.foo.php';
- if ( copy( $target_file, $backup_file ) ) {
- unlink( $target_file );
- }
- self::assertFalse( $this->redis_cache()->object_cache_dropin_exists() );
- if ( copy( $backup_file, $target_file ) ) {
- unlink( $backup_file );
- }
- }
-
- /**
- * @depends test_object_cache_dropin_exists
- */
- public function test_validate_object_cache_dropin() : void {
- self::assertTrue( $this->redis_cache()->validate_object_cache_dropin() );
- }
-
- /**
- * @depends test_object_cache_dropin_exists
- */
- public function test_validate_object_cache_dropin_filter() : void {
- $test = 0;
- add_filter(
- 'redis_cache_validate_dropin',
- function( $is_valid ) use ( &$test ) {
- $test++;
- return $is_valid;
- }
- );
- $this->redis_cache()->validate_object_cache_dropin();
- // Test if the filter was executed exactly one time.
- self::assertEquals( 1, $test );
- }
-
- /**
- * @depends test_object_cache_dropin_exists
- */
- public function test_object_cache_dropin_outdated() : void {
- self::assertFalse( $this->redis_cache()->object_cache_dropin_outdated() );
- }
-
-}
diff --git a/tests/phpunit/meta/class-plugin-meta-test.php b/tests/phpunit/meta/class-plugin-meta-test.php
deleted file mode 100644
index 759b0146..00000000
--- a/tests/phpunit/meta/class-plugin-meta-test.php
+++ /dev/null
@@ -1,107 +0,0 @@
- 'Tested up to',
- 'StableTag' => 'Stable tag',
- ]
- );
- }
-
- private function dropinHeaders() : ?array {
- return self::fileHeaders(
- self::basepath( self::DROPIN_PATH ),
- [
- 'Name' => 'Plugin Name',
- 'PluginURI' => 'Plugin URI',
- 'Version' => 'Version',
- 'Description' => 'Description',
- 'Author' => 'Author',
- 'AuthorURI' => 'Author URI',
- 'License' => 'License',
- 'LicenseURI' => 'License URI',
- ]
- );
- }
-
- private function pluginHeaders() : ?array {
- return self::fileHeaders(
- self::basepath( self::PLUGIN_PATH ),
- [
- 'Name' => 'Plugin Name',
- 'PluginURI' => 'Plugin URI',
- 'Version' => 'Version',
- 'Description' => 'Description',
- 'Author' => 'Author',
- 'AuthorURI' => 'Author URI',
- 'License' => 'License',
- 'LicenseURI' => 'License URI',
- ]
- );
- }
-
-}