Skip to content

Commit 2563756

Browse files
committed
test
1 parent 14d2e0f commit 2563756

File tree

4 files changed

+100
-16
lines changed

4 files changed

+100
-16
lines changed

utils/swift-xcodegen/Sources/SwiftXcodeGen/Ninja/NinjaBuildFile.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ extension NinjaBuildFile {
4747
}
4848
}
4949

50-
struct Rule {
50+
struct Rule: Equatable {
5151
let name: String
5252
var bindings: Bindings
5353

utils/swift-xcodegen/Sources/SwiftXcodeGen/Ninja/NinjaParser.swift

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,19 @@ import Foundation
1414

1515
struct NinjaParser {
1616
private let filePath: AbsolutePath
17+
private let fileReader: (AbsolutePath) throws -> Data
1718
private var lexer: Lexer
1819

19-
private init(filePath: AbsolutePath, input: UnsafeRawBufferPointer) throws {
20+
private init(input: UnsafeRawBufferPointer, filePath: AbsolutePath, fileReader: @escaping (AbsolutePath) throws -> Data) throws {
2021
self.filePath = filePath
22+
self.fileReader = fileReader
2123
self.lexer = Lexer(ByteScanner(input))
2224
}
2325

24-
static func parse(filePath: AbsolutePath, input: Data) throws -> NinjaBuildFile {
25-
try input.withUnsafeBytes { bytes in
26-
var parser = try Self(filePath: filePath, input: bytes)
26+
static func parse(filePath: AbsolutePath, fileReader: @escaping (AbsolutePath) throws -> Data = { try $0.read() }) throws -> NinjaBuildFile {
27+
28+
try fileReader(filePath).withUnsafeBytes { bytes in
29+
var parser = try Self(input: bytes, filePath: filePath, fileReader: fileReader)
2730
return try parser.parse()
2831
}
2932
}
@@ -347,7 +350,7 @@ fileprivate extension NinjaParser {
347350

348351
let baseDirectory = self.filePath.parentDir!
349352
let path = AnyPath(fileName).absolute(in: baseDirectory)
350-
return try NinjaParser.parse(filePath: path, input: path.read())
353+
return try NinjaParser.parse(filePath: path, fileReader: fileReader)
351354
}
352355

353356
mutating func parse() throws -> NinjaBuildFile {

utils/swift-xcodegen/Sources/SwiftXcodeGen/Ninja/RepoBuildDir.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ extension RepoBuildDir {
8282
}
8383

8484
log.debug("[*] Reading '\(fileName)'")
85-
let ninjaFile = try NinjaParser.parse(filePath: fileName, input: fileName.read())
85+
let ninjaFile = try NinjaParser.parse(filePath: fileName)
8686
_ninjaFile = ninjaFile
8787
return ninjaFile
8888
}

utils/swift-xcodegen/Tests/SwiftXcodeGenTest/NinjaParserTests.swift

Lines changed: 90 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,27 @@ fileprivate func expectEqual<T, U: Equatable>(
5454
fileprivate func assertParse(
5555
_ str: String,
5656
bindings: [String: String] = [:],
57+
rules: [String: NinjaBuildFile.Rule] = [:],
58+
edges: [NinjaBuildFile.BuildEdge],
59+
file: StaticString = #file, line: UInt = #line
60+
) {
61+
let filePath: AbsolutePath = "/tmp/build.ninja"
62+
let files: [AbsolutePath: String] = [
63+
filePath: str
64+
]
65+
assertParse(filePath, in: files, bindings: bindings, rules: rules, edges: edges, file: file, line: line)
66+
}
67+
68+
fileprivate func assertParse(
69+
_ filePath: AbsolutePath,
70+
in fileSystem: [AbsolutePath: String],
71+
bindings: [String: String] = [:],
72+
rules: [String: NinjaBuildFile.Rule] = [:],
5773
edges: [NinjaBuildFile.BuildEdge],
5874
file: StaticString = #file, line: UInt = #line
5975
) {
6076
do {
61-
let buildFile = try NinjaParser.parse(filePath: "/tmp/build.ninja", input: Data(str.utf8))
77+
let buildFile = try NinjaParser.parse(filePath: "/tmp/build.ninja", fileReader: { Data(fileSystem[$0]!.utf8) })
6278
guard edges.count == buildFile.buildEdges.count else {
6379
XCTFail(
6480
"Expected \(edges.count) rules, got \(buildFile.buildEdges.count)",
@@ -71,6 +87,10 @@ fileprivate func assertParse(
7187
buildFile.bindings.values,
7288
file: file, line: line
7389
)
90+
XCTAssertEqual(
91+
rules, buildFile.rules,
92+
file: file, line: line
93+
)
7494
for (expected, actual) in zip(edges, buildFile.buildEdges) {
7595
expectEqual(expected, actual, \.ruleName, file: file, line: line)
7696
expectEqual(expected, actual, \.inputs, file: file, line: line)
@@ -87,12 +107,14 @@ fileprivate func assertParse(
87107

88108
class NinjaParserTests: XCTestCase {
89109
func testBuildEdge() throws {
90-
assertParse("""
110+
assertParse(
111+
"""
91112
# ignore comment, build foo.o: a.swift | dep || orderdep
92113
#another build comment
93114
build foo.o foo.swiftmodule: SWIFTC a.swift | dep || orderdep
94115
notpartofthebuildrule
95-
""", edges: [
116+
""",
117+
edges: [
96118
.init(
97119
ruleName: "SWIFTC",
98120
inputs: ["a.swift"],
@@ -104,10 +126,66 @@ class NinjaParserTests: XCTestCase {
104126
)
105127
}
106128

129+
func testRule() throws {
130+
assertParse(
131+
"""
132+
rule SWIFTC
133+
command = /bin/switfc -wmo -target unknown
134+
other = whatever
135+
notpartoftherule
136+
""",
137+
rules: [
138+
"SWIFTC": .init(
139+
name: "SWIFTC",
140+
bindings: [
141+
"command": "/bin/switfc -wmo -target unknown",
142+
"other": "whatever",
143+
])
144+
],
145+
edges: []
146+
)
147+
}
148+
149+
func testInclude() throws {
150+
let files: [AbsolutePath: String] = [
151+
"/tmp/build.ninja": """
152+
include path/to/sub.ninja
153+
154+
build foo.swiftmodule : SWIFTC foo.swift
155+
""",
156+
"/tmp/path/to/sub.ninja": """
157+
rule SWIFTC
158+
command = /bin/swiftc $in -o $out
159+
"""
160+
]
161+
assertParse(
162+
"/tmp/build.ninja",
163+
in: files,
164+
rules: [
165+
"SWIFTC": .init(
166+
name: "SWIFTC",
167+
bindings: [
168+
"command": "/bin/swiftc $in -o $out",
169+
])
170+
],
171+
edges: [
172+
.init(
173+
ruleName: "SWIFTC",
174+
inputs: ["foo.swift"],
175+
outputs: ["foo.swiftmodule"],
176+
dependencies: [],
177+
bindings: [:]
178+
)
179+
]
180+
)
181+
}
182+
107183
func testPhonyRule() throws {
108-
assertParse("""
184+
assertParse(
185+
"""
109186
build foo.swiftmodule : phony bar.swiftmodule
110-
""", edges: [
187+
""",
188+
edges: [
111189
.phony(
112190
for: ["foo.swiftmodule"],
113191
inputs: ["bar.swiftmodule"]
@@ -116,8 +194,9 @@ class NinjaParserTests: XCTestCase {
116194
)
117195
}
118196

119-
func testAttributes() throws {
120-
assertParse("""
197+
func testBindings() throws {
198+
assertParse(
199+
"""
121200
x = y
122201
123202
CONFIGURATION = Debug
@@ -175,12 +254,14 @@ class NinjaParserTests: XCTestCase {
175254

176255
func testEscape() throws {
177256
for newline in ["\n", "\r", "\r\n"] {
178-
assertParse("""
257+
assertParse(
258+
"""
179259
build foo.o$:: SWIFTC xyz$ foo$$.swift | baz$ bar.o
180260
FLAGS = -I /a$\(newline)\
181261
/b -wmo
182262
COMMAND = swiftc$$
183-
""", edges: [
263+
""",
264+
edges: [
184265
.init(
185266
ruleName: "SWIFTC",
186267
inputs: ["xyz foo$.swift"],

0 commit comments

Comments
 (0)