diff --git a/tests/Feature/Console/InstallCommandMultiselectTest.php b/tests/Feature/Console/InstallCommandMultiselectTest.php index 1d9729d3..f4d421be 100644 --- a/tests/Feature/Console/InstallCommandMultiselectTest.php +++ b/tests/Feature/Console/InstallCommandMultiselectTest.php @@ -25,12 +25,10 @@ ); // Assert that we get the keys, not the values - expect($result)->toBeArray(); - expect($result)->toHaveCount(2, 'Should have 2 items selected'); - expect($result)->toContain('mcp_server'); - expect($result)->toContain('ai_guidelines'); - expect($result)->not->toContain('Boost MCP Server'); - expect($result)->not->toContain('Package AI Guidelines'); + expect($result)->toBeArray() + ->toHaveCount(2, 'Should have 2 items selected') + ->toContain('mcp_server', 'ai_guidelines') + ->not->toContain('Boost MCP Server', 'Package AI Guidelines'); })->skipOnWindows(); test('multiselect returns values for indexed array', function (): void { @@ -48,9 +46,8 @@ ); // For indexed arrays, it returns the actual values - expect($result)->toBeArray(); - expect($result)->toContain('Option 1'); - expect($result)->toContain('Option 2'); + expect($result)->toBeArray() + ->toContain('Option 1', 'Option 2'); })->skipOnWindows(); test('multiselect behavior matches install command expectations', function (): void { @@ -79,10 +76,7 @@ // Verify we get keys that can be used with in_array checks expect($result)->toBeArray() - ->and($result)->toHaveCount(3) - ->and($result)->toContain('mcp_server') - ->and($result)->toContain('ai_guidelines') - ->and($result)->toContain('style_guidelines') - ->and($result)->not->toContain('Boost MCP Server') - ->and($result)->not->toContain('Package AI Guidelines (i.e. Framework, Inertia, Pest)'); + ->toHaveCount(3) + ->toContain('mcp_server', 'ai_guidelines', 'style_guidelines') + ->not->toContain('Boost MCP Server', 'Package AI Guidelines (i.e. Framework, Inertia, Pest)'); })->skipOnWindows(); diff --git a/tests/Feature/Install/CodeEnvironment/CodeEnvironmentPathResolutionTest.php b/tests/Feature/Install/CodeEnvironment/CodeEnvironmentPathResolutionTest.php index 5d01d69c..157135a9 100644 --- a/tests/Feature/Install/CodeEnvironment/CodeEnvironmentPathResolutionTest.php +++ b/tests/Feature/Install/CodeEnvironment/CodeEnvironmentPathResolutionTest.php @@ -21,7 +21,7 @@ // Should be an absolute path ending with 'artisan' expect($artisanPath)->toEndWith('artisan') - ->and($artisanPath)->not()->toBe('artisan'); + ->not->toBe('artisan'); }); test('Cursor returns relative php string', function (): void { @@ -44,7 +44,7 @@ expect($cursor->getPhpPath(true))->toBe(PHP_BINARY); expect($cursor->getArtisanPath(true))->toEndWith('artisan') - ->and($cursor->getArtisanPath(true))->not()->toBe('artisan'); + ->not->toBe('artisan'); }); test('CodeEnvironment maintains relative paths when forceAbsolutePath is false', function (): void { @@ -65,7 +65,7 @@ $artisanPath = $phpStorm->getArtisanPath(true); expect($artisanPath)->toEndWith('artisan') - ->and($artisanPath)->not()->toBe('artisan'); + ->not->toBe('artisan'); expect($phpStorm->getArtisanPath(false))->toBe($artisanPath); }); diff --git a/tests/Feature/Mcp/Tools/BrowserLogsTest.php b/tests/Feature/Mcp/Tools/BrowserLogsTest.php index ba56781d..60bb2174 100644 --- a/tests/Feature/Mcp/Tools/BrowserLogsTest.php +++ b/tests/Feature/Mcp/Tools/BrowserLogsTest.php @@ -94,11 +94,14 @@ // Test that the script contains expected content $script = BrowserLogger::getScript(); - 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'); + + expect($script)->toContain( + 'browser-logger-active', + '/_boost/browser-logs', + 'console.log', + 'console.error', + 'window.onerror' + ); }); test('browser logs endpoint processes logs correctly', function (): void { @@ -202,7 +205,7 @@ $content = $result->getContent(); expect($content)->toContain('browser-logger-active') - ->and($content)->toContain('') + ->toContain('') // Should not inject twice ->and(substr_count($content, 'browser-logger-active'))->toBe(1); }); @@ -219,7 +222,7 @@ $content = $result->getContent(); expect($content)->toBe($json) - ->and($content)->not->toContain('browser-logger-active'); + ->not->toContain('browser-logger-active'); }); test('InjectBoost middleware does not inject script twice', function (): void { @@ -266,5 +269,5 @@ $content = $result->getContent(); expect($content)->toContain('browser-logger-active') - ->and($content)->toMatch('/]*browser-logger-active[^>]*>.*<\/script>\s*<\/body>/s'); + ->toMatch('/]*browser-logger-active[^>]*>.*<\/script>\s*<\/body>/s'); }); diff --git a/tests/Feature/Mcp/Tools/ListArtisanCommandsTest.php b/tests/Feature/Mcp/Tools/ListArtisanCommandsTest.php index 801b41c9..05befe1a 100644 --- a/tests/Feature/Mcp/Tools/ListArtisanCommandsTest.php +++ b/tests/Feature/Mcp/Tools/ListArtisanCommandsTest.php @@ -13,13 +13,13 @@ ->toolHasNoError() ->toolJsonContent(function ($content): void { expect($content)->toBeArray() - ->and($content)->not->toBeEmpty(); + ->not->toBeEmpty(); // Check that it contains some basic Laravel commands $commandNames = array_column($content, 'name'); expect($commandNames)->toContain('migrate') - ->and($commandNames)->toContain('make:model') - ->and($commandNames)->toContain('route:list'); + ->toContain('make:model') + ->toContain('route:list'); // Check the structure of each command foreach ($content as $command) { diff --git a/tests/Feature/Mcp/Tools/ListAvailableConfigKeysTest.php b/tests/Feature/Mcp/Tools/ListAvailableConfigKeysTest.php index 85e75c80..3d956f58 100644 --- a/tests/Feature/Mcp/Tools/ListAvailableConfigKeysTest.php +++ b/tests/Feature/Mcp/Tools/ListAvailableConfigKeysTest.php @@ -19,16 +19,18 @@ ->toolHasNoError() ->toolJsonContent(function ($content): void { expect($content)->toBeArray() - ->and($content)->not->toBeEmpty() - // Check that it contains common Laravel config keys - ->and($content)->toContain('app.name') - ->and($content)->toContain('app.env') - ->and($content)->toContain('database.default') - // Check that it contains our test keys - ->and($content)->toContain('test.simple') - ->and($content)->toContain('test.nested.key') - ->and($content)->toContain('test.array.0') - ->and($content)->toContain('test.array.1'); + ->not->toBeEmpty() + ->toContain( + // Check that it constains common Laravel config keys + 'app.name', + 'app.env', + 'database.default', + // Check that it contains our test keys + 'test.simple', + 'test.nested.key', + 'test.array.0', + 'test.array.1' + ); // Check that keys are sorted $sortedContent = $content; @@ -49,6 +51,6 @@ ->toolJsonContent(function ($content): void { expect($content)->toBeArray() // Should still have Laravel default config keys - ->and($content)->toContain('app.name'); + ->toContain('app.name'); }); }); diff --git a/tests/Feature/Mcp/Tools/ListRoutesTest.php b/tests/Feature/Mcp/Tools/ListRoutesTest.php index c93244e8..91860ca1 100644 --- a/tests/Feature/Mcp/Tools/ListRoutesTest.php +++ b/tests/Feature/Mcp/Tools/ListRoutesTest.php @@ -37,17 +37,17 @@ expect($response)->isToolResult() ->toolHasNoError() ->toolTextContains('admin.dashboard', 'admin.users.store') - ->and($response)->not->toolTextContains('user.profile', 'two-factor.enable'); + ->not->toolTextContains('user.profile', 'two-factor.enable'); $response = $tool->handle(new Request(['name' => '*two-factor*'])); expect($response)->toolTextContains('two-factor.enable') - ->and($response)->not->toolTextContains('admin.dashboard', 'user.profile'); + ->not->toolTextContains('admin.dashboard', 'user.profile'); $response = $tool->handle(new Request(['name' => '*api*'])); expect($response)->toolTextContains('api.posts.index', 'api.posts.update') - ->and($response)->not->toolTextContains('admin.dashboard', 'user.profile'); + ->not->toolTextContains('admin.dashboard', 'user.profile'); }); @@ -63,12 +63,12 @@ $response = $tool->handle(new Request(['method' => '*GET*'])); expect($response)->toolTextContains('admin.dashboard', 'user.profile', 'api.posts.index') - ->and($response)->not->toolTextContains('admin.users.store'); + ->not->toolTextContains('admin.users.store'); $response = $tool->handle(new Request(['method' => '*POST*'])); expect($response)->toolTextContains('admin.users.store') - ->and($response)->not->toolTextContains('admin.dashboard'); + ->not->toolTextContains('admin.dashboard'); }); test('it handles edge cases and empty results correctly', function (): void { diff --git a/tests/Unit/Install/Cli/DisplayHelperTest.php b/tests/Unit/Install/Cli/DisplayHelperTest.php index a05e075a..1bf4e3f8 100644 --- a/tests/Unit/Install/Cli/DisplayHelperTest.php +++ b/tests/Unit/Install/Cli/DisplayHelperTest.php @@ -21,12 +21,7 @@ ]); $output = ob_get_clean(); - expect($output)->toContain('Name') - ->and($output)->toContain('Age') - ->and($output)->toContain('╭') - ->and($output)->toContain('╮') - ->and($output)->toContain('╰') - ->and($output)->toContain('╯'); + expect($output)->toContain('Name', 'Age', '╭', '╮', '╰', '╯'); }); it('displays a multi-row table', function (): void { @@ -38,12 +33,7 @@ ]); $output = ob_get_clean(); - expect($output)->toContain('Name') - ->and($output)->toContain('John') - ->and($output)->toContain('Jane') - ->and($output)->toContain('├') - ->and($output)->toContain('┤') - ->and($output)->toContain('┼'); + expect($output)->toContain('Name', 'John', 'Jane', '├', '┤', '┼'); }); it('handles different data types in cells', function (): void { @@ -55,11 +45,7 @@ ]); $output = ob_get_clean(); - expect($output)->toContain('text') - ->and($output)->toContain('123') - ->and($output)->toContain('true') - ->and($output)->toContain('another') - ->and($output)->toContain('456'); + expect($output)->toContain('text', '123', 'true', 'another', '456'); }); it('applies bold formatting to first column', function (): void { @@ -70,8 +56,7 @@ ]); $output = ob_get_clean(); - expect($output)->toContain("\e[1mHeader1\e[0m") - ->and($output)->toContain("\e[1mValue1\e[0m") + expect($output)->toContain("\e[1mHeader1\e[0m", "\e[1mValue1\e[0m") ->and($output)->not->toContain("\e[1mHeader2\e[0m"); }); @@ -83,10 +68,7 @@ ]); $output = ob_get_clean(); - expect($output)->toContain('名前') - ->and($output)->toContain('Émile') - ->and($output)->toContain('測試') - ->and($output)->toContain('café'); + expect($output)->toContain('名前', 'Émile', '測試', 'café'); }); }); @@ -104,11 +86,7 @@ DisplayHelper::grid(['Item1']); $output = ob_get_clean(); - expect($output)->toContain('Item1') - ->and($output)->toContain('╭') - ->and($output)->toContain('╮') - ->and($output)->toContain('╰') - ->and($output)->toContain('╯'); + expect($output)->toContain('Item1', '╭', '╮', '╰', '╯'); }); it('displays multiple items in grid', function (): void { @@ -116,10 +94,7 @@ DisplayHelper::grid(['Item1', 'Item2', 'Item3', 'Item4']); $output = ob_get_clean(); - expect($output)->toContain('Item1') - ->and($output)->toContain('Item2') - ->and($output)->toContain('Item3') - ->and($output)->toContain('Item4'); + expect($output)->toContain('Item1', 'Item2', 'Item3', 'Item4'); }); it('handles items of different lengths', function (): void { @@ -127,9 +102,7 @@ DisplayHelper::grid(['Short', 'Very Long Item Name', 'Med']); $output = ob_get_clean(); - expect($output)->toContain('Short') - ->and($output)->toContain('Very Long Item Name') - ->and($output)->toContain('Med'); + expect($output)->toContain('Short', 'Very Long Item Name', 'Med'); }); it('respects column width parameter', function (): void { @@ -137,8 +110,7 @@ DisplayHelper::grid(['Item1', 'Item2'], 40); $output = ob_get_clean(); - expect($output)->toContain('Item1') - ->and($output)->toContain('Item2'); + expect($output)->toContain('Item1', 'Item2'); }); it('handles unicode characters in grid', function (): void { @@ -146,9 +118,7 @@ DisplayHelper::grid(['測試', 'café', '🚀']); $output = ob_get_clean(); - expect($output)->toContain('測試') - ->and($output)->toContain('café') - ->and($output)->toContain('🚀'); + expect($output)->toContain('測試', 'café', '🚀'); }); it('fills empty cells when items do not fill complete rows', function (): void { diff --git a/tests/Unit/Install/GuidelineWriterTest.php b/tests/Unit/Install/GuidelineWriterTest.php index 7c879849..99eab3f4 100644 --- a/tests/Unit/Install/GuidelineWriterTest.php +++ b/tests/Unit/Install/GuidelineWriterTest.php @@ -265,10 +265,12 @@ ->and($content)->toContain('updated guidelines from boost'); // Verify user content after guidelines is preserved - 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.'); + expect($content)->toContain( + '# User Added Section', + 'This content was added by the user after the guidelines.', + '## Another user section', + '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.\n"); diff --git a/tests/Unit/Install/Mcp/FileWriterTest.php b/tests/Unit/Install/Mcp/FileWriterTest.php index f83424de..ed70d56f 100644 --- a/tests/Unit/Install/Mcp/FileWriterTest.php +++ b/tests/Unit/Install/Mcp/FileWriterTest.php @@ -88,10 +88,12 @@ expect($result)->toBeTrue(); $decoded = json_decode((string) $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)->toHaveKey('existing') + ->toHaveKey('other') + ->toHaveKey('nested.key') // From fixture + ->toHaveKey('servers.new-server'); + expect($decoded['servers']['new-server']['command'])->toBe('npm'); }); @@ -119,8 +121,9 @@ $decoded = json_decode((string) $writtenContent, true); - expect($decoded)->toHaveKey('mcpServers.existing-server'); // Original preserved - expect($decoded)->toHaveKey('mcpServers.boost'); // New server added + expect($decoded)->toHaveKey('mcpServers.existing-server') // Original preserved + ->toHaveKey('mcpServers.boost'); // New server added + expect($decoded['mcpServers']['boost']['command'])->toBe('php'); }); @@ -141,11 +144,13 @@ ->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($writtenContent)->toContain( + '"test"', // New server added + '// Here are comments within my JSON', // Preserve block comments + "// I'm trailing", // Preserve inline comments + '// Ooo, pretty cool', // Preserve comments in arrays + 'MYSQL_HOST' // Preserve complex nested structure + ); }); test('detects plain JSON with comments inside strings as safe', function (): void { @@ -166,8 +171,8 @@ expect($result)->toBeTrue(); $decoded = json_decode((string) $writtenContent, true); - expect($decoded)->toHaveKey('exampleCode'); // Original preserved - expect($decoded)->toHaveKey('mcpServers.new-server'); // New server added + expect($decoded)->toHaveKey('exampleCode') // Original preserved + ->toHaveKey('mcpServers.new-server'); // New server added expect($decoded['exampleCode'])->toContain('// here is the example code'); // Comment in string preserved }); @@ -255,10 +260,12 @@ ->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($writtenContent)->toContain( + '"mcpServers"', + '"boost"', + '"php"', + '// No mcpServers key at all' // Preserve existing comments + ); }); test('injects into existing configKey preserving JSON5 features', function (): void { @@ -281,11 +288,13 @@ ->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($writtenContent)->toContain( + '"boost"', // New server added + 'mysql', // Existing server preserved + 'laravel-boost', // Existing server preserved + '// Here are comments within my JSON', // Comments preserved + '// Ooo, pretty cool' // Inline comments preserved + ); }); test("injecting twice into existing JSON 5 doesn't cause duplicates", function (): void { @@ -315,11 +324,13 @@ $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($capturedContent)->toContain( + '"boost"', // New server added + 'mysql', // Existing server preserved + 'laravel-boost', // Existing server preserved + '// Here are comments within my JSON', // Comments preserved + '// Ooo, pretty cool' // Inline comments preserved + ); $newContent = $capturedContent; @@ -365,9 +376,11 @@ ->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($writtenContent)->toContain( + '"boost"', // New server added + '// Empty mcpServers object', // Comments preserved + 'test_input' // Existing content preserved + ); }); test('preserves trailing commas when injecting into existing servers', function (): void { @@ -389,10 +402,12 @@ ->save(); 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 + ->and($writtenContent)->toContain( + '"boost"', // New server added + 'existing-server', // Existing server preserved + '// Trailing comma here', // Comments preserved + 'arg1' // Existing args preserved + ); }); test('detectIndentation works correctly with various patterns', function (string $content, int $position, int $expected, string $description): void {