update
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
name: Package Plugin
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
tags:
|
||||
- 'v*'
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
test-and-package:
|
||||
name: Test and package plugin
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: '8.4'
|
||||
tools: composer:v2
|
||||
coverage: none
|
||||
|
||||
- name: Install Composer dependencies
|
||||
run: composer install --no-interaction --prefer-dist --no-progress
|
||||
|
||||
- name: Run tests
|
||||
run: composer test
|
||||
|
||||
- name: Lint PHP
|
||||
run: composer lint
|
||||
|
||||
- name: Build installable plugin archive
|
||||
id: package
|
||||
run: |
|
||||
set -eu
|
||||
plugin_slug="wp-translate"
|
||||
version="$(grep -E '^ \* Version:' wp-translate.php | sed -E 's/^ \* Version: *//')"
|
||||
archive_name="${plugin_slug}-${version}.zip"
|
||||
|
||||
rm -rf build
|
||||
mkdir -p "build/${plugin_slug}"
|
||||
cp wp-translate.php README.md "build/${plugin_slug}/"
|
||||
cp -R includes "build/${plugin_slug}/"
|
||||
(
|
||||
cd build
|
||||
zip -qr "../${archive_name}" "${plugin_slug}"
|
||||
)
|
||||
|
||||
printf 'archive=%s\n' "${archive_name}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Upload plugin archive
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: wp-translate-plugin
|
||||
path: ${{ steps.package.outputs.archive }}
|
||||
if-no-files-found: error
|
||||
retention-days: 30
|
||||
@@ -1,3 +1,10 @@
|
||||
/vendor/
|
||||
/node_modules/
|
||||
/.phpunit.result.cache
|
||||
/coverage/
|
||||
/build/
|
||||
/dist/
|
||||
/phpunit.xml
|
||||
/.intelephense/
|
||||
.DS_Store
|
||||
*.zip
|
||||
@@ -45,5 +45,5 @@ Unless a user explicitly requests a refresh, each translatable value must be tra
|
||||
- Mock Baidu API calls in every test. Tests must not require live credentials or outbound network access.
|
||||
- Keep changes narrow and avoid unrelated refactors or formatting churn.
|
||||
- Plugin slug and PHP prefix: `wp-translate` and `wpt_`/`WPT_`. The current minimum supported PHP version is 8.1 and the current minimum WordPress version is 6.4.
|
||||
- Composer is not installed in the initial development environment. Until a WordPress test suite is added, validate syntax with `find . -path './.git' -prune -o -type f -name '*.php' -print0 | xargs -0 -n1 php -l`.
|
||||
- Composer manages the development dependencies. Run `composer test` for isolated unit tests and `composer lint` for PHP syntax checks. WordPress API calls must be mocked in tests; tests must not require live credentials, external network access, or a WordPress database.
|
||||
- Document supported languages, routing modes, data retention, translation lifecycle, and known limitations in the README whenever the implementation changes.
|
||||
|
||||
@@ -47,7 +47,15 @@ Use HTTPS and restrict database access appropriately because WordPress options a
|
||||
|
||||
## Development
|
||||
|
||||
The project currently has no Composer dependencies. Validate PHP syntax with:
|
||||
Install development dependencies with `composer install`. The project includes WordPress API stubs for Intelephense and PHPUnit tests that use fake providers and storage, so they do not need WordPress, a database, credentials, or network access.
|
||||
|
||||
Run tests with:
|
||||
|
||||
```sh
|
||||
composer test
|
||||
```
|
||||
|
||||
Validate PHP syntax with:
|
||||
|
||||
```sh
|
||||
find . -path './.git' -prune -o -type f -name '*.php' -print0 | xargs -0 -n1 php -l
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "wp-translate/wp-translate",
|
||||
"description": "Persistent multilingual WordPress translations powered by Baidu Translate.",
|
||||
"type": "wordpress-plugin",
|
||||
"license": "proprietary",
|
||||
"require": {
|
||||
"php": "^8.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"php-stubs/wordpress-stubs": "^6.8",
|
||||
"phpunit/phpunit": "^12"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "find . -path './.git' -prune -o -path './vendor' -prune -o -type f -name '*.php' -print0 | xargs -0 -n1 php -l",
|
||||
"test": "phpunit"
|
||||
}
|
||||
}
|
||||
Generated
+1754
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit bootstrap="tests/bootstrap.php" colors="true">
|
||||
<testsuites>
|
||||
<testsuite name="WP Translate">
|
||||
<directory suffix="Test.php">tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
</phpunit>
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class TranslationIdentityTest extends TestCase {
|
||||
public function test_key_is_stable_for_identical_translation_input() {
|
||||
$first = WPT_Translation_Identity::key( 'Hello', 'en', 'zh', 'post:15:post_title', 'provider-v1' );
|
||||
$second = WPT_Translation_Identity::key( 'Hello', 'en', 'zh', 'post:15:post_title', 'provider-v1' );
|
||||
|
||||
$this->assertSame( $first, $second );
|
||||
}
|
||||
|
||||
public function test_key_changes_when_source_value_changes() {
|
||||
$first = WPT_Translation_Identity::key( 'Hello', 'en', 'zh', 'post:15:post_title', 'provider-v1' );
|
||||
$second = WPT_Translation_Identity::key( 'Hello again', 'en', 'zh', 'post:15:post_title', 'provider-v1' );
|
||||
|
||||
$this->assertNotSame( $first, $second );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class WPT_Test_Translation_Store extends WPT_Translation_Store {
|
||||
public $values = array();
|
||||
public $save_calls = array();
|
||||
|
||||
public function find_valid( $identity_key ) {
|
||||
return $this->values[ $identity_key ] ?? null;
|
||||
}
|
||||
|
||||
public function save( $identity_key, $source_language, $target_language, $field_context, $source_fingerprint, $translated_value, $status ) {
|
||||
$this->save_calls[] = compact( 'identity_key', 'source_language', 'target_language', 'field_context', 'source_fingerprint', 'translated_value', 'status' );
|
||||
if ( 'complete' === $status ) {
|
||||
$this->values[ $identity_key ] = array( 'translated_value' => $translated_value );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class WPT_Test_Translation_Provider implements WPT_Translation_Provider {
|
||||
public $calls = 0;
|
||||
|
||||
public function get_version() {
|
||||
return 'test-provider-v1';
|
||||
}
|
||||
|
||||
public function translate( $source_value, $source_language, $target_language, $context ) {
|
||||
++$this->calls;
|
||||
|
||||
return WPT_Translation_Result::success( '[' . $target_language . '] ' . $source_value );
|
||||
}
|
||||
}
|
||||
|
||||
class TranslationServiceTest extends TestCase {
|
||||
public function test_second_request_reuses_persisted_translation_without_provider_call() {
|
||||
$store = new WPT_Test_Translation_Store();
|
||||
$provider = new WPT_Test_Translation_Provider();
|
||||
$service = new WPT_Translation_Service( $store, $provider );
|
||||
|
||||
$first = $service->get_or_translate( 'Welcome', 'en', 'zh', 'post:8:post_title' );
|
||||
$second = $service->get_or_translate( 'Welcome', 'en', 'zh', 'post:8:post_title' );
|
||||
|
||||
$this->assertTrue( $first->success );
|
||||
$this->assertSame( '[zh] Welcome', $second->value );
|
||||
$this->assertSame( 1, $provider->calls );
|
||||
$this->assertCount( 1, $store->save_calls );
|
||||
}
|
||||
|
||||
public function test_failed_request_is_persisted_with_failed_status() {
|
||||
$store = new WPT_Test_Translation_Store();
|
||||
$provider = new class implements WPT_Translation_Provider {
|
||||
public function get_version() {
|
||||
return 'test-provider-v1';
|
||||
}
|
||||
|
||||
public function translate( $source_value, $source_language, $target_language, $context ) {
|
||||
return WPT_Translation_Result::failure( 'request_failed', 'Network error' );
|
||||
}
|
||||
};
|
||||
$service = new WPT_Translation_Service( $store, $provider );
|
||||
|
||||
$result = $service->get_or_translate( 'Welcome', 'en', 'zh', 'post:8:post_title' );
|
||||
|
||||
$this->assertFalse( $result->success );
|
||||
$this->assertSame( 'failed', $store->save_calls[0]['status'] );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
define( 'ABSPATH', __DIR__ . '/' );
|
||||
|
||||
require_once dirname( __DIR__ ) . '/includes/interface-wpt-translation-provider.php';
|
||||
require_once dirname( __DIR__ ) . '/includes/class-wpt-translation-result.php';
|
||||
require_once dirname( __DIR__ ) . '/includes/class-wpt-translation-identity.php';
|
||||
require_once dirname( __DIR__ ) . '/includes/class-wpt-translation-store.php';
|
||||
require_once dirname( __DIR__ ) . '/includes/class-wpt-translation-service.php';
|
||||
Reference in New Issue
Block a user