From 784d8fd91e92f7088a76c645004ba22de724785b Mon Sep 17 00:00:00 2001 From: maatheusgois-dd Date: Wed, 20 May 2026 18:09:00 -0300 Subject: [PATCH] refactor: extract testFilterArgs helper for consistent test filter handling Centralizes test filter argument construction into a single `testFilterArgs()` function in `src/core/bazel.ts`, replacing duplicated inline logic across 5 handler/streaming files. Adds support for pipe-separated values (e.g. "SuiteA |SuiteB") which are converted to comma-separated format for rules_apple compatibility. Co-authored-by: Cursor --- src/core/bazel.test.ts | 24 ++++++++++++++++++++++++ src/core/bazel.ts | 10 ++++++++++ src/tools/handlers/build.ts | 13 +++++-------- src/tools/handlers/device.ts | 5 +++-- src/tools/handlers/macos.ts | 12 +++++------- src/tools/handlers/multi-platform.ts | 12 +++++------- src/tools/streaming.ts | 21 ++++++--------------- 7 files changed, 58 insertions(+), 39 deletions(-) diff --git a/src/core/bazel.test.ts b/src/core/bazel.test.ts index d7bf22c..93cd84a 100644 --- a/src/core/bazel.test.ts +++ b/src/core/bazel.test.ts @@ -14,6 +14,7 @@ import { requireLabel, sanitizeQueryExpression, simulatorArgs, + testFilterArgs, runBazel, runBazelStreaming, getLastCommand, @@ -168,6 +169,29 @@ describe('Bazel argument helpers', () => { expect(() => configArgs(['bad;config'])).toThrow('Invalid config value'); }); + it('testFilterArgs returns single --test_filter for simple string', () => { + expect(testFilterArgs('MyTestSuite')).toEqual(['--test_filter=MyTestSuite']); + }); + + it('testFilterArgs joins pipe-separated values with commas for rules_apple', () => { + expect(testFilterArgs('SuiteA|SuiteB')).toEqual([ + '--test_filter=SuiteA,SuiteB', + ]); + }); + + it('testFilterArgs handles whitespace around pipes', () => { + expect(testFilterArgs(' A | B | C ')).toEqual([ + '--test_filter=A,B,C', + ]); + }); + + it('testFilterArgs returns empty array for falsy values', () => { + expect(testFilterArgs(undefined)).toEqual([]); + expect(testFilterArgs('')).toEqual([]); + expect(testFilterArgs(' ')).toEqual([]); + expect(testFilterArgs(null)).toEqual([]); + }); + it('builds a simulator build command with stable flag ordering', () => { expect( buildCommandArgs({ diff --git a/src/core/bazel.ts b/src/core/bazel.ts index c8c5a5e..19af5b3 100644 --- a/src/core/bazel.ts +++ b/src/core/bazel.ts @@ -90,6 +90,16 @@ export function platformArgs(platform?: BuildPlatform): string[] { } } +export function testFilterArgs(testFilter: unknown): string[] { + if (typeof testFilter !== 'string' || !testFilter.trim()) return []; + const trimmed = testFilter.trim(); + if (trimmed.includes('|')) { + const joined = trimmed.split('|').map(p => p.trim()).filter(Boolean).join(','); + return [`--test_filter=${joined}`]; + } + return [`--test_filter=${trimmed}`]; +} + export function configArgs(value: unknown): string[] { return asStringArray(value, 'configs').map((config) => { if (!/^[A-Za-z0-9_.-]+$/.test(config)) { diff --git a/src/tools/handlers/build.ts b/src/tools/handlers/build.ts index 5f0dcc3..045d771 100644 --- a/src/tools/handlers/build.ts +++ b/src/tools/handlers/build.ts @@ -9,6 +9,7 @@ import { runBazel, sanitizeQueryExpression, simulatorArgs, + testFilterArgs, } from '../../core/bazel.js'; import { bootSimulatorIfNeeded, @@ -136,7 +137,7 @@ export const definitions: ToolDefinition[] = [ type: 'object', properties: { target: { type: 'string', description: 'Bazel test target label.' }, - testFilter: { type: 'string', description: 'Optional --test_filter value.' }, + testFilter: { type: 'string', description: 'Optional test filter. Supports pipe-separated values (e.g. "SuiteA|SuiteB") to run multiple suites.' }, simulatorName: { type: 'string' }, simulatorVersion: { type: 'string' }, configs: { type: 'array', items: { type: 'string' } }, @@ -251,7 +252,7 @@ export const definitions: ToolDefinition[] = [ type: 'object', properties: { target: { type: 'string', description: 'Bazel test target label.' }, - testFilter: { type: 'string', description: 'Optional --test_filter value.' }, + testFilter: { type: 'string', description: 'Optional test filter. Supports pipe-separated values (e.g. "SuiteA|SuiteB") to run multiple suites.' }, simulatorName: { type: 'string' }, simulatorVersion: { type: 'string' }, configs: { type: 'array', items: { type: 'string' } }, @@ -365,10 +366,8 @@ export async function handle(name: string, args: JsonObject): Promise