Skip to content

Commit ed04cf8

Browse files
committed
Add a SwiftSyntaxTestSupport target
Extract the duplicated test utilities into their own target that each test target can use instead.
1 parent cafd34b commit ed04cf8

File tree

10 files changed

+118
-79
lines changed

10 files changed

+118
-79
lines changed

Package.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@ let package = Package(
9090
],
9191
linkerSettings: swiftSyntaxParserLinkerSettings
9292
),
93+
.target(
94+
name: "SwiftSyntaxTestSupport",
95+
dependencies: ["SwiftSyntax"]
96+
),
9397
.target(
9498
name: "lit-test-helper",
9599
dependencies: ["SwiftSyntax", "SwiftSyntaxParser"]
@@ -121,15 +125,15 @@ let package = Package(
121125
),
122126
.testTarget(
123127
name: "SwiftSyntaxTest",
124-
dependencies: ["SwiftSyntax"]
128+
dependencies: ["SwiftSyntax", "SwiftSyntaxTestSupport"]
125129
),
126130
.testTarget(
127131
name: "SwiftSyntaxBuilderTest",
128132
dependencies: ["SwiftSyntaxBuilder"]
129133
),
130134
.testTarget(
131135
name: "SwiftSyntaxParserTest",
132-
dependencies: ["SwiftSyntaxParser"],
136+
dependencies: ["SwiftSyntaxParser", "SwiftSyntaxTestSupport"],
133137
exclude: ["Inputs"]
134138
),
135139
.testTarget(
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//===------------------- Syntax+Assertions.swift -------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// Syntax assertion helpers.
14+
//
15+
//===----------------------------------------------------------------------===//
16+
17+
import SwiftSyntax
18+
import XCTest
19+
20+
/// Verifies that there is a next item returned by the iterator and that it
21+
/// satisfies the given predicate.
22+
public func XCTAssertNext<Iterator: IteratorProtocol>(
23+
_ iterator: inout Iterator,
24+
satisfies predicate: (Iterator.Element) throws -> Bool,
25+
file: StaticString = #filePath, line: UInt = #line
26+
) throws {
27+
let next = try XCTUnwrap(iterator.next(), file: file, line: line)
28+
XCTAssertTrue(try predicate(next), file: file, line: line)
29+
}
30+
31+
/// Verifies that the iterator is exhausted.
32+
public func XCTAssertNextIsNil<Iterator: IteratorProtocol>(_ iterator: inout Iterator) {
33+
XCTAssertNil(iterator.next())
34+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//===----------------- SyntaxCollection+AtIndex.swift --------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// O(n) test method for grabbing a child at a particular index.
14+
//
15+
//===----------------------------------------------------------------------===//
16+
17+
import SwiftSyntax
18+
19+
public extension SyntaxCollection {
20+
/// Gets the child at the provided index in this node's present children.
21+
/// This is not provided by the Syntax API because its performance is O(n).
22+
/// We add it here in `SyntaxCollection` for testing purposes.
23+
func child(at index: Int) -> Element? {
24+
guard index >= 0 && index < self.count else { return nil }
25+
var iter = self.makeIterator()
26+
for _ in 0..<index { _ = iter.next() }
27+
return iter.next()!
28+
}
29+
30+
subscript(_ index: Int) -> Element {
31+
return child(at: index)!
32+
}
33+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//===--------- TestUtils.swift - Syntax Parsing ---------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// Various utilities to aid in syntax tree testing.
14+
//
15+
//===----------------------------------------------------------------------===//
16+
17+
import Foundation
18+
import SwiftSyntax
19+
20+
public func getTestInput(_ file: String, baseFile: String = #file) -> URL {
21+
var result = URL(fileURLWithPath: baseFile)
22+
result.deleteLastPathComponent()
23+
result.appendPathComponent("Inputs")
24+
result.appendPathComponent(file)
25+
return result
26+
}

Tests/SwiftSyntaxParserTest/AbsolutePositionTests.swift

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import XCTest
22
import SwiftSyntax
33
import SwiftSyntaxParser
4+
import SwiftSyntaxTestSupport
45

56
fileprivate class FuncRenamer: SyntaxRewriter {
67
override func visit(_ node: FunctionDeclSyntax) -> DeclSyntax {
@@ -15,8 +16,8 @@ public class AbsolutePositionTests: XCTestCase {
1516

1617
public func testVisitor() {
1718
XCTAssertNoThrow(try {
18-
let source = try String(contentsOf: getInput("visitor.swift"))
19-
let parsed = try SyntaxParser.parse(getInput("visitor.swift"))
19+
let source = try String(contentsOf: getTestInput("visitor.swift"))
20+
let parsed = try SyntaxParser.parse(getTestInput("visitor.swift"))
2021
XCTAssertEqual(0, parsed.position.utf8Offset)
2122
XCTAssertEqual(source.count,
2223
parsed.eofToken.positionAfterSkippingLeadingTrivia.utf8Offset)
@@ -27,8 +28,8 @@ public class AbsolutePositionTests: XCTestCase {
2728

2829
public func testClosure() {
2930
XCTAssertNoThrow(try {
30-
let source = try String(contentsOf: getInput("closure.swift"))
31-
let parsed = try SyntaxParser.parse(getInput("closure.swift"))
31+
let source = try String(contentsOf: getTestInput("closure.swift"))
32+
let parsed = try SyntaxParser.parse(getTestInput("closure.swift"))
3233
XCTAssertEqual(source.count,
3334
parsed.eofToken.positionAfterSkippingLeadingTrivia.utf8Offset)
3435
XCTAssertEqual(0, parsed.position.utf8Offset)
@@ -38,7 +39,7 @@ public class AbsolutePositionTests: XCTestCase {
3839

3940
public func testRename() {
4041
XCTAssertNoThrow(try {
41-
let parsed = try SyntaxParser.parse(getInput("visitor.swift"))
42+
let parsed = try SyntaxParser.parse(getTestInput("visitor.swift"))
4243
let renamed = FuncRenamer().visit(parsed).as(SourceFileSyntax.self)!
4344
let renamedSource = renamed.description
4445
XCTAssertEqual(renamedSource.count,

Tests/SwiftSyntaxParserTest/SyntaxVisitorTests.swift

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import XCTest
22
import SwiftSyntax
33
import SwiftSyntaxParser
4+
import SwiftSyntaxTestSupport
45

56
public class SyntaxVisitorTests: XCTestCase {
67

@@ -13,7 +14,7 @@ public class SyntaxVisitorTests: XCTestCase {
1314
}
1415
}
1516
XCTAssertNoThrow(try {
16-
let parsed = try SyntaxParser.parse(getInput("visitor.swift"))
17+
let parsed = try SyntaxParser.parse(getTestInput("visitor.swift"))
1718
let counter = FuncCounter()
1819
let hashBefore = parsed.hashValue
1920
counter.walk(parsed)
@@ -30,7 +31,7 @@ public class SyntaxVisitorTests: XCTestCase {
3031
}
3132
}
3233
XCTAssertNoThrow(try {
33-
let parsed = try SyntaxParser.parse(getInput("closure.swift"))
34+
let parsed = try SyntaxParser.parse(getTestInput("closure.swift"))
3435
let rewriter = ClosureRewriter()
3536
let rewritten = rewriter.visit(parsed)
3637
XCTAssertEqual(parsed.description, rewritten.description)
@@ -51,7 +52,7 @@ public class SyntaxVisitorTests: XCTestCase {
5152
}
5253
}
5354
XCTAssertNoThrow(try {
54-
let parsed = try SyntaxParser.parse(getInput("near-empty.swift"))
55+
let parsed = try SyntaxParser.parse(getTestInput("near-empty.swift"))
5556
let rewriter = VisitAnyRewriter(transform: { _ in
5657
return SyntaxFactory.makeIdentifier("")
5758
})
@@ -71,7 +72,7 @@ public class SyntaxVisitorTests: XCTestCase {
7172
}
7273

7374
XCTAssertNoThrow(try {
74-
let parsed = try SyntaxParser.parse(getInput("nested-blocks.swift"))
75+
let parsed = try SyntaxParser.parse(getTestInput("nested-blocks.swift"))
7576
let visitor = VisitCollections()
7677
visitor.walk(parsed)
7778
XCTAssertEqual(4, visitor.numberOfCodeBlockItems)
@@ -87,7 +88,7 @@ public class SyntaxVisitorTests: XCTestCase {
8788
}
8889
}
8990
XCTAssertNoThrow(try {
90-
let parsed = try SyntaxParser.parse(getInput("visitor.swift"))
91+
let parsed = try SyntaxParser.parse(getTestInput("visitor.swift"))
9192
let counter = FuncCounter()
9293
let hashBefore = parsed.hashValue
9394
counter.walk(parsed)

Tests/SwiftSyntaxParserTest/TestUtils.swift

Lines changed: 0 additions & 27 deletions
This file was deleted.

Tests/SwiftSyntaxTest/SyntaxChildrenTests.swift

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,27 @@
11
import XCTest
22
import SwiftSyntax
3+
import SwiftSyntaxTestSupport
34

45
public class SyntaxChildrenTests: XCTestCase {
56

6-
public func testIterateWithAllPresent() {
7+
public func testIterateWithAllPresent() throws {
78
let returnStmt = SyntaxFactory.makeReturnStmt(
89
returnKeyword: SyntaxFactory.makeReturnKeyword(),
910
expression: ExprSyntax(SyntaxFactory.makeBlankUnknownExpr()))
1011

1112
var iterator = returnStmt.children.makeIterator()
12-
XCTAssertNext(&iterator) { $0.as(TokenSyntax.self)?.tokenKind == .returnKeyword }
13-
XCTAssertNext(&iterator) { $0.is(ExprSyntax.self) }
13+
try XCTAssertNext(&iterator) { $0.as(TokenSyntax.self)?.tokenKind == .returnKeyword }
14+
try XCTAssertNext(&iterator) { $0.is(ExprSyntax.self) }
1415
XCTAssertNextIsNil(&iterator)
1516
}
1617

17-
public func testIterateWithSomeMissing() {
18+
public func testIterateWithSomeMissing() throws {
1819
let returnStmt = SyntaxFactory.makeReturnStmt(
1920
returnKeyword: SyntaxFactory.makeReturnKeyword(),
2021
expression: nil)
2122

2223
var iterator = returnStmt.children.makeIterator()
23-
XCTAssertNext(&iterator) { $0.as(TokenSyntax.self)?.tokenKind == .returnKeyword }
24+
try XCTAssertNext(&iterator) { $0.as(TokenSyntax.self)?.tokenKind == .returnKeyword }
2425
XCTAssertNextIsNil(&iterator)
2526
}
2627

Tests/SwiftSyntaxTest/SyntaxCollectionsTests.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import XCTest
22
import SwiftSyntax
3+
import SwiftSyntaxTestSupport
34

45
fileprivate func integerLiteralElement(_ int: Int) -> ArrayElementSyntax {
56
let literal = SyntaxFactory.makeIntegerLiteral("\(int)")

Tests/SwiftSyntaxTest/TestUtils.swift

Lines changed: 0 additions & 35 deletions
This file was deleted.

0 commit comments

Comments
 (0)