Skip to content

Commit 4e8e791

Browse files
committed
Cleanup and rewrite the README
1 parent ab48c8e commit 4e8e791

File tree

7 files changed

+167
-103
lines changed

7 files changed

+167
-103
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ matrix:
88
osx_image: xcode8.2
99
script:
1010
- swift test
11-
- os: linux
11+
- os: linux
1212
language: generic
1313
sudo: required
1414
dist: trusty

README.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,67 @@
11
# FileCheck
2+
[![Build Status](https://travis-ci.org/trill-lang/FileCheck.svg?branch=master)](https://travis-ci.org/trill-lang/FileCheck)
3+
24
A standalone Swift version of LLVM's flexible pattern matching file verifier
5+
6+
## Introduction
7+
8+
FileCheck is a utility for verifying the contents of two files match (for example,
9+
one from standard input, and one residing on disk). This implementation of
10+
FileCheck emphasizes its use as a tool for checking output generated by programs
11+
against an expected set of strings that can be specified inline next to the
12+
`print` statement that generated it.
13+
14+
The primary API in this package is the `fileCheckOutput` function, which comes
15+
with a number of convenient optional parameters to modify the behavior of the
16+
verification process. For example, here is a self-contained test that verifies
17+
the output of FizzBuzz:
18+
19+
```swift
20+
assert(fileCheckOutput(withPrefixes: ["FIZZBUZZ"]) {
21+
for i in (1..<10) {
22+
var out = ""
23+
if i % 3 == 0 {
24+
out += "Fizz"
25+
}
26+
if i % 5 == 0 {
27+
out += "Buzz"
28+
}
29+
if out.isEmpty {
30+
out += "\(i)"
31+
}
32+
// FIZZBUZZ: 1
33+
// FIZZBUZZ-NEXT: 2
34+
// FIZZBUZZ-NEXT: Fizz
35+
// FIZZBUZZ-NEXT: 4
36+
// FIZZBUZZ-NEXT: Buzz
37+
// FIZZBUZZ-NEXT: Fizz
38+
// FIZZBUZZ-NEXT: 7
39+
// FIZZBUZZ-NEXT: 8
40+
// FIZZBUZZ-NEXT: Fizz
41+
print(out)
42+
}
43+
})
44+
```
45+
46+
Executing this test in any file will cause FileCheck to read it in
47+
from disk and verify the output of the program against the check-strings in the
48+
comments.
49+
50+
## Setup
51+
52+
**Using The Swift Package Manager**
53+
54+
- Add FileCheck to your `Package.swift` file's dependencies section:
55+
56+
```swift
57+
.Package(url: "https://github.com/trill-lang/FileCheck.git", versions: Version(0,0,1)..<Version(1,0,0))
58+
```
59+
60+
## Authors
61+
62+
- Harlan Haskins ([@harlanhaskins](https://github.com/harlanhaskins))
63+
- Robert Widmann ([@CodaFi](https://github.com/CodaFi))
64+
65+
## License
66+
67+
This project is released under the MIT license, a copy of which is available in this repo.

Sources/FileCheck/ANSIColor.swift

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

Sources/FileCheck/ColoredStream.swift

Lines changed: 95 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -2,78 +2,117 @@ import Foundation
22

33
/// Represents a stream that can write text with a specific set of ANSI colors
44
protocol ColoredStream: TextOutputStream {
5-
mutating func write(_ string: String, with: [ANSIColor])
5+
mutating func write(_ string: String, with: [ANSIColor])
66
}
77

88
extension ColoredStream {
9-
/// Default conformance to TextOutputStream
10-
mutating func write(_ string: String) {
11-
write(string, with: [])
12-
}
9+
/// Default conformance to TextOutputStream
10+
mutating func write(_ string: String) {
11+
write(string, with: [])
12+
}
1313
}
1414

1515
/// An output stream that prints to an underlying stream including ANSI color
1616
/// codes.
1717
class ColoredANSIStream<StreamTy: TextOutputStream>: ColoredStream {
1818

19-
typealias StreamType = StreamTy
19+
typealias StreamType = StreamTy
2020

21-
var currentColors = [ANSIColor]()
22-
var stream: StreamType
23-
let colored: Bool
21+
var currentColors = [ANSIColor]()
22+
var stream: StreamType
23+
let colored: Bool
2424

25-
/// Creates a new ColoredANSIStream that prints to an underlying stream.
26-
///
27-
/// - Parameters:
28-
/// - stream: The underlying stream
29-
/// - colored: Whether to provide any colors or to pass text through
30-
/// unmodified. Set this to false and ColoredANSIStream is
31-
/// a transparent wrapper.
32-
init(_ stream: inout StreamType, colored: Bool = true) {
33-
self.stream = stream
34-
self.colored = colored
35-
}
25+
/// Creates a new ColoredANSIStream that prints to an underlying stream.
26+
///
27+
/// - Parameters:
28+
/// - stream: The underlying stream
29+
/// - colored: Whether to provide any colors or to pass text through
30+
/// unmodified. Set this to false and ColoredANSIStream is
31+
/// a transparent wrapper.
32+
init(_ stream: inout StreamType, colored: Bool = true) {
33+
self.stream = stream
34+
self.colored = colored
35+
}
3636

37-
/// Initializes with a stream, always colored.
38-
///
39-
/// - Parameter stream: The underlying stream receiving writes.
40-
required init(_ stream: inout StreamType) {
41-
self.stream = stream
42-
self.colored = true
43-
}
37+
/// Initializes with a stream, always colored.
38+
///
39+
/// - Parameter stream: The underlying stream receiving writes.
40+
required init(_ stream: inout StreamType) {
41+
self.stream = stream
42+
self.colored = true
43+
}
4444

45-
/// Adds a color to the in-progress colors.
46-
func addColor(_ color: ANSIColor) {
47-
guard colored else { return }
48-
stream.write(color.rawValue)
49-
currentColors.append(color)
50-
}
45+
/// Adds a color to the in-progress colors.
46+
func addColor(_ color: ANSIColor) {
47+
guard colored else { return }
48+
stream.write(color.rawValue)
49+
currentColors.append(color)
50+
}
5151

52-
/// Resets this stream back to the default color.
53-
func reset() {
54-
if currentColors.isEmpty { return }
55-
stream.write(ANSIColor.reset.rawValue)
56-
currentColors = []
57-
}
52+
/// Resets this stream back to the default color.
53+
func reset() {
54+
if currentColors.isEmpty { return }
55+
stream.write(ANSIColor.reset.rawValue)
56+
currentColors = []
57+
}
5858

59-
/// Sets the current ANSI color codes to the passed-in colors.
60-
func setColors(_ colors: [ANSIColor]) {
61-
guard colored else { return }
62-
reset()
63-
for color in colors {
64-
stream.write(color.rawValue)
65-
}
66-
currentColors = colors
59+
/// Sets the current ANSI color codes to the passed-in colors.
60+
func setColors(_ colors: [ANSIColor]) {
61+
guard colored else { return }
62+
reset()
63+
for color in colors {
64+
stream.write(color.rawValue)
6765
}
66+
currentColors = colors
67+
}
6868

69-
/// Writes the string to the output with the provided colors.
70-
///
71-
/// - Parameters:
72-
/// - string: The string to write
73-
/// - colors: The colors used on the string
74-
func write(_ string: String, with colors: [ANSIColor]) {
75-
self.setColors(colors)
76-
stream.write(string)
77-
self.reset()
69+
/// Writes the string to the output with the provided colors.
70+
///
71+
/// - Parameters:
72+
/// - string: The string to write
73+
/// - colors: The colors used on the string
74+
func write(_ string: String, with colors: [ANSIColor]) {
75+
self.setColors(colors)
76+
stream.write(string)
77+
self.reset()
78+
}
79+
}
80+
81+
/// Represents the possible ANSI color codes.
82+
enum ANSIColor: String {
83+
case black = "\u{001B}[30m"
84+
case red = "\u{001B}[31m"
85+
case green = "\u{001B}[32m"
86+
case yellow = "\u{001B}[33m"
87+
case blue = "\u{001B}[34m"
88+
case magenta = "\u{001B}[35m"
89+
case cyan = "\u{001B}[36m"
90+
case white = "\u{001B}[37m"
91+
case bold = "\u{001B}[1m"
92+
case reset = "\u{001B}[0m"
93+
94+
func name() -> String {
95+
switch self {
96+
case .black: return "Black"
97+
case .red: return "Red"
98+
case .green: return "Green"
99+
case .yellow: return "Yellow"
100+
case .blue: return "Blue"
101+
case .magenta: return "Magenta"
102+
case .cyan: return "Cyan"
103+
case .white: return "White"
104+
case .bold: return "Bold"
105+
case .reset: return "Reset"
78106
}
107+
}
108+
109+
static func all() -> [ANSIColor] {
110+
return [.black, .red, .green,
111+
.yellow, .blue, .magenta,
112+
.cyan, .white, .bold, .reset]
113+
}
114+
}
115+
116+
func + (left: ANSIColor, right: String) -> String {
117+
return left.rawValue + right
79118
}

Sources/FileCheck/Diagnostics.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ func diagnose(_ kind : DiagnosticKind, at loc : CheckLoc, with message : String,
2727
}
2828
}
2929

30-
3130
enum DiagnosticKind: String {
3231
case error
3332
case warning

Sources/FileCheck/FileCheck.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ private func findCheckType(in buf : UnsafeBufferPointer<CChar>, with prefix : St
214214
length: buf.count - (prefix.utf8.count + 1),
215215
encoding: .utf8,
216216
freeWhenDone: false
217-
)!
217+
)!
218218
if rest.hasPrefix("NEXT:") {
219219
return .next
220220
}
@@ -243,7 +243,8 @@ private func findCheckType(in buf : UnsafeBufferPointer<CChar>, with prefix : St
243243
"NOT-NEXT:",
244244
"SAME-NOT:",
245245
"NOT-SAME:",
246-
]
246+
]
247+
247248
if badNotPrefixes.reduce(false, { (acc, s) in acc || rest.hasPrefix(s) }) {
248249
return .badNot
249250
}
@@ -493,12 +494,12 @@ private func check(input b : String, against checkStrings : [CheckString], optio
493494

494495
checkRegion = checkRegion.substring(from: checkRegion.index(checkRegion.startIndex, offsetBy: NSMaxRange(range)))
495496
}
496-
497+
497498
if j == checkStrings.count {
498499
break
499500
}
500501
}
501-
502+
502503
// Success if no checks failed.
503504
return !failedChecks
504505
}

Tests/LinuxMain.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import XCTest
22

3-
@testable import LLVMTests
3+
@testable import FileCheckTests
44

55
#if !os(macOS)
66
XCTMain([

0 commit comments

Comments
 (0)