Skip to content

Commit 4394b95

Browse files
committed
updated tests.
1 parent 0d97133 commit 4394b95

4 files changed

Lines changed: 447 additions & 0 deletions

File tree

tests/Patterns/Criteria/CriteriaTest.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,30 @@ public function testAndCriteria()
3737
);
3838
}
3939

40+
public function testAndCriteriaReturnsEmptyWhenFirstCriteriaMatchesNothing()
41+
{
42+
$aTest = [
43+
[
44+
'name' => 'one',
45+
'type' => 1
46+
],
47+
[
48+
'name' => 'two',
49+
'type' => 2
50+
],
51+
];
52+
53+
// First criteria will match nothing
54+
$matchesNothing = new KeyValue( 'type', '999' );
55+
$matchesSomething = new KeyValue( 'name', 'one' );
56+
57+
$aResult = $matchesNothing->_and( $matchesSomething )->meetCriteria( $aTest );
58+
59+
// Should return empty array immediately
60+
$this->assertEquals( 0, count( $aResult ) );
61+
$this->assertEmpty( $aResult );
62+
}
63+
4064
public function testOrCriteria()
4165
{
4266
$aTest = [
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
<?php
2+
3+
namespace Tests\Patterns\Singleton;
4+
5+
use PHPUnit\Framework\TestCase;
6+
use Neuron\Patterns\Singleton\Memcache;
7+
8+
/**
9+
* Test concrete class extending Memcache for testing.
10+
*/
11+
class MemcacheSingletonTest extends Memcache
12+
{
13+
public $testValue;
14+
}
15+
16+
/**
17+
* Comprehensive tests for Memcache Singleton.
18+
*
19+
* Tests singleton pattern with Memcached backend using mocked Memcached.
20+
*/
21+
class MemcacheTest extends TestCase
22+
{
23+
private $memcachedMock;
24+
25+
protected function setUp(): void
26+
{
27+
parent::setUp();
28+
29+
// Create stub for Memcached if it doesn't exist
30+
if (!class_exists('\Memcached')) {
31+
// Create a stub class for testing
32+
eval('
33+
class Memcached {
34+
public function addServer($host, $port) {}
35+
public function get($key) {}
36+
public function set($key, $value) {}
37+
}
38+
');
39+
}
40+
41+
// Create mock Memcached
42+
$this->memcachedMock = $this->createMock(\Memcached::class);
43+
}
44+
45+
public function testInstanceReturnsStoredObject(): void
46+
{
47+
// Create test object
48+
$instance = new MemcacheSingletonTest();
49+
$instance->testValue = 'test123';
50+
51+
// Mock memcached to return our instance
52+
$this->memcachedMock
53+
->expects($this->once())
54+
->method('get')
55+
->with(MemcacheSingletonTest::class)
56+
->willReturn($instance);
57+
58+
// Inject mock using reflection
59+
$reflection = new \ReflectionClass(Memcache::class);
60+
$property = $reflection->getProperty('_memcache');
61+
$property->setAccessible(true);
62+
$property->setValue(null, $this->memcachedMock);
63+
64+
$retrieved = MemcacheSingletonTest::instance();
65+
66+
$this->assertSame($instance, $retrieved);
67+
$this->assertEquals('test123', $retrieved->testValue);
68+
}
69+
70+
public function testSerializeSetsObjectInMemcache(): void
71+
{
72+
$instance = new MemcacheSingletonTest();
73+
$instance->testValue = 'serialize_test';
74+
75+
// Mock memcached to expect set() call
76+
$this->memcachedMock
77+
->expects($this->once())
78+
->method('set')
79+
->with(
80+
MemcacheSingletonTest::class,
81+
$instance
82+
);
83+
84+
// Inject mock using reflection
85+
$reflection = new \ReflectionClass(Memcache::class);
86+
$property = $reflection->getProperty('_memcache');
87+
$property->setAccessible(true);
88+
$property->setValue(null, $this->memcachedMock);
89+
90+
$instance->serialize();
91+
}
92+
93+
public function testInvalidateSetsToFalse(): void
94+
{
95+
// Mock memcached to expect set with false
96+
$this->memcachedMock
97+
->expects($this->once())
98+
->method('set')
99+
->with(
100+
MemcacheSingletonTest::class,
101+
false
102+
);
103+
104+
// Inject mock using reflection
105+
$reflection = new \ReflectionClass(Memcache::class);
106+
$property = $reflection->getProperty('_memcache');
107+
$property->setAccessible(true);
108+
$property->setValue(null, $this->memcachedMock);
109+
110+
MemcacheSingletonTest::invalidate();
111+
}
112+
113+
public function testGetMemcacheCreatesConnectionOnFirstCall(): void
114+
{
115+
// Reset static memcache
116+
$reflection = new \ReflectionClass(Memcache::class);
117+
$property = $reflection->getProperty('_memcache');
118+
$property->setAccessible(true);
119+
$property->setValue(null, null);
120+
121+
// Get the protected method
122+
$method = $reflection->getMethod('getMemcache');
123+
$method->setAccessible(true);
124+
125+
// First call should create new Memcached
126+
$memcache1 = $method->invoke(null);
127+
$this->assertInstanceOf(\Memcached::class, $memcache1);
128+
129+
// Second call should return same instance
130+
$memcache2 = $method->invoke(null);
131+
$this->assertSame($memcache1, $memcache2);
132+
}
133+
}
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
<?php
2+
3+
namespace Tests\Patterns\Singleton;
4+
5+
use PHPUnit\Framework\TestCase;
6+
use Neuron\Patterns\Singleton\Redis;
7+
8+
/**
9+
* Test concrete class extending Redis for testing.
10+
*/
11+
class RedisSingletonTest extends Redis
12+
{
13+
public $testValue;
14+
}
15+
16+
/**
17+
* Comprehensive tests for Redis Singleton.
18+
*
19+
* Tests singleton pattern with Redis backend using mocked Redis.
20+
*/
21+
class RedisTest extends TestCase
22+
{
23+
private $redisMock;
24+
25+
protected function setUp(): void
26+
{
27+
parent::setUp();
28+
29+
// Create stub for Redis if it doesn't exist
30+
if (!class_exists('\Redis')) {
31+
// Create a stub class for testing
32+
eval('
33+
class Redis {
34+
public function connect($host, $port) {}
35+
public function get($key) {}
36+
public function set($key, $value) {}
37+
public function del($key) {}
38+
}
39+
');
40+
}
41+
42+
// Create mock Redis
43+
$this->redisMock = $this->createMock(\Redis::class);
44+
}
45+
46+
public function testInstanceReturnsDeserializedObject(): void
47+
{
48+
// Create test object
49+
$instance = new RedisSingletonTest();
50+
$instance->testValue = 'redis_test_123';
51+
$serialized = serialize($instance);
52+
53+
// Mock Redis to return serialized data
54+
$this->redisMock
55+
->expects($this->once())
56+
->method('get')
57+
->with(RedisSingletonTest::class)
58+
->willReturn($serialized);
59+
60+
// Inject mock using reflection
61+
$reflection = new \ReflectionClass(Redis::class);
62+
$property = $reflection->getProperty('_redis');
63+
$property->setAccessible(true);
64+
$property->setValue(null, $this->redisMock);
65+
66+
$retrieved = RedisSingletonTest::instance();
67+
68+
$this->assertInstanceOf(RedisSingletonTest::class, $retrieved);
69+
$this->assertEquals('redis_test_123', $retrieved->testValue);
70+
}
71+
72+
public function testInstanceReturnsNullWhenNoData(): void
73+
{
74+
// Mock Redis to return false (no data)
75+
$this->redisMock
76+
->expects($this->once())
77+
->method('get')
78+
->with(RedisSingletonTest::class)
79+
->willReturn(false);
80+
81+
// Inject mock using reflection
82+
$reflection = new \ReflectionClass(Redis::class);
83+
$property = $reflection->getProperty('_redis');
84+
$property->setAccessible(true);
85+
$property->setValue(null, $this->redisMock);
86+
87+
$retrieved = RedisSingletonTest::instance();
88+
89+
$this->assertNull($retrieved);
90+
}
91+
92+
public function testSerializeStoresSerializedObject(): void
93+
{
94+
$instance = new RedisSingletonTest();
95+
$instance->testValue = 'serialize_redis';
96+
97+
// Mock Redis to expect set() with serialized object
98+
$this->redisMock
99+
->expects($this->once())
100+
->method('set')
101+
->with(
102+
RedisSingletonTest::class,
103+
$this->callback(function($value) use ($instance) {
104+
$unserialized = unserialize($value);
105+
return $unserialized->testValue === $instance->testValue;
106+
})
107+
);
108+
109+
// Inject mock using reflection
110+
$reflection = new \ReflectionClass(Redis::class);
111+
$property = $reflection->getProperty('_redis');
112+
$property->setAccessible(true);
113+
$property->setValue(null, $this->redisMock);
114+
115+
$instance->serialize();
116+
}
117+
118+
public function testInvalidateDeletesKey(): void
119+
{
120+
// Mock Redis to expect del() call
121+
$this->redisMock
122+
->expects($this->once())
123+
->method('del')
124+
->with(RedisSingletonTest::class);
125+
126+
// Inject mock using reflection
127+
$reflection = new \ReflectionClass(Redis::class);
128+
$property = $reflection->getProperty('_redis');
129+
$property->setAccessible(true);
130+
$property->setValue(null, $this->redisMock);
131+
132+
RedisSingletonTest::invalidate();
133+
}
134+
135+
public function testGetRedisCreatesConnectionOnFirstCall(): void
136+
{
137+
// Reset static redis
138+
$reflection = new \ReflectionClass(Redis::class);
139+
$property = $reflection->getProperty('_redis');
140+
$property->setAccessible(true);
141+
$property->setValue(null, null);
142+
143+
// Get the protected method
144+
$method = $reflection->getMethod('getRedis');
145+
$method->setAccessible(true);
146+
147+
// First call should create new Redis
148+
$redis1 = $method->invoke(null);
149+
$this->assertInstanceOf(\Redis::class, $redis1);
150+
151+
// Second call should return same instance
152+
$redis2 = $method->invoke(null);
153+
$this->assertSame($redis1, $redis2);
154+
}
155+
}

0 commit comments

Comments
 (0)