diff --git a/tests/Feature/BoostServiceProviderTest.php b/tests/Feature/BoostServiceProviderTest.php index c855cc18..61beeef0 100644 --- a/tests/Feature/BoostServiceProviderTest.php +++ b/tests/Feature/BoostServiceProviderTest.php @@ -30,8 +30,8 @@ $provider->register(); $provider->boot(app('router')); - expect(app()->bound(Laravel\Roster\Roster::class))->toBeTrue(); - expect(config('logging.channels.browser'))->not->toBeNull(); + expect(app()->bound(Laravel\Roster\Roster::class))->toBeTrue() + ->and(config('logging.channels.browser'))->not->toBeNull(); }); }); diff --git a/tests/Feature/Mcp/ToolExecutorTest.php b/tests/Feature/Mcp/ToolExecutorTest.php index b226b520..461073f9 100644 --- a/tests/Feature/Mcp/ToolExecutorTest.php +++ b/tests/Feature/Mcp/ToolExecutorTest.php @@ -37,8 +37,8 @@ expect(false)->toBeTrue("Tool execution failed with error: {$errorText}"); } - expect($result->isError)->toBeFalse(); - expect($result->content)->toBeArray(); + expect($result->isError)->toBeFalse() + ->and($result->content)->toBeArray(); // The content should contain the app name (which should be "Laravel" in testbench) $textContent = $result->content[0]->text ?? ''; @@ -64,15 +64,15 @@ $result1 = $executor->execute(Tinker::class, ['code' => 'return getmypid();']); $result2 = $executor->execute(Tinker::class, ['code' => 'return getmypid();']); - expect($result1->isError)->toBeFalse(); - expect($result2->isError)->toBeFalse(); + expect($result1->isError)->toBeFalse() + ->and($result2->isError)->toBeFalse(); $pid1 = json_decode($result1->content[0]->text, true)['result']; $pid2 = json_decode($result2->content[0]->text, true)['result']; - expect($pid1)->toBeInt()->not->toBe(getmypid()); - expect($pid2)->toBeInt()->not->toBe(getmypid()); - expect($pid1)->not()->toBe($pid2); + expect($pid1)->toBeInt()->not->toBe(getmypid()) + ->and($pid2)->toBeInt()->not->toBe(getmypid()) + ->and($pid1)->not()->toBe($pid2); }); test('subprocess sees modified autoloaded code changes', function () { @@ -110,8 +110,8 @@ $result2 = $executor->execute(GetConfig::class, ['key' => 'app.name']); $response2 = json_decode($result2->content[0]->text, true); - expect($result2->isError)->toBeFalse(); - expect($response2['value'])->toBe('MODIFIED_BY_TEST'); // Using updated code, not cached + expect($result2->isError)->toBeFalse() + ->and($response2['value'])->toBe('MODIFIED_BY_TEST'); // Using updated code, not cached } finally { $cleanup(); } diff --git a/tests/Feature/Mcp/ToolRegistryTest.php b/tests/Feature/Mcp/ToolRegistryTest.php index 4ece3c4c..618f8612 100644 --- a/tests/Feature/Mcp/ToolRegistryTest.php +++ b/tests/Feature/Mcp/ToolRegistryTest.php @@ -11,8 +11,8 @@ }); test('can check if tool is allowed', function () { - expect(ToolRegistry::isToolAllowed(ApplicationInfo::class))->toBeTrue(); - expect(ToolRegistry::isToolAllowed('NonExistentTool'))->toBeFalse(); + expect(ToolRegistry::isToolAllowed(ApplicationInfo::class))->toBeTrue() + ->and(ToolRegistry::isToolAllowed('NonExistentTool'))->toBeFalse(); }); test('can get tool names', function () { diff --git a/tests/Feature/Mcp/Tools/ApplicationInfoTest.php b/tests/Feature/Mcp/Tools/ApplicationInfoTest.php index 0053bffc..7df6ba82 100644 --- a/tests/Feature/Mcp/Tools/ApplicationInfoTest.php +++ b/tests/Feature/Mcp/Tools/ApplicationInfoTest.php @@ -34,20 +34,20 @@ expect($data['isError'])->toBeFalse(); $content = json_decode($data['content'][0]['text'], true); - expect($content['php_version'])->toBe(PHP_VERSION); - expect($content['laravel_version'])->toBe(app()->version()); - expect($content['database_engine'])->toBe(config('database.default')); - expect($content['packages'])->toHaveCount(2); - expect($content['packages'][0]['roster_name'])->toBe('LARAVEL'); - expect($content['packages'][0]['package_name'])->toBe('laravel/framework'); - expect($content['packages'][0]['version'])->toBe('11.0.0'); - expect($content['packages'][1]['roster_name'])->toBe('PEST'); - expect($content['packages'][1]['package_name'])->toBe('pestphp/pest'); - expect($content['packages'][1]['version'])->toBe('2.0.0'); - expect($content['models'])->toBeArray(); - expect($content['models'])->toHaveCount(2); - expect($content['models'])->toContain('App\\Models\\User'); - expect($content['models'])->toContain('App\\Models\\Post'); + expect($content['php_version'])->toBe(PHP_VERSION) + ->and($content['laravel_version'])->toBe(app()->version()) + ->and($content['database_engine'])->toBe(config('database.default')) + ->and($content['packages'])->toHaveCount(2) + ->and($content['packages'][0]['roster_name'])->toBe('LARAVEL') + ->and($content['packages'][0]['package_name'])->toBe('laravel/framework') + ->and($content['packages'][0]['version'])->toBe('11.0.0') + ->and($content['packages'][1]['roster_name'])->toBe('PEST') + ->and($content['packages'][1]['package_name'])->toBe('pestphp/pest') + ->and($content['packages'][1]['version'])->toBe('2.0.0') + ->and($content['models'])->toBeArray() + ->and($content['models'])->toHaveCount(2) + ->and($content['models'])->toContain('App\\Models\\User') + ->and($content['models'])->toContain('App\\Models\\Post'); }); test('it returns application info with no packages', function () { @@ -60,17 +60,17 @@ $tool = new ApplicationInfo($roster, $guidelineAssist); $result = $tool->handle([]); - expect($result)->toBeInstanceOf(ToolResult::class); - expect($result)->toBeInstanceOf(ToolResult::class); + expect($result)->toBeInstanceOf(ToolResult::class) + ->and($result)->toBeInstanceOf(ToolResult::class); $data = $result->toArray(); expect($data['isError'])->toBeFalse(); $content = json_decode($data['content'][0]['text'], true); - expect($content['php_version'])->toBe(PHP_VERSION); - expect($content['laravel_version'])->toBe(app()->version()); - expect($content['database_engine'])->toBe(config('database.default')); - expect($content['packages'])->toHaveCount(0); - expect($content['models'])->toBeArray(); - expect($content['models'])->toHaveCount(0); + expect($content['php_version'])->toBe(PHP_VERSION) + ->and($content['laravel_version'])->toBe(app()->version()) + ->and($content['database_engine'])->toBe(config('database.default')) + ->and($content['packages'])->toHaveCount(0) + ->and($content['models'])->toBeArray() + ->and($content['models'])->toHaveCount(0); }); diff --git a/tests/Feature/Mcp/Tools/BrowserLogsTest.php b/tests/Feature/Mcp/Tools/BrowserLogsTest.php index ed11d060..ade18c27 100644 --- a/tests/Feature/Mcp/Tools/BrowserLogsTest.php +++ b/tests/Feature/Mcp/Tools/BrowserLogsTest.php @@ -39,13 +39,13 @@ expect($result)->toBeInstanceOf(ToolResult::class); $data = $result->toArray(); - expect($data['isError'])->toBeFalse(); - expect($data['content'][0]['type'])->toBe('text'); + expect($data['isError'])->toBeFalse() + ->and($data['content'][0]['type'])->toBe('text'); $text = $data['content'][0]['text']; - expect($text)->toContain('browser.WARNING: Warning message'); - expect($text)->toContain('browser.ERROR: JavaScript error occurred'); - expect($text)->not->toContain('browser.DEBUG: console log message'); + expect($text)->toContain('browser.WARNING: Warning message') + ->and($text)->toContain('browser.ERROR: JavaScript error occurred') + ->and($text)->not->toContain('browser.DEBUG: console log message'); }); test('it returns error when entries argument is invalid', function () { @@ -56,16 +56,16 @@ expect($result)->toBeInstanceOf(ToolResult::class); $data = $result->toArray(); - expect($data['isError'])->toBeTrue(); - expect($data['content'][0]['text'])->toBe('The "entries" argument must be greater than 0.'); + expect($data['isError'])->toBeTrue() + ->and($data['content'][0]['text'])->toBe('The "entries" argument must be greater than 0.'); // Test with negative $result = $tool->handle(['entries' => -5]); expect($result)->toBeInstanceOf(ToolResult::class); $data = $result->toArray(); - expect($data['isError'])->toBeTrue(); - expect($data['content'][0]['text'])->toBe('The "entries" argument must be greater than 0.'); + expect($data['isError'])->toBeTrue() + ->and($data['content'][0]['text'])->toBe('The "entries" argument must be greater than 0.'); }); test('it returns error when log file does not exist', function () { @@ -75,8 +75,8 @@ expect($result)->toBeInstanceOf(ToolResult::class); $data = $result->toArray(); - expect($data['isError'])->toBeTrue(); - expect($data['content'][0]['text'])->toBe('No log file found, probably means no logs yet.'); + expect($data['isError'])->toBeTrue() + ->and($data['content'][0]['text'])->toBe('No log file found, probably means no logs yet.'); }); test('it returns error when log file is empty', function () { @@ -91,8 +91,8 @@ expect($result)->toBeInstanceOf(ToolResult::class); $data = $result->toArray(); - expect($data['isError'])->toBeFalse(); - expect($data['content'][0]['text'])->toBe('Unable to retrieve log entries, or no logs'); + expect($data['isError'])->toBeFalse() + ->and($data['content'][0]['text'])->toBe('Unable to retrieve log entries, or no logs'); }); test('@boostJs blade directive renders browser logger script', function () { @@ -106,11 +106,11 @@ // Test that the script contains expected content $script = BrowserLogger::getScript(); - expect($script)->toContain('browser-logger-active'); - expect($script)->toContain('/_boost/browser-logs'); - expect($script)->toContain('console.log'); - expect($script)->toContain('console.error'); - expect($script)->toContain('window.onerror'); + expect($script)->toContain('browser-logger-active') + ->and($script)->toContain('/_boost/browser-logs') + ->and($script)->toContain('console.log') + ->and($script)->toContain('console.error') + ->and($script)->toContain('window.onerror'); }); test('browser logs endpoint processes logs correctly', function () { @@ -215,9 +215,10 @@ }); $content = $result->getContent(); - expect($content)->toContain('browser-logger-active'); - expect($content)->toContain(''); - expect(substr_count($content, 'browser-logger-active'))->toBe(1); // Should not inject twice + expect($content)->toContain('browser-logger-active') + ->and($content)->toContain('') + ->and(substr_count($content, 'browser-logger-active'))->toBe(1); + // Should not inject twice }); test('InjectBoost middleware does not inject into non-HTML responses', function () { @@ -233,8 +234,8 @@ }); $content = $result->getContent(); - expect($content)->toBe($json); - expect($content)->not->toContain('browser-logger-active'); + expect($content)->toBe($json) + ->and($content)->not->toContain('browser-logger-active'); }); test('InjectBoost middleware does not inject script twice', function () { @@ -284,6 +285,6 @@ }); $content = $result->getContent(); - expect($content)->toContain('browser-logger-active'); - expect($content)->toMatch('/]*browser-logger-active[^>]*>.*<\/script>\s*<\/body>/s'); + expect($content)->toContain('browser-logger-active') + ->and($content)->toMatch('/]*browser-logger-active[^>]*>.*<\/script>\s*<\/body>/s'); }); diff --git a/tests/Feature/Mcp/Tools/DatabaseConnectionsTest.php b/tests/Feature/Mcp/Tools/DatabaseConnectionsTest.php index 705265eb..78dd9074 100644 --- a/tests/Feature/Mcp/Tools/DatabaseConnectionsTest.php +++ b/tests/Feature/Mcp/Tools/DatabaseConnectionsTest.php @@ -23,11 +23,11 @@ expect($data['isError'])->toBe(false); $content = json_decode($data['content'][0]['text'], true); - expect($content['default_connection'])->toBe('mysql'); - expect($content['connections'])->toHaveCount(3); - expect($content['connections'])->toContain('mysql'); - expect($content['connections'])->toContain('pgsql'); - expect($content['connections'])->toContain('sqlite'); + expect($content['default_connection'])->toBe('mysql') + ->and($content['connections'])->toHaveCount(3) + ->and($content['connections'])->toContain('mysql') + ->and($content['connections'])->toContain('pgsql') + ->and($content['connections'])->toContain('sqlite'); }); test('it returns empty connections when none configured', function () { @@ -41,6 +41,6 @@ expect($data['isError'])->toBe(false); $content = json_decode($data['content'][0]['text'], true); - expect($content['default_connection'])->toBe('mysql'); - expect($content['connections'])->toHaveCount(0); + expect($content['default_connection'])->toBe('mysql') + ->and($content['connections'])->toHaveCount(0); }); diff --git a/tests/Feature/Mcp/Tools/DatabaseSchemaTest.php b/tests/Feature/Mcp/Tools/DatabaseSchemaTest.php index 535cbf9f..92518018 100644 --- a/tests/Feature/Mcp/Tools/DatabaseSchemaTest.php +++ b/tests/Feature/Mcp/Tools/DatabaseSchemaTest.php @@ -44,30 +44,27 @@ $schemaArray = json_decode($responseArray['content'][0]['text'], true); - expect($schemaArray)->toHaveKey('engine'); - expect($schemaArray['engine'])->toBe('sqlite'); - - expect($schemaArray)->toHaveKey('tables'); - expect($schemaArray['tables'])->toHaveKey('examples'); + expect($schemaArray)->toHaveKey('engine') + ->and($schemaArray['engine'])->toBe('sqlite') + ->and($schemaArray)->toHaveKey('tables') + ->and($schemaArray['tables'])->toHaveKey('examples'); $exampleTable = $schemaArray['tables']['examples']; - expect($exampleTable)->toHaveKey('columns'); - expect($exampleTable['columns'])->toHaveKey('id'); - expect($exampleTable['columns'])->toHaveKey('name'); - - expect($exampleTable['columns']['id']['type'])->toBe('integer'); - expect($exampleTable['columns']['name']['type'])->toBe('varchar'); - - expect($exampleTable)->toHaveKey('indexes'); - expect($exampleTable)->toHaveKey('foreign_keys'); - expect($exampleTable)->toHaveKey('triggers'); - expect($exampleTable)->toHaveKey('check_constraints'); - - expect($schemaArray)->toHaveKey('global'); - expect($schemaArray['global'])->toHaveKey('views'); - expect($schemaArray['global'])->toHaveKey('stored_procedures'); - expect($schemaArray['global'])->toHaveKey('functions'); - expect($schemaArray['global'])->toHaveKey('sequences'); + expect($exampleTable)->toHaveKey('columns') + ->and($exampleTable['columns'])->toHaveKey('id') + ->and($exampleTable['columns'])->toHaveKey('name') + ->and($exampleTable['columns']['id']['type'])->toBe('integer') + ->and($exampleTable['columns']['name']['type'])->toBe('varchar') + ->and($exampleTable)->toHaveKey('indexes') + ->and($exampleTable)->toHaveKey('foreign_keys') + ->and($exampleTable)->toHaveKey('triggers') + ->and($exampleTable)->toHaveKey('check_constraints') + ->and($schemaArray)->toHaveKey('global') + ->and($schemaArray['global'])->toHaveKey('views') + ->and($schemaArray['global'])->toHaveKey('stored_procedures') + ->and($schemaArray['global'])->toHaveKey('functions') + ->and($schemaArray['global'])->toHaveKey('sequences'); + }); test('it filters tables by name', function () { @@ -84,14 +81,14 @@ $responseArray = $response->toArray(); $schemaArray = json_decode($responseArray['content'][0]['text'], true); - expect($schemaArray['tables'])->toHaveKey('examples'); - expect($schemaArray['tables'])->not->toHaveKey('users'); + expect($schemaArray['tables'])->toHaveKey('examples') + ->and($schemaArray['tables'])->not->toHaveKey('users'); // Test filtering for 'user' $response = $tool->handle(['filter' => 'user']); $responseArray = $response->toArray(); $schemaArray = json_decode($responseArray['content'][0]['text'], true); - expect($schemaArray['tables'])->toHaveKey('users'); - expect($schemaArray['tables'])->not->toHaveKey('examples'); + expect($schemaArray['tables'])->toHaveKey('users') + ->and($schemaArray['tables'])->not->toHaveKey('examples'); }); diff --git a/tests/Feature/Mcp/Tools/GetAbsoluteUrlTest.php b/tests/Feature/Mcp/Tools/GetAbsoluteUrlTest.php index 7ca6f310..050da4f2 100644 --- a/tests/Feature/Mcp/Tools/GetAbsoluteUrlTest.php +++ b/tests/Feature/Mcp/Tools/GetAbsoluteUrlTest.php @@ -19,8 +19,8 @@ expect($result)->toBeInstanceOf(ToolResult::class); $data = $result->toArray(); - expect($data['isError'])->toBe(false); - expect($data['content'][0]['text'])->toBe('http://localhost'); + expect($data['isError'])->toBe(false) + ->and($data['content'][0]['text'])->toBe('http://localhost'); }); test('it returns absolute url for given path', function () { @@ -29,8 +29,8 @@ expect($result)->toBeInstanceOf(ToolResult::class); $data = $result->toArray(); - expect($data['isError'])->toBe(false); - expect($data['content'][0]['text'])->toBe('http://localhost/dashboard'); + expect($data['isError'])->toBe(false) + ->and($data['content'][0]['text'])->toBe('http://localhost/dashboard'); }); test('it returns absolute url for named route', function () { @@ -39,8 +39,8 @@ expect($result)->toBeInstanceOf(ToolResult::class); $data = $result->toArray(); - expect($data['isError'])->toBe(false); - expect($data['content'][0]['text'])->toBe('http://localhost/test'); + expect($data['isError'])->toBe(false) + ->and($data['content'][0]['text'])->toBe('http://localhost/test'); }); test('it prioritizes path over route when both are provided', function () { @@ -49,8 +49,8 @@ expect($result)->toBeInstanceOf(ToolResult::class); $data = $result->toArray(); - expect($data['isError'])->toBe(false); - expect($data['content'][0]['text'])->toBe('http://localhost/dashboard'); + expect($data['isError'])->toBe(false) + ->and($data['content'][0]['text'])->toBe('http://localhost/dashboard'); }); test('it handles empty path', function () { @@ -59,6 +59,6 @@ expect($result)->toBeInstanceOf(ToolResult::class); $data = $result->toArray(); - expect($data['isError'])->toBe(false); - expect($data['content'][0]['text'])->toBe('http://localhost'); + expect($data['isError'])->toBe(false) + ->and($data['content'][0]['text'])->toBe('http://localhost'); }); diff --git a/tests/Feature/Mcp/Tools/GetConfigTest.php b/tests/Feature/Mcp/Tools/GetConfigTest.php index cf451003..e66caf16 100644 --- a/tests/Feature/Mcp/Tools/GetConfigTest.php +++ b/tests/Feature/Mcp/Tools/GetConfigTest.php @@ -18,8 +18,8 @@ expect($result)->toBeInstanceOf(ToolResult::class); $data = $result->toArray(); - expect($data['content'][0]['text'])->toContain('"key": "test.key"'); - expect($data['content'][0]['text'])->toContain('"value": "test_value"'); + expect($data['content'][0]['text'])->toContain('"key": "test.key"') + ->and($data['content'][0]['text'])->toContain('"value": "test_value"'); }); test('it returns nested config value', function () { @@ -29,8 +29,8 @@ expect($result)->toBeInstanceOf(ToolResult::class); $data = $result->toArray(); - expect($data['content'][0]['text'])->toContain('"key": "nested.config.key"'); - expect($data['content'][0]['text'])->toContain('"value": "nested_value"'); + expect($data['content'][0]['text'])->toContain('"key": "nested.config.key"') + ->and($data['content'][0]['text'])->toContain('"value": "nested_value"'); }); test('it returns error when config key does not exist', function () { @@ -40,8 +40,8 @@ expect($result)->toBeInstanceOf(ToolResult::class); $data = $result->toArray(); - expect($data['isError'])->toBe(true); - expect($data['content'][0]['text'])->toContain("Config key 'nonexistent.key' not found."); + expect($data['isError'])->toBe(true) + ->and($data['content'][0]['text'])->toContain("Config key 'nonexistent.key' not found."); }); test('it works with built-in Laravel config keys', function () { @@ -51,6 +51,6 @@ expect($result)->toBeInstanceOf(ToolResult::class); $data = $result->toArray(); - expect($data['content'][0]['text'])->toContain('"key": "app.name"'); - expect($data['content'][0]['text'])->toContain('"value": "Test App"'); + expect($data['content'][0]['text'])->toContain('"key": "app.name"') + ->and($data['content'][0]['text'])->toContain('"value": "Test App"'); }); diff --git a/tests/Feature/Mcp/Tools/ListArtisanCommandsTest.php b/tests/Feature/Mcp/Tools/ListArtisanCommandsTest.php index 95418f46..1441914e 100644 --- a/tests/Feature/Mcp/Tools/ListArtisanCommandsTest.php +++ b/tests/Feature/Mcp/Tools/ListArtisanCommandsTest.php @@ -14,21 +14,21 @@ expect($data['isError'])->toBe(false); $content = json_decode($data['content'][0]['text'], true); - expect($content)->toBeArray(); - expect($content)->not->toBeEmpty(); + expect($content)->toBeArray() + ->and($content)->not->toBeEmpty(); // Check that it contains some basic Laravel commands $commandNames = array_column($content, 'name'); - expect($commandNames)->toContain('migrate'); - expect($commandNames)->toContain('make:model'); - expect($commandNames)->toContain('route:list'); + expect($commandNames)->toContain('migrate') + ->and($commandNames)->toContain('make:model') + ->and($commandNames)->toContain('route:list'); // Check the structure of each command foreach ($content as $command) { - expect($command)->toHaveKey('name'); - expect($command)->toHaveKey('description'); - expect($command['name'])->toBeString(); - expect($command['description'])->toBeString(); + expect($command)->toHaveKey('name') + ->and($command)->toHaveKey('description') + ->and($command['name'])->toBeString() + ->and($command['description'])->toBeString(); } // Check that commands are sorted alphabetically diff --git a/tests/Feature/Mcp/Tools/ListAvailableConfigKeysTest.php b/tests/Feature/Mcp/Tools/ListAvailableConfigKeysTest.php index e25dc46d..4eb1b794 100644 --- a/tests/Feature/Mcp/Tools/ListAvailableConfigKeysTest.php +++ b/tests/Feature/Mcp/Tools/ListAvailableConfigKeysTest.php @@ -20,19 +20,19 @@ expect($data['isError'])->toBe(false); $content = json_decode($data['content'][0]['text'], true); - expect($content)->toBeArray(); - expect($content)->not->toBeEmpty(); + expect($content)->toBeArray() + ->and($content)->not->toBeEmpty(); // Check that it contains common Laravel config keys - expect($content)->toContain('app.name'); - expect($content)->toContain('app.env'); - expect($content)->toContain('database.default'); + expect($content)->toContain('app.name') + ->and($content)->toContain('app.env') + ->and($content)->toContain('database.default'); // Check that it contains our test keys - expect($content)->toContain('test.simple'); - expect($content)->toContain('test.nested.key'); - expect($content)->toContain('test.array.0'); - expect($content)->toContain('test.array.1'); + expect($content)->toContain('test.simple') + ->and($content)->toContain('test.nested.key') + ->and($content)->toContain('test.array.0') + ->and($content)->toContain('test.array.1'); // Check that keys are sorted $sortedContent = $content; diff --git a/tests/Unit/Install/CodeEnvironment/CodeEnvironmentTest.php b/tests/Unit/Install/CodeEnvironment/CodeEnvironmentTest.php index 1a628d5c..81ae1de3 100644 --- a/tests/Unit/Install/CodeEnvironment/CodeEnvironmentTest.php +++ b/tests/Unit/Install/CodeEnvironment/CodeEnvironmentTest.php @@ -327,9 +327,9 @@ public function mcpConfigPath(): string $result = $environment->installMcp('test-key', 'test-command', ['arg1'], ['ENV' => 'value']); - expect($result)->toBe(true); - expect($capturedPath)->toBe($environment->mcpConfigPath()); - expect($capturedContent)->toBe($expectedContent); + expect($result)->toBe(true) + ->and($capturedPath)->toBe($environment->mcpConfigPath()) + ->and($capturedContent)->toBe($expectedContent); }); test('installFileMcp updates existing config file', function () { diff --git a/tests/Unit/Install/CodeEnvironmentsDetectorTest.php b/tests/Unit/Install/CodeEnvironmentsDetectorTest.php index 5ec57c38..37f64915 100644 --- a/tests/Unit/Install/CodeEnvironmentsDetectorTest.php +++ b/tests/Unit/Install/CodeEnvironmentsDetectorTest.php @@ -225,10 +225,10 @@ $detected = $this->detector->discoverProjectInstalledCodeEnvironments($tempDir); - expect($detected)->toContain('vscode'); - expect($detected)->toContain('cursor'); - expect($detected)->toContain('claudecode'); - expect(count($detected))->toBeGreaterThanOrEqual(3); + expect($detected)->toContain('vscode') + ->and($detected)->toContain('cursor') + ->and($detected)->toContain('claudecode') + ->and(count($detected))->toBeGreaterThanOrEqual(3); // Cleanup rmdir($tempDir.'/.vscode'); diff --git a/tests/Unit/Install/Detection/DirectoryDetectionStrategyTest.php b/tests/Unit/Install/Detection/DirectoryDetectionStrategyTest.php index 9e1ee3ba..cba43233 100644 --- a/tests/Unit/Install/Detection/DirectoryDetectionStrategyTest.php +++ b/tests/Unit/Install/Detection/DirectoryDetectionStrategyTest.php @@ -185,13 +185,13 @@ expect($isAbsolutePathMethod->invoke($this->strategy, '/usr/local/bin'))->toBeTrue(); // Windows absolute paths - expect($isAbsolutePathMethod->invoke($this->strategy, 'C:\\Program Files'))->toBeTrue(); - expect($isAbsolutePathMethod->invoke($this->strategy, 'D:\\test'))->toBeTrue(); + expect($isAbsolutePathMethod->invoke($this->strategy, 'C:\\Program Files'))->toBeTrue() + ->and($isAbsolutePathMethod->invoke($this->strategy, 'D:\\test'))->toBeTrue(); // Relative paths - expect($isAbsolutePathMethod->invoke($this->strategy, 'relative/path'))->toBeFalse(); - expect($isAbsolutePathMethod->invoke($this->strategy, './relative'))->toBeFalse(); - expect($isAbsolutePathMethod->invoke($this->strategy, '../relative'))->toBeFalse(); + expect($isAbsolutePathMethod->invoke($this->strategy, 'relative/path'))->toBeFalse() + ->and($isAbsolutePathMethod->invoke($this->strategy, './relative'))->toBeFalse() + ->and($isAbsolutePathMethod->invoke($this->strategy, '../relative'))->toBeFalse(); }); function removeDirectory(string $dir): void diff --git a/tests/Unit/Install/GuidelineWriterTest.php b/tests/Unit/Install/GuidelineWriterTest.php index 892ee6ad..5b6727f9 100644 --- a/tests/Unit/Install/GuidelineWriterTest.php +++ b/tests/Unit/Install/GuidelineWriterTest.php @@ -238,14 +238,14 @@ $content = file_get_contents($tempFile); // Verify guidelines were replaced in-place - expect($content)->toContain(''); - expect($content)->toContain('updated guidelines from boost'); + expect($content)->toContain('') + ->and($content)->toContain('updated guidelines from boost'); // Verify user content after guidelines is preserved - expect($content)->toContain('# User Added Section'); - expect($content)->toContain('This content was added by the user after the guidelines.'); - expect($content)->toContain('## Another user section'); - expect($content)->toContain('More content here.'); + expect($content)->toContain('# User Added Section') + ->and($content)->toContain('This content was added by the user after the guidelines.') + ->and($content)->toContain('## Another user section') + ->and($content)->toContain('More content here.'); // Verify exact structure expect($content)->toBe("# My Project\n\n\nupdated guidelines from boost\n\n\n# User Added Section\nThis content was added by the user after the guidelines.\n\n## Another user section\nMore content here."); diff --git a/tests/Unit/Install/Mcp/FileWriterTest.php b/tests/Unit/Install/Mcp/FileWriterTest.php index 5d1dc442..569ca977 100644 --- a/tests/Unit/Install/Mcp/FileWriterTest.php +++ b/tests/Unit/Install/Mcp/FileWriterTest.php @@ -62,8 +62,8 @@ $result = $writer->save(); $simpleContents = Str::of($writtenContent)->replaceMatches('/\s+/', ''); - expect($result)->toBe(true); - expect($simpleContents)->toEqual($expectedJson); + expect($result)->toBe(true) + ->and($simpleContents)->toEqual($expectedJson); })->with(newFileServerConfigurations()); test('updates existing plain JSON file using simple method', function () { @@ -88,11 +88,12 @@ expect($result)->toBeTrue(); $decoded = json_decode($writtenContent, true); - expect($decoded)->toHaveKey('existing'); - expect($decoded)->toHaveKey('other'); - expect($decoded)->toHaveKey('nested.key'); // From fixture - expect($decoded)->toHaveKey('servers.new-server'); - expect($decoded['servers']['new-server']['command'])->toBe('npm'); + expect($decoded)->toHaveKey('existing') + ->and($decoded)->toHaveKey('other') + ->and($decoded)->toHaveKey('nested.key') + ->and($decoded)->toHaveKey('servers.new-server') + ->and($decoded['servers']['new-server']['command'])->toBe('npm'); + // From fixture }); test('adds to existing mcpServers in plain JSON', function () { @@ -116,9 +117,10 @@ $decoded = json_decode($writtenContent, true); - expect($decoded)->toHaveKey('mcpServers.existing-server'); // Original preserved - expect($decoded)->toHaveKey('mcpServers.boost'); // New server added - expect($decoded['mcpServers']['boost']['command'])->toBe('php'); + expect($decoded)->toHaveKey('mcpServers.existing-server') + ->and($decoded)->toHaveKey('mcpServers.boost') + ->and($decoded['mcpServers']['boost']['command'])->toBe('php'); // Original preserved + // New server added }); test('preserves complex JSON5 features that VS Code supports', function () { @@ -137,12 +139,12 @@ ->addServer('test', 'cmd') ->save(); - expect($result)->toBeTrue(); - expect($writtenContent)->toContain('"test"'); // New server added - expect($writtenContent)->toContain('// Here are comments within my JSON'); // Preserve block comments - expect($writtenContent)->toContain("// I'm trailing"); // Preserve inline comments - expect($writtenContent)->toContain('// Ooo, pretty cool'); // Preserve comments in arrays - expect($writtenContent)->toContain('MYSQL_HOST'); // Preserve complex nested structure + expect($result)->toBeTrue() + ->and($writtenContent)->toContain('"test"') // New server added + ->and($writtenContent)->toContain('// Here are comments within my JSON') // Preserve block comments + ->and($writtenContent)->toContain("// I'm trailing") // Preserve inline comments + ->and($writtenContent)->toContain('// Ooo, pretty cool') // Preserve comments in arrays + ->and($writtenContent)->toContain('MYSQL_HOST'); // Preserve complex nested structure }); test('detects plain JSON with comments inside strings as safe', function () { @@ -163,9 +165,9 @@ expect($result)->toBeTrue(); $decoded = json_decode($writtenContent, true); - expect($decoded)->toHaveKey('exampleCode'); // Original preserved - expect($decoded)->toHaveKey('mcpServers.new-server'); // New server added - expect($decoded['exampleCode'])->toContain('// here is the example code'); // Comment in string preserved + expect($decoded)->toHaveKey('exampleCode') // Original preserved + ->and($decoded)->toHaveKey('mcpServers.new-server') // New server added + ->and($decoded['exampleCode'])->toContain('// here is the example code'); // Comment in string preserved }); test('hasUnquotedComments detects comments correctly', function (string $content, bool $expected, string $description) { @@ -251,11 +253,11 @@ ->addServer('boost', 'php', ['artisan', 'boost:mcp']) ->save(); - expect($result)->toBeTrue(); - expect($writtenContent)->toContain('"mcpServers"'); - expect($writtenContent)->toContain('"boost"'); - expect($writtenContent)->toContain('"php"'); - expect($writtenContent)->toContain('// No mcpServers key at all'); // Preserve existing comments + expect($result)->toBeTrue() + ->and($writtenContent)->toContain('"mcpServers"') + ->and($writtenContent)->toContain('"boost"') + ->and($writtenContent)->toContain('"php"') + ->and($writtenContent)->toContain('// No mcpServers key at all'); // Preserve existing comments }); test('injects into existing configKey preserving JSON5 features', function () { @@ -274,12 +276,12 @@ ->addServer('boost', 'php', ['artisan', 'boost:mcp']) ->save(); - expect($result)->toBeTrue(); - expect($writtenContent)->toContain('"boost"'); // New server added - expect($writtenContent)->toContain('mysql'); // Existing server preserved - expect($writtenContent)->toContain('laravel-boost'); // Existing server preserved - expect($writtenContent)->toContain('// Here are comments within my JSON'); // Comments preserved - expect($writtenContent)->toContain('// Ooo, pretty cool'); // Inline comments preserved + expect($result)->toBeTrue() + ->and($writtenContent)->toContain('"boost"') // New server added + ->and($writtenContent)->toContain('mysql') // Existing server preserved + ->and($writtenContent)->toContain('laravel-boost') // Existing server preserved + ->and($writtenContent)->toContain('// Here are comments within my JSON') // Comments preserved + ->and($writtenContent)->toContain('// Ooo, pretty cool'); // Inline comments preserved }); test('injecting twice into existing JSON 5 doesn\'t cause duplicates', function () { @@ -305,13 +307,13 @@ ->save(); $boostCounts = substr_count($capturedContent, '"boost"'); - expect($result)->toBeTrue(); - expect($boostCounts)->toBe(1); - expect($capturedContent)->toContain('"boost"'); // New server added - expect($capturedContent)->toContain('mysql'); // Existing server preserved - expect($capturedContent)->toContain('laravel-boost'); // Existing server preserved - expect($capturedContent)->toContain('// Here are comments within my JSON'); // Comments preserved - expect($capturedContent)->toContain('// Ooo, pretty cool'); // Inline comments preserved + expect($result)->toBeTrue() + ->and($boostCounts)->toBe(1) + ->and($capturedContent)->toContain('"boost"') // New server added + ->and($capturedContent)->toContain('mysql') // Existing server preserved + ->and($capturedContent)->toContain('laravel-boost') // Existing server preserved + ->and($capturedContent)->toContain('// Here are comments within my JSON') // Comments preserved + ->and($capturedContent)->toContain('// Ooo, pretty cool'); // Inline comments preserved $newContent = $capturedContent; @@ -351,10 +353,10 @@ ->addServer('boost', 'php', ['artisan', 'boost:mcp']) ->save(); - expect($result)->toBeTrue(); - expect($writtenContent)->toContain('"boost"'); // New server added - expect($writtenContent)->toContain('// Empty mcpServers object'); // Comments preserved - expect($writtenContent)->toContain('test_input'); // Existing content preserved + expect($result)->toBeTrue() + ->and($writtenContent)->toContain('"boost"') // New server added + ->and($writtenContent)->toContain('// Empty mcpServers object') // Comments preserved + ->and($writtenContent)->toContain('test_input'); // Existing content preserved }); test('preserves trailing commas when injecting into existing servers', function () { @@ -372,11 +374,11 @@ ->addServer('boost', 'php', ['artisan', 'boost:mcp']) ->save(); - expect($result)->toBeTrue(); - expect($writtenContent)->toContain('"boost"'); // New server added - expect($writtenContent)->toContain('existing-server'); // Existing server preserved - expect($writtenContent)->toContain('// Trailing comma here'); // Comments preserved - expect($writtenContent)->toContain('arg1'); // Existing args preserved + expect($result)->toBeTrue() + ->and($writtenContent)->toContain('"boost"') // New server added + ->and($writtenContent)->toContain('existing-server') // Existing server preserved + ->and($writtenContent)->toContain('// Trailing comma here') // Comments preserved + ->and($writtenContent)->toContain('arg1'); // Existing args preserved }); test('detectIndentation works correctly with various patterns', function (string $content, int $position, int $expected, string $description) {