mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Merge pull request #84482 from eeckstein/smallprojectionpath-tests
SIL: use `Test` for the SmallProjectionPath's unit tests
This commit is contained in:
@@ -680,308 +680,307 @@ extension StringParser {
|
||||
// Unit Tests
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
extension SmallProjectionPath {
|
||||
public static func runUnitTests() {
|
||||
|
||||
basicPushPop()
|
||||
parsing()
|
||||
merging()
|
||||
subtracting()
|
||||
matching()
|
||||
overlapping()
|
||||
predicates()
|
||||
path2path()
|
||||
indexedElements()
|
||||
let smallProjectionPathTest = Test("small_projection_path") {
|
||||
function, arguments, context in
|
||||
|
||||
func basicPushPop() {
|
||||
let p1 = SmallProjectionPath(.structField, index: 3)
|
||||
.push(.classField, index: 12345678)
|
||||
let (k2, i2, p2) = p1.pop()
|
||||
assert(k2 == .classField && i2 == 12345678)
|
||||
let (k3, i3, p3) = p2.pop()
|
||||
assert(k3 == .structField && i3 == 3)
|
||||
assert(p3.isEmpty)
|
||||
let (k4, i4, _) = p2.push(.enumCase, index: 876).pop()
|
||||
assert(k4 == .enumCase && i4 == 876)
|
||||
let p5 = SmallProjectionPath(.anything)
|
||||
assert(p5.pop().path.isEmpty)
|
||||
let p6 = SmallProjectionPath(.indexedElement, index: 1).push(.indexedElement, index: 2)
|
||||
let (k6, i6, p7) = p6.pop()
|
||||
assert(k6 == .indexedElement && i6 == 3 && p7.isEmpty)
|
||||
let p8 = SmallProjectionPath(.indexedElement, index: 0)
|
||||
assert(p8.isEmpty)
|
||||
let p9 = SmallProjectionPath(.indexedElement, index: 1).push(.anyIndexedElement)
|
||||
let (k9, i9, p10) = p9.pop()
|
||||
assert(k9 == .anyIndexedElement && i9 == 0 && p10.isEmpty)
|
||||
let p11 = SmallProjectionPath(.anyIndexedElement).push(.indexedElement, index: 1)
|
||||
let (k11, i11, p12) = p11.pop()
|
||||
assert(k11 == .anyIndexedElement && i11 == 0 && p12.isEmpty)
|
||||
basicPushPop()
|
||||
parsing()
|
||||
merging()
|
||||
subtracting()
|
||||
matching()
|
||||
overlapping()
|
||||
predicates()
|
||||
path2path()
|
||||
indexedElements()
|
||||
|
||||
func basicPushPop() {
|
||||
let p1 = SmallProjectionPath(.structField, index: 3)
|
||||
.push(.classField, index: 12345678)
|
||||
let (k2, i2, p2) = p1.pop()
|
||||
assert(k2 == .classField && i2 == 12345678)
|
||||
let (k3, i3, p3) = p2.pop()
|
||||
assert(k3 == .structField && i3 == 3)
|
||||
assert(p3.isEmpty)
|
||||
let (k4, i4, _) = p2.push(.enumCase, index: 876).pop()
|
||||
assert(k4 == .enumCase && i4 == 876)
|
||||
let p5 = SmallProjectionPath(.anything)
|
||||
assert(p5.pop().path.isEmpty)
|
||||
let p6 = SmallProjectionPath(.indexedElement, index: 1).push(.indexedElement, index: 2)
|
||||
let (k6, i6, p7) = p6.pop()
|
||||
assert(k6 == .indexedElement && i6 == 3 && p7.isEmpty)
|
||||
let p8 = SmallProjectionPath(.indexedElement, index: 0)
|
||||
assert(p8.isEmpty)
|
||||
let p9 = SmallProjectionPath(.indexedElement, index: 1).push(.anyIndexedElement)
|
||||
let (k9, i9, p10) = p9.pop()
|
||||
assert(k9 == .anyIndexedElement && i9 == 0 && p10.isEmpty)
|
||||
let p11 = SmallProjectionPath(.anyIndexedElement).push(.indexedElement, index: 1)
|
||||
let (k11, i11, p12) = p11.pop()
|
||||
assert(k11 == .anyIndexedElement && i11 == 0 && p12.isEmpty)
|
||||
}
|
||||
|
||||
func parsing() {
|
||||
testParse("v**.c*", expect: SmallProjectionPath(.anyClassField)
|
||||
.push(.anyValueFields))
|
||||
testParse("s3.c*.v**.s1", expect: SmallProjectionPath(.structField, index: 1)
|
||||
.push(.anyValueFields)
|
||||
.push(.anyClassField)
|
||||
.push(.structField, index: 3))
|
||||
testParse("2.c*.e6.ct.**", expect: SmallProjectionPath(.anything)
|
||||
.push(.tailElements)
|
||||
.push(.enumCase, index: 6)
|
||||
.push(.anyClassField)
|
||||
.push(.tupleField, index: 2))
|
||||
testParse("i3.x.b.i*", expect: SmallProjectionPath(.anyIndexedElement)
|
||||
.push(.vectorBase)
|
||||
.push(.existential)
|
||||
.push(.indexedElement, index: 3))
|
||||
|
||||
do {
|
||||
var parser = StringParser("c*.s123.s3.s123.s3.s123.s3.s123.s3.s123.s3.s123.s3.s123.s3.s123.s3.s123.s3.s123.s3.s123.s3.s123.s3.s123.s3.**")
|
||||
_ = try parser.parseProjectionPathFromSIL()
|
||||
fatalError("too long path not detected")
|
||||
} catch {
|
||||
}
|
||||
|
||||
func parsing() {
|
||||
testParse("v**.c*", expect: SmallProjectionPath(.anyClassField)
|
||||
.push(.anyValueFields))
|
||||
testParse("s3.c*.v**.s1", expect: SmallProjectionPath(.structField, index: 1)
|
||||
.push(.anyValueFields)
|
||||
.push(.anyClassField)
|
||||
.push(.structField, index: 3))
|
||||
testParse("2.c*.e6.ct.**", expect: SmallProjectionPath(.anything)
|
||||
.push(.tailElements)
|
||||
.push(.enumCase, index: 6)
|
||||
.push(.anyClassField)
|
||||
.push(.tupleField, index: 2))
|
||||
testParse("i3.x.b.i*", expect: SmallProjectionPath(.anyIndexedElement)
|
||||
.push(.vectorBase)
|
||||
.push(.existential)
|
||||
.push(.indexedElement, index: 3))
|
||||
|
||||
do {
|
||||
var parser = StringParser("c*.s123.s3.s123.s3.s123.s3.s123.s3.s123.s3.s123.s3.s123.s3.s123.s3.s123.s3.s123.s3.s123.s3.s123.s3.s123.s3.**")
|
||||
_ = try parser.parseProjectionPathFromSIL()
|
||||
fatalError("too long path not detected")
|
||||
} catch {
|
||||
}
|
||||
do {
|
||||
var parser = StringParser("**.s0")
|
||||
_ = try parser.parseProjectionPathFromSIL()
|
||||
fatalError("wrong '**' not detected")
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
|
||||
func testParse(_ pathStr: String, expect: SmallProjectionPath) {
|
||||
var parser = StringParser(pathStr)
|
||||
let path = try! parser.parseProjectionPathFromSIL()
|
||||
assert(path == expect)
|
||||
let str = path.description
|
||||
assert(str == pathStr)
|
||||
}
|
||||
|
||||
func merging() {
|
||||
testMerge("c1.c0", "c0", expect: "c*.**")
|
||||
testMerge("c2.c1", "c2", expect: "c2.**")
|
||||
testMerge("s3.c0", "v**.c0", expect: "v**.c0")
|
||||
testMerge("c0", "s2.c1", expect: "v**.c*")
|
||||
testMerge("s1.s1.c2", "s1.c2", expect: "s1.v**.c2")
|
||||
testMerge("s1.s0", "s2.s0", expect: "v**")
|
||||
testMerge("ct", "c2", expect: "c*")
|
||||
testMerge("i1", "i2", expect: "i*")
|
||||
testMerge("i*", "i2", expect: "i*")
|
||||
testMerge("s0.i*.e3", "s0.e3", expect: "s0.i*.e3")
|
||||
testMerge("i*", "v**", expect: "v**")
|
||||
testMerge("s0.b.i1", "s0.b.i0", expect: "s0.b.i*")
|
||||
testMerge("s0.b", "s0.1", expect: "s0.v**")
|
||||
|
||||
testMerge("ct.s0.e0.v**.c0", "ct.s0.e0.v**.c0", expect: "ct.s0.e0.v**.c0")
|
||||
testMerge("ct.s0.s0.c0", "ct.s0.e0.s0.c0", expect: "ct.s0.v**.c0")
|
||||
}
|
||||
|
||||
func testMerge(_ lhsStr: String, _ rhsStr: String,
|
||||
expect expectStr: String) {
|
||||
var lhsParser = StringParser(lhsStr)
|
||||
let lhs = try! lhsParser.parseProjectionPathFromSIL()
|
||||
var rhsParser = StringParser(rhsStr)
|
||||
let rhs = try! rhsParser.parseProjectionPathFromSIL()
|
||||
var expectParser = StringParser(expectStr)
|
||||
let expect = try! expectParser.parseProjectionPathFromSIL()
|
||||
|
||||
let result = lhs.merge(with: rhs)
|
||||
assert(result == expect)
|
||||
let result2 = rhs.merge(with: lhs)
|
||||
assert(result2 == expect)
|
||||
}
|
||||
|
||||
func subtracting() {
|
||||
testSubtract("s0", "s0.s1", expect: "s1")
|
||||
testSubtract("s0", "s1", expect: nil)
|
||||
testSubtract("s0.s1", "s0.s1", expect: "")
|
||||
testSubtract("i*.s1", "i*.s1", expect: nil)
|
||||
testSubtract("ct.s1.0.i3.x", "ct.s1.0.i3.x", expect: "")
|
||||
testSubtract("c0.s1.0.i3", "c0.s1.0.i3.x", expect: "x")
|
||||
testSubtract("s1.0.i3.x", "s1.0.i3", expect: nil)
|
||||
testSubtract("v**.s1", "v**.s1", expect: nil)
|
||||
testSubtract("i*", "i*", expect: nil)
|
||||
}
|
||||
|
||||
func testSubtract(_ lhsStr: String, _ rhsStr: String, expect expectStr: String?) {
|
||||
var lhsParser = StringParser(lhsStr)
|
||||
let lhs = try! lhsParser.parseProjectionPathFromSIL()
|
||||
var rhsParser = StringParser(rhsStr)
|
||||
let rhs = try! rhsParser.parseProjectionPathFromSIL()
|
||||
|
||||
let result = lhs.subtract(from: rhs)
|
||||
|
||||
if let expectStr = expectStr {
|
||||
var expectParser = StringParser(expectStr)
|
||||
let expect = try! expectParser.parseProjectionPathFromSIL()
|
||||
assert(result! == expect)
|
||||
} else {
|
||||
assert(result == nil)
|
||||
}
|
||||
}
|
||||
|
||||
func matching() {
|
||||
testMatch("ct", "c*", expect: true)
|
||||
testMatch("c1", "c*", expect: true)
|
||||
testMatch("s2", "v**", expect: true)
|
||||
testMatch("1", "v**", expect: true)
|
||||
testMatch("e1", "v**", expect: true)
|
||||
testMatch("c*", "c1", expect: false)
|
||||
testMatch("c*", "ct", expect: false)
|
||||
testMatch("v**", "s0", expect: false)
|
||||
testMatch("i1", "i1", expect: true)
|
||||
testMatch("i1", "i*", expect: true)
|
||||
testMatch("i*", "i1", expect: false)
|
||||
|
||||
testMatch("s0.s1", "s0.s1", expect: true)
|
||||
testMatch("s0.s2", "s0.s1", expect: false)
|
||||
testMatch("s0", "s0.v**", expect: true)
|
||||
testMatch("s0.s1", "s0.v**", expect: true)
|
||||
testMatch("s0.1.e2", "s0.v**", expect: true)
|
||||
testMatch("s0.v**.x.e2", "v**", expect: true)
|
||||
testMatch("s0.v**", "s0.s1", expect: false)
|
||||
testMatch("s0.s1.c*", "s0.v**", expect: false)
|
||||
testMatch("s0.v**", "s0.**", expect: true)
|
||||
testMatch("s1.v**", "s0.**", expect: false)
|
||||
testMatch("s0.**", "s0.v**", expect: false)
|
||||
testMatch("s0.s1", "s0.i*.s1", expect: true)
|
||||
testMatch("s0.b.s1", "s0.b.i*.s1", expect: true)
|
||||
}
|
||||
|
||||
func testMatch(_ lhsStr: String, _ rhsStr: String, expect: Bool) {
|
||||
var lhsParser = StringParser(lhsStr)
|
||||
let lhs = try! lhsParser.parseProjectionPathFromSIL()
|
||||
var rhsParser = StringParser(rhsStr)
|
||||
let rhs = try! rhsParser.parseProjectionPathFromSIL()
|
||||
let result = lhs.matches(pattern: rhs)
|
||||
assert(result == expect)
|
||||
}
|
||||
|
||||
func overlapping() {
|
||||
testOverlap("s0.s1.s2", "s0.s1.s2", expect: true)
|
||||
testOverlap("s0.s1.s2", "s0.s2.s2", expect: false)
|
||||
testOverlap("s0.s1.s2", "s0.e1.s2", expect: false)
|
||||
testOverlap("s0.s1.s2", "s0.s1", expect: true)
|
||||
testOverlap("s0.s1.s2", "s1.s2", expect: false)
|
||||
|
||||
testOverlap("s0.c*.s2", "s0.ct.s2", expect: true)
|
||||
testOverlap("s0.c*.s2", "s0.c1.s2", expect: true)
|
||||
testOverlap("s0.c*.s2", "s0.c1.c2.s2", expect: false)
|
||||
testOverlap("s0.c*.s2", "s0.s2", expect: false)
|
||||
|
||||
testOverlap("s0.v**.s2", "s0.s3.x", expect: true)
|
||||
testOverlap("s0.v**.s2.c2", "s0.s3.c1", expect: false)
|
||||
testOverlap("s0.v**.s2", "s1.s3", expect: false)
|
||||
testOverlap("s0.v**.s2", "s0.v**.s3", expect: true)
|
||||
|
||||
testOverlap("s0.**", "s0.s3.c1", expect: true)
|
||||
testOverlap("**", "s0.s3.c1", expect: true)
|
||||
|
||||
testOverlap("i1", "i*", expect: true)
|
||||
testOverlap("i1", "v**", expect: true)
|
||||
testOverlap("s0.i*.s1", "s0.s1", expect: true)
|
||||
testOverlap("s0.b.s1", "s0.b.i*.s1", expect: true)
|
||||
testOverlap("s0.b.i0.s1", "s0.b.i1.s1", expect: false)
|
||||
testOverlap("s0.b.i2.s1", "s0.b.i1.s1", expect: false)
|
||||
testOverlap("s0.b.s1", "s0.b.i0.s1", expect: true)
|
||||
testOverlap("s0.b", "s0.b.i1", expect: false)
|
||||
testOverlap("s0.b.i1", "s0.b", expect: false)
|
||||
testOverlap("s0.b.i1", "s0", expect: true)
|
||||
}
|
||||
|
||||
func testOverlap(_ lhsStr: String, _ rhsStr: String, expect: Bool) {
|
||||
var lhsParser = StringParser(lhsStr)
|
||||
let lhs = try! lhsParser.parseProjectionPathFromSIL()
|
||||
var rhsParser = StringParser(rhsStr)
|
||||
let rhs = try! rhsParser.parseProjectionPathFromSIL()
|
||||
let result = lhs.mayOverlap(with: rhs)
|
||||
assert(result == expect)
|
||||
let reversedResult = rhs.mayOverlap(with: lhs)
|
||||
assert(reversedResult == expect)
|
||||
}
|
||||
|
||||
func predicates() {
|
||||
testPredicate("v**", \.hasClassProjection, expect: false)
|
||||
testPredicate("v**.c0.s1.v**", \.hasClassProjection, expect: true)
|
||||
testPredicate("c0.**", \.hasClassProjection, expect: true)
|
||||
testPredicate("c0.c1", \.hasClassProjection, expect: true)
|
||||
testPredicate("ct", \.hasClassProjection, expect: true)
|
||||
testPredicate("s0", \.hasClassProjection, expect: false)
|
||||
|
||||
testPredicate("v**", \.mayHaveClassProjection, expect: false)
|
||||
testPredicate("c0", \.mayHaveClassProjection, expect: true)
|
||||
testPredicate("1", \.mayHaveClassProjection, expect: false)
|
||||
testPredicate("**", \.mayHaveClassProjection, expect: true)
|
||||
|
||||
testPredicate("v**", \.mayHaveTwoClassProjections, expect: false)
|
||||
testPredicate("c0", \.mayHaveTwoClassProjections, expect: false)
|
||||
testPredicate("**", \.mayHaveTwoClassProjections, expect: true)
|
||||
testPredicate("v**.c*.s2.1.c0", \.mayHaveTwoClassProjections, expect: true)
|
||||
testPredicate("c*.s2.1.c0.v**", \.mayHaveTwoClassProjections, expect: true)
|
||||
testPredicate("v**.c*.**", \.mayHaveTwoClassProjections, expect: true)
|
||||
}
|
||||
|
||||
func testPredicate(_ pathStr: String, _ property: (SmallProjectionPath) -> Bool, expect: Bool) {
|
||||
var parser = StringParser(pathStr)
|
||||
let path = try! parser.parseProjectionPathFromSIL()
|
||||
let result = property(path)
|
||||
assert(result == expect)
|
||||
}
|
||||
|
||||
func path2path() {
|
||||
testPath2Path("s0.b.e2.3.c4.s1", { $0.popAllValueFields() }, expect: "c4.s1")
|
||||
testPath2Path("v**.c4.s1", { $0.popAllValueFields() }, expect: "c4.s1")
|
||||
testPath2Path("**", { $0.popAllValueFields() }, expect: "**")
|
||||
|
||||
testPath2Path("s0.e2.3.c4.s1.e2.v**.**", { $0.popLastClassAndValuesFromTail() }, expect: "s0.e2.3.c4.s1.e2.v**.**")
|
||||
testPath2Path("s0.c2.3.c4.s1", { $0.popLastClassAndValuesFromTail() }, expect: "s0.c2.3")
|
||||
testPath2Path("v**.c*.s1", { $0.popLastClassAndValuesFromTail() }, expect: "v**")
|
||||
testPath2Path("s1.ct.v**", { $0.popLastClassAndValuesFromTail() }, expect: "s1")
|
||||
testPath2Path("c0.c1.c2", { $0.popLastClassAndValuesFromTail() }, expect: "c0.c1")
|
||||
testPath2Path("**", { $0.popLastClassAndValuesFromTail() }, expect: "**")
|
||||
|
||||
testPath2Path("v**.c3", { $0.popIfMatches(.anyValueFields) }, expect: "v**.c3")
|
||||
testPath2Path("**", { $0.popIfMatches(.anyValueFields) }, expect: "**")
|
||||
testPath2Path("s0.c3", { $0.popIfMatches(.anyValueFields) }, expect: nil)
|
||||
|
||||
testPath2Path("c0.s3", { $0.popIfMatches(.anyClassField) }, expect: nil)
|
||||
testPath2Path("**", { $0.popIfMatches(.anyClassField) }, expect: "**")
|
||||
testPath2Path("c*.e3", { $0.popIfMatches(.anyClassField) }, expect: "e3")
|
||||
|
||||
testPath2Path("i*.e3.s0", { $0.popIfMatches(.enumCase, index: 3) }, expect: "s0")
|
||||
testPath2Path("i1.e3.s0", { $0.popIfMatches(.enumCase, index: 3) }, expect: nil)
|
||||
testPath2Path("i*.e3.s0", { $0.popIfMatches(.indexedElement, index: 0) }, expect: "i*.e3.s0")
|
||||
}
|
||||
|
||||
func testPath2Path(_ pathStr: String, _ transform: (SmallProjectionPath) -> SmallProjectionPath?, expect: String?) {
|
||||
var parser = StringParser(pathStr)
|
||||
let path = try! parser.parseProjectionPathFromSIL()
|
||||
let result = transform(path)
|
||||
if let expect = expect {
|
||||
var expectParser = StringParser(expect)
|
||||
let expectPath = try! expectParser.parseProjectionPathFromSIL()
|
||||
assert(result == expectPath)
|
||||
} else {
|
||||
assert(result == nil)
|
||||
}
|
||||
}
|
||||
|
||||
func indexedElements() {
|
||||
let p1 = SmallProjectionPath(.indexedElement, index: 1)
|
||||
let (k1, i1, s1) = p1.pop()
|
||||
assert(k1 == .indexedElement && i1 == 1 && s1.isEmpty)
|
||||
|
||||
let p2 = SmallProjectionPath(.indexedElement, index: -1)
|
||||
let (k2, _, s2) = p2.pop()
|
||||
assert(k2 == .anything && s2.isEmpty)
|
||||
|
||||
let p3 = SmallProjectionPath(.indexedElement, index: 0xfffffffffffff)
|
||||
let (k3, i3, s3) = p3.pop()
|
||||
assert(k3 == .indexedElement && i3 == 0xfffffffffffff && s3.isEmpty)
|
||||
|
||||
let p4 = p3.push(.indexedElement, index: Int.max)
|
||||
let (k4, _, s4) = p4.pop()
|
||||
assert(k4 == .anyIndexedElement && s4.isEmpty)
|
||||
do {
|
||||
var parser = StringParser("**.s0")
|
||||
_ = try parser.parseProjectionPathFromSIL()
|
||||
fatalError("wrong '**' not detected")
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
|
||||
func testParse(_ pathStr: String, expect: SmallProjectionPath) {
|
||||
var parser = StringParser(pathStr)
|
||||
let path = try! parser.parseProjectionPathFromSIL()
|
||||
assert(path == expect)
|
||||
let str = path.description
|
||||
assert(str == pathStr)
|
||||
}
|
||||
|
||||
func merging() {
|
||||
testMerge("c1.c0", "c0", expect: "c*.**")
|
||||
testMerge("c2.c1", "c2", expect: "c2.**")
|
||||
testMerge("s3.c0", "v**.c0", expect: "v**.c0")
|
||||
testMerge("c0", "s2.c1", expect: "v**.c*")
|
||||
testMerge("s1.s1.c2", "s1.c2", expect: "s1.v**.c2")
|
||||
testMerge("s1.s0", "s2.s0", expect: "v**")
|
||||
testMerge("ct", "c2", expect: "c*")
|
||||
testMerge("i1", "i2", expect: "i*")
|
||||
testMerge("i*", "i2", expect: "i*")
|
||||
testMerge("s0.i*.e3", "s0.e3", expect: "s0.i*.e3")
|
||||
testMerge("i*", "v**", expect: "v**")
|
||||
testMerge("s0.b.i1", "s0.b.i0", expect: "s0.b.i*")
|
||||
testMerge("s0.b", "s0.1", expect: "s0.v**")
|
||||
|
||||
testMerge("ct.s0.e0.v**.c0", "ct.s0.e0.v**.c0", expect: "ct.s0.e0.v**.c0")
|
||||
testMerge("ct.s0.s0.c0", "ct.s0.e0.s0.c0", expect: "ct.s0.v**.c0")
|
||||
}
|
||||
|
||||
func testMerge(_ lhsStr: String, _ rhsStr: String,
|
||||
expect expectStr: String) {
|
||||
var lhsParser = StringParser(lhsStr)
|
||||
let lhs = try! lhsParser.parseProjectionPathFromSIL()
|
||||
var rhsParser = StringParser(rhsStr)
|
||||
let rhs = try! rhsParser.parseProjectionPathFromSIL()
|
||||
var expectParser = StringParser(expectStr)
|
||||
let expect = try! expectParser.parseProjectionPathFromSIL()
|
||||
|
||||
let result = lhs.merge(with: rhs)
|
||||
assert(result == expect)
|
||||
let result2 = rhs.merge(with: lhs)
|
||||
assert(result2 == expect)
|
||||
}
|
||||
|
||||
func subtracting() {
|
||||
testSubtract("s0", "s0.s1", expect: "s1")
|
||||
testSubtract("s0", "s1", expect: nil)
|
||||
testSubtract("s0.s1", "s0.s1", expect: "")
|
||||
testSubtract("i*.s1", "i*.s1", expect: nil)
|
||||
testSubtract("ct.s1.0.i3.x", "ct.s1.0.i3.x", expect: "")
|
||||
testSubtract("c0.s1.0.i3", "c0.s1.0.i3.x", expect: "x")
|
||||
testSubtract("s1.0.i3.x", "s1.0.i3", expect: nil)
|
||||
testSubtract("v**.s1", "v**.s1", expect: nil)
|
||||
testSubtract("i*", "i*", expect: nil)
|
||||
}
|
||||
|
||||
func testSubtract(_ lhsStr: String, _ rhsStr: String, expect expectStr: String?) {
|
||||
var lhsParser = StringParser(lhsStr)
|
||||
let lhs = try! lhsParser.parseProjectionPathFromSIL()
|
||||
var rhsParser = StringParser(rhsStr)
|
||||
let rhs = try! rhsParser.parseProjectionPathFromSIL()
|
||||
|
||||
let result = lhs.subtract(from: rhs)
|
||||
|
||||
if let expectStr = expectStr {
|
||||
var expectParser = StringParser(expectStr)
|
||||
let expect = try! expectParser.parseProjectionPathFromSIL()
|
||||
assert(result! == expect)
|
||||
} else {
|
||||
assert(result == nil)
|
||||
}
|
||||
}
|
||||
|
||||
func matching() {
|
||||
testMatch("ct", "c*", expect: true)
|
||||
testMatch("c1", "c*", expect: true)
|
||||
testMatch("s2", "v**", expect: true)
|
||||
testMatch("1", "v**", expect: true)
|
||||
testMatch("e1", "v**", expect: true)
|
||||
testMatch("c*", "c1", expect: false)
|
||||
testMatch("c*", "ct", expect: false)
|
||||
testMatch("v**", "s0", expect: false)
|
||||
testMatch("i1", "i1", expect: true)
|
||||
testMatch("i1", "i*", expect: true)
|
||||
testMatch("i*", "i1", expect: false)
|
||||
|
||||
testMatch("s0.s1", "s0.s1", expect: true)
|
||||
testMatch("s0.s2", "s0.s1", expect: false)
|
||||
testMatch("s0", "s0.v**", expect: true)
|
||||
testMatch("s0.s1", "s0.v**", expect: true)
|
||||
testMatch("s0.1.e2", "s0.v**", expect: true)
|
||||
testMatch("s0.v**.x.e2", "v**", expect: true)
|
||||
testMatch("s0.v**", "s0.s1", expect: false)
|
||||
testMatch("s0.s1.c*", "s0.v**", expect: false)
|
||||
testMatch("s0.v**", "s0.**", expect: true)
|
||||
testMatch("s1.v**", "s0.**", expect: false)
|
||||
testMatch("s0.**", "s0.v**", expect: false)
|
||||
testMatch("s0.s1", "s0.i*.s1", expect: true)
|
||||
testMatch("s0.b.s1", "s0.b.i*.s1", expect: true)
|
||||
}
|
||||
|
||||
func testMatch(_ lhsStr: String, _ rhsStr: String, expect: Bool) {
|
||||
var lhsParser = StringParser(lhsStr)
|
||||
let lhs = try! lhsParser.parseProjectionPathFromSIL()
|
||||
var rhsParser = StringParser(rhsStr)
|
||||
let rhs = try! rhsParser.parseProjectionPathFromSIL()
|
||||
let result = lhs.matches(pattern: rhs)
|
||||
assert(result == expect)
|
||||
}
|
||||
|
||||
func overlapping() {
|
||||
testOverlap("s0.s1.s2", "s0.s1.s2", expect: true)
|
||||
testOverlap("s0.s1.s2", "s0.s2.s2", expect: false)
|
||||
testOverlap("s0.s1.s2", "s0.e1.s2", expect: false)
|
||||
testOverlap("s0.s1.s2", "s0.s1", expect: true)
|
||||
testOverlap("s0.s1.s2", "s1.s2", expect: false)
|
||||
|
||||
testOverlap("s0.c*.s2", "s0.ct.s2", expect: true)
|
||||
testOverlap("s0.c*.s2", "s0.c1.s2", expect: true)
|
||||
testOverlap("s0.c*.s2", "s0.c1.c2.s2", expect: false)
|
||||
testOverlap("s0.c*.s2", "s0.s2", expect: false)
|
||||
|
||||
testOverlap("s0.v**.s2", "s0.s3.x", expect: true)
|
||||
testOverlap("s0.v**.s2.c2", "s0.s3.c1", expect: false)
|
||||
testOverlap("s0.v**.s2", "s1.s3", expect: false)
|
||||
testOverlap("s0.v**.s2", "s0.v**.s3", expect: true)
|
||||
|
||||
testOverlap("s0.**", "s0.s3.c1", expect: true)
|
||||
testOverlap("**", "s0.s3.c1", expect: true)
|
||||
|
||||
testOverlap("i1", "i*", expect: true)
|
||||
testOverlap("i1", "v**", expect: true)
|
||||
testOverlap("s0.i*.s1", "s0.s1", expect: true)
|
||||
testOverlap("s0.b.s1", "s0.b.i*.s1", expect: true)
|
||||
testOverlap("s0.b.i0.s1", "s0.b.i1.s1", expect: false)
|
||||
testOverlap("s0.b.i2.s1", "s0.b.i1.s1", expect: false)
|
||||
testOverlap("s0.b.s1", "s0.b.i0.s1", expect: true)
|
||||
testOverlap("s0.b", "s0.b.i1", expect: false)
|
||||
testOverlap("s0.b.i1", "s0.b", expect: false)
|
||||
testOverlap("s0.b.i1", "s0", expect: true)
|
||||
}
|
||||
|
||||
func testOverlap(_ lhsStr: String, _ rhsStr: String, expect: Bool) {
|
||||
var lhsParser = StringParser(lhsStr)
|
||||
let lhs = try! lhsParser.parseProjectionPathFromSIL()
|
||||
var rhsParser = StringParser(rhsStr)
|
||||
let rhs = try! rhsParser.parseProjectionPathFromSIL()
|
||||
let result = lhs.mayOverlap(with: rhs)
|
||||
assert(result == expect)
|
||||
let reversedResult = rhs.mayOverlap(with: lhs)
|
||||
assert(reversedResult == expect)
|
||||
}
|
||||
|
||||
func predicates() {
|
||||
testPredicate("v**", \.hasClassProjection, expect: false)
|
||||
testPredicate("v**.c0.s1.v**", \.hasClassProjection, expect: true)
|
||||
testPredicate("c0.**", \.hasClassProjection, expect: true)
|
||||
testPredicate("c0.c1", \.hasClassProjection, expect: true)
|
||||
testPredicate("ct", \.hasClassProjection, expect: true)
|
||||
testPredicate("s0", \.hasClassProjection, expect: false)
|
||||
|
||||
testPredicate("v**", \.mayHaveClassProjection, expect: false)
|
||||
testPredicate("c0", \.mayHaveClassProjection, expect: true)
|
||||
testPredicate("1", \.mayHaveClassProjection, expect: false)
|
||||
testPredicate("**", \.mayHaveClassProjection, expect: true)
|
||||
|
||||
testPredicate("v**", \.mayHaveTwoClassProjections, expect: false)
|
||||
testPredicate("c0", \.mayHaveTwoClassProjections, expect: false)
|
||||
testPredicate("**", \.mayHaveTwoClassProjections, expect: true)
|
||||
testPredicate("v**.c*.s2.1.c0", \.mayHaveTwoClassProjections, expect: true)
|
||||
testPredicate("c*.s2.1.c0.v**", \.mayHaveTwoClassProjections, expect: true)
|
||||
testPredicate("v**.c*.**", \.mayHaveTwoClassProjections, expect: true)
|
||||
}
|
||||
|
||||
func testPredicate(_ pathStr: String, _ property: (SmallProjectionPath) -> Bool, expect: Bool) {
|
||||
var parser = StringParser(pathStr)
|
||||
let path = try! parser.parseProjectionPathFromSIL()
|
||||
let result = property(path)
|
||||
assert(result == expect)
|
||||
}
|
||||
|
||||
func path2path() {
|
||||
testPath2Path("s0.b.e2.3.c4.s1", { $0.popAllValueFields() }, expect: "c4.s1")
|
||||
testPath2Path("v**.c4.s1", { $0.popAllValueFields() }, expect: "c4.s1")
|
||||
testPath2Path("**", { $0.popAllValueFields() }, expect: "**")
|
||||
|
||||
testPath2Path("s0.e2.3.c4.s1.e2.v**.**", { $0.popLastClassAndValuesFromTail() }, expect: "s0.e2.3.c4.s1.e2.v**.**")
|
||||
testPath2Path("s0.c2.3.c4.s1", { $0.popLastClassAndValuesFromTail() }, expect: "s0.c2.3")
|
||||
testPath2Path("v**.c*.s1", { $0.popLastClassAndValuesFromTail() }, expect: "v**")
|
||||
testPath2Path("s1.ct.v**", { $0.popLastClassAndValuesFromTail() }, expect: "s1")
|
||||
testPath2Path("c0.c1.c2", { $0.popLastClassAndValuesFromTail() }, expect: "c0.c1")
|
||||
testPath2Path("**", { $0.popLastClassAndValuesFromTail() }, expect: "**")
|
||||
|
||||
testPath2Path("v**.c3", { $0.popIfMatches(.anyValueFields) }, expect: "v**.c3")
|
||||
testPath2Path("**", { $0.popIfMatches(.anyValueFields) }, expect: "**")
|
||||
testPath2Path("s0.c3", { $0.popIfMatches(.anyValueFields) }, expect: nil)
|
||||
|
||||
testPath2Path("c0.s3", { $0.popIfMatches(.anyClassField) }, expect: nil)
|
||||
testPath2Path("**", { $0.popIfMatches(.anyClassField) }, expect: "**")
|
||||
testPath2Path("c*.e3", { $0.popIfMatches(.anyClassField) }, expect: "e3")
|
||||
|
||||
testPath2Path("i*.e3.s0", { $0.popIfMatches(.enumCase, index: 3) }, expect: "s0")
|
||||
testPath2Path("i1.e3.s0", { $0.popIfMatches(.enumCase, index: 3) }, expect: nil)
|
||||
testPath2Path("i*.e3.s0", { $0.popIfMatches(.indexedElement, index: 0) }, expect: "i*.e3.s0")
|
||||
}
|
||||
|
||||
func testPath2Path(_ pathStr: String, _ transform: (SmallProjectionPath) -> SmallProjectionPath?, expect: String?) {
|
||||
var parser = StringParser(pathStr)
|
||||
let path = try! parser.parseProjectionPathFromSIL()
|
||||
let result = transform(path)
|
||||
if let expect = expect {
|
||||
var expectParser = StringParser(expect)
|
||||
let expectPath = try! expectParser.parseProjectionPathFromSIL()
|
||||
assert(result == expectPath)
|
||||
} else {
|
||||
assert(result == nil)
|
||||
}
|
||||
}
|
||||
|
||||
func indexedElements() {
|
||||
let p1 = SmallProjectionPath(.indexedElement, index: 1)
|
||||
let (k1, i1, s1) = p1.pop()
|
||||
assert(k1 == .indexedElement && i1 == 1 && s1.isEmpty)
|
||||
|
||||
let p2 = SmallProjectionPath(.indexedElement, index: -1)
|
||||
let (k2, _, s2) = p2.pop()
|
||||
assert(k2 == .anything && s2.isEmpty)
|
||||
|
||||
let p3 = SmallProjectionPath(.indexedElement, index: 0xfffffffffffff)
|
||||
let (k3, i3, s3) = p3.pop()
|
||||
assert(k3 == .indexedElement && i3 == 0xfffffffffffff && s3.isEmpty)
|
||||
|
||||
let p4 = p3.push(.indexedElement, index: Int.max)
|
||||
let (k4, _, s4) = p4.pop()
|
||||
assert(k4 == .anyIndexedElement && s4.isEmpty)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,6 +142,7 @@ public func registerTests() {
|
||||
// Register each test.
|
||||
registerTests(
|
||||
parseTestSpecificationTest,
|
||||
smallProjectionPathTest,
|
||||
getAccessBaseTest,
|
||||
borrowIntroducersTest,
|
||||
enclosingValuesTest,
|
||||
|
||||
Reference in New Issue
Block a user