Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions Sources/ArgumentParserTestHelpers/TestHelpers+SwiftTesting.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
//===----------------------------------------------------------------------===//

import ArgumentParser
import ArgumentParserToolInfo
import Foundation
import Testing

Expand Down Expand Up @@ -200,3 +201,105 @@ public func expectSnapshot(
return expected
}
}

public func expectJSONEqualFromString<T: Codable & Equatable>(
actual: String,
expected: String,
for type: T.Type,
sourceLocation: SourceLocation = #_sourceLocation
) throws {
expectEqualStrings(
actual: actual,
expected: expected,
sourceLocation: sourceLocation
)

let actualJSONData = try #require(
actual.data(using: .utf8),
sourceLocation: sourceLocation
)
let actualDumpJSON = try JSONDecoder().decode(type, from: actualJSONData)

let expectedJSONData = try #require(
expected.data(using: .utf8),
sourceLocation: sourceLocation
)
let expectedDumpJSON = try JSONDecoder().decode(type, from: expectedJSONData)

#expect(
actualDumpJSON == expectedDumpJSON,
sourceLocation: sourceLocation
)
}

public func expectDumpHelp<T: ParsableArguments>(
type: T.Type,
record: Bool = false,
test: String = #function,
filePath: StaticString = #filePath,
sourceLocation: SourceLocation = #_sourceLocation
) throws {
// TODO: migrate to the following API when the minimum Swift version supports it
///
// let error = #expect(throws: (any Error).self) {
// _ = try T.parse(["--experimental-dump-help"])
// }
// let actual = T.fullMessage(for: error)
let actual: String
do {
_ = try T.parse(["--experimental-dump-help"])
Issue.record(
"Expected T.parse to throw a help request.",
sourceLocation: sourceLocation)
return
} catch {
actual = T.fullMessage(for: error)
}

let apiOutput = T._dumpHelp()
expectEqualStrings(
actual: actual,
expected: apiOutput,
sourceLocation: sourceLocation
)

let expected = try expectSnapshot(
actual: actual,
extension: "json",
record: record,
test: test,
filePath: filePath,
sourceLocation: sourceLocation
)

guard let expected else { return }

try expectJSONEqualFromString(
actual: actual,
expected: expected,
for: ToolInfoV0.self,
sourceLocation: sourceLocation
)
}

public func expectDumpHelp(
command: String,
record: Bool = false,
test: String = #function,
filePath: StaticString = #filePath,
sourceLocation: SourceLocation = #_sourceLocation
) throws {
let actual = try requireExecuteCommand(
command: command + " --experimental-dump-help",
expected: nil,
sourceLocation: sourceLocation
)
try expectSnapshot(
actual: actual,
extension: "json",
record: record,
test: test,
filePath: filePath,
sourceLocation: sourceLocation
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,41 @@
//
// This source file is part of the Swift Argument Parser open source project
//
// Copyright (c) 2025 Apple Inc. and the Swift project authors
// Copyright (c) 2025-2026 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
//
//===----------------------------------------------------------------------===//

import ArgumentParserTestHelpers
import XCTest
import Testing

@testable import ArgumentParser

final class DefaultAsFlagCompletionTests: XCTestCase {
func testDefaultAsFlagCompletion_Bash() throws {
@Suite struct DefaultAsFlagCompletionTests {
@Test func defaultAsFlagCompletion_Bash() throws {
let script = try CompletionsGenerator(
command: DefaultAsFlagCommand.self, shell: .bash
)
.generateCompletionScript()
try assertSnapshot(actual: script, extension: "bash")
try expectSnapshot(actual: script, extension: "bash")
}

func testDefaultAsFlagCompletion_Zsh() throws {
@Test func defaultAsFlagCompletion_Zsh() throws {
let script = try CompletionsGenerator(
command: DefaultAsFlagCommand.self, shell: .zsh
)
.generateCompletionScript()
try assertSnapshot(actual: script, extension: "zsh")
try expectSnapshot(actual: script, extension: "zsh")
}

func testDefaultAsFlagCompletion_Fish() throws {
@Test func defaultAsFlagCompletion_Fish() throws {
let script = try CompletionsGenerator(
command: DefaultAsFlagCommand.self, shell: .fish
)
.generateCompletionScript()
try assertSnapshot(actual: script, extension: "fish")
try expectSnapshot(actual: script, extension: "fish")
}
}

Expand Down
14 changes: 7 additions & 7 deletions Tests/ArgumentParserUnitTests/DefaultAsFlagDumpHelpTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,25 @@
//
// This source file is part of the Swift Argument Parser open source project
//
// Copyright (c) 2025 Apple Inc. and the Swift project authors
// Copyright (c) 2025-2026 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
//
//===----------------------------------------------------------------------===//

import ArgumentParserTestHelpers
import XCTest
import Testing

@testable import ArgumentParser

final class DefaultAsFlagDumpHelpTests: XCTestCase {
func testDefaultAsFlagDumpHelp() throws {
try assertDumpHelp(type: DefaultAsFlagCommand.self)
@Suite struct DefaultAsFlagDumpHelpTests {
@Test func defaultAsFlagDumpHelp() throws {
try expectDumpHelp(type: DefaultAsFlagCommand.self)
}

func testDefaultAsFlagWithTransformDumpHelp() throws {
try assertDumpHelp(type: DefaultAsFlagWithTransformCommand.self)
@Test func defaultAsFlagWithTransformDumpHelp() throws {
try expectDumpHelp(type: DefaultAsFlagWithTransformCommand.self)
}
}

Expand Down
42 changes: 25 additions & 17 deletions Tests/ArgumentParserUnitTests/DumpHelpGenerationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,53 @@
//
// This source file is part of the Swift Argument Parser open source project
//
// Copyright (c) 2020 Apple Inc. and the Swift project authors
// Copyright (c) 2020-2026 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
//
//===----------------------------------------------------------------------===//

import ArgumentParserTestHelpers
import XCTest
import Testing

@testable import ArgumentParser

final class DumpHelpGenerationTests: XCTestCase {
public func testADumpHelp() throws {
try assertDumpHelp(type: A.self)
@Suite struct DumpHelpGenerationTests {
@Test func aDumpHelp() throws {
try expectDumpHelp(type: A.self)
}

public func testBDumpHelp() throws {
try assertDumpHelp(type: B.self)
@Test func bDumpHelp() throws {
try expectDumpHelp(type: B.self)
}

public func testCDumpHelp() throws {
try assertDumpHelp(type: C.self)
@Test func cDumpHelp() throws {
try expectDumpHelp(type: C.self)
}

func testMathDumpHelp() throws {
try assertDumpHelp(command: "math")
@Test(
.requiresProcessExecution
) func mathDumpHelp() throws {
try expectDumpHelp(command: "math")
}

func testMathAddDumpHelp() throws {
try assertDumpHelp(command: "math add")
@Test(
.requiresProcessExecution
) func mathAddDumpHelp() throws {
try expectDumpHelp(command: "math add")
}

func testMathMultiplyDumpHelp() throws {
try assertDumpHelp(command: "math multiply")
@Test(
.requiresProcessExecution
) func mathMultiplyDumpHelp() throws {
try expectDumpHelp(command: "math multiply")
}

func testMathStatsDumpHelp() throws {
try assertDumpHelp(command: "math stats")
@Test(
.requiresProcessExecution
) func mathStatsDumpHelp() throws {
try expectDumpHelp(command: "math stats")
}
}

Expand Down
Loading
Loading