Skip to content

Commit c0e4524

Browse files
committed
chore: Inline shared test package
1 parent 9c6ca70 commit c0e4524

File tree

6 files changed

+301
-34
lines changed

6 files changed

+301
-34
lines changed

.github/actions/ci/action.yml

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,6 @@ inputs:
1010
type: boolean
1111
required: false
1212
default: false
13-
shared-test-version:
14-
description: 'Which version of the shared test package should we required'
15-
required: false
16-
default: 4.x-dev
1713
token:
1814
description: 'Token used to prevent composer rate limiting'
1915
required: true
@@ -33,10 +29,6 @@ runs:
3329
shell: bash
3430
run: composer install --no-progress
3531

36-
- name: Require appropriate shared tests package
37-
shell: bash
38-
run: composer require --dev 'launchdarkly/server-sdk-shared-tests:${{ inputs.shared-test-version }}'
39-
4032
- name: Downgrade to lowest versions
4133
if: ${{ inputs.use-lowest-dependencies }}
4234
shell: bash

.github/workflows/ci.yml

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,29 +23,14 @@ jobs:
2323
fail-fast: false
2424
matrix:
2525
include:
26-
# 8.1 configurations
2726
- php-version: 8.1
2827
use-lowest-dependencies: true
29-
shared-test-version: 5.x-dev
30-
- php-version: 8.1
31-
use-lowest-dependencies: true
32-
shared-test-version: dev-main
3328

34-
# 8.2 configurations
35-
- php-version: 8.2
36-
use-lowest-dependencies: false
37-
shared-test-version: 5.x-dev
3829
- php-version: 8.2
3930
use-lowest-dependencies: false
40-
shared-test-version: dev-main
4131

42-
# 8.3 configurations
43-
- php-version: 8.3
44-
use-lowest-dependencies: false
45-
shared-test-version: 5.x-dev
4632
- php-version: 8.3
4733
use-lowest-dependencies: false
48-
shared-test-version: dev-main
4934

5035
steps:
5136
- uses: actions/checkout@v4
@@ -56,5 +41,4 @@ jobs:
5641
with:
5742
php-version: ${{ matrix.php-version }}
5843
use-lowest-dependencies: ${{ matrix.use-lowest-dependencies }}
59-
shared-test-version: ${{ matrix.shared-test-version }}
6044
token: ${{ secrets.GITHUB_TOKEN }}

composer.json

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
11
{
2-
"repositories": [
3-
{
4-
"type": "vcs",
5-
"url": "https://github.com/launchdarkly/php-server-sdk-shared-tests"
6-
}
7-
],
82
"name": "launchdarkly/server-sdk-redis-phpredis",
93
"description": "LaunchDarkly PHP SDK Redis integration using the phpredis extension",
104
"keywords": [
Lines changed: 301 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,301 @@
1+
<?php
2+
3+
4+
namespace LaunchDarkly\Impl\Integrations\Tests;
5+
6+
use LaunchDarkly\Impl\Model\FeatureFlag;
7+
use LaunchDarkly\Impl\Model\Segment;
8+
use PHPUnit\Framework\TestCase;
9+
10+
/**
11+
* A base class providing standardized PHPUnit tests for database integrations.
12+
*/
13+
class DatabaseFeatureRequesterTestBase extends TestCase
14+
{
15+
const TEST_PREFIX = 'testprefix';
16+
17+
/**
18+
* Override this method to remove all data from the underlying data store for
19+
* the specified prefix string.
20+
*
21+
* @param string $prefix the key prefix; may be empty/null, in which case we should
22+
* use whatever the default prefix is for this database integration.
23+
*/
24+
protected function clearExistingData(?string $prefix): void
25+
{
26+
throw new \RuntimeException("test class did not implement clearExistingData");
27+
}
28+
29+
/**
30+
* Override this method to create an instance of the feature requester class being
31+
* tested.
32+
*
33+
* @param string $prefix the key prefix; may be empty/null, in which case we should
34+
* use whatever the default prefix is for this database integration.
35+
*
36+
* @return an implementation instance
37+
*/
38+
protected function makeRequester(?string $prefix)
39+
{
40+
throw new \RuntimeException("test class did not implement makeRequester");
41+
}
42+
43+
/**
44+
* Override this method to insert an item into the data store.
45+
*
46+
* @param string $prefix the key prefix; may be empty/null, in which case we should
47+
* use whatever the default prefix is for this database integration.
48+
* @param string $namespace the namespace string, such as "features"
49+
* @param string $key the flag/segment key
50+
* @param int $version the version number
51+
* @param string $json the JSON data
52+
*/
53+
protected function putSerializedItem(
54+
?string $prefix,
55+
string $namespace,
56+
string $key,
57+
int $version,
58+
string $json): void
59+
{
60+
throw new \RuntimeException("test class did not implement putSerializedItem");
61+
}
62+
63+
/**
64+
* @dataProvider prefixParameters
65+
*/
66+
public function testGetFeature(?string $prefix): void
67+
{
68+
$this->clearExistingData($prefix);
69+
$fr = $this->makeRequester($prefix);
70+
71+
$flagKey = 'foo';
72+
$flagVersion = 10;
73+
$flagJson = self::makeFlagJson($flagKey, $flagVersion);
74+
$this->putSerializedItem($prefix, 'features', $flagKey, $flagVersion, $flagJson);
75+
76+
$fr = $this->makeRequester($prefix);
77+
$flag = $fr->getFeature($flagKey);
78+
79+
$this->assertInstanceOf(FeatureFlag::class, $flag);
80+
$this->assertEquals($flagVersion, $flag->getVersion());
81+
}
82+
83+
/**
84+
* @dataProvider prefixParameters
85+
*/
86+
public function testGetMissingFeature(?string $prefix): void
87+
{
88+
$this->clearExistingData($prefix);
89+
$fr = $this->makeRequester($prefix);
90+
91+
$flag = $fr->getFeature('unavailable');
92+
$this->assertNull($flag);
93+
}
94+
95+
/**
96+
* @dataProvider prefixParameters
97+
*/
98+
public function testGetDeletedFeature(?string $prefix): void
99+
{
100+
$this->clearExistingData($prefix);
101+
$fr = $this->makeRequester($prefix);
102+
103+
$flagKey = 'foo';
104+
$flagVersion = 10;
105+
$flagJson = self::makeFlagJson($flagKey, $flagVersion, true);
106+
$this->putSerializedItem($prefix, 'features', $flagKey, $flagVersion, $flagJson);
107+
108+
$flag = $fr->getFeature($flagKey);
109+
110+
$this->assertNull($flag);
111+
}
112+
113+
/**
114+
* @dataProvider prefixParameters
115+
*/
116+
public function testGetAllFeatures(?string $prefix): void
117+
{
118+
$this->clearExistingData($prefix);
119+
$fr = $this->makeRequester($prefix);
120+
121+
$flagKey1 = 'foo';
122+
$flagKey2 = 'bar';
123+
$flagKey3 = 'deleted';
124+
$flagVersion = 10;
125+
$flagJson1 = self::makeFlagJson($flagKey1, $flagVersion);
126+
$flagJson2 = self::makeFlagJson($flagKey2, $flagVersion);
127+
$flagJson3 = self::makeFlagJson($flagKey3, $flagVersion, true);
128+
129+
$this->putSerializedItem($prefix, 'features', $flagKey1, $flagVersion, $flagJson1);
130+
$this->putSerializedItem($prefix, 'features', $flagKey2, $flagVersion, $flagJson2);
131+
$this->putSerializedItem($prefix, 'features', $flagKey3, $flagVersion, $flagJson3);
132+
133+
$flags = $fr->getAllFeatures();
134+
135+
$this->assertEquals(2, count($flags));
136+
$flag1 = $flags[$flagKey1];
137+
$this->assertEquals($flagKey1, $flag1->getKey());
138+
$this->assertEquals($flagVersion, $flag1->getVersion());
139+
$flag2 = $flags[$flagKey2];
140+
$this->assertEquals($flagKey2, $flag2->getKey());
141+
$this->assertEquals($flagVersion, $flag2->getVersion());
142+
}
143+
144+
/**
145+
* @dataProvider prefixParameters
146+
*/
147+
public function testAllFeaturesWithEmptyStore(?string $prefix): void
148+
{
149+
$this->clearExistingData($prefix);
150+
$fr = $this->makeRequester($prefix);
151+
152+
$flags = $fr->getAllFeatures();
153+
$this->assertEquals(array(), $flags);
154+
}
155+
156+
/**
157+
* @dataProvider prefixParameters
158+
*/
159+
public function testGetSegment(?string $prefix): void
160+
{
161+
$this->clearExistingData($prefix);
162+
$fr = $this->makeRequester($prefix);
163+
164+
$segKey = 'foo';
165+
$segVersion = 10;
166+
$segJson = self::makeSegmentJson($segKey, $segVersion);
167+
$this->putSerializedItem($prefix, 'segments', $segKey, $segVersion, $segJson);
168+
169+
$segment = $fr->getSegment($segKey);
170+
171+
$this->assertInstanceOf(Segment::class, $segment);
172+
$this->assertEquals($segVersion, $segment->getVersion());
173+
}
174+
175+
/**
176+
* @dataProvider prefixParameters
177+
*/
178+
public function testGetMissingSegment(?string $prefix): void
179+
{
180+
$this->clearExistingData($prefix);
181+
$fr = $this->makeRequester($prefix);
182+
183+
$segment = $fr->getSegment('unavailable');
184+
$this->assertNull($segment);
185+
}
186+
187+
/**
188+
* @dataProvider prefixParameters
189+
*/
190+
public function testGetDeletedSegment(?string $prefix): void
191+
{
192+
$this->clearExistingData($prefix);
193+
$fr = $this->makeRequester($prefix);
194+
195+
$segKey = 'foo';
196+
$segVersion = 10;
197+
$segJson = self::makeSegmentJson($segKey, $segVersion, true);
198+
$this->putSerializedItem($prefix, 'segments', $segKey, $segVersion, $segJson);
199+
200+
$segment = $fr->getSegment($segKey);
201+
202+
$this->assertNull($segment);
203+
}
204+
205+
public function testPrefixIndependence(): void
206+
{
207+
$prefix1 = 'prefix1';
208+
$prefix2 = 'prefix2';
209+
210+
$this->clearExistingData(null);
211+
$this->clearExistingData($prefix1);
212+
$this->clearExistingData($prefix2);
213+
214+
$flagKey = 'my-flag';
215+
$segmentKey = 'my-segment';
216+
$version0 = 10;
217+
$version1 = 11;
218+
$version2 = 12;
219+
$this->setupForPrefix(null, $flagKey, $segmentKey, $version0);
220+
$this->setupForPrefix($prefix1, $flagKey, $segmentKey, $version1);
221+
$this->setupForPrefix($prefix2, $flagKey, $segmentKey, $version2);
222+
223+
$this->verifyForPrefix($this->makeRequester(null), $flagKey, $segmentKey, $version0);
224+
$this->verifyForPrefix($this->makeRequester(''), $flagKey, $segmentKey, $version0);
225+
$this->verifyForPrefix($this->makeRequester($prefix1), $flagKey, $segmentKey, $version1);
226+
$this->verifyForPrefix($this->makeRequester($prefix2), $flagKey, $segmentKey, $version2);
227+
}
228+
229+
private function setupForPrefix(?string $prefix, string $flagKey, string $segmentKey, int $flagVersion): void
230+
{
231+
$segmentVersion = $flagVersion * 2;
232+
$this->putSerializedItem($prefix, 'features', $flagKey, $flagVersion,
233+
self::makeFlagJson($flagKey, $flagVersion));
234+
$this->putSerializedItem($prefix, 'segments', $segmentKey, $segmentVersion,
235+
self::makeSegmentJson($flagKey, $segmentVersion));
236+
}
237+
238+
private function verifyForPrefix($fr, string $flagKey, string $segmentKey, int $flagVersion): void
239+
{
240+
$segmentVersion = $flagVersion * 2;
241+
242+
$flag = $fr->getFeature($flagKey);
243+
$this->assertNotNull($flag);
244+
$this->assertEquals($flagVersion, $flag->getVersion());
245+
246+
$flags = $fr->getAllFeatures();
247+
$this->assertEquals(1, count($flags));
248+
$this->assertEquals($flagVersion, $flags[$flagKey]->getVersion());
249+
250+
$segment = $fr->getSegment($segmentKey);
251+
$this->assertNotNull($segment);
252+
$this->assertEquals($segmentVersion, $segment->getVersion());
253+
}
254+
255+
/**
256+
* @return array<int,mixed>
257+
*/
258+
public function prefixParameters(): array
259+
{
260+
return [
261+
[ self::TEST_PREFIX ],
262+
[ '' ],
263+
[ null ]
264+
];
265+
}
266+
267+
private static function makeFlagJson(string $key, int $version, bool $deleted = false): string|bool
268+
{
269+
return json_encode(array(
270+
'key' => $key,
271+
'version' => $version,
272+
'on' => true,
273+
'prerequisites' => [],
274+
'salt' => '',
275+
'targets' => [],
276+
'rules' => [],
277+
'fallthrough' => [
278+
'variation' => 0,
279+
],
280+
'offVariation' => null,
281+
'variations' => [
282+
true,
283+
false,
284+
],
285+
'deleted' => $deleted
286+
));
287+
}
288+
289+
private static function makeSegmentJson(string $key, int $version, bool $deleted = false): string|bool
290+
{
291+
return json_encode(array(
292+
'key' => $key,
293+
'version' => $version,
294+
'included' => array(),
295+
'excluded' => array(),
296+
'rules' => [],
297+
'salt' => '',
298+
'deleted' => $deleted
299+
));
300+
}
301+
}

tests/PHPRedisFeatureRequesterTest.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
namespace LaunchDarkly\Impl\Integrations\Tests;
44

55
use LaunchDarkly\Integrations\PHPRedis;
6-
use LaunchDarkly\SharedTest\DatabaseFeatureRequesterTestBase;
76

87
class PHPRedisFeatureRequesterTest extends DatabaseFeatureRequesterTestBase
98
{

tests/PHPRedisFeatureRequesterWithClientTest.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@
22

33
namespace LaunchDarkly\Impl\Integrations\Tests;
44

5-
use \Redis;
6-
use LaunchDarkly\Impl\Integrations\PHPRedisFeatureRequester;
75
use LaunchDarkly\Integrations\PHPRedis;
8-
use LaunchDarkly\SharedTest\DatabaseFeatureRequesterTestBase;
96

107
class PHPRedisFeatureRequesterWithClientTest extends DatabaseFeatureRequesterTestBase
118
{

0 commit comments

Comments
 (0)