1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
|
//===---------------- Antisymmetry.swift - Swift Testing ------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2021 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 XCTest
import IncrementalTestFramework
// This test establishes an "antisymmetric" chain of modules that import one
// another and ensures that rebuilds propagate in one direction.
//
// Module B Module A
// -------- -> --------
// ^ x
// | |
// ----XXX-----
class AntisymmetryTest: XCTestCase {
private let defAdditions = [
"b-add-struct",
"b-add-class",
"b-add-protocol",
"b-add-extension",
]
private let useAdditions = [
"use-struct",
"use-class",
"use-protocol",
"use-extension",
]
func testAntisymmetricTopLevelDefs() throws {
try IncrementalTest.perform([
// The baseline step is special, we want everything to get built first.
Step(adding: defAdditions,
building: [ .B, .A ],
.expecting(.init(always: [ .main, .B ])))
] + defAdditions.dropFirst().indices.map { idx in
// Make sure the addition of defs without users only causes cascading
// rebuilds when incremental imports are disabled.
Step(adding: Array(defAdditions[0..<idx]),
building: [ .B, .A ],
.expecting(.init(always: [ .B ], andWhenDisabled: [ .main ])))
})
}
func testAntisymmetricTopLevelUses() throws {
try IncrementalTest.perform([
// The baseline step is special, we want everything to get built first.
Step(adding: defAdditions,
building: [ .B, .A ],
.expecting(.init(always: [ .main, .B ])))
] + useAdditions.indices.dropFirst().map { idx in
// Make sure the addition of uses causes only users to recompile.
Step(adding: defAdditions + Array(useAdditions[0..<idx]),
building: [ .B, .A ],
.expecting(.init(always: [ .main ])))
})
}
}
fileprivate extension Module {
static var A = Module(named: "A", containing: [
.main,
], importing: [
.B,
], producing: .executable)
static var B = Module(named: "B", containing: [
.B,
], producing: .library)
}
fileprivate extension Source {
static var main: Source {
Self(
named: "main",
containing: """
import B
//# use-struct _ = BStruct()
//# use-class _ = BClass()
//# use-protocol extension BStruct: BProtocol { public func foo(parameter: Int = 0) {} }
//# use-extension BStruct().foo()
""")
}
}
fileprivate extension Source {
static var B: Source {
Self(
named: "B",
containing: """
//# b-add-struct public struct BStruct { public init() {} }
//# b-add-class public class BClass { public init() {} }
//# b-add-protocol public protocol BProtocol {}
//# b-add-extension extension BStruct { public func foo() {} }
""")
}
}
|