toBe($expected); })->with([ ['true', true], ['1', true], [1, true], [true, true], ['on', true], ['false', false], ['0', false], [0, false], [false, false], ['', false], ]); test('normalize int returns null for empty string and null', function () { expect(SettingValueCaster::normalize('', 'int'))->toBeNull(); expect(SettingValueCaster::normalize(null, 'int'))->toBeNull(); }); test('normalize int casts numeric strings', function () { expect(SettingValueCaster::normalize('42', 'int'))->toBe(42); expect(SettingValueCaster::normalize('0', 'int'))->toBe(0); }); test('normalize float casts numeric strings', function () { expect(SettingValueCaster::normalize('3.14', 'float'))->toBe(3.14); }); test('normalize json passes through arrays and parses strings', function () { expect(SettingValueCaster::normalize(['a' => 1], 'json'))->toBe(['a' => 1]); expect(SettingValueCaster::normalize('{"b":2}', 'json'))->toBe(['b' => 2]); expect(SettingValueCaster::normalize('not-json', 'json'))->toBe([]); }); test('normalize string trims whitespace', function () { expect(SettingValueCaster::normalize(' hello ', 'string'))->toBe('hello'); }); test('normalize image_path returns trimmed string or null', function () { expect(SettingValueCaster::normalize(' assets/img/logo.png ', 'image_path'))->toBe('assets/img/logo.png'); expect(SettingValueCaster::normalize(null, 'image_path'))->toBeNull(); }); test('serialize bool emits 1 or 0', function () { expect(SettingValueCaster::serialize(true))->toBe('1'); expect(SettingValueCaster::serialize(false))->toBe('0'); }); test('serialize null returns null', function () { expect(SettingValueCaster::serialize(null))->toBeNull(); }); test('serialize array emits json', function () { expect(SettingValueCaster::serialize(['x' => 'y']))->toBe('{"x":"y"}'); }); test('serialize scalar returns string', function () { expect(SettingValueCaster::serialize(42))->toBe('42'); expect(SettingValueCaster::serialize('abc'))->toBe('abc'); }); test('deserialize round-trips bool, int, float, json', function () { expect(SettingValueCaster::deserialize('1', 'bool'))->toBeTrue(); expect(SettingValueCaster::deserialize('0', 'bool'))->toBeFalse(); expect(SettingValueCaster::deserialize('42', 'int'))->toBe(42); expect(SettingValueCaster::deserialize('3.14', 'float'))->toBe(3.14); expect(SettingValueCaster::deserialize('{"a":1}', 'json'))->toBe(['a' => 1]); }); test('deserialize null returns null', function () { expect(SettingValueCaster::deserialize(null, 'bool'))->toBeNull(); expect(SettingValueCaster::deserialize(null, 'json'))->toBeNull(); }); test('isUnchanged compares serialized form', function () { expect(SettingValueCaster::isUnchanged(true, '1'))->toBeTrue(); expect(SettingValueCaster::isUnchanged(false, '0'))->toBeTrue(); expect(SettingValueCaster::isUnchanged(null, null))->toBeTrue(); expect(SettingValueCaster::isUnchanged('abc', 'abc'))->toBeTrue(); expect(SettingValueCaster::isUnchanged('abc', 'xyz'))->toBeFalse(); expect(SettingValueCaster::isUnchanged(['a' => 1], ['a' => 1]))->toBeTrue(); });