Update regex validation and add validation class to return full information. Add helper to return last error message from defined constant
405 lines
9.4 KiB
PHP
405 lines
9.4 KiB
PHP
<?php
|
|
|
|
// This code was created by Claude Sonnet 4
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace tests;
|
|
|
|
use PHPUnit\Framework\TestCase;
|
|
use CoreLibs\Combined\ArrayHandler;
|
|
|
|
class CoreLibsCombinedArrayHandlerFindArraysMissingKeyTest extends TestCase
|
|
{
|
|
private const DATA_SEPARATOR = ':'; // Updated to match your class's separator
|
|
|
|
/**
|
|
* Test finding missing single key when searching by value without specific key
|
|
*/
|
|
public function testFindMissingSingleKeyWithValueSearch()
|
|
{
|
|
$array = [
|
|
'item1' => [
|
|
'name' => 'John',
|
|
'age' => 25
|
|
// missing 'email' key
|
|
],
|
|
'item2' => [
|
|
'name' => 'Jane',
|
|
'age' => 30,
|
|
'email' => 'jane@example.com'
|
|
],
|
|
'item3' => [
|
|
'name' => 'John', // same value as item1
|
|
'age' => 35,
|
|
'email' => 'john2@example.com'
|
|
]
|
|
];
|
|
|
|
$result = ArrayHandler::findArraysMissingKey($array, 'John', 'email');
|
|
|
|
$this->assertCount(1, $result);
|
|
$this->assertEquals($array['item1'], $result[0]['content']);
|
|
$this->assertEquals('item1', $result[0]['path']);
|
|
$this->assertEquals(['email'], $result[0]['missing_key']);
|
|
}
|
|
|
|
/**
|
|
* Test finding missing single key when searching by specific key-value pair
|
|
*/
|
|
public function testFindMissingSingleKeyWithKeyValueSearch()
|
|
{
|
|
$array = [
|
|
'user1' => [
|
|
'id' => 1,
|
|
'name' => 'Alice'
|
|
// missing 'status' key
|
|
],
|
|
'user2' => [
|
|
'id' => 2,
|
|
'name' => 'Bob',
|
|
'status' => 'active'
|
|
],
|
|
'user3' => [
|
|
'id' => 1, // same id as user1
|
|
'name' => 'Charlie',
|
|
'status' => 'inactive'
|
|
]
|
|
];
|
|
|
|
$result = ArrayHandler::findArraysMissingKey($array, 1, 'status', 'id');
|
|
|
|
$this->assertCount(1, $result);
|
|
$this->assertEquals($array['user1'], $result[0]['content']);
|
|
$this->assertEquals('user1', $result[0]['path']);
|
|
$this->assertEquals(['status'], $result[0]['missing_key']);
|
|
}
|
|
|
|
/**
|
|
* Test finding missing multiple keys
|
|
*/
|
|
public function testFindMissingMultipleKeys()
|
|
{
|
|
$array = [
|
|
'record1' => [
|
|
'name' => 'Test',
|
|
'value' => 100
|
|
// missing both 'date' and 'status' keys
|
|
],
|
|
'record2' => [
|
|
'name' => 'Test',
|
|
'value' => 200,
|
|
'date' => '2023-01-01'
|
|
// missing 'status' key
|
|
],
|
|
'record3' => [
|
|
'name' => 'Test',
|
|
'value' => 300,
|
|
'date' => '2023-01-02',
|
|
'status' => 'complete'
|
|
]
|
|
];
|
|
|
|
$result = ArrayHandler::findArraysMissingKey($array, 'Test', ['date', 'status']);
|
|
|
|
$this->assertCount(2, $result);
|
|
|
|
// First result should be record1 missing both keys
|
|
$this->assertEquals($array['record1'], $result[0]['content']);
|
|
$this->assertEquals('record1', $result[0]['path']);
|
|
$this->assertContains('date', $result[0]['missing_key']);
|
|
$this->assertContains('status', $result[0]['missing_key']);
|
|
$this->assertCount(2, $result[0]['missing_key']);
|
|
|
|
// Second result should be record2 missing status key
|
|
$this->assertEquals($array['record2'], $result[1]['content']);
|
|
$this->assertEquals('record2', $result[1]['path']);
|
|
$this->assertEquals(['status'], $result[1]['missing_key']);
|
|
}
|
|
|
|
/**
|
|
* Test with nested arrays
|
|
*/
|
|
public function testFindMissingKeyInNestedArrays()
|
|
{
|
|
$array = [
|
|
'section1' => [
|
|
'items' => [
|
|
'item1' => [
|
|
'name' => 'Product A',
|
|
'price' => 99.99
|
|
// missing 'category' key
|
|
],
|
|
'item2' => [
|
|
'name' => 'Product B',
|
|
'price' => 149.99,
|
|
'category' => 'electronics'
|
|
]
|
|
]
|
|
],
|
|
'section2' => [
|
|
'data' => [
|
|
'name' => 'Product A', // same name as nested item
|
|
'category' => 'books'
|
|
]
|
|
]
|
|
];
|
|
|
|
$result = ArrayHandler::findArraysMissingKey($array, 'Product A', 'category');
|
|
|
|
$this->assertCount(1, $result);
|
|
$this->assertEquals($array['section1']['items']['item1'], $result[0]['content']);
|
|
$this->assertEquals('section1:items:item1', $result[0]['path']);
|
|
$this->assertEquals(['category'], $result[0]['missing_key']);
|
|
}
|
|
|
|
/**
|
|
* Test when no arrays are missing the required key
|
|
*/
|
|
public function testNoMissingKeys()
|
|
{
|
|
$array = [
|
|
'item1' => [
|
|
'name' => 'John',
|
|
'email' => 'john@example.com'
|
|
],
|
|
'item2' => [
|
|
'name' => 'Jane',
|
|
'email' => 'jane@example.com'
|
|
]
|
|
];
|
|
|
|
$result = ArrayHandler::findArraysMissingKey($array, 'John', 'email');
|
|
|
|
$this->assertEmpty($result);
|
|
}
|
|
|
|
/**
|
|
* Test when search value is not found in any array
|
|
*/
|
|
public function testSearchValueNotFound()
|
|
{
|
|
$array = [
|
|
'item1' => [
|
|
'name' => 'John',
|
|
'age' => 25
|
|
],
|
|
'item2' => [
|
|
'name' => 'Jane',
|
|
'age' => 30
|
|
]
|
|
];
|
|
|
|
$result = ArrayHandler::findArraysMissingKey($array, 'Bob', 'email');
|
|
|
|
$this->assertEmpty($result);
|
|
}
|
|
|
|
/**
|
|
* Test with different data types for search value
|
|
*/
|
|
public function testDifferentSearchValueTypes()
|
|
{
|
|
$array = [
|
|
'item1' => [
|
|
'active' => true,
|
|
'count' => 5
|
|
// missing 'label' key
|
|
],
|
|
'item2' => [
|
|
'active' => false,
|
|
'count' => 10,
|
|
'label' => 'test'
|
|
],
|
|
'item3' => [
|
|
'active' => true, // same boolean as item1
|
|
'count' => 15,
|
|
'label' => 'another'
|
|
]
|
|
];
|
|
|
|
// Test with boolean
|
|
$result = ArrayHandler::findArraysMissingKey($array, true, 'label', 'active');
|
|
$this->assertCount(1, $result);
|
|
$this->assertEquals('item1', $result[0]['path']);
|
|
|
|
// Test with integer
|
|
$result = ArrayHandler::findArraysMissingKey($array, 5, 'label', 'count');
|
|
$this->assertCount(1, $result);
|
|
$this->assertEquals('item1', $result[0]['path']);
|
|
}
|
|
|
|
/**
|
|
* Test with empty array
|
|
*/
|
|
public function testEmptyArray()
|
|
{
|
|
$array = [];
|
|
|
|
$result = ArrayHandler::findArraysMissingKey($array, 'test', 'key');
|
|
|
|
$this->assertEmpty($result);
|
|
}
|
|
|
|
/**
|
|
* Test with array containing non-array values
|
|
*/
|
|
public function testMixedArrayTypes()
|
|
{
|
|
$array = [
|
|
'string_value' => 'hello',
|
|
'numeric_value' => 123,
|
|
'array_value' => [
|
|
'name' => 'test',
|
|
// missing 'type' key
|
|
],
|
|
'another_array' => [
|
|
'name' => 'test',
|
|
'type' => 'example'
|
|
]
|
|
];
|
|
|
|
$result = ArrayHandler::findArraysMissingKey($array, 'test', 'type');
|
|
|
|
$this->assertCount(1, $result);
|
|
$this->assertEquals($array['array_value'], $result[0]['content']);
|
|
$this->assertEquals('array_value', $result[0]['path']);
|
|
$this->assertEquals(['type'], $result[0]['missing_key']);
|
|
}
|
|
|
|
/**
|
|
* Test path building with deeper nesting
|
|
*/
|
|
public function testDeepNestingPathBuilding()
|
|
{
|
|
$array = [
|
|
'level1' => [
|
|
'level2' => [
|
|
'level3' => [
|
|
'items' => [
|
|
'target_item' => [
|
|
'name' => 'deep_test',
|
|
// missing 'required_field'
|
|
]
|
|
]
|
|
]
|
|
]
|
|
]
|
|
];
|
|
|
|
$result = ArrayHandler::findArraysMissingKey($array, 'deep_test', 'required_field');
|
|
|
|
$this->assertCount(1, $result);
|
|
$this->assertEquals('level1:level2:level3:items:target_item', $result[0]['path']);
|
|
}
|
|
|
|
/**
|
|
* Test with custom path separator
|
|
*/
|
|
public function testCustomPathSeparator()
|
|
{
|
|
$array = [
|
|
'level1' => [
|
|
'level2' => [
|
|
'item' => [
|
|
'name' => 'test',
|
|
// missing 'type' key
|
|
]
|
|
]
|
|
]
|
|
];
|
|
|
|
$result = ArrayHandler::findArraysMissingKey($array, 'test', 'type', null, '/');
|
|
|
|
$this->assertCount(1, $result);
|
|
$this->assertEquals('level1/level2/item', $result[0]['path']);
|
|
}
|
|
|
|
/**
|
|
* Test default path separator behavior
|
|
*/
|
|
public function testDefaultPathSeparator()
|
|
{
|
|
$array = [
|
|
'parent' => [
|
|
'child' => [
|
|
'name' => 'test',
|
|
// missing 'value' key
|
|
]
|
|
]
|
|
];
|
|
|
|
// Using default separator (should be ':')
|
|
$result = ArrayHandler::findArraysMissingKey($array, 'test', 'value');
|
|
|
|
$this->assertCount(1, $result);
|
|
$this->assertEquals('parent:child', $result[0]['path']);
|
|
}
|
|
|
|
/**
|
|
* Test different path separators don't affect search logic
|
|
*/
|
|
public function testPathSeparatorDoesNotAffectSearchLogic()
|
|
{
|
|
$array = [
|
|
'section' => [
|
|
'data' => [
|
|
'id' => 123,
|
|
'name' => 'item'
|
|
// missing 'status'
|
|
]
|
|
]
|
|
];
|
|
|
|
// Test with different separators - results should be identical except for path
|
|
$result1 = ArrayHandler::findArraysMissingKey($array, 123, 'status', 'id', ':');
|
|
$result2 = ArrayHandler::findArraysMissingKey($array, 123, 'status', 'id', '.');
|
|
$result3 = ArrayHandler::findArraysMissingKey($array, 123, 'status', 'id', '/');
|
|
|
|
$this->assertCount(1, $result1);
|
|
$this->assertCount(1, $result2);
|
|
$this->assertCount(1, $result3);
|
|
|
|
// Content and missing_key should be the same
|
|
$this->assertEquals($result1[0]['content'], $result2[0]['content']);
|
|
$this->assertEquals($result1[0]['content'], $result3[0]['content']);
|
|
$this->assertEquals($result1[0]['missing_key'], $result2[0]['missing_key']);
|
|
$this->assertEquals($result1[0]['missing_key'], $result3[0]['missing_key']);
|
|
|
|
// Paths should be different based on separator
|
|
$this->assertEquals('section:data', $result1[0]['path']);
|
|
$this->assertEquals('section.data', $result2[0]['path']);
|
|
$this->assertEquals('section/data', $result3[0]['path']);
|
|
}
|
|
|
|
/**
|
|
* test type checking
|
|
*/
|
|
public function testStrictTypeChecking()
|
|
{
|
|
$array = [
|
|
'item1' => [
|
|
'id' => '123', // string
|
|
'name' => 'test'
|
|
// missing 'status'
|
|
],
|
|
'item2' => [
|
|
'id' => 123, // integer
|
|
'name' => 'test2',
|
|
'status' => 'active'
|
|
]
|
|
];
|
|
|
|
// Search for integer 123 - should only match item2
|
|
$result = ArrayHandler::findArraysMissingKey($array, 123, 'status', 'id');
|
|
$this->assertEmpty($result); // item2 has the status key
|
|
|
|
// Search for string '123' - should only match item1
|
|
$result = ArrayHandler::findArraysMissingKey($array, '123', 'status', 'id');
|
|
$this->assertCount(1, $result);
|
|
$this->assertEquals('item1', $result[0]['path']);
|
|
}
|
|
}
|
|
|
|
// __END__
|