This repository has been archived by the owner on Sep 16, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Revise expectation syntax, fix regular expression bug, refactor imple…
…mentation (#30) * Remove LinuxMain * Update expectations to type, value, match, and error * Refactor scanning logic into Scanner type * Fix Scanner regular expression pattern Add test for Scanner * Internalize inessential APIs * Extract tests into separate files * Add changelog entries for #30 * Update README * Add CI badge to README * Feed source file into REPL when not running in package context * Log notice for blocks without any import statements when running through SPM
- Loading branch information
Showing
14 changed files
with
214 additions
and
77 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,42 @@ | ||
import Foundation | ||
|
||
public enum Expectation: Hashable { | ||
case value(String) | ||
case error | ||
case type(String) | ||
case value(String) | ||
case match(String) | ||
|
||
public init?(_ string: String?) { | ||
guard let string = string?.trimmingCharacters(in: .whitespacesAndNewlines) else { return nil } | ||
if string.starts(with: "=>"), | ||
let index = string.firstIndex(where: { $0.isWhitespace }) | ||
{ | ||
self = .value(string.suffix(from: index).trimmingCharacters(in: .whitespaces)) | ||
} else if string.starts(with: "!!") { | ||
guard let string = string?.trimmed, | ||
let index = string.index(string.startIndex, offsetBy: 2, limitedBy: string.endIndex) | ||
else { return nil } | ||
|
||
switch string.prefix(upTo: index) { | ||
case "!!": | ||
self = .error | ||
} else { | ||
case "->": | ||
self = .type(string.suffix(from: index).trimmed) | ||
case "=>": | ||
self = .value(string.suffix(from: index).trimmed) | ||
case "~>": | ||
self = .match(string.suffix(from: index).trimmed) | ||
default: | ||
return nil | ||
} | ||
} | ||
|
||
public func evaluate(_ output: String) -> Bool { | ||
let output = output.trimmed | ||
|
||
switch self { | ||
case .error: | ||
return output.hasPrefix("error:") | ||
case .type(let type): | ||
return output.hasPrefix("\(type) =") | ||
case .value(let value): | ||
return output.hasSuffix("= \(value)") | ||
case .match(let pattern): | ||
return output.range(of: pattern, options: .regularExpression) != nil | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import Foundation | ||
|
||
extension StringProtocol { | ||
var trimmed: String { | ||
trimmingCharacters(in: .whitespacesAndNewlines) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import Foundation | ||
import StringLocationConverter | ||
|
||
public class Scanner { | ||
public typealias Match = (line: Int, column: Int, content: String) | ||
|
||
private var regularExpression: NSRegularExpression | ||
|
||
public init() throws { | ||
let pattern = #""" | ||
^ | ||
\h* \`{3} \h* swift \h+ doctest \h* \n | ||
(.+)\n | ||
\h* \`{3} \h* | ||
$ | ||
"""# | ||
self.regularExpression = try NSRegularExpression(pattern: pattern, | ||
options: [ | ||
.allowCommentsAndWhitespace, | ||
.anchorsMatchLines, | ||
.caseInsensitive, | ||
.dotMatchesLineSeparators | ||
]) | ||
} | ||
|
||
public func matches(in source: String) -> [Match] { | ||
let range = NSRange(source.startIndex..<source.endIndex, in: source) | ||
return regularExpression.matches(in: source, options: [], range: range).compactMap { result in | ||
guard result.numberOfRanges == 2, | ||
let range = Range(result.range(at: 1), in: source) | ||
else { return nil } | ||
let content = source[range] | ||
|
||
let converter = StringLocationConverter(for: source) | ||
|
||
let line: Int, column: Int | ||
if let location = converter.location(for: range.lowerBound, in: source) { | ||
line = location.line | ||
column = location.column | ||
} else { | ||
line = 0 | ||
column = range.lowerBound.utf16Offset(in: source) | ||
} | ||
|
||
return (line, column, content.trimmed) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.