'Test', 'content' => 'Hello']); expect($data->toArray())->toBe(['title' => 'Test', 'content' => 'Hello']); }); it('can be created as empty', function () { $data = BlockData::empty(); expect($data->toArray())->toBe([]); expect($data->has('key'))->toBeFalse(); }); it('can get values by key', function () { $data = BlockData::fromArray(['title' => 'Test', 'count' => 5]); expect($data->get('title'))->toBe('Test'); expect($data->get('count'))->toBe(5); expect($data->get('missing'))->toBeNull(); expect($data->get('missing', 'default'))->toBe('default'); }); it('can check if key exists', function () { $data = BlockData::fromArray(['title' => 'Test']); expect($data->has('title'))->toBeTrue(); expect($data->has('missing'))->toBeFalse(); }); it('can add new key-value pair', function () { $data = BlockData::fromArray(['title' => 'Test']); $newData = $data->with('content', 'Hello'); expect($newData->get('title'))->toBe('Test'); expect($newData->get('content'))->toBe('Hello'); expect($data->has('content'))->toBeFalse(); // Original unchanged }); it('can remove key', function () { $data = BlockData::fromArray(['title' => 'Test', 'content' => 'Hello']); $newData = $data->without('title'); expect($newData->has('title'))->toBeFalse(); expect($newData->has('content'))->toBeTrue(); expect($data->has('title'))->toBeTrue(); // Original unchanged }); it('can merge with another array', function () { $data = BlockData::fromArray(['title' => 'Test']); $merged = $data->merge(['content' => 'Hello', 'title' => 'Updated']); expect($merged->get('title'))->toBe('Updated'); expect($merged->get('content'))->toBe('Hello'); }); it('accepts scalar values', function () { $data = BlockData::fromArray([ 'string' => 'test', 'int' => 123, 'float' => 45.67, 'bool' => true, 'null' => null, ]); expect($data->get('string'))->toBe('test'); expect($data->get('int'))->toBe(123); expect($data->get('float'))->toBe(45.67); expect($data->get('bool'))->toBeTrue(); expect($data->get('null'))->toBeNull(); }); it('accepts arrays of scalar values', function () { $data = BlockData::fromArray([ 'tags' => ['php', 'testing', 'pest'], 'numbers' => [1, 2, 3], ]); expect($data->get('tags'))->toBe(['php', 'testing', 'pest']); expect($data->get('numbers'))->toBe([1, 2, 3]); }); it('accepts nested arrays', function () { $data = BlockData::fromArray([ 'config' => [ 'width' => 100, 'height' => 200, ], ]); expect($data->get('config'))->toBe(['width' => 100, 'height' => 200]); }); it('throws exception for non-string keys', function () { expect(fn () => BlockData::fromArray([0 => 'value'])) ->toThrow(InvalidArgumentException::class, 'BlockData keys must be strings'); }); it('throws exception for non-serializable values', function () { expect(fn () => BlockData::fromArray(['key' => fopen('php://memory', 'r')])) ->toThrow(InvalidArgumentException::class, 'BlockData value for key'); }); });