Skip to content

Commit e6b4500

Browse files
caothu159Bột
andcommitted
test(simba): Phase F - unit tests for PO3 SP wrappers (#255)
- AsPOGetPO3Test: reflection-based param mapping + DB skip - AsPOSavePO3Test: 10 tests for 50+ param defaults + DB skip - AsPODeletePO3Test: 4 tests for 3 param structure + DB skip - All DB-dependent tests skip gracefully when no Simba connection Co-authored-by: Bột <bot@diepxuan.corp>
1 parent b44f1d5 commit e6b4500

3 files changed

Lines changed: 323 additions & 0 deletions

File tree

tests/Unit/AsPODeletePO3Test.php

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Diepxuan\Simba\Tests\Unit;
6+
7+
use Diepxuan\Simba\StoredProcedures\AsPODeletePO3;
8+
use PHPUnit\Framework\TestCase;
9+
10+
final class AsPODeletePO3Test extends TestCase
11+
{
12+
/** @var array<string, mixed> */
13+
private static ?array $procParams = null;
14+
15+
public static function setUpBeforeClass(): void
16+
{
17+
$ref = new \ReflectionMethod(AsPODeletePO3::class, 'call');
18+
$file = file_get_contents($ref->getFileName());
19+
$lines = explode("\n", $file);
20+
21+
$inCall = false;
22+
$params = [];
23+
foreach ($lines as $line) {
24+
if (str_contains($line, "ProcedureCaller::call('asPODeletePO3'")) {
25+
$inCall = true;
26+
continue;
27+
}
28+
if ($inCall) {
29+
if (str_contains($line, '], $connection)')) {
30+
break;
31+
}
32+
// Pattern 1: param tu $paramObj
33+
if (preg_match("/=>\s*\\\$paramObj->(p\w+)\s*\?\?\s*(.+),/", $line, $m)) {
34+
$params[$m[1]] = [
35+
'key' => $m[1],
36+
'default' => trim($m[2], ' ,'),
37+
];
38+
continue;
39+
}
40+
// Pattern 2: output param (pRet)
41+
if (preg_match("/'(p\w+)'\s*=>\s*\[/", $line, $m)) {
42+
$params[$m[1]] = [
43+
'key' => $m[1],
44+
'default' => 'array',
45+
];
46+
}
47+
}
48+
}
49+
self::$procParams = $params;
50+
}
51+
52+
public function testCallHasThreeParameters(): void
53+
{
54+
self::assertCount(3, self::$procParams ?? []);
55+
}
56+
57+
public function testCallHasPmaCtyParam(): void
58+
{
59+
self::assertArrayHasKey('pMa_cty', self::$procParams ?? []);
60+
}
61+
62+
public function testCallHasPsttRecParam(): void
63+
{
64+
self::assertArrayHasKey('pStt_rec', self::$procParams ?? []);
65+
}
66+
67+
public function testCallHasPRetOutputParam(): void
68+
{
69+
self::assertArrayHasKey('pRet', self::$procParams ?? []);
70+
self::assertSame('array', self::$procParams['pRet']['default'] ?? null);
71+
}
72+
73+
public function testCallWithParamsExists(): void
74+
{
75+
self::assertTrue(method_exists(AsPODeletePO3::class, 'callWithParams'));
76+
}
77+
78+
public function testCallReturnsCollectionWhenDbAvailable(): void
79+
{
80+
if (!self::hasSimbaDb()) {
81+
$this->markTestSkipped('Requires Simba DB connection.');
82+
}
83+
84+
$result = AsPODeletePO3::call([]);
85+
self::assertInstanceOf(\Illuminate\Support\Collection::class, $result);
86+
}
87+
88+
private static function hasSimbaDb(): bool
89+
{
90+
try {
91+
return \DB::connection('sqlsrv')->getPdo() !== null;
92+
} catch (\Throwable) {
93+
return false;
94+
}
95+
}
96+
}

tests/Unit/AsPOGetPO3Test.php

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Diepxuan\Simba\Tests\Unit;
6+
7+
use Diepxuan\Simba\StoredProcedures\AsPOGetPO3;
8+
use PHPUnit\Framework\TestCase;
9+
10+
final class AsPOGetPO3Test extends TestCase
11+
{
12+
/** @var array<string, mixed> param map tu ReflectionMethod */
13+
private static ?array $procParams = null;
14+
15+
public static function setUpBeforeClass(): void
16+
{
17+
// Dung reflection de doc cau truc parameter mapping tu call()
18+
$ref = new \ReflectionMethod(AsPOGetPO3::class, 'call');
19+
$file = file_get_contents($ref->getFileName());
20+
$lines = explode("\n", $file);
21+
22+
$inCall = false;
23+
$params = [];
24+
foreach ($lines as $line) {
25+
if (str_contains($line, "ProcedureCaller::call('asPOGetPO3'")) {
26+
$inCall = true;
27+
continue;
28+
}
29+
if ($inCall) {
30+
if (str_contains($line, '], $connection)')) {
31+
break;
32+
}
33+
// Lay cac param: 'pMa_cty' => $paramObj->pMa_cty ?? SModel::CTY,
34+
if (preg_match("/=>\s*\\\$paramObj->(p\w+)\s*\?\?\s*(.+),/", $line, $m)) {
35+
$params[$m[1]] = [
36+
'key' => $m[1],
37+
'default' => trim($m[2], ' ,'),
38+
];
39+
}
40+
}
41+
}
42+
self::$procParams = $params;
43+
}
44+
45+
public function testCallUsesTwoParameters(): void
46+
{
47+
self::assertCount(2, self::$procParams ?: []);
48+
}
49+
50+
public function testCallHasPmaCtyParamWithDefault(): void
51+
{
52+
self::assertArrayHasKey('pMa_cty', self::$procParams ?: []);
53+
if (isset(self::$procParams['pMa_cty'])) {
54+
self::assertStringContainsString('SModel::CTY', self::$procParams['pMa_cty']['default']);
55+
}
56+
}
57+
58+
public function testCallHasPsttRecParam(): void
59+
{
60+
self::assertArrayHasKey('pStt_rec', self::$procParams ?: []);
61+
}
62+
63+
public function testCallWithParamsExists(): void
64+
{
65+
self::assertTrue(method_exists(AsPOGetPO3::class, 'callWithParams'));
66+
}
67+
68+
public function testCallReturnsCollectionWhenDbAvailable(): void
69+
{
70+
if (!self::hasSimbaDb()) {
71+
$this->markTestSkipped('Requires Simba DB connection.');
72+
}
73+
74+
$result = AsPOGetPO3::call([]);
75+
self::assertInstanceOf(\Illuminate\Support\Collection::class, $result);
76+
}
77+
78+
private static function hasSimbaDb(): bool
79+
{
80+
try {
81+
return \DB::connection('sqlsrv')->getPdo() !== null;
82+
} catch (\Throwable) {
83+
return false;
84+
}
85+
}
86+
}

tests/Unit/AsPOSavePO3Test.php

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Diepxuan\Simba\Tests\Unit;
6+
7+
use Diepxuan\Simba\StoredProcedures\AsPOSavePO3;
8+
use PHPUnit\Framework\TestCase;
9+
10+
final class AsPOSavePO3Test extends TestCase
11+
{
12+
/** @var array<string, array{key: string, default: string}> */
13+
private static ?array $procParams = null;
14+
15+
public static function setUpBeforeClass(): void
16+
{
17+
$ref = new \ReflectionMethod(AsPOSavePO3::class, 'call');
18+
$file = file_get_contents($ref->getFileName());
19+
$lines = explode("\n", $file);
20+
21+
$inCall = false;
22+
$params = [];
23+
foreach ($lines as $line) {
24+
if (str_contains($line, "ProcedureCaller::call('asPOSavePO3'")) {
25+
$inCall = true;
26+
continue;
27+
}
28+
if ($inCall) {
29+
if (str_contains($line, '], $connection)')) {
30+
break;
31+
}
32+
// Pattern 1: param tu $paramObj (co ?? default)
33+
if (preg_match("/=>\s*\\\$paramObj->(p\w+)\s*\?\?\s*(.+),/", $line, $m)) {
34+
$params[$m[1]] = [
35+
'key' => $m[1],
36+
'default' => trim($m[2], ' ,'),
37+
];
38+
continue;
39+
}
40+
// Pattern 2: output param (pRet) co array value
41+
if (preg_match("/'(p\w+)'\s*=>\s*\[/", $line, $m)) {
42+
$params[$m[1]] = [
43+
'key' => $m[1],
44+
'default' => 'array',
45+
];
46+
}
47+
}
48+
}
49+
self::$procParams = $params;
50+
}
51+
52+
public function testCallHasKeyStructuralParameters(): void
53+
{
54+
$expectedKeys = [
55+
'pMa_cty', 'pStt_rec', 'pMa_ct', 'pMa_kh',
56+
'pMa_httt', 'pTk_pt', 'pDien_giai', 'pSo_hd',
57+
'pNgay_hd', 'pNgay_ct', 'pNgay_lct', 'pMa_nt',
58+
'pTy_gia',
59+
'pT_tien_nt0', 'pT_tien0', 'pT_cp_nt', 'pT_cp',
60+
'pT_thue_nt', 'pT_thue', 'pT_ck', 'pT_ck_nt',
61+
'pT_tt', 'pT_tt_nt', 'pT_so_luong',
62+
'pChiTiet', 'pChiPhi', 'pRet',
63+
];
64+
$actualKeys = array_keys(self::$procParams ?? []);
65+
66+
foreach ($expectedKeys as $key) {
67+
self::assertArrayHasKey($key, self::$procParams ?: [], "Missing param: {$key}");
68+
}
69+
}
70+
71+
public function testCallHasAtLeast50Parameters(): void
72+
{
73+
self::assertGreaterThanOrEqual(50, count(self::$procParams ?? []),
74+
'AsPOSavePO3 should have 50+ parameters in call()');
75+
}
76+
77+
public function testDefaultMaCtIsPO3(): void
78+
{
79+
self::assertSame("'PO3'", self::$procParams['pMa_ct']['default'] ?? null);
80+
}
81+
82+
public function testDefaultMaNtIsVND(): void
83+
{
84+
self::assertSame("'VND'", self::$procParams['pMa_nt']['default'] ?? null);
85+
}
86+
87+
public function testDefaultTyGiaIs1(): void
88+
{
89+
self::assertSame('1', self::$procParams['pTy_gia']['default'] ?? null);
90+
}
91+
92+
public function testDefaultKhtTainIs0(): void
93+
{
94+
self::assertSame('0', self::$procParams['pKht_tain']['default'] ?? null);
95+
}
96+
97+
public function testDefaultPost2glIs0(): void
98+
{
99+
self::assertSame('0', self::$procParams['pPost2gl']['default'] ?? null);
100+
}
101+
102+
public function testDefaultPost2inIs0(): void
103+
{
104+
self::assertSame('0', self::$procParams['pPost2in']['default'] ?? null);
105+
}
106+
107+
public function testChiTietDefaultsToEmptyArray(): void
108+
{
109+
self::assertSame('[]', self::$procParams['pChiTiet']['default'] ?? null);
110+
}
111+
112+
public function testChiPhiDefaultsToEmptyArray(): void
113+
{
114+
self::assertSame('[]', self::$procParams['pChiPhi']['default'] ?? null);
115+
}
116+
117+
public function testHasPRetOutputParam(): void
118+
{
119+
self::assertArrayHasKey('pRet', self::$procParams ?: []);
120+
self::assertSame('array', self::$procParams['pRet']['default'] ?? null);
121+
}
122+
123+
public function testCallReturnsCollectionWhenDbAvailable(): void
124+
{
125+
if (!self::hasSimbaDb()) {
126+
$this->markTestSkipped('Requires Simba DB connection.');
127+
}
128+
129+
$result = AsPOSavePO3::call([]);
130+
self::assertInstanceOf(\Illuminate\Support\Collection::class, $result);
131+
}
132+
133+
private static function hasSimbaDb(): bool
134+
{
135+
try {
136+
return \DB::connection('sqlsrv')->getPdo() !== null;
137+
} catch (\Throwable) {
138+
return false;
139+
}
140+
}
141+
}

0 commit comments

Comments
 (0)