Skip to content

Commit 5909640

Browse files
committed
feat: Some tests would fail on older versions of the json-rpc api, allow tests to only run on specific versions through an attribute
1 parent 1fa7714 commit 5909640

File tree

4 files changed

+152
-8
lines changed

4 files changed

+152
-8
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace RefRing\MoneroRpcPhp\Tests\Attribute;
6+
7+
use Attribute;
8+
9+
/**
10+
* Mark a test method as requiring a specific Monero daemon version.
11+
*
12+
* The test will be skipped if the daemon version is below the minimum
13+
* or above the maximum (if specified).
14+
*
15+
* Version format: "0.18.4.0" (as returned by getInfo()->version)
16+
*/
17+
#[Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_CLASS)]
18+
final class RequiresMoneroVersion
19+
{
20+
public function __construct(
21+
public readonly string $minVersion,
22+
public readonly ?string $maxVersion = null,
23+
) {
24+
}
25+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace RefRing\MoneroRpcPhp\Tests\Trait;
6+
7+
use ReflectionMethod;
8+
use RefRing\MoneroRpcPhp\DaemonRpcClient;
9+
use RefRing\MoneroRpcPhp\Tests\Attribute\RequiresMoneroVersion;
10+
11+
/**
12+
* Trait to add version requirement checking to integration tests.
13+
*
14+
* Classes using this trait must implement getDaemonRpcClient() to provide
15+
* the client instance for version checking.
16+
*/
17+
trait RequiresMoneroVersionTrait
18+
{
19+
private static ?string $cachedDaemonVersion = null;
20+
21+
abstract protected static function getDaemonRpcClient(): DaemonRpcClient;
22+
23+
protected function checkMoneroVersionRequirements(): void
24+
{
25+
$reflection = new ReflectionMethod($this, $this->name());
26+
27+
// Check method-level attribute first, then class-level
28+
$attributes = $reflection->getAttributes(RequiresMoneroVersion::class);
29+
30+
if (empty($attributes)) {
31+
$classReflection = $reflection->getDeclaringClass();
32+
$attributes = $classReflection->getAttributes(RequiresMoneroVersion::class);
33+
}
34+
35+
if (empty($attributes)) {
36+
return;
37+
}
38+
39+
$requirement = $attributes[0]->newInstance();
40+
$currentVersion = $this->getDaemonVersion();
41+
$currentVersion = preg_replace('/[^0-9.]/', '', $currentVersion);
42+
43+
if (version_compare($currentVersion, $requirement->minVersion, '<')) {
44+
$this->markTestSkipped(sprintf(
45+
'Test requires Monero >= %s (current: %s)',
46+
$requirement->minVersion,
47+
$currentVersion
48+
));
49+
}
50+
51+
if ($requirement->maxVersion !== null) {
52+
if (version_compare($currentVersion, $requirement->maxVersion, '>')) {
53+
$this->markTestSkipped(sprintf(
54+
'Test requires Monero <= %s (current: %s)',
55+
$requirement->maxVersion,
56+
$currentVersion
57+
));
58+
}
59+
}
60+
}
61+
62+
private function getDaemonVersion(): string
63+
{
64+
if (self::$cachedDaemonVersion === null) {
65+
self::$cachedDaemonVersion = static::getDaemonRpcClient()->getInfo()->version;
66+
}
67+
68+
return self::$cachedDaemonVersion;
69+
}
70+
}

tests/integration/DaemonTest.php

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,13 @@
1111
use RefRing\MoneroRpcPhp\Enum\ResponseStatus;
1212
use RefRing\MoneroRpcPhp\Exception\InvalidHostOrSubnetException;
1313
use RefRing\MoneroRpcPhp\Exception\NoIpOrHostSuppliedException;
14+
use RefRing\MoneroRpcPhp\Tests\Attribute\RequiresMoneroVersion;
15+
use RefRing\MoneroRpcPhp\Tests\Trait\RequiresMoneroVersionTrait;
1416

1517
final class DaemonTest extends TestCase
1618
{
19+
use RequiresMoneroVersionTrait;
20+
1721
private static DaemonRpcClient $rpcClient;
1822

1923
public static function setUpBeforeClass(): void
@@ -22,6 +26,16 @@ public static function setUpBeforeClass(): void
2226
self::$rpcClient = new DaemonRpcClient($httpClient, getenv('DAEMON_RPC_URL'));
2327
}
2428

29+
protected function setUp(): void
30+
{
31+
$this->checkMoneroVersionRequirements();
32+
}
33+
34+
protected static function getDaemonRpcClient(): DaemonRpcClient
35+
{
36+
return self::$rpcClient;
37+
}
38+
2539
public function testSetBansOk(): void
2640
{
2741
$node = new Node('127.0.0.1', null, true, 60);
@@ -37,12 +51,12 @@ public function testSetBansInvalidHost(): void
3751
$result = self::$rpcClient->setBans([$node]);
3852
}
3953

40-
// @TODO This will fail on versions before v0.18.4.0, find a way to only run tests against certain versions
41-
// public function testSetBansMissingIp(): void
42-
// {
43-
// $this->expectException(NoIpOrHostSuppliedException::class);
44-
//
45-
// $node = new Node(null, null, true, 60);
46-
// $result = self::$rpcClient->setBans([$node]);
47-
// }
54+
#[RequiresMoneroVersion('0.18.4.0')]
55+
public function testSetBansMissingIp(): void
56+
{
57+
$this->expectException(NoIpOrHostSuppliedException::class);
58+
59+
$node = new Node(null, null, true, 60);
60+
$result = self::$rpcClient->setBans([$node]);
61+
}
4862
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace RefRing\MoneroRpcPhp\Tests\unit;
6+
7+
use PHPUnit\Framework\TestCase;
8+
use RefRing\MoneroRpcPhp\Tests\Attribute\RequiresMoneroVersion;
9+
10+
final class RequiresMoneroVersionTest extends TestCase
11+
{
12+
public function testAttributeInstantiation(): void
13+
{
14+
$attr = new RequiresMoneroVersion('0.18.4.0');
15+
$this->assertSame('0.18.4.0', $attr->minVersion);
16+
$this->assertNull($attr->maxVersion);
17+
}
18+
19+
public function testAttributeInstantiationWithMax(): void
20+
{
21+
$attr = new RequiresMoneroVersion('0.18.0.0', '0.19.0.0');
22+
$this->assertSame('0.18.0.0', $attr->minVersion);
23+
$this->assertSame('0.19.0.0', $attr->maxVersion);
24+
}
25+
26+
public function testVersionCompareWorks(): void
27+
{
28+
// Verify PHP's version_compare works correctly with Monero version strings
29+
$this->assertSame(-1, version_compare('0.18.3.0', '0.18.4.0'));
30+
$this->assertSame(0, version_compare('0.18.4.0', '0.18.4.0'));
31+
$this->assertSame(1, version_compare('0.18.5.0', '0.18.4.0'));
32+
$this->assertSame(-1, version_compare('0.17.3.2', '0.18.4.0'));
33+
$this->assertSame(1, version_compare('0.19.0.0', '0.18.4.0'));
34+
}
35+
}

0 commit comments

Comments
 (0)