Skip to content

Commit cea1a08

Browse files
authored
Extend snapshot testing to completion scripts (#698)
As the title suggests this commit moves the completion script tests to use the snapshot testing recently introduced.
1 parent b551ec8 commit cea1a08

14 files changed

+579
-657
lines changed

Sources/ArgumentParserTestHelpers/TestHelpers.swift

Lines changed: 104 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -360,11 +360,68 @@ extension XCTest {
360360
return outputActual
361361
}
362362

363-
public func AssertGenerateManual(
363+
public func AssertJSONEqualFromString<T: Codable & Equatable>(actual: String, expected: String, for type: T.Type, file: StaticString = #filePath, line: UInt = #line) throws {
364+
if #available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *) {
365+
AssertEqualStrings(
366+
actual: actual.trimmingCharacters(in: .whitespacesAndNewlines),
367+
expected: expected.trimmingCharacters(in: .whitespacesAndNewlines),
368+
file: file,
369+
line: line)
370+
}
371+
372+
let actualJSONData = try XCTUnwrap(actual.data(using: .utf8), file: file, line: line)
373+
let actualDumpJSON = try XCTUnwrap(JSONDecoder().decode(type, from: actualJSONData), file: file, line: line)
374+
375+
let expectedJSONData = try XCTUnwrap(expected.data(using: .utf8), file: file, line: line)
376+
let expectedDumpJSON = try XCTUnwrap(JSONDecoder().decode(type, from: expectedJSONData), file: file, line: line)
377+
XCTAssertEqual(actualDumpJSON, expectedDumpJSON)
378+
}
379+
}
380+
381+
382+
// MARK: - Snapshot testing
383+
extension XCTest {
384+
@discardableResult
385+
public func assertSnapshot(
386+
actual: String,
387+
extension: String,
388+
record: Bool = false,
389+
test: StaticString = #function,
390+
file: StaticString = #filePath,
391+
line: UInt = #line
392+
) throws -> String {
393+
let snapshotDirectoryURL = URL(fileURLWithPath: "\(file)")
394+
.deletingLastPathComponent()
395+
.appendingPathComponent("Snapshots")
396+
let snapshotFileURL = snapshotDirectoryURL
397+
.appendingPathComponent("\(test).\(`extension`)")
398+
399+
if record || !FileManager.default.fileExists(atPath: snapshotFileURL.path) {
400+
let recordedValue = actual + "\n"
401+
try FileManager.default.createDirectory(
402+
at: snapshotDirectoryURL,
403+
withIntermediateDirectories: true,
404+
attributes: nil)
405+
try recordedValue.write(to: snapshotFileURL, atomically: true, encoding: .utf8)
406+
XCTFail("Recorded new baseline", file: file, line: line)
407+
struct EarlyExit: Error {}
408+
throw EarlyExit()
409+
} else {
410+
let expected = try String(contentsOf: snapshotFileURL, encoding: .utf8)
411+
AssertEqualStrings(
412+
actual: actual,
413+
expected: expected.trimmingCharacters(in: .newlines),
414+
file: file,
415+
line: line)
416+
return expected
417+
}
418+
}
419+
420+
public func assertGenerateManual(
364421
multiPage: Bool,
365422
command: String,
366-
expected: URL,
367423
record: Bool = false,
424+
test: StaticString = #function,
368425
file: StaticString = #filePath,
369426
line: UInt = #line
370427
) throws {
@@ -390,24 +447,19 @@ extension XCTest {
390447
file: file,
391448
line: line)
392449

393-
if record || !FileManager.default.fileExists(atPath: expected.path) {
394-
let recordedValue = actual + "\n"
395-
try recordedValue.write(to: expected, atomically: true, encoding: .utf8)
396-
XCTFail("Recorded new baseline", file: file, line: line)
397-
} else {
398-
let expected = try String(contentsOf: expected, encoding: .utf8)
399-
AssertEqualStrings(
400-
actual: actual,
401-
expected: expected.trimmingCharacters(in: .whitespacesAndNewlines),
402-
file: file,
403-
line: line)
404-
}
450+
try self.assertSnapshot(
451+
actual: actual,
452+
extension: "mdoc",
453+
record: record,
454+
test: test,
455+
file: file,
456+
line: line)
405457
}
406458

407-
public func AssertGenerateDoccReference(
459+
public func assertGenerateDoccReference(
408460
command: String,
409-
expected: URL,
410461
record: Bool = false,
462+
test: StaticString = #function,
411463
file: StaticString = #filePath,
412464
line: UInt = #line
413465
) throws {
@@ -424,58 +476,55 @@ extension XCTest {
424476
command: command,
425477
file: file,
426478
line: line)
427-
if record || !FileManager.default.fileExists(atPath: expected.path) {
428-
let recordedValue = actual + "\n"
429-
try recordedValue.write(to: expected, atomically: true, encoding: .utf8)
430-
XCTFail("Recorded new baseline", file: file, line: line)
431-
} else {
432-
let expected = try String(contentsOf: expected, encoding: .utf8)
433-
AssertEqualStrings(
434-
actual: actual,
435-
expected: expected.trimmingCharacters(in: .whitespacesAndNewlines),
436-
file: file,
437-
line: line)
438-
}
479+
480+
try self.assertSnapshot(
481+
actual: actual,
482+
extension: "md",
483+
record: record,
484+
test: test,
485+
file: file,
486+
line: line)
439487
}
440488

441-
public func AssertDump<T: ParsableArguments>(
489+
public func assertDumpHelp<T: ParsableArguments>(
442490
type: T.Type,
443-
expected: URL,
444491
record: Bool = false,
492+
test: StaticString = #function,
445493
file: StaticString = #filePath,
446494
line: UInt = #line
447495
) throws {
448-
let cliOutput: String
496+
let actual: String
449497
do {
450498
_ = try T.parse(["--experimental-dump-help"])
451499
XCTFail(file: file, line: line)
452500
return
453501
} catch {
454-
cliOutput = T.fullMessage(for: error)
502+
actual = T.fullMessage(for: error)
455503
}
456504

457505
let apiOutput = T._dumpHelp()
458-
AssertEqualStrings(actual: cliOutput, expected: apiOutput)
506+
AssertEqualStrings(actual: actual, expected: apiOutput)
459507

460-
if record || !FileManager.default.fileExists(atPath: expected.path) {
461-
let recordedValue = apiOutput + "\n"
462-
try recordedValue.write(to: expected, atomically: true, encoding: .utf8)
463-
XCTFail("Recorded new baseline", file: file, line: line)
464-
} else {
465-
let expected = try String(contentsOf: expected, encoding: .utf8)
466-
try AssertJSONEqualFromString(
467-
actual: apiOutput,
468-
expected: expected,
469-
for: ToolInfoV0.self,
470-
file: file,
471-
line: line)
472-
}
508+
let expected = try self.assertSnapshot(
509+
actual: actual,
510+
extension: "json",
511+
record: record,
512+
test: test,
513+
file: file,
514+
line: line)
515+
516+
try AssertJSONEqualFromString(
517+
actual: actual,
518+
expected: expected,
519+
for: ToolInfoV0.self,
520+
file: file,
521+
line: line)
473522
}
474523

475-
public func AssertDump(
524+
public func assertDumpHelp(
476525
command: String,
477-
expected: URL,
478526
record: Bool = false,
527+
test: StaticString = #function,
479528
file: StaticString = #filePath,
480529
line: UInt = #line
481530
) throws {
@@ -484,35 +533,12 @@ extension XCTest {
484533
expected: nil,
485534
file: file,
486535
line: line)
487-
if record || !FileManager.default.fileExists(atPath: expected.path) {
488-
let recordedValue = actual + "\n"
489-
try recordedValue.write(to: expected, atomically: true, encoding: .utf8)
490-
XCTFail("Recorded new baseline", file: file, line: line)
491-
} else {
492-
let expected = try String(contentsOf: expected, encoding: .utf8)
493-
try AssertJSONEqualFromString(
494-
actual: actual,
495-
expected: expected,
496-
for: ToolInfoV0.self,
497-
file: file,
498-
line: line)
499-
}
500-
}
501-
502-
public func AssertJSONEqualFromString<T: Codable & Equatable>(actual: String, expected: String, for type: T.Type, file: StaticString = #filePath, line: UInt = #line) throws {
503-
if #available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *) {
504-
AssertEqualStrings(
505-
actual: actual.trimmingCharacters(in: .whitespacesAndNewlines),
506-
expected: expected.trimmingCharacters(in: .whitespacesAndNewlines),
507-
file: file,
508-
line: line)
509-
}
510-
511-
let actualJSONData = try XCTUnwrap(actual.data(using: .utf8), file: file, line: line)
512-
let actualDumpJSON = try XCTUnwrap(JSONDecoder().decode(type, from: actualJSONData), file: file, line: line)
513-
514-
let expectedJSONData = try XCTUnwrap(expected.data(using: .utf8), file: file, line: line)
515-
let expectedDumpJSON = try XCTUnwrap(JSONDecoder().decode(type, from: expectedJSONData), file: file, line: line)
516-
XCTAssertEqual(actualDumpJSON, expectedDumpJSON)
536+
try self.assertSnapshot(
537+
actual: actual,
538+
extension: "json",
539+
record: record,
540+
test: test,
541+
file: file,
542+
line: line)
517543
}
518544
}

Tests/ArgumentParserGenerateDoccReferenceTests/GenerateDoccReferenceTests.swift

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,34 +14,26 @@ import XCTest
1414
import ArgumentParserTestHelpers
1515

1616
final class GenerateDoccReferenceTests: XCTestCase {
17-
let snapshotsDirectory = URL(fileURLWithPath: #filePath)
18-
.deletingLastPathComponent()
19-
.appendingPathComponent("Snapshots")
20-
21-
func url(_ test: StaticString = #function) -> URL {
22-
return self.snapshotsDirectory.appendingPathComponent("\(test).md")
23-
}
24-
2517
#if os(macOS)
2618
func testCountLinesDoccReference() throws {
2719
guard #available(macOS 12, *) else { return }
28-
try AssertGenerateDoccReference(command: "count-lines", expected: self.url())
20+
try assertGenerateDoccReference(command: "count-lines")
2921
}
3022
#endif
3123

3224
func testColorDoccReference() throws {
33-
try AssertGenerateDoccReference(command: "color", expected: self.url())
25+
try assertGenerateDoccReference(command: "color")
3426
}
3527

3628
func testMathDoccReference() throws {
37-
try AssertGenerateDoccReference(command: "math", expected: self.url())
29+
try assertGenerateDoccReference(command: "math")
3830
}
3931

4032
func testRepeatDoccReference() throws {
41-
try AssertGenerateDoccReference(command: "repeat", expected: self.url())
33+
try assertGenerateDoccReference(command: "repeat")
4234
}
4335

4436
func testRollDoccReference() throws {
45-
try AssertGenerateDoccReference(command: "roll", expected: self.url())
37+
try assertGenerateDoccReference(command: "roll")
4638
}
4739
}

Tests/ArgumentParserGenerateManualTests/GenerateManualTests.swift

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,55 +14,47 @@ import XCTest
1414
import ArgumentParserTestHelpers
1515

1616
final class GenerateManualTests: XCTestCase {
17-
let snapshotsDirectory = URL(fileURLWithPath: #filePath)
18-
.deletingLastPathComponent()
19-
.appendingPathComponent("Snapshots")
20-
21-
func url(_ test: StaticString = #function) -> URL {
22-
return self.snapshotsDirectory.appendingPathComponent("\(test).mdoc")
23-
}
24-
2517
#if os(macOS)
2618
func testCountLinesSinglePageManual() throws {
2719
guard #available(macOS 12, *) else { return }
28-
try AssertGenerateManual(multiPage: false, command: "count-lines", expected: self.url())
20+
try assertGenerateManual(multiPage: false, command: "count-lines")
2921
}
3022

3123
func testCountLinesMultiPageManual() throws {
3224
guard #available(macOS 12, *) else { return }
33-
try AssertGenerateManual(multiPage: true, command: "count-lines", expected: self.url())
25+
try assertGenerateManual(multiPage: true, command: "count-lines")
3426
}
3527
#endif
3628

3729
func testColorSinglePageManual() throws {
38-
try AssertGenerateManual(multiPage: false, command: "color", expected: self.url())
30+
try assertGenerateManual(multiPage: false, command: "color")
3931
}
4032

4133
func testColorMultiPageManual() throws {
42-
try AssertGenerateManual(multiPage: true, command: "color", expected: self.url())
34+
try assertGenerateManual(multiPage: true, command: "color")
4335
}
4436

4537
func testMathSinglePageManual() throws {
46-
try AssertGenerateManual(multiPage: false, command: "math", expected: self.url())
38+
try assertGenerateManual(multiPage: false, command: "math")
4739
}
4840

4941
func testMathMultiPageManual() throws {
50-
try AssertGenerateManual(multiPage: true, command: "math", expected: self.url())
42+
try assertGenerateManual(multiPage: true, command: "math")
5143
}
5244

5345
func testRepeatSinglePageManual() throws {
54-
try AssertGenerateManual(multiPage: false, command: "repeat", expected: self.url())
46+
try assertGenerateManual(multiPage: false, command: "repeat")
5547
}
5648

5749
func testRepeatMultiPageManual() throws {
58-
try AssertGenerateManual(multiPage: true, command: "repeat", expected: self.url())
50+
try assertGenerateManual(multiPage: true, command: "repeat")
5951
}
6052

6153
func testRollSinglePageManual() throws {
62-
try AssertGenerateManual(multiPage: false, command: "roll", expected: self.url())
54+
try assertGenerateManual(multiPage: false, command: "roll")
6355
}
6456

6557
func testRollMultiPageManual() throws {
66-
try AssertGenerateManual(multiPage: true, command: "roll", expected: self.url())
58+
try assertGenerateManual(multiPage: true, command: "roll")
6759
}
6860
}

0 commit comments

Comments
 (0)