From 93d6116819dea9628ae747de4c7fbe59567221d5 Mon Sep 17 00:00:00 2001 From: Lucas Romano Date: Tue, 19 Nov 2024 14:38:19 -0300 Subject: [PATCH] add code coverage option on test_options Signed-off-by: Lucas Romano update autogeneration_config docs Signed-off-by: Lucas Romano Update tools/generators/xcschemes/test/CreateAutomaticSchemeInfoTests.swift Co-authored-by: Brentley Jones Signed-off-by: Lucas Romano Update tools/generators/xcschemes/test/CreateAutomaticSchemeInfoTests.swift Co-authored-by: Brentley Jones Signed-off-by: Lucas Romano Update tools/generators/xcschemes/src/Generator/Generator.swift Signed-off-by: Lucas Romano --- docs/bazel.md | 5 +-- examples/integration/xcodeproj_targets.bzl | 2 ++ .../xcschemes/info_constructors_tests.bzl | 5 +++ .../xcschemes/infos_from_json_tests.bzl | 2 ++ test/internal/xcschemes/utils.bzl | 1 + .../xcschemes/write_schemes_tests.bzl | 7 ++++ .../lib/XCScheme/src/CreateTestAction.swift | 7 ++++ .../XCScheme/test/CreateTestActionTests.swift | 35 +++++++++++++++++++ .../AutogenerationConfigArguments.swift | 7 ++++ .../Generator/CreateCustomSchemeInfos.swift | 8 ++++- .../src/Generator/CreateScheme.swift | 1 + .../xcschemes/src/Generator/Generator.swift | 7 ++-- .../xcschemes/src/Generator/SchemeInfo.swift | 1 + .../test/CreateAutomaticSchemeInfoTests.swift | 12 +++++-- xcodeproj/internal/xcodeproj_rule.bzl | 2 +- .../internal/xcschemes/xcscheme_infos.bzl | 5 ++- .../xcschemes/xcschemes_execution.bzl | 1 + xcodeproj/xcschemes.bzl | 15 +++++++- 18 files changed, 113 insertions(+), 10 deletions(-) diff --git a/docs/bazel.md b/docs/bazel.md index 857cdff3d..24ed8fe6d 100755 --- a/docs/bazel.md +++ b/docs/bazel.md @@ -265,7 +265,7 @@ Creates a value for the [`scheme_autogeneration_config`](xcodeproj-scheme_autoge | Name | Description | Default Value | | :------------- | :------------- | :------------- | | scheme_name_exclude_patterns | A `list` of regex patterns used to skip creating matching autogenerated schemes.

Example:

xcodeproj(
    ...
    scheme_name_exclude_patterns = xcschemes.autogeneration_config(
        scheme_name_exclude_patterns = [
            ".*somePattern.*",
            "^AnotherPattern.*",
        ],
    ),
)
| `None` | -| test | Options to use for the test action.

Example:

```starlark xcodeproj( ... scheme_autogeneration_config = xcschemes.autogeneration_config( test = xcschemes.autogeneration.test( options = xcschemes.test_options( app_language = "en", app_region = "US", ) ) ) ) | `None` | +| test | Options to use for the test action.

Example:

xcodeproj(
    ...
    scheme_autogeneration_config = xcschemes.autogeneration_config(
        test = xcschemes.autogeneration.test(
            options = xcschemes.test_options(
                app_language = "en",
                app_region = "US",
                code_coverage = False,
            )
        )
    )
)
| `None` | **RETURNS** @@ -536,7 +536,7 @@ Defines the Test action. ## xcschemes.test_options
-xcschemes.test_options(app_language, app_region)
+xcschemes.test_options(app_language, app_region, code_coverage)
 
Defines the test options for a custom scheme. @@ -548,6 +548,7 @@ Defines the test options for a custom scheme. | :------------- | :------------- | :------------- | | app_language | Language to set in scheme.

Defaults to system settings if not set. | `None` | | app_region | Region to set in scheme.

Defaults to system settings if not set. | `None` | +| code_coverage | Whether to enable code coverage.

If `True`, code coverage will be enabled. | `False` | diff --git a/examples/integration/xcodeproj_targets.bzl b/examples/integration/xcodeproj_targets.bzl index 3f13c5f7c..9846b6b53 100644 --- a/examples/integration/xcodeproj_targets.bzl +++ b/examples/integration/xcodeproj_targets.bzl @@ -152,6 +152,7 @@ SCHEME_AUTOGENERATION_CONFIG = xcschemes.autogeneration_config( options = xcschemes.test_options( app_language = "en", app_region = "US", + code_coverage = False, ), ), ) @@ -187,6 +188,7 @@ XCSCHEMES = [ test_options = xcschemes.test_options( app_language = "en", app_region = "US", + code_coverage = False, ), test_targets = [ "//iOSApp/Test/SwiftUnitTests:iOSAppSwiftUnitTests", diff --git a/test/internal/xcschemes/info_constructors_tests.bzl b/test/internal/xcschemes/info_constructors_tests.bzl index 3036f69e8..e9d3e138a 100644 --- a/test/internal/xcschemes/info_constructors_tests.bzl +++ b/test/internal/xcschemes/info_constructors_tests.bzl @@ -271,6 +271,7 @@ def info_constructors_test_suite(name): expected_info = struct( app_language = "", app_region = "", + code_coverage = "0", ), ) @@ -281,12 +282,14 @@ def info_constructors_test_suite(name): info = xcscheme_infos_testable.make_test_options( app_language = "en", app_region = "US", + code_coverage = "0", ), # Expected expected_info = struct( app_language = "en", app_region = "US", + code_coverage = "0", ), ) @@ -756,6 +759,7 @@ def info_constructors_test_suite(name): options = xcscheme_infos_testable.make_test_options( app_language = "en", app_region = "US", + code_coverage = "0", ), test_targets = [ xcscheme_infos_testable.make_test_target("tt 9"), @@ -793,6 +797,7 @@ def info_constructors_test_suite(name): options = xcscheme_infos_testable.make_test_options( app_language = "en", app_region = "US", + code_coverage = "0", ), test_targets = [ xcscheme_infos_testable.make_test_target("tt 9"), diff --git a/test/internal/xcschemes/infos_from_json_tests.bzl b/test/internal/xcschemes/infos_from_json_tests.bzl index ae1331bc2..f0ea1ccba 100644 --- a/test/internal/xcschemes/infos_from_json_tests.bzl +++ b/test/internal/xcschemes/infos_from_json_tests.bzl @@ -958,6 +958,7 @@ def infos_from_json_test_suite(name): options = struct( app_language = "en", app_region = "US", + code_coverage = "0", ), test_targets = [ "tt 1 label", @@ -1050,6 +1051,7 @@ def infos_from_json_test_suite(name): options = xcscheme_infos_testable.make_test_options( app_language = "en", app_region = "US", + code_coverage = "0", ), test_targets = [ xcscheme_infos_testable.make_test_target("sim tt 1"), diff --git a/test/internal/xcschemes/utils.bzl b/test/internal/xcschemes/utils.bzl index 0aa2fff8b..610da33e3 100644 --- a/test/internal/xcschemes/utils.bzl +++ b/test/internal/xcschemes/utils.bzl @@ -24,6 +24,7 @@ def _dict_to_test_options_info(d): return struct( app_language = d["app_language"], app_region = d["app_region"], + code_coverage = d["code_coverage"], ) def _dict_to_launch_target_info(d): diff --git a/test/internal/xcschemes/write_schemes_tests.bzl b/test/internal/xcschemes/write_schemes_tests.bzl index 35b920991..9ace9e32e 100644 --- a/test/internal/xcschemes/write_schemes_tests.bzl +++ b/test/internal/xcschemes/write_schemes_tests.bzl @@ -614,6 +614,7 @@ def write_schemes_test_suite(name): options = xcscheme_infos_testable.make_test_options( app_language = "en", app_region = "US", + code_coverage = "0", ), test_targets = [ xcscheme_infos_testable.make_test_target( @@ -1090,6 +1091,8 @@ def write_schemes_test_suite(name): "", # - test - app_region "", + # - test - code_coverage + "0", # - test - xcodeConfiguration "", # - run - buildTargets @@ -1191,6 +1194,8 @@ def write_schemes_test_suite(name): "en", # - test - app_region "US", + # - test - code_coverage + "0", # - test - xcodeConfiguration "Test", # - run - buildTargets @@ -1320,6 +1325,8 @@ def write_schemes_test_suite(name): "", # - test - app_region "", + # - test - code_coverage + "0", # - test - xcodeConfiguration "", # - run - buildTargets diff --git a/tools/generators/lib/XCScheme/src/CreateTestAction.swift b/tools/generators/lib/XCScheme/src/CreateTestAction.swift index 26c945f77..ddd6b5341 100644 --- a/tools/generators/lib/XCScheme/src/CreateTestAction.swift +++ b/tools/generators/lib/XCScheme/src/CreateTestAction.swift @@ -12,6 +12,7 @@ public struct CreateTestAction { public func callAsFunction( appLanguage: String?, appRegion: String?, + codeCoverage: Bool, buildConfiguration: String, commandLineArguments: [CommandLineArgument], enableAddressSanitizer: Bool, @@ -29,6 +30,7 @@ public struct CreateTestAction { return callable( /*appLanguage:*/ appLanguage, /*appRegion:*/ appRegion, + /*codeCoverage:*/ codeCoverage, /*buildConfiguration:*/ buildConfiguration, /*commandLineArguments:*/ commandLineArguments, /*enableAddressSanitizer:*/ enableAddressSanitizer, @@ -52,6 +54,7 @@ extension CreateTestAction { public typealias Callable = ( _ appLanguage: String?, _ appRegion: String?, + _ codeCoverage: Bool, _ buildConfiguration: String, _ commandLineArguments: [CommandLineArgument], _ enableAddressSanitizer: Bool, @@ -70,6 +73,7 @@ extension CreateTestAction { public static func defaultCallable( appLanguage: String?, appRegion: String?, + codeCoverage: Bool, buildConfiguration: String, commandLineArguments: [CommandLineArgument], enableAddressSanitizer: Bool, @@ -118,6 +122,9 @@ buildConfiguration = "\#(buildConfiguration)" if let appRegion { components.append("region = \"\(appRegion)\"") } + if codeCoverage { + components.append("codeCoverageEnabled = \"YES\"") + } let macroExpansion: String if let macroReference { diff --git a/tools/generators/lib/XCScheme/test/CreateTestActionTests.swift b/tools/generators/lib/XCScheme/test/CreateTestActionTests.swift index e8c7ea137..1ee20ed9e 100644 --- a/tools/generators/lib/XCScheme/test/CreateTestActionTests.swift +++ b/tools/generators/lib/XCScheme/test/CreateTestActionTests.swift @@ -417,11 +417,45 @@ final class CreateTestActionTests: XCTestCase { XCTAssertNoDifference(action, expectedAction) } + + func test_codeCoverageEnable() { + // Arrange + + let buildConfiguration = "Release" + let useLaunchSchemeArgsEnv = false + + let expectedAction = #""" + + + + +"""# + + // Act + + let action = createTestActionWithDefaults( + appLanguage: "en", + appRegion: "US", + buildConfiguration: buildConfiguration, + useLaunchSchemeArgsEnv: useLaunchSchemeArgsEnv + ) + + // Assert + + XCTAssertNoDifference(action, expectedAction) + } } private func createTestActionWithDefaults( appLanguage: String? = nil, appRegion: String? = nil, + codeCoverage: Bool = false, buildConfiguration: String, commandLineArguments: [CommandLineArgument] = [], enableAddressSanitizer: Bool = false, @@ -439,6 +473,7 @@ private func createTestActionWithDefaults( return CreateTestAction.defaultCallable( appLanguage: appLanguage, appRegion: appRegion, + codeCoverage: codeCoverage, buildConfiguration: buildConfiguration, commandLineArguments: commandLineArguments, enableAddressSanitizer: enableAddressSanitizer, diff --git a/tools/generators/xcschemes/src/Generator/AutogenerationConfigArguments.swift b/tools/generators/xcschemes/src/Generator/AutogenerationConfigArguments.swift index 919d9f1c1..41f5a55bc 100644 --- a/tools/generators/xcschemes/src/Generator/AutogenerationConfigArguments.swift +++ b/tools/generators/xcschemes/src/Generator/AutogenerationConfigArguments.swift @@ -4,6 +4,7 @@ import ToolCommon struct AutogenerationConfigArguments { let appLanguage: String? let appRegion: String? + let codeCoverage: Bool let schemeNameExcludePatterns: [String] static func parse( @@ -21,6 +22,11 @@ struct AutogenerationConfigArguments { as: String?.self, in: url ) + let codeCoverage = try rawArgs.consumeArg( + "code-coverage", + as: Bool.self, + in: url + ) let schemeNameExcludePatterns = try rawArgs.consumeArgs( "scheme-name-exclude-patterns", in: url @@ -29,6 +35,7 @@ struct AutogenerationConfigArguments { return AutogenerationConfigArguments( appLanguage: appLanguage, appRegion: appRegion, + codeCoverage: codeCoverage, schemeNameExcludePatterns: schemeNameExcludePatterns ) } diff --git a/tools/generators/xcschemes/src/Generator/CreateCustomSchemeInfos.swift b/tools/generators/xcschemes/src/Generator/CreateCustomSchemeInfos.swift index 56996b293..22753af66 100644 --- a/tools/generators/xcschemes/src/Generator/CreateCustomSchemeInfos.swift +++ b/tools/generators/xcschemes/src/Generator/CreateCustomSchemeInfos.swift @@ -639,6 +639,11 @@ set as: String?.self, in: url ) + let codeCoverage = try consumeArg( + "test-code-coverage", + as: Bool.self, + in: url + ) let xcodeConfiguration = try consumeArg( "test-xcode-configuration", as: String?.self, @@ -719,7 +724,8 @@ set enableThreadPerformanceChecker: enableThreadPerformanceChecker, environmentVariables: environmentVariables, options: .init(appLanguage: appLanguage, - appRegion: appRegion), + appRegion: appRegion, + codeCoverage: codeCoverage), testTargets: testTargets, useRunArgsAndEnv: useRunArgsAndEnv, xcodeConfiguration: xcodeConfiguration diff --git a/tools/generators/xcschemes/src/Generator/CreateScheme.swift b/tools/generators/xcschemes/src/Generator/CreateScheme.swift index 0725e0c23..f00da6a8a 100644 --- a/tools/generators/xcschemes/src/Generator/CreateScheme.swift +++ b/tools/generators/xcschemes/src/Generator/CreateScheme.swift @@ -362,6 +362,7 @@ extension Generator.CreateScheme { testAction: createTestAction( appLanguage: schemeInfo.test.options?.appLanguage, appRegion: schemeInfo.test.options?.appRegion, + codeCoverage: schemeInfo.test.options?.codeCoverage ?? false, buildConfiguration: schemeInfo.test.xcodeConfiguration ?? defaultXcodeConfiguration, commandLineArguments: schemeInfo.test.commandLineArguments, diff --git a/tools/generators/xcschemes/src/Generator/Generator.swift b/tools/generators/xcschemes/src/Generator/Generator.swift index b7ffd0c67..8f5b82072 100644 --- a/tools/generators/xcschemes/src/Generator/Generator.swift +++ b/tools/generators/xcschemes/src/Generator/Generator.swift @@ -57,8 +57,11 @@ struct Generator { targets: targets, targetsByID: targetsByID, targetsByKey: targetsByKey, - testOptions: .init(appLanguage: autogenerationConfigArguments.appLanguage, - appRegion: autogenerationConfigArguments.appRegion) + testOptions: .init( + appLanguage: autogenerationConfigArguments.appLanguage, + appRegion: autogenerationConfigArguments.appRegion, + codeCoverage: autogenerationConfigArguments.codeCoverage + ) ) let filteredAutomaticSchemeInfos = try automaticSchemeInfos.filter { scheme in diff --git a/tools/generators/xcschemes/src/Generator/SchemeInfo.swift b/tools/generators/xcschemes/src/Generator/SchemeInfo.swift index b9b05e171..74c04a7a8 100644 --- a/tools/generators/xcschemes/src/Generator/SchemeInfo.swift +++ b/tools/generators/xcschemes/src/Generator/SchemeInfo.swift @@ -38,6 +38,7 @@ struct SchemeInfo: Equatable { struct Options: Equatable { let appLanguage: String? let appRegion: String? + let codeCoverage: Bool } let buildTargets: [Target] diff --git a/tools/generators/xcschemes/test/CreateAutomaticSchemeInfoTests.swift b/tools/generators/xcschemes/test/CreateAutomaticSchemeInfoTests.swift index 95aff2f5a..a07888053 100644 --- a/tools/generators/xcschemes/test/CreateAutomaticSchemeInfoTests.swift +++ b/tools/generators/xcschemes/test/CreateAutomaticSchemeInfoTests.swift @@ -727,7 +727,11 @@ final class CreateAutomaticSchemeInfoTests: XCTestCase { enableMainThreadChecker: false, enableThreadPerformanceChecker: false, environmentVariables: baseEnvironmentVariables, - options: .init(appLanguage: "en", appRegion: "US"), + options: .init( + appLanguage: "en", + appRegion: "US", + codeCoverage: false + ), testTargets: [.init(target: test, isEnabled: true)], useRunArgsAndEnv: false, xcodeConfiguration: nil @@ -761,7 +765,11 @@ final class CreateAutomaticSchemeInfoTests: XCTestCase { let schemeInfo = try createAutomaticSchemeInfoWithDefaults( target: test, - testOptions: .init(appLanguage: "en", appRegion: "US") + testOptions: .init( + appLanguage: "en", + appRegion: "US", + codeCoverage: false + ) ) // Assert diff --git a/xcodeproj/internal/xcodeproj_rule.bzl b/xcodeproj/internal/xcodeproj_rule.bzl index bbe87196f..d294e3b01 100644 --- a/xcodeproj/internal/xcodeproj_rule.bzl +++ b/xcodeproj/internal/xcodeproj_rule.bzl @@ -214,7 +214,7 @@ def _write_autogeneration_config_file( args = actions.args() args.set_param_file_format("multiline") - args.add_all(config.get("test_options", ["", ""])) + args.add_all(config.get("test_options", ["", "", False])) args.add_all( config.get("scheme_name_exclude_patterns", []), omit_if_empty = False, diff --git a/xcodeproj/internal/xcschemes/xcscheme_infos.bzl b/xcodeproj/internal/xcschemes/xcscheme_infos.bzl index afe7ae7e2..4d569b242 100644 --- a/xcodeproj/internal/xcschemes/xcscheme_infos.bzl +++ b/xcodeproj/internal/xcschemes/xcscheme_infos.bzl @@ -52,10 +52,12 @@ def _make_diagnostics( def _make_test_options( *, app_region = EMPTY_STRING, - app_language = EMPTY_STRING): + app_language = EMPTY_STRING, + code_coverage = FALSE_ARG): return struct( app_region = app_region, app_language = app_language, + code_coverage = code_coverage, ) def _make_launch_target( @@ -312,6 +314,7 @@ def _options_info_from_dict(options): return _make_test_options( app_region = options["app_region"], app_language = options["app_language"], + code_coverage = options["code_coverage"], ) def _env_infos_from_dict(env): diff --git a/xcodeproj/internal/xcschemes/xcschemes_execution.bzl b/xcodeproj/internal/xcschemes/xcschemes_execution.bzl index 8c2d05f1d..53e54af20 100644 --- a/xcodeproj/internal/xcschemes/xcschemes_execution.bzl +++ b/xcodeproj/internal/xcschemes/xcschemes_execution.bzl @@ -218,6 +218,7 @@ def _write_schemes( def _add_test_options(test_options): custom_scheme_args.add(test_options.app_language) custom_scheme_args.add(test_options.app_region) + custom_scheme_args.add(test_options.code_coverage) def _add_env(env): if env == None: diff --git a/xcodeproj/xcschemes.bzl b/xcodeproj/xcschemes.bzl index c43793736..5c28a7fec 100644 --- a/xcodeproj/xcschemes.bzl +++ b/xcodeproj/xcschemes.bzl @@ -1196,7 +1196,11 @@ Address Sanitizer cannot be used together with Thread Sanitizer. ), ) -def _test_options(*, app_language = None, app_region = None): +def _test_options( + *, + app_language = None, + app_region = None, + code_coverage = False): """Defines the test options for a custom scheme. Args: @@ -1206,11 +1210,17 @@ def _test_options(*, app_language = None, app_region = None): app_language: Language to set in scheme. Defaults to system settings if not set. + code_coverage: Whether to enable code coverage. + + If `True`, code coverage will be enabled. """ return struct( app_region = app_region, app_language = app_language, + code_coverage = ( + TRUE_ARG if code_coverage else FALSE_ARG + ), ) def _autogeneration_test(*, options = None): @@ -1264,10 +1274,12 @@ def _autogeneration_config(*, scheme_name_exclude_patterns = None, test = None): options = xcschemes.test_options( app_language = "en", app_region = "US", + code_coverage = False, ) ) ) ) + ``` Returns: An opaque value for the [`scheme_autogeneration_config`](xcodeproj-scheme_autogeneration_config) attribute of `xcodeproj`. @@ -1280,6 +1292,7 @@ def _autogeneration_config(*, scheme_name_exclude_patterns = None, test = None): d["test_options"] = [ test.test_options.app_language or "", test.test_options.app_region or "", + test.test_options.code_coverage or "", ] return d