Skip to content

Commit ca005ba

Browse files
committed
feat(tests): adicionar testes para validar o uso de capacidade ótima no método encodeWithPool
1 parent ae08da7 commit ca005ba

File tree

2 files changed

+209
-2
lines changed

2 files changed

+209
-2
lines changed

src/Json/Pool/JsonBufferPool.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,8 @@ public static function encodeWithPool(
137137
mixed $data,
138138
int $flags = JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE
139139
): string {
140-
$estimatedSize = self::estimateJsonSize($data);
141-
$buffer = self::getBuffer($estimatedSize);
140+
$optimalCapacity = self::getOptimalCapacity($data);
141+
$buffer = self::getBuffer($optimalCapacity);
142142

143143
try {
144144
$buffer->appendJson($data, $flags);
Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PivotPHP\Core\Tests\Json\Pool;
6+
7+
use PHPUnit\Framework\TestCase;
8+
use PivotPHP\Core\Json\Pool\JsonBufferPool;
9+
10+
/**
11+
* Test JsonBufferPool encodeWithPool method uses optimal capacity
12+
*/
13+
class JsonBufferPoolEncodeTest extends TestCase
14+
{
15+
protected function setUp(): void
16+
{
17+
// Clear pools and reset configuration before each test
18+
JsonBufferPool::clearPools();
19+
JsonBufferPool::resetConfiguration();
20+
}
21+
22+
protected function tearDown(): void
23+
{
24+
// Clear pools and reset configuration after each test
25+
JsonBufferPool::clearPools();
26+
JsonBufferPool::resetConfiguration();
27+
}
28+
29+
/**
30+
* Test that encodeWithPool uses standard size categories
31+
*/
32+
public function testEncodeWithPoolUsesStandardCapacities(): void
33+
{
34+
// Test small data that should use 1KB buffer
35+
$smallData = ['id' => 1, 'name' => 'test'];
36+
$json1 = JsonBufferPool::encodeWithPool($smallData);
37+
38+
// Test medium data that should use 4KB buffer
39+
$mediumData = array_fill(0, 50, ['field' => 'value', 'num' => 123]);
40+
$json2 = JsonBufferPool::encodeWithPool($mediumData);
41+
42+
// Test large data that should use 16KB buffer
43+
$largeData = array_fill(0, 500, ['item' => 'data', 'id' => rand(1, 1000)]);
44+
$json3 = JsonBufferPool::encodeWithPool($largeData);
45+
46+
$stats = JsonBufferPool::getStatistics();
47+
$poolSizes = $stats['pool_sizes'];
48+
49+
// Should have created standard sized pools, not arbitrary ones
50+
$this->assertArrayHasKey('1.0KB (1024 bytes)', $poolSizes);
51+
$this->assertArrayHasKey('4.0KB (4096 bytes)', $poolSizes);
52+
$this->assertArrayHasKey('16.0KB (16384 bytes)', $poolSizes);
53+
54+
// Each pool should have exactly 1 buffer returned to it
55+
$this->assertEquals(1, $poolSizes['1.0KB (1024 bytes)']);
56+
$this->assertEquals(1, $poolSizes['4.0KB (4096 bytes)']);
57+
$this->assertEquals(1, $poolSizes['16.0KB (16384 bytes)']);
58+
59+
// Verify JSON output is correct
60+
$this->assertIsString($json1);
61+
$this->assertIsString($json2);
62+
$this->assertIsString($json3);
63+
64+
$this->assertStringContainsString('test', $json1);
65+
$this->assertStringContainsString('value', $json2);
66+
$this->assertStringContainsString('data', $json3);
67+
}
68+
69+
/**
70+
* Test that multiple calls with similar data reuse same pool
71+
*/
72+
public function testEncodeWithPoolReusesBuffers(): void
73+
{
74+
// Encode similar sized data multiple times
75+
for ($i = 0; $i < 5; $i++) {
76+
$data = ['iteration' => $i, 'test' => 'data'];
77+
$json = JsonBufferPool::encodeWithPool($data);
78+
$this->assertStringContainsString((string)$i, $json);
79+
}
80+
81+
$stats = JsonBufferPool::getStatistics();
82+
83+
// Should have high reuse rate since all data uses same buffer size
84+
$this->assertEquals(5, $stats['total_operations']);
85+
$this->assertEquals(4, $stats['detailed_stats']['reuses']); // 4 reuses (first is allocation)
86+
$this->assertEquals(80.0, $stats['reuse_rate']); // 4/5 * 100 = 80%
87+
88+
// Should only have one pool type
89+
$this->assertEquals(1, $stats['active_pool_count']);
90+
$this->assertArrayHasKey('1.0KB (1024 bytes)', $stats['pool_sizes']);
91+
}
92+
93+
/**
94+
* Test edge case with very large data
95+
*/
96+
public function testEncodeWithPoolLargeData(): void
97+
{
98+
// Create data that exceeds standard categories
99+
$veryLargeData = array_fill(0, 2000, ['id' => rand(1, 10000), 'data' => str_repeat('x', 50)]);
100+
$json = JsonBufferPool::encodeWithPool($veryLargeData);
101+
102+
$this->assertIsString($json);
103+
$this->assertGreaterThan(100000, strlen($json)); // Should be large JSON
104+
105+
$stats = JsonBufferPool::getStatistics();
106+
$poolsByCapacity = $stats['pools_by_capacity'];
107+
108+
// Should have created a large custom capacity pool
109+
$this->assertNotEmpty($poolsByCapacity);
110+
$largestPool = end($poolsByCapacity);
111+
$this->assertGreaterThanOrEqual(65536, $largestPool['capacity_bytes']); // At least 64KB
112+
}
113+
114+
/**
115+
* Test that different data types get appropriate buffer sizes
116+
*/
117+
public function testEncodeWithPoolDataTypeOptimization(): void
118+
{
119+
// String data - should use small buffer
120+
$stringData = 'This is a simple string';
121+
JsonBufferPool::encodeWithPool($stringData);
122+
123+
// Array data - should use appropriately sized buffer
124+
$arrayData = range(1, 100);
125+
JsonBufferPool::encodeWithPool($arrayData);
126+
127+
// Object data - should use appropriately sized buffer
128+
$objectData = (object)array_fill_keys(range('a', 'z'), 'value');
129+
JsonBufferPool::encodeWithPool($objectData);
130+
131+
$stats = JsonBufferPool::getStatistics();
132+
133+
// Should have multiple pool sizes for different data types
134+
$this->assertGreaterThanOrEqual(2, $stats['active_pool_count']);
135+
$this->assertGreaterThanOrEqual(2, count($stats['pool_sizes']));
136+
}
137+
138+
/**
139+
* Test consistency between encodeWithPool and manual buffer usage
140+
*/
141+
public function testEncodeWithPoolConsistency(): void
142+
{
143+
$testData = ['message' => 'Hello World', 'count' => 42, 'active' => true];
144+
145+
// Encode using pool
146+
$pooledResult = JsonBufferPool::encodeWithPool($testData);
147+
148+
// Encode manually with same flags
149+
$manualResult = json_encode($testData, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
150+
151+
// Results should be identical
152+
$this->assertEquals($manualResult, $pooledResult);
153+
$this->assertStringContainsString('Hello World', $pooledResult);
154+
$this->assertStringContainsString('42', $pooledResult);
155+
$this->assertStringContainsString('true', $pooledResult);
156+
}
157+
158+
/**
159+
* Test that encodeWithPool handles encoding failures gracefully
160+
*/
161+
public function testEncodeWithPoolErrorHandling(): void
162+
{
163+
// Create data that should encode fine
164+
$validData = ['test' => 'data'];
165+
$result = JsonBufferPool::encodeWithPool($validData);
166+
167+
$this->assertIsString($result);
168+
$this->assertEquals('{"test":"data"}', $result);
169+
170+
// Verify buffer was returned to pool even after successful encoding
171+
$stats = JsonBufferPool::getStatistics();
172+
$this->assertEquals(1, $stats['total_buffers_pooled']);
173+
}
174+
175+
/**
176+
* Test memory efficiency with optimal capacity selection
177+
*/
178+
public function testEncodeWithPoolMemoryEfficiency(): void
179+
{
180+
$memBefore = memory_get_usage();
181+
182+
// Encode various sized data multiple times
183+
for ($i = 0; $i < 10; $i++) {
184+
// Small data
185+
JsonBufferPool::encodeWithPool(['small' => $i]);
186+
187+
// Medium data
188+
JsonBufferPool::encodeWithPool(array_fill(0, 20, ['med' => $i]));
189+
190+
// Large data
191+
JsonBufferPool::encodeWithPool(array_fill(0, 100, ['large' => $i]));
192+
}
193+
194+
$memAfter = memory_get_usage();
195+
$stats = JsonBufferPool::getStatistics();
196+
197+
// Memory growth should be reasonable due to buffer reuse
198+
$memoryGrowth = $memAfter - $memBefore;
199+
$this->assertLessThan(1024 * 1024, $memoryGrowth); // Less than 1MB growth
200+
201+
// Should have high reuse rate
202+
$this->assertGreaterThan(70, $stats['reuse_rate']); // At least 70% reuse
203+
204+
// Should have created standard pool sizes
205+
$this->assertEquals(3, $stats['active_pool_count']); // 3 different sizes
206+
}
207+
}

0 commit comments

Comments
 (0)