Enable Discovery debug logging for production troubleshooting
- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
This commit is contained in:
168
tests/Framework/Database/ChangeTrackingLogicTest.php
Normal file
168
tests/Framework/Database/ChangeTrackingLogicTest.php
Normal file
@@ -0,0 +1,168 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
// Simple test to verify change tracking logic
|
||||
test('change tracking detects property changes correctly', function () {
|
||||
// Test class
|
||||
$testClass = new class () {
|
||||
public function __construct(
|
||||
public readonly int $id = 1,
|
||||
public string $name = '',
|
||||
public string $email = '',
|
||||
public int $age = 0,
|
||||
) {
|
||||
}
|
||||
};
|
||||
|
||||
$original = new $testClass(id: 1, name: 'John Doe', email: 'john@example.com', age: 30);
|
||||
$modified = new $testClass(id: 1, name: 'John Smith', email: 'john@example.com', age: 31);
|
||||
|
||||
// Simulate change detection
|
||||
$changes = [];
|
||||
$oldValues = [];
|
||||
$newValues = [];
|
||||
|
||||
$reflectionClass = new ReflectionClass($original);
|
||||
foreach ($reflectionClass->getProperties() as $property) {
|
||||
if ($property->getName() === 'id') {
|
||||
continue;
|
||||
} // Skip ID
|
||||
|
||||
$property->setAccessible(true);
|
||||
$oldValue = $property->getValue($original);
|
||||
$newValue = $property->getValue($modified);
|
||||
|
||||
if ($oldValue !== $newValue) {
|
||||
$changes[] = $property->getName();
|
||||
$oldValues[$property->getName()] = $oldValue;
|
||||
$newValues[$property->getName()] = $newValue;
|
||||
}
|
||||
}
|
||||
|
||||
// Assertions
|
||||
expect($changes)->toBe(['name', 'age']);
|
||||
expect($oldValues)->toBe(['name' => 'John Doe', 'age' => 30]);
|
||||
expect($newValues)->toBe(['name' => 'John Smith', 'age' => 31]);
|
||||
});
|
||||
|
||||
test('change tracking detects no changes when objects are identical', function () {
|
||||
$testClass = new class () {
|
||||
public function __construct(
|
||||
public readonly int $id = 1,
|
||||
public string $name = '',
|
||||
public string $email = '',
|
||||
public int $age = 0,
|
||||
) {
|
||||
}
|
||||
};
|
||||
|
||||
$original = new $testClass(id: 1, name: 'John Doe', email: 'john@example.com', age: 30);
|
||||
$identical = new $testClass(id: 1, name: 'John Doe', email: 'john@example.com', age: 30);
|
||||
|
||||
// Simulate change detection
|
||||
$changes = [];
|
||||
$reflectionClass = new ReflectionClass($original);
|
||||
foreach ($reflectionClass->getProperties() as $property) {
|
||||
if ($property->getName() === 'id') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$property->setAccessible(true);
|
||||
$oldValue = $property->getValue($original);
|
||||
$newValue = $property->getValue($identical);
|
||||
|
||||
if ($oldValue !== $newValue) {
|
||||
$changes[] = $property->getName();
|
||||
}
|
||||
}
|
||||
|
||||
expect($changes)->toBeEmpty();
|
||||
});
|
||||
|
||||
test('change tracking handles type-sensitive comparisons', function () {
|
||||
$testClass = new class () {
|
||||
public function __construct(
|
||||
public readonly int $id = 1,
|
||||
public mixed $value = null,
|
||||
) {
|
||||
}
|
||||
};
|
||||
|
||||
$original = new $testClass(id: 1, value: 0);
|
||||
$modified = new $testClass(id: 1, value: '0'); // String vs int
|
||||
|
||||
// Simulate change detection
|
||||
$changes = [];
|
||||
$reflectionClass = new ReflectionClass($original);
|
||||
foreach ($reflectionClass->getProperties() as $property) {
|
||||
if ($property->getName() === 'id') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$property->setAccessible(true);
|
||||
$oldValue = $property->getValue($original);
|
||||
$newValue = $property->getValue($modified);
|
||||
|
||||
if ($oldValue !== $newValue) {
|
||||
$changes[] = $property->getName();
|
||||
}
|
||||
}
|
||||
|
||||
// Should detect change due to type difference (0 !== '0')
|
||||
expect($changes)->toBe(['value']);
|
||||
});
|
||||
|
||||
test('change tracking handles null values correctly', function () {
|
||||
$testClass = new class () {
|
||||
public function __construct(
|
||||
public readonly int $id = 1,
|
||||
public ?string $nullable = null,
|
||||
) {
|
||||
}
|
||||
};
|
||||
|
||||
// Test 1: null to value
|
||||
$original = new $testClass(id: 1, nullable: null);
|
||||
$modified = new $testClass(id: 1, nullable: 'value');
|
||||
|
||||
$changes = [];
|
||||
$reflectionClass = new ReflectionClass($original);
|
||||
foreach ($reflectionClass->getProperties() as $property) {
|
||||
if ($property->getName() === 'id') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$property->setAccessible(true);
|
||||
$oldValue = $property->getValue($original);
|
||||
$newValue = $property->getValue($modified);
|
||||
|
||||
if ($oldValue !== $newValue) {
|
||||
$changes[] = $property->getName();
|
||||
}
|
||||
}
|
||||
|
||||
expect($changes)->toBe(['nullable']);
|
||||
|
||||
// Test 2: value to null
|
||||
$original2 = new $testClass(id: 1, nullable: 'value');
|
||||
$modified2 = new $testClass(id: 1, nullable: null);
|
||||
|
||||
$changes2 = [];
|
||||
foreach ($reflectionClass->getProperties() as $property) {
|
||||
if ($property->getName() === 'id') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$property->setAccessible(true);
|
||||
$oldValue = $property->getValue($original2);
|
||||
$newValue = $property->getValue($modified2);
|
||||
|
||||
if ($oldValue !== $newValue) {
|
||||
$changes2[] = $property->getName();
|
||||
}
|
||||
}
|
||||
|
||||
expect($changes2)->toBe(['nullable']);
|
||||
});
|
||||
Reference in New Issue
Block a user