Skip to content

Commit dda2e42

Browse files
committed
Add tests, linting
1 parent 5c4365b commit dda2e42

17 files changed

Lines changed: 900 additions & 8 deletions

.github/workflows/ci.yml

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
name: CI
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches:
7+
- main
8+
9+
concurrency:
10+
group: ${{ github.workflow }}-${{ github.ref }}
11+
cancel-in-progress: true
12+
13+
jobs:
14+
lint:
15+
name: Lint
16+
runs-on: ubuntu-latest
17+
steps:
18+
- uses: actions/checkout@v4
19+
20+
- uses: shivammathur/setup-php@v2
21+
with:
22+
php-version: '8.3'
23+
coverage: none
24+
tools: composer
25+
26+
- uses: ramsey/composer-install@v3
27+
28+
- run: composer lint
29+
30+
phpstan:
31+
name: PHPStan
32+
runs-on: ubuntu-latest
33+
steps:
34+
- uses: actions/checkout@v4
35+
36+
- uses: shivammathur/setup-php@v2
37+
with:
38+
php-version: '8.3'
39+
coverage: none
40+
tools: composer
41+
42+
- uses: ramsey/composer-install@v3
43+
44+
- run: composer phpstan
45+
46+
phpunit:
47+
name: PHPUnit - PHP ${{ matrix.php }}
48+
runs-on: ubuntu-latest
49+
strategy:
50+
fail-fast: false
51+
matrix:
52+
php: ['8.1', '8.2', '8.3', '8.4']
53+
steps:
54+
- uses: actions/checkout@v4
55+
56+
- uses: shivammathur/setup-php@v2
57+
with:
58+
php-version: ${{ matrix.php }}
59+
coverage: none
60+
tools: composer
61+
62+
- uses: ramsey/composer-install@v3
63+
64+
- run: composer phpunit
65+
66+
behat:
67+
name: Behat - PHP ${{ matrix.php }}, WP ${{ matrix.wp }}
68+
runs-on: ubuntu-latest
69+
strategy:
70+
fail-fast: false
71+
matrix:
72+
php: ['8.1', '8.3']
73+
wp: ['latest']
74+
include:
75+
- php: '8.4'
76+
wp: 'trunk'
77+
env:
78+
WP_CLI_TEST_DBROOTUSER: root
79+
WP_CLI_TEST_DBROOTPASS: root
80+
WP_CLI_TEST_DBNAME: wp_cli_test
81+
WP_CLI_TEST_DBUSER: wp_cli_test
82+
WP_CLI_TEST_DBPASS: password1
83+
WP_CLI_TEST_DBHOST: 127.0.0.1:3306
84+
steps:
85+
- uses: actions/checkout@v4
86+
87+
- uses: shivammathur/setup-php@v2
88+
with:
89+
php-version: ${{ matrix.php }}
90+
extensions: gd, imagick, mysql, zip
91+
coverage: none
92+
tools: composer
93+
94+
- uses: ramsey/composer-install@v3
95+
96+
- uses: shogo82148/actions-setup-mysql@v1
97+
with:
98+
mysql-version: '8.0'
99+
auto-start: true
100+
root-password: root
101+
user: wp_cli_test
102+
password: password1
103+
my-cnf: |
104+
default_authentication_plugin=mysql_native_password
105+
106+
- name: Prepare test database
107+
run: composer prepare-tests
108+
109+
- name: Run Behat
110+
env:
111+
WP_VERSION: ${{ matrix.wp }}
112+
run: composer behat || composer behat-rerun

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
/vendor/
2+
.phpunit.cache/
3+
composer.lock

behat.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
default:
2+
suites:
3+
default:
4+
contexts:
5+
- WP_CLI\Tests\Context\FeatureContext
6+
paths:
7+
- features

composer.json

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,23 @@
77
"php": "^8.3",
88
"wp-cli/wp-cli": "^2.12"
99
},
10+
"require-dev": {
11+
"phpstan/phpstan": "^2.0",
12+
"phpunit/phpunit": "^12.0",
13+
"wp-cli/entity-command": "^2",
14+
"wp-cli/extension-command": "^2",
15+
"wp-cli/wp-cli-tests": "^5"
16+
},
17+
"config": {
18+
"process-timeout": 7200,
19+
"sort-packages": true,
20+
"allow-plugins": {
21+
"dealerdirect/phpcodesniffer-composer-installer": true,
22+
"johnpbloch/wordpress-core-installer": true,
23+
"phpstan/extension-installer": true
24+
},
25+
"lock": false
26+
},
1027
"autoload": {
1128
"psr-4": {
1229
"Vector\\Archive\\": "src/"
@@ -15,7 +32,25 @@
1532
"vector-archive-command.php"
1633
]
1734
},
18-
"config": {
19-
"sort-packages": true
35+
"autoload-dev": {
36+
"psr-4": {
37+
"Vector\\Archive\\Tests\\": "tests/"
38+
}
39+
},
40+
"minimum-stability": "dev",
41+
"prefer-stable": true,
42+
"scripts": {
43+
"behat": "run-behat-tests",
44+
"behat-rerun": "rerun-behat-tests",
45+
"lint": "run-linter-tests",
46+
"phpstan": "phpstan analyse --configuration=phpstan.neon.dist",
47+
"phpunit": "run-php-unit-tests",
48+
"prepare-tests": "install-package-tests",
49+
"test": [
50+
"@lint",
51+
"@phpstan",
52+
"@phpunit",
53+
"@behat"
54+
]
2055
}
2156
}

features/export.feature

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
Feature: Export a WordPress site to a Vector archive
2+
3+
Background:
4+
Given a WP install
5+
6+
Scenario: Full export creates a valid archive
7+
When I run `wp vector-archive export --scope=full --output={RUN_DIR}/full.tar.gz`
8+
Then the return code should be 0
9+
And STDOUT should contain:
10+
"""
11+
Success: Archive created:
12+
"""
13+
And the file full.tar.gz should exist
14+
15+
When I run `wp vector-archive validate {RUN_DIR}/full.tar.gz`
16+
Then the return code should be 0
17+
And STDOUT should contain:
18+
"""
19+
Success: All checks passed
20+
"""
21+
22+
Scenario: Database-only export excludes files
23+
When I run `wp vector-archive export --scope=database --output={RUN_DIR}/db.tar.gz`
24+
Then the return code should be 0
25+
And the file db.tar.gz should exist
26+
27+
When I run `wp vector-archive info {RUN_DIR}/db.tar.gz --field=scope`
28+
Then STDOUT should be:
29+
"""
30+
database
31+
"""
32+
33+
Scenario: Files-only export excludes database
34+
When I run `wp vector-archive export --scope=files --output={RUN_DIR}/files.tar.gz`
35+
Then the return code should be 0
36+
And the file files.tar.gz should exist
37+
38+
When I run `wp vector-archive info {RUN_DIR}/files.tar.gz --field=scope`
39+
Then STDOUT should be:
40+
"""
41+
files
42+
"""
43+
44+
Scenario: Export with description
45+
When I run `wp vector-archive export --scope=full --output={RUN_DIR}/described.tar.gz --description="Before update"`
46+
Then the return code should be 0
47+
48+
When I run `wp vector-archive info {RUN_DIR}/described.tar.gz --field=description`
49+
Then STDOUT should be:
50+
"""
51+
Before update
52+
"""
53+
54+
Scenario: Export fails with invalid scope
55+
When I try `wp vector-archive export --scope=invalid --output={RUN_DIR}/bad.tar.gz`
56+
Then the return code should not be 0
57+
And STDERR should contain:
58+
"""
59+
--scope must be one of: full, database, files
60+
"""

features/info.feature

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
Feature: Display information about a Vector archive
2+
3+
Background:
4+
Given a WP install
5+
6+
Scenario: Displays archive metadata in table format
7+
When I run `wp vector-archive export --scope=full --output={RUN_DIR}/info.tar.gz`
8+
Then the return code should be 0
9+
10+
When I run `wp vector-archive info {RUN_DIR}/info.tar.gz`
11+
Then the return code should be 0
12+
And STDOUT should contain:
13+
"""
14+
Scope:
15+
"""
16+
And STDOUT should contain:
17+
"""
18+
Application:
19+
"""
20+
And STDOUT should contain:
21+
"""
22+
wordpress
23+
"""
24+
25+
Scenario: Displays archive metadata in JSON format
26+
When I run `wp vector-archive export --scope=full --output={RUN_DIR}/info.tar.gz`
27+
Then the return code should be 0
28+
29+
When I run `wp vector-archive info {RUN_DIR}/info.tar.gz --format=json`
30+
Then the return code should be 0
31+
And STDOUT should be JSON containing:
32+
"""
33+
{"version":"1.0","scope":"full"}
34+
"""
35+
36+
Scenario: Extracts a single field
37+
When I run `wp vector-archive export --scope=database --output={RUN_DIR}/info.tar.gz`
38+
Then the return code should be 0
39+
40+
When I run `wp vector-archive info {RUN_DIR}/info.tar.gz --field=app.type`
41+
Then STDOUT should be:
42+
"""
43+
wordpress
44+
"""
45+
46+
Scenario: Reports error for missing field
47+
When I run `wp vector-archive export --scope=full --output={RUN_DIR}/info.tar.gz`
48+
Then the return code should be 0
49+
50+
When I try `wp vector-archive info {RUN_DIR}/info.tar.gz --field=nonexistent.field`
51+
Then the return code should not be 0
52+
And STDERR should contain:
53+
"""
54+
Field 'nonexistent.field' not found
55+
"""

features/manifest.feature

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
Feature: Generate a Vector archive manifest
2+
3+
Background:
4+
Given a WP install
5+
6+
Scenario: Outputs manifest JSON to stdout
7+
When I run `wp vector-archive manifest --scope=full`
8+
Then the return code should be 0
9+
And STDOUT should be JSON containing:
10+
"""
11+
{"version":"1.0","scope":"full","compression":"gzip"}
12+
"""
13+
And STDOUT should be JSON containing:
14+
"""
15+
{"app":{"type":"wordpress"}}
16+
"""
17+
18+
Scenario: Database scope includes database section
19+
When I run `wp vector-archive manifest --scope=database`
20+
Then the return code should be 0
21+
And STDOUT should be JSON containing:
22+
"""
23+
{"scope":"database"}
24+
"""
25+
26+
Scenario: Files scope includes files section
27+
When I run `wp vector-archive manifest --scope=files`
28+
Then the return code should be 0
29+
And STDOUT should be JSON containing:
30+
"""
31+
{"scope":"files"}
32+
"""
33+
34+
Scenario: Manifest fails with invalid scope
35+
When I try `wp vector-archive manifest --scope=invalid`
36+
Then the return code should not be 0
37+
And STDERR should contain:
38+
"""
39+
--scope must be one of: full, database, files
40+
"""

features/validate.feature

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
Feature: Validate a Vector archive
2+
3+
Background:
4+
Given a WP install
5+
6+
Scenario: Validates a good archive
7+
When I run `wp vector-archive export --scope=full --output={RUN_DIR}/good.tar.gz`
8+
Then the return code should be 0
9+
10+
When I run `wp vector-archive validate {RUN_DIR}/good.tar.gz`
11+
Then the return code should be 0
12+
And STDOUT should contain:
13+
"""
14+
Success: All checks passed
15+
"""
16+
And STDOUT should contain:
17+
"""
18+
PASS
19+
"""
20+
21+
Scenario: Validates a good archive in quiet mode
22+
When I run `wp vector-archive export --scope=full --output={RUN_DIR}/good.tar.gz`
23+
Then the return code should be 0
24+
25+
When I run `wp vector-archive validate {RUN_DIR}/good.tar.gz --quiet`
26+
Then the return code should be 0
27+
And STDOUT should be empty
28+
29+
Scenario: Reports error for missing archive
30+
When I try `wp vector-archive validate /nonexistent/archive.tar.gz`
31+
Then the return code should not be 0
32+
And STDERR should contain:
33+
"""
34+
Archive does not exist
35+
"""

phpstan.neon.dist

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
parameters:
2+
level: 8
3+
paths:
4+
- src
5+
scanDirectories:
6+
- vendor/wp-cli/wp-cli
7+
scanFiles:
8+
- vendor/wp-cli/wp-cli/php/utils.php
9+
treatPhpDocTypesAsCertain: false
10+
ignoreErrors:
11+
# WP-CLI command signatures use untyped arrays — imposed by the framework.
12+
-
13+
identifier: missingType.iterableValue
14+
path: src/*Command.php
15+
reportUnmatched: false

0 commit comments

Comments
 (0)