Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Matejkob committed Sep 18, 2023
1 parent d8a5f0b commit 79a5db9
Showing 1 changed file with 222 additions and 0 deletions.
222 changes: 222 additions & 0 deletions Tests/SwiftDiagnosticsTest/NewDiagnosticsFormatterTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2023 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
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

import SwiftDiagnostics
import XCTest
import SwiftSyntax
import SwiftSyntaxBuilder
import _SwiftSyntaxTestSupport
import SwiftParser

struct DiagnosticDescriptor {
let locationMarker: String
let id: MessageID
let message: String
let severity: DiagnosticSeverity
let highlight: [Syntax] // TODO: How to create an abstract model for this?
let noteDescriptors: [NoteDescriptor]
let fixIts: [FixIt] // TODO: How to create an abstract model for this?

init(
locationMarker: String,
id: MessageID,
message: String,
severity: DiagnosticSeverity = .error,
highlight: [Syntax] = [],
noteDescriptors: [NoteDescriptor] = [],
fixIts: [FixIt] = []
) {
self.locationMarker = locationMarker
self.id = id
self.message = message
self.severity = severity
self.highlight = highlight
self.noteDescriptors = noteDescriptors
self.fixIts = fixIts
}
}

struct NoteDescriptor {
let locationMarker: String
let id: MessageID
let message: String
}

func assertAnnotated(
markedSource: String,
withDiagnostics diagnosticDescriptors: [DiagnosticDescriptor],
matches expectedAnnotatedSource: String,
file: StaticString = #file,
line: UInt = #line
) {
let (markers, source) = extractMarkers(markedSource)
let tree = Parser.parse(source: source)

var diagnostics = [Diagnostic]()
for diagnosticDescriptor in diagnosticDescriptors {
guard let markerOffset = markers[diagnosticDescriptor.locationMarker] else {
XCTFail("Marker \(diagnosticDescriptor.locationMarker) not found in the marked source", file: file, line: line)
continue
}
let markerPosition = AbsolutePosition(utf8Offset: markerOffset)
guard let token = tree.token(at: markerPosition), let node = token.parent else {
XCTFail("Node not found at marker \(diagnosticDescriptor.locationMarker)", file: file, line: line)
continue
}

var notes = [Note]()
for noteDescriptor in diagnosticDescriptor.noteDescriptors {
guard let markerOffset = markers[noteDescriptor.locationMarker] else {
XCTFail("Marker \(noteDescriptor.locationMarker) not found in the marked source", file: file, line: line)
continue
}
let markerPosition = AbsolutePosition(utf8Offset: markerOffset)
guard let token = tree.token(at: markerPosition), let node = token.parent else {
XCTFail("Node not found at marker \(noteDescriptor.locationMarker)", file: file, line: line)
continue
}

let note = Note(
node: node,
message: SimpleNoteMessage(message: noteDescriptor.message, fixItID: noteDescriptor.id)
)
notes.append(note)
}

let diagnostic = Diagnostic(
node: node,
message: SimpleDiagnosticMessage(
message: diagnosticDescriptor.message,
diagnosticID: diagnosticDescriptor.id,
severity: diagnosticDescriptor.severity
),
highlights: diagnosticDescriptor.highlight,
notes: notes,
fixIts: diagnosticDescriptor.fixIts
)
diagnostics.append(diagnostic)
}

let annotatedSource = DiagnosticsFormatter.annotatedSource(tree: tree, diags: diagnostics)

assertStringsEqualWithDiff(
annotatedSource,
expectedAnnotatedSource,
file: file,
line: line
)
}

final class DiagnosticsFormatterTests: XCTestCase {
func test_1() {
assertAnnotated(
markedSource: """
func foo() -> Int {
if 1️⃣1 != 0 {
return 0
}
return 1
}
""",
withDiagnostics: [
DiagnosticDescriptor(
locationMarker: "1️⃣",
id: .test,
message: "My message goes here!",
severity: .warning
),
],
matches: """
1 │ func foo() -> Int {
2 │ if 1 != 0 {
│ ╰─ warning: My message goes here!
3 │ return 0
4 │ }
"""
)
}

func test_2() {
assertAnnotated(
markedSource: """
func foo() -> Int {
if 1️⃣1 != 0 2️⃣{
return 0
}
return 1
}
""",
withDiagnostics: [
DiagnosticDescriptor(
locationMarker: "1️⃣",
id: .test,
message: "My message goes here!",
noteDescriptors: [
NoteDescriptor(locationMarker: "1️⃣", id: .test, message: "First message"),
NoteDescriptor(locationMarker: "1️⃣", id: .test, message: "Second message"),
NoteDescriptor(locationMarker: "2️⃣", id: .test, message: "Other message")
]
),
],
matches: """
1 │ func foo() -> Int {
2 │ if 1 != 0 {
│ │ ╰─ note: Other message
│ ├─ error: My message goes here!
│ ├─ note: First message
│ ╰─ note: Second message
3 │ return 0
4 │ }
"""
)
}

func test_3() {
assertAnnotated(
markedSource: """
func 2️⃣foo() -> Int {
if 1️⃣1 != 0 {
return 0
}
return 1
}
""",
withDiagnostics: [
DiagnosticDescriptor(
locationMarker: "1️⃣",
id: .test,
message: "My message goes here!",
noteDescriptors: [
NoteDescriptor(locationMarker: "1️⃣", id: .test, message: "First message"),
NoteDescriptor(locationMarker: "2️⃣", id: .test, message: "Second message"),
]
),
],
matches: """
1 │ func foo() -> Int {
| ╰─ note: Second message // This note comes from from diagnostic, how to present it?
2 │ if 1 != 0 {
│ ├─ error: My message goes here!
│ ╰─ note: First message
3 │ return 0
4 │ }
"""
)
}
}

fileprivate extension MessageID {
static let test = Self(domain: "test", id: "conjured")
}

0 comments on commit 79a5db9

Please sign in to comment.