From 32f5cab2dc0912f5039a07e0877c16fc9d548ece Mon Sep 17 00:00:00 2001
From: meatball <69751659+meatball133@users.noreply.github.com>
Date: Fri, 18 Aug 2023 20:39:38 +0000
Subject: [PATCH] Fixes and updates
---
changelog.md | 5 +
src/testrunner/Package.swift | 30 +-
src/testrunner/Sources/TestRunner/main.swift | 531 ++++++++++---------
3 files changed, 303 insertions(+), 263 deletions(-)
diff --git a/changelog.md b/changelog.md
index 8e985f4..001816e 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,8 @@
+# 1.1.3
+
+- Fixed an issue making so outputs on multiple lines missed the last line
+- Formatted all files using the formatter
+
# 1.1.2
- Updated test files to follow a more modern design.
diff --git a/src/testrunner/Package.swift b/src/testrunner/Package.swift
index a221679..f0df711 100644
--- a/src/testrunner/Package.swift
+++ b/src/testrunner/Package.swift
@@ -4,18 +4,20 @@
import PackageDescription
let package = Package(
- name: "TestRunner",
- dependencies: [
- // Dependencies declare other packages that this package depends on.
- // .package(url: /* package url */, from: "1.0.0"),
- .package(url: "https://github.com/apple/swift-syntax.git", exact: "508.0.1")
- ],
- targets: [
- // Targets are the basic building blocks of a package. A target can define a module or a test suite.
- // Targets can depend on other targets in this package, and on products in packages which this package depends on.
- .target(name: "TestRunner", dependencies: [
- .product(name: "SwiftSyntax", package: "swift-syntax"),
- .product(name: "SwiftParser", package: "swift-syntax"),
- ]),
- ]
+ name: "TestRunner",
+ dependencies: [
+ // Dependencies declare other packages that this package depends on.
+ // .package(url: /* package url */, from: "1.0.0"),
+ .package(url: "https://github.com/apple/swift-syntax.git", exact: "508.0.1")
+ ],
+ targets: [
+ // Targets are the basic building blocks of a package. A target can define a module or a test suite.
+ // Targets can depend on other targets in this package, and on products in packages which this package depends on.
+ .target(
+ name: "TestRunner",
+ dependencies: [
+ .product(name: "SwiftSyntax", package: "swift-syntax"),
+ .product(name: "SwiftParser", package: "swift-syntax"),
+ ])
+ ]
)
diff --git a/src/testrunner/Sources/TestRunner/main.swift b/src/testrunner/Sources/TestRunner/main.swift
index 413a3c6..4941a1a 100644
--- a/src/testrunner/Sources/TestRunner/main.swift
+++ b/src/testrunner/Sources/TestRunner/main.swift
@@ -1,95 +1,99 @@
-import SwiftParser
import Foundation
-import SwiftSyntax
import FoundationXML
+import SwiftParser
+import SwiftSyntax
-struct testFile: Codable {
- var version: Int = 3
- var status: String = "pass"
- var message: String? = nil
- var tests: [testCases] = []
+struct testFile: Codable {
+ var version: Int = 3
+ var status: String = "pass"
+ var message: String? = nil
+ var tests: [testCases] = []
}
struct testCases: Codable {
- var name: String = ""
- var test_code: String = ""
- var status: String? = nil
- var message: String? = nil
- var output: String? = nil
- var task_id: Int? = nil
+ var name: String = ""
+ var test_code: String = ""
+ var status: String? = nil
+ var message: String? = nil
+ var output: String? = nil
+ var task_id: Int? = nil
}
+class TestRunner {
+ var xmlTests: [testCases] = []
-class TestRunner{
- var xmlTests: [testCases] = []
-
- class getTestName: SyntaxVisitor {
- var tests: [testCases] = []
- var taskId = 0
- var inClass = 0
- let charactersToRemove = CharacterSet(charactersIn: "\n ")
-
- override func visit(_ node: FunctionDeclSyntax) -> SyntaxVisitorContinueKind {
- let bodyCheck = node.body
- if bodyCheck != nil{
- let name: String = String(describing: node.identifier)
- guard name.hasPrefix("test") else { return SyntaxVisitorContinueKind.visitChildren }
- var body: String = String(describing: bodyCheck!).trimmingCharacters(in: charactersToRemove)
- body = String(body[body.index(after: body.startIndex)..
1 {
- count = bodyList[1].prefix(while: { $0.isWhitespace }).count
- }
- for (rowIdx, row) in bodyList[1...].enumerated(){
- bodyList[rowIdx + 1] = String(row.dropFirst(count))
- }
- body = bodyList.joined(separator: "\n")
- tests.append(testCases(name: name, test_code: body, task_id: taskId == 0 ? nil : taskId))
- }
- return SyntaxVisitorContinueKind.visitChildren
- }
+ class getTestName: SyntaxVisitor {
+ var tests: [testCases] = []
+ var taskId = 0
+ var inClass = 0
+ let charactersToRemove = CharacterSet(charactersIn: "\n ")
- override func visit(_ node: ClassDeclSyntax) -> SyntaxVisitorContinueKind {
- if inClass == 0 && String(describing: node.identifier).hasPrefix("Task") {
- taskId += 1
- }
- inClass += 1
- return SyntaxVisitorContinueKind.visitChildren
+ override func visit(_ node: FunctionDeclSyntax) -> SyntaxVisitorContinueKind {
+ let bodyCheck = node.body
+ if bodyCheck != nil {
+ let name: String = String(describing: node.identifier)
+ guard name.hasPrefix("test") else { return SyntaxVisitorContinueKind.visitChildren }
+ var body: String = String(describing: bodyCheck!).trimmingCharacters(in: charactersToRemove)
+ body = String(body[body.index(after: body.startIndex).. 1 {
+ count = bodyList[1].prefix(while: { $0.isWhitespace }).count
}
-
- override func visitPost(_ node: ClassDeclSyntax) {
- inClass -= 1
+ for (rowIdx, row) in bodyList[1...].enumerated() {
+ bodyList[rowIdx + 1] = String(row.dropFirst(count))
}
+ body = bodyList.joined(separator: "\n")
+ tests.append(testCases(name: name, test_code: body, task_id: taskId == 0 ? nil : taskId))
+ }
+ return SyntaxVisitorContinueKind.visitChildren
}
- class MyXMLParserDelegate: NSObject, XMLParserDelegate {
- var counter = 0
- var tests: [testCases] // Add a property for tests
+ override func visit(_ node: ClassDeclSyntax) -> SyntaxVisitorContinueKind {
+ if inClass == 0 && String(describing: node.identifier).hasPrefix("Task") {
+ taskId += 1
+ }
+ inClass += 1
+ return SyntaxVisitorContinueKind.visitChildren
+ }
- init(tests: [testCases]) {
- self.tests = tests
- }
- // Called when the parser encounters the start of an element
- func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName _: String?, attributes attributeDict: [String : String] = [:]) {
- if elementName == "failure"{
- tests[counter].status = "fail"
- }
- else{
- counter = tests.firstIndex(where: {$0.name == attributeDict["name"]}) ?? counter
- tests[counter].status = "pass"
- }
- }
+ override func visitPost(_ node: ClassDeclSyntax) {
+ inClass -= 1
}
+ }
+ class MyXMLParserDelegate: NSObject, XMLParserDelegate {
+ var counter = 0
+ var tests: [testCases] // Add a property for tests
+
+ init(tests: [testCases]) {
+ self.tests = tests
+ }
+ // Called when the parser encounters the start of an element
+ func parser(
+ _ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?,
+ qualifiedName _: String?, attributes attributeDict: [String: String] = [:]
+ ) {
+ if elementName == "failure" {
+ tests[counter].status = "fail"
+ } else {
+ counter = tests.firstIndex(where: { $0.name == attributeDict["name"] }) ?? counter
+ tests[counter].status = "pass"
+ }
+ }
+ }
- func run(filePath : String, xmlPath : String, contextPath : String, resultPath : String, slug : String){
+ func run(filePath: String, xmlPath: String, contextPath: String, resultPath: String, slug: String)
+ {
var swiftSource = ""
do {
- swiftSource = try NSString(contentsOfFile: filePath,
- encoding: String.Encoding.ascii.rawValue) as String
- }catch {
- print("Error filePath: \(error)")
+ swiftSource =
+ try NSString(
+ contentsOfFile: filePath,
+ encoding: String.Encoding.ascii.rawValue) as String
+ } catch {
+ print("Error filePath: \(error)")
}
let rootNode: SourceFileSyntax = try! Parser.parse(source: swiftSource)
var process = getTestName(viewMode: SyntaxTreeViewMode.all)
@@ -97,209 +101,238 @@ class TestRunner{
let tests = process.tests
var result = ""
do {
- result = try NSString(contentsOfFile: xmlPath,
- encoding: String.Encoding.ascii.rawValue) as String
- }catch {
- print("Error xmlPath: \(error)")
- writeJson(resultPath: resultPath, error: errorContext(context: contextPath, slug: slug))
- return
+ result =
+ try NSString(
+ contentsOfFile: xmlPath,
+ encoding: String.Encoding.ascii.rawValue) as String
+ } catch {
+ print("Error xmlPath: \(error)")
+ writeJson(resultPath: resultPath, error: errorContext(context: contextPath, slug: slug))
+ return
}
let xmlData = Data(result.utf8)
let xmlParser = XMLParser(data: xmlData)
- let delegate = MyXMLParserDelegate(tests: tests)
- xmlParser.delegate = delegate
+ let delegate = MyXMLParserDelegate(tests: tests)
+ xmlParser.delegate = delegate
xmlParser.parse()
xmlTests = delegate.tests
var context = ""
do {
- context = try NSString(contentsOfFile: contextPath,
- encoding: String.Encoding.ascii.rawValue) as String
- }catch {
- print("Error contextPath: \(error)")
- }
+ context =
+ try NSString(
+ contentsOfFile: contextPath,
+ encoding: String.Encoding.ascii.rawValue) as String
+ } catch {
+ print("Error contextPath: \(error)")
+ }
addContext(context: context, slug: slug)
writeJson(resultPath: resultPath)
- }
+ }
- func addContext(context: String, slug: String) {
- for (testIdx, testCase) in xmlTests.enumerated(){
- var error = false
- if testCase.status == "fail"{
- let contextLines = context.components(separatedBy: "\n")[1...]
- var found = false
- var start = ""
- var current = 0
- for (rowIdx, row) in contextLines.enumerated(){
- if found {
- if let endRange = row.range(of: "Test Case "){
- let middle = contextLines[current.. 0{
- if row.contains(testCase.name) && row[startIndex] != "[" {
- current = testCase.name
- if let startRange = row.range(of: "started at", options: .backwards) {
- if let newStartRange = row.range(of: ".", options: [], range: (startRange.upperBound.. 0{
- if start == 0 && row.contains(testCase.name + "'") && row[startIndex] != "[" && !row.contains("error"){
- if let startRange = row.range(of: "started at", options: .backwards) {
- if let newStartRange = row.range(of: ".", options: [], range: (startRange.upperBound.. 0 {
+ if row.contains(testCase.name) && row[startIndex] != "[" {
+ current = testCase.name
+ if let startRange = row.range(of: "started at", options: .backwards) {
+ if let newStartRange = row.range(
+ of: ".", options: [], range: (startRange.upperBound.. String{
- var something = ""
- do {
- // Use contentsOfFile overload.
- // ... Specify ASCII encoding.
- // ... Ignore errors.
- something = try NSString(contentsOfFile: context,
- encoding: String.Encoding.ascii.rawValue) as String
-
- // If a value was returned, print it.
- }catch {
- print("Error context_path: \(error)")
- }
- let message = something.components(separatedBy: "\n")[1...]
+ }
+ if !error {
+ let contextLinesOutput = context.components(separatedBy: "\n")[1...]
var start = 0
- for (rowIdx, row) in message.enumerated(){
- if row.contains("CompileError.swift:") || row.contains("\(camelCase(slug: slug))Tests.swift:") || row.contains("\(camelCase(slug: slug)).swift:") {
- start = rowIdx + 1
- break
+ var startString = ""
+ for (rowIdx, row) in contextLinesOutput.enumerated() {
+ let startIndex = row.index(row.startIndex, offsetBy: 0)
+ if row.count > 0 {
+ if start == 0 && row.contains(testCase.name + "'") && row[startIndex] != "["
+ && !row.contains("error")
+ {
+ if let startRange = row.range(of: "started at", options: .backwards) {
+ if let newStartRange = row.range(
+ of: ".", options: [], range: (startRange.upperBound.. String {
+ var something = ""
+ do {
+ // Use contentsOfFile overload.
+ // ... Specify ASCII encoding.
+ // ... Ignore errors.
+ something =
+ try NSString(
+ contentsOfFile: context,
+ encoding: String.Encoding.ascii.rawValue) as String
+
+ // If a value was returned, print it.
+ } catch {
+ print("Error context_path: \(error)")
+ }
+ let message = something.components(separatedBy: "\n")[1...]
+ var start = 0
+ for (rowIdx, row) in message.enumerated() {
+ if row.contains("CompileError.swift:") || row.contains("\(camelCase(slug: slug))Tests.swift:")
+ || row.contains("\(camelCase(slug: slug)).swift:")
+ {
+ start = rowIdx + 1
+ break
+ }
}
+ if start != 0 {
+ return message[start...].joined(separator: "\n")
+ }
+ return message.joined(separator: "\n")
+ }
- private func camelCase(slug: String) -> String{
- let words = slug.components(separatedBy: "-")
- var camelCase = ""
- for word in words{
- if word != ""{
- camelCase += word.prefix(1).uppercased() + word.dropFirst()
- }
- }
- return camelCase
+ func writeJson(resultPath: String, error: String = "") {
+ let encoder = JSONEncoder()
+ encoder.outputFormatting.update(with: .prettyPrinted)
+ encoder.outputFormatting.update(with: .sortedKeys)
+ var json: testFile
+ if xmlTests.contains { $0.status == "fail" } {
+ json = testFile(status: "fail", tests: xmlTests)
+ } else if error != "" {
+ json = testFile(status: "error", message: error)
+ } else {
+ json = testFile(tests: xmlTests)
+ }
+ var data: Data
+ do {
+ data = try encoder.encode(json)
+ } catch {
+ print("Error can't encode json: \(error)")
+ return
+ }
+ let dataJson = String(data: data, encoding: .utf8)!
+ do {
+ try dataJson.write(toFile: resultPath, atomically: true, encoding: String.Encoding.utf8)
+ } catch {
+ print("Error resultPath: \(error)")
+ return
+ }
+ }
+
+ private func camelCase(slug: String) -> String {
+ let words = slug.components(separatedBy: "-")
+ var camelCase = ""
+ for word in words {
+ if word != "" {
+ camelCase += word.prefix(1).uppercased() + word.dropFirst()
+ }
}
+ return camelCase
+ }
}
-TestRunner().run(filePath: CommandLine.arguments[1], xmlPath: CommandLine.arguments[2], contextPath: CommandLine.arguments[3], resultPath: CommandLine.arguments[4], slug : CommandLine.arguments[5])
+TestRunner().run(
+ filePath: CommandLine.arguments[1], xmlPath: CommandLine.arguments[2],
+ contextPath: CommandLine.arguments[3], resultPath: CommandLine.arguments[4],
+ slug: CommandLine.arguments[5])