Skip to content

Commit 40e93c6

Browse files
committed
chore: Inline shared test package
1 parent 21c61b8 commit 40e93c6

File tree

7 files changed

+300
-30
lines changed

7 files changed

+300
-30
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 & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,26 +26,14 @@ jobs:
2626
# 8.1 configurations
2727
- php-version: 8.1
2828
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
3329

3430
# 8.2 configurations
3531
- php-version: 8.2
3632
use-lowest-dependencies: false
37-
shared-test-version: 5.x-dev
38-
- php-version: 8.2
39-
use-lowest-dependencies: false
40-
shared-test-version: dev-main
4133

4234
# 8.3 configurations
4335
- php-version: 8.3
4436
use-lowest-dependencies: false
45-
shared-test-version: 5.x-dev
46-
- php-version: 8.3
47-
use-lowest-dependencies: false
48-
shared-test-version: dev-main
4937

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

tests/RedisFeatureRequesterTest.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\Redis;
6-
use LaunchDarkly\SharedTest\DatabaseFeatureRequesterTestBase;
76
use Predis\Client;
87

98
class RedisFeatureRequesterTest extends DatabaseFeatureRequesterTestBase

tests/RedisFeatureRequesterWithClientTest.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\Redis;
6-
use LaunchDarkly\SharedTest\DatabaseFeatureRequesterTestBase;
76
use Predis\Client;
87

98
class RedisFeatureRequesterWithClientTest extends DatabaseFeatureRequesterTestBase

tests/RedisFeatureRequesterWithPredisOptionsTest.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\Redis;
6-
use LaunchDarkly\SharedTest\DatabaseFeatureRequesterTestBase;
76
use Predis\Client;
87

98
class RedisFeatureRequesterWithPredisOptionsTest extends DatabaseFeatureRequesterTestBase

0 commit comments

Comments
 (0)