From bacefea4d84aa687b6764c8cc177179d903281a7 Mon Sep 17 00:00:00 2001 From: Hokila <1647434+Hokila@users.noreply.github.com> Date: Fri, 18 Sep 2026 01:14:39 +0800 Subject: [PATCH 1/2] Test project required-capability compatibility checks Cover unsupported capability diagnostics and precedence over missing fields, plus known, empty, and omitted requirements without depending on diagnostic list order. --- Sources/Tests/ProjectCapabilityTests.swift | 80 ++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 Sources/Tests/ProjectCapabilityTests.swift diff --git a/Sources/Tests/ProjectCapabilityTests.swift b/Sources/Tests/ProjectCapabilityTests.swift new file mode 100644 index 0000000..1da1f6a --- /dev/null +++ b/Sources/Tests/ProjectCapabilityTests.swift @@ -0,0 +1,80 @@ +//===----------------------------------------------------------------------===// +// Copyright © 2026 Apple Inc. and the xcode-project-format project authors +// +// Licensed under Apache License v2.0 +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import XcodeProjectFormat +import Foundation +import Testing + +struct ProjectCapabilityTests { + @Test(arguments: [ + ["glow in the dark files"], + ["glow in the dark files", "holographic targets"], + ]) + func rejectsUnknownCapabilities(unknownCapabilities: [String]) throws { + let known = XCSchema.Capability.knownCapabilityForTesting.capabilityDescription + let data = try projectData(requiredCapabilities: [known] + unknownCapabilities) + + expectUnsupportedCapabilities(in: data, named: unknownCapabilities) + } + + @Test func checksCapabilitiesBeforeMissingRequiredFields() throws { + // No files, default-configuration, or localizations: compatibility must be checked first. + let data = Data(#"{"required-capabilities": ["glow in the dark files"]}"#.utf8) + + expectUnsupportedCapabilities(in: data, named: ["glow in the dark files"]) + } + + @Test func acceptsKnownCapability() throws { + let known = XCSchema.Capability.knownCapabilityForTesting + let data = try projectData(requiredCapabilities: [known.capabilityDescription]) + let project = try XCSchema.Project(jsonRepresentation: data) + + #expect(project.requiredCapabilities == [known]) + let roundTripped = try XCSchema.Project(jsonRepresentation: project.jsonRepresentation()) + #expect(roundTripped == project) + } + + @Test func acceptsEmptyCapabilities() throws { + let project = try XCSchema.Project(jsonRepresentation: projectData(requiredCapabilities: [])) + + #expect(project.requiredCapabilities.isEmpty) + } + + @Test func acceptsOmittedCapabilities() throws { + let project = try XCSchema.Project(jsonRepresentation: projectData(requiredCapabilities: nil)) + + #expect(project.requiredCapabilities.isEmpty) + } + + private func projectData(requiredCapabilities: [String]?) throws -> Data { + var object: [String: Any] = [ + "files": [], + "default-configuration": "Debug", + "localizations": ["development": "en"], + ] + if let requiredCapabilities { + object["required-capabilities"] = requiredCapabilities + } + return try JSONSerialization.data(withJSONObject: object) + } + + private func expectUnsupportedCapabilities(in data: Data, named names: [String]) { + do { + _ = try XCSchema.Project(jsonRepresentation: data) + Issue.record("Expected decoding to reject unsupported capabilities") + } catch { + let message = (error as NSError).localizedDescription + #expect(message.contains("requires a newer version of Xcode")) + // Capability storage is a Set, so the diagnostic's list order is not a contract. + for name in names { + #expect(message.contains(name)) + } + #expect(!message.contains(XCSchema.Capability.knownCapabilityForTesting.capabilityDescription)) + } + } +} From f5ef51863a0d6ab42faddf3ffd711a0b971ee09c Mon Sep 17 00:00:00 2001 From: Hokila Jan <1647434+Hokila@users.noreply.github.com> Date: Fri, 2 Oct 2026 15:59:15 +0800 Subject: [PATCH 2/2] Fix license header --- Sources/Tests/ProjectCapabilityTests.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/Tests/ProjectCapabilityTests.swift b/Sources/Tests/ProjectCapabilityTests.swift index 1da1f6a..78fb422 100644 --- a/Sources/Tests/ProjectCapabilityTests.swift +++ b/Sources/Tests/ProjectCapabilityTests.swift @@ -1,8 +1,8 @@ //===----------------------------------------------------------------------===// // Copyright © 2026 Apple Inc. and the xcode-project-format project authors // -// Licensed under Apache License v2.0 -// SPDX-License-Identifier: Apache-2.0 +// Licensed under Apache License v2.0 with Runtime Library Exception +// SPDX-License-Identifier: Apache-2.0 WITH Swift-exception // //===----------------------------------------------------------------------===//