Downgrade Swift version to 5.0

This commit is contained in:
Moritz Lang 2020-08-17 10:39:42 +02:00
parent 1fdb3a6d05
commit a6a00c3edf
20 changed files with 458 additions and 88 deletions

View File

@ -4,10 +4,14 @@ on: [push, pull_request]
jobs:
unit-test:
strategy:
matrix:
# GitHub Actions replaces 5.0 with 5 so we have to be specific here
swift: [5.0.3, 5.1, 5.2]
runs-on: ubuntu-latest
container: swift:5.2
container: swift:${{ matrix.swift }}
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Build & Test
run: swift test -c release --enable-test-discovery
run: swift test

View File

@ -1,8 +1,10 @@
# file options
--swiftversion 5.2
--swiftversion 5.0
--exclude .build
--exclude UseCases/.build
--exclude Tests/LinuxMain.swift
--exclude **/*Tests+XCTest.swift
# format options

View File

@ -1,4 +1,4 @@
// swift-tools-version:5.2
// swift-tools-version:5.0
import PackageDescription
let package = Package(

View File

@ -52,7 +52,7 @@ public struct BaggageContext: BaggageContextProtocol {
public subscript<Key: BaggageContextKey>(_ key: Key.Type) -> Key.Value? {
get {
self._storage[AnyBaggageContextKey(key)]?.forceUnwrap(key)
return self._storage[AnyBaggageContextKey(key)]?.forceUnwrap(key)
} set {
self._storage[AnyBaggageContextKey(key)] = newValue.map {
ValueContainer(value: $0)
@ -70,14 +70,14 @@ public struct BaggageContext: BaggageContextProtocol {
let value: Any
func forceUnwrap<Key: BaggageContextKey>(_ key: Key.Type) -> Key.Value {
self.value as! Key.Value
return self.value as! Key.Value
}
}
}
extension BaggageContext: CustomStringConvertible {
public var description: String {
"\(Self.self)(keys: \(self._storage.map(\.key.name)))"
return "\(type(of: self).self)(keys: \(self._storage.map { $0.key.name }))"
}
}
@ -118,7 +118,7 @@ public protocol BaggageContextKey {
}
extension BaggageContextKey {
public static var name: String? { nil }
public static var name: String? { return nil }
}
public struct AnyBaggageContextKey {
@ -129,7 +129,7 @@ public struct AnyBaggageContextKey {
/// A human-readable String representation of the underlying key.
/// If no explicit name has been set on the wrapped key the type name is used.
public var name: String {
self._name ?? String(describing: self.keyType.self)
return self._name ?? String(describing: self.keyType.self)
}
public init<Key>(_ keyType: Key.Type) where Key: BaggageContextKey {
@ -140,7 +140,7 @@ public struct AnyBaggageContextKey {
extension AnyBaggageContextKey: Hashable {
public static func == (lhs: AnyBaggageContextKey, rhs: AnyBaggageContextKey) -> Bool {
ObjectIdentifier(lhs.keyType) == ObjectIdentifier(rhs.keyType)
return ObjectIdentifier(lhs.keyType) == ObjectIdentifier(rhs.keyType)
}
public func hash(into hasher: inout Hasher) {

View File

@ -30,7 +30,7 @@ public protocol BaggageContextCarrier: BaggageContextProtocol {
extension BaggageContextCarrier {
public subscript<Key: BaggageContextKey>(baggageKey: Key.Type) -> Key.Value? {
get {
self.baggage[baggageKey]
return self.baggage[baggageKey]
} set {
self.baggage[baggageKey] = newValue
}
@ -45,7 +45,7 @@ extension BaggageContextCarrier {
extension BaggageContext: BaggageContextCarrier {
public var baggage: BaggageContext {
get {
self
return self
}
set {
self = newValue

View File

@ -29,7 +29,7 @@ public struct BaggageMetadataLogHandler: LogHandler {
public var logLevel: Logger.Level {
get {
self.underlying.logLevel
return self.underlying.logLevel
}
set {
self.underlying.logLevel = newValue
@ -58,7 +58,7 @@ public struct BaggageMetadataLogHandler: LogHandler {
public var metadata: Logger.Metadata {
get {
[:]
return [:]
}
set {
newValue.forEach { k, v in
@ -74,7 +74,7 @@ public struct BaggageMetadataLogHandler: LogHandler {
/// into a baggage with String keys through this handler (as that is not a capability `BaggageContext` offers in any case.
public subscript(metadataKey metadataKey: Logger.Metadata.Key) -> Logger.Metadata.Value? {
get {
self.underlying[metadataKey: metadataKey]
return self.underlying[metadataKey: metadataKey]
}
set {
self.underlying[metadataKey: metadataKey] = newValue
@ -104,7 +104,7 @@ public struct BaggageMetadataLogHandler: LogHandler {
}
var description: String {
"\(self.value)"
return "\(self.value)"
}
}
}

View File

@ -21,7 +21,7 @@ extension Logger {
/// The rendering of baggage values into metadata values is performed on demand,
/// whenever a log statement is effective (i.e. will be logged, according to active `logLevel`).
public func with(context: BaggageContext) -> Logger {
Logger(
return Logger(
label: self.label,
factory: { _ in BaggageMetadataLogHandler(logger: self, context: context) }
)

View File

@ -158,32 +158,32 @@ private enum TestKD1: BaggageContextKey {
extension BaggageContext {
fileprivate var passCounter: TestPassCounterKey.Value {
get { self[TestPassCounterKey.self] ?? 0 }
get { return self[TestPassCounterKey.self] ?? 0 }
set { self[TestPassCounterKey.self] = newValue }
}
fileprivate var k1: TestK1.Value? {
get { self[TestK1.self] }
get { return self[TestK1.self] }
set { self[TestK1.self] = newValue }
}
fileprivate var k2: TestK2.Value? {
get { self[TestK2.self] }
get { return self[TestK2.self] }
set { self[TestK2.self] = newValue }
}
fileprivate var k3: TestK3.Value? {
get { self[TestK3.self] }
get { return self[TestK3.self] }
set { self[TestK3.self] = newValue }
}
fileprivate var k4: TestK4.Value? {
get { self[TestK4.self] }
get { return self[TestK4.self] }
set { self[TestK4.self] = newValue }
}
fileprivate var kd1: TestKD1.Value? {
get { self[TestKD1.self] }
get { return self[TestKD1.self] }
set { self[TestKD1.self] = newValue }
}
}

View File

@ -43,7 +43,7 @@ internal class CountDownLatch {
}
var count: Int {
self.lock.synchronized {
return self.lock.synchronized {
self.counter
}
}
@ -63,7 +63,7 @@ internal class CountDownLatch {
extension CountDownLatch: CustomStringConvertible {
public var description: String {
"CountDownLatch(remaining:\(self.count)"
return "CountDownLatch(remaining:\(self.count)"
}
}

View File

@ -74,7 +74,7 @@ func checked<T>(
class ArgumentParser<U> {
private var result: U
private var validOptions: [String] {
self.arguments.compactMap { $0.name }
return self.arguments.compactMap { $0.name }
}
private var arguments: [Argument] = []

View File

@ -25,13 +25,13 @@ import Darwin
extension BenchmarkCategory: CustomStringConvertible {
public var description: String {
self.rawValue
return self.rawValue
}
}
extension BenchmarkCategory: Comparable {
public static func < (lhs: BenchmarkCategory, rhs: BenchmarkCategory) -> Bool {
lhs.rawValue < rhs.rawValue
return lhs.rawValue < rhs.rawValue
}
}
@ -54,7 +54,7 @@ public struct BenchmarkPlatformSet: OptionSet {
}
public static var allPlatforms: BenchmarkPlatformSet {
[.darwin, .linux]
return [.darwin, .linux]
}
}
@ -124,17 +124,17 @@ public struct BenchmarkInfo {
/// Returns true if this benchmark should be run on the current platform.
var shouldRun: Bool {
!self.unsupportedPlatforms.contains(.currentPlatform)
return !self.unsupportedPlatforms.contains(.currentPlatform)
}
}
extension BenchmarkInfo: Comparable {
public static func < (lhs: BenchmarkInfo, rhs: BenchmarkInfo) -> Bool {
lhs.name < rhs.name
return lhs.name < rhs.name
}
public static func == (lhs: BenchmarkInfo, rhs: BenchmarkInfo) -> Bool {
lhs.name == rhs.name
return lhs.name == rhs.name
}
}
@ -175,7 +175,7 @@ public func SRand() {
}
public func Random() -> Int64 {
lfsrRandomGenerator.randInt()
return lfsrRandomGenerator.randInt()
}
@inlinable // FIXME(inline-always)
@ -192,16 +192,16 @@ public func CheckResults(
}
}
public func False() -> Bool { false }
public func False() -> Bool { return false }
/// This is a dummy protocol to test the speed of our protocol dispatch.
public protocol SomeProtocol { func getValue() -> Int }
struct MyStruct: SomeProtocol {
init() {}
func getValue() -> Int { 1 }
func getValue() -> Int { return 1 }
}
public func someProtocolFactory() -> SomeProtocol { MyStruct() }
public func someProtocolFactory() -> SomeProtocol { return MyStruct() }
// Just consume the argument.
// It's important that this function is in another module than the tests
@ -212,19 +212,19 @@ public func blackHole<T>(_: T) {}
// Return the passed argument without letting the optimizer know that.
@inline(never)
public func identity<T>(_ x: T) -> T {
x
return x
}
// Return the passed argument without letting the optimizer know that.
// It's important that this function is in another module than the tests
// which are using it.
@inline(never)
public func getInt(_ x: Int) -> Int { x }
public func getInt(_ x: Int) -> Int { return x }
// The same for String.
@inline(never)
public func getString(_ s: String) -> String { s }
public func getString(_ s: String) -> String { return s }
// The same for Substring.
@inline(never)
public func getSubstring(_ s: Substring) -> Substring { s }
public func getSubstring(_ s: Substring) -> Substring { return s }

View File

@ -54,12 +54,12 @@ public struct BenchResults {
return self.samples[index]
}
var sampleCount: T { self.samples.count }
var min: T { self.samples.first! }
var max: T { self.samples.last! }
var mean: T { Int(self.stats.mean.rounded()) }
var sd: T { Int(self.stats.standardDeviation.rounded()) }
var median: T { self[0.5] }
var sampleCount: T { return self.samples.count }
var min: T { return self.samples.first! }
var max: T { return self.samples.last! }
var mean: T { return Int(self.stats.mean.rounded()) }
var sd: T { return Int(self.stats.standardDeviation.rounded()) }
var median: T { return self[0.5] }
}
public var registeredBenchmarks: [BenchmarkInfo] = []
@ -135,14 +135,14 @@ struct TestConfig {
// We support specifying multiple tags by splitting on comma, i.e.:
// --tags=Array,Dictionary
// --skip-tags=Array,Set,unstable,skip
Set(
return Set(
try tags.split(separator: ",").map(String.init).map {
try checked({ BenchmarkCategory(rawValue: $0) }, $0)
}
)
}
func finiteDouble(value: String) -> Double? {
Double(value).flatMap { $0.isFinite ? $0 : nil }
return Double(value).flatMap { $0.isFinite ? $0 : nil }
}
// Configure the command line argument parser
@ -294,11 +294,11 @@ struct TestConfig {
)
func byTags(b: BenchmarkInfo) -> Bool {
b.tags.isSuperset(of: tags) &&
return b.tags.isSuperset(of: tags) &&
b.tags.isDisjoint(with: skipTags)
}
func byNamesOrIndices(b: BenchmarkInfo) -> Bool {
specifiedTests.contains(b.name) ||
return specifiedTests.contains(b.name) ||
specifiedTests.contains(indices[b.name]!)
} // !! "`allTests` have been assigned an index"
return allTests
@ -311,8 +311,8 @@ struct Stats {
var n: Int = 0
var S: Double = 0.0
var mean: Double = 0.0
var variance: Double { self.n < 2 ? 0.0 : self.S / Double(self.n - 1) }
var standardDeviation: Double { self.variance.squareRoot() }
var variance: Double { return self.n < 2 ? 0.0 : self.S / Double(self.n - 1) }
var standardDeviation: Double { return self.variance.squareRoot() }
static func collect(_ s: inout Stats, _ x: Int) {
Stats.runningMeanVariance(&s, Double(x))
@ -353,7 +353,7 @@ public final class Timer {
}
public func getTimeAsInt() -> UInt64 {
UInt64(getTime().tv_nsec)
return UInt64(getTime().tv_nsec)
}
public func diffTimeInNanoSeconds(from start: TimeT, to end: TimeT) -> UInt64 {
@ -378,11 +378,11 @@ public final class Timer {
}
public func getTime() -> TimeT {
mach_absolute_time()
return mach_absolute_time()
}
public func getTimeAsInt() -> UInt64 {
UInt64(getTime())
return UInt64(getTime())
}
public func diffTimeInNanoSeconds(from start: TimeT, to end: TimeT) -> UInt64 {
@ -393,10 +393,10 @@ public final class Timer {
}
extension UInt64 {
public var nanoseconds: Int { Int(self) }
public var microseconds: Int { Int(self / 1000) }
public var milliseconds: Int { Int(self / 1000 / 1000) }
public var seconds: Int { Int(self / 1000 / 1000 / 1000) }
public var nanoseconds: Int { return Int(self) }
public var microseconds: Int { return Int(self / 1000) }
public var milliseconds: Int { return Int(self / 1000 / 1000) }
public var seconds: Int { return Int(self / 1000 / 1000 / 1000) }
}
enum TimeUnit: String {
@ -420,7 +420,7 @@ enum TimeUnit: String {
extension TimeUnit: CustomStringConvertible {
public var description: String {
self.rawValue
return self.rawValue
}
}
@ -447,7 +447,7 @@ final class TestRunner {
private static func getExecutedInstructions() -> UInt64 {
// FIXME: there is a Linux PMC API you can use to get this, but it's
// not quite so straightforward.
0
return 0
}
#else
@ -460,7 +460,7 @@ final class TestRunner {
// }
// return u.ri_instructions
// } else {
0
return 0
// }
}
#endif
@ -533,7 +533,7 @@ final class TestRunner {
/// Time in nanoseconds spent running the last function
var lastSampleTime: UInt64 {
timer.diffTimeInNanoSeconds(from: start, to: end)
return timer.diffTimeInNanoSeconds(from: start, to: end)
}
/// Measure the `fn` and return the average sample time per iteration (in c.timeUnit).

View File

@ -0,0 +1,33 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift Baggage Context open source project
//
// Copyright (c) 2020 Moritz Lang and the Swift Baggage Context project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
//
// LoggingBaggageContextCarrierTests+XCTest.swift
//
import XCTest
///
/// NOTE: This file was generated by generate_linux_tests.rb
///
/// Do NOT edit this file directly as it will be regenerated automatically when needed.
///
extension LoggingBaggageContextCarrierTests {
@available(*, deprecated, message: "not actually deprecated. Just deprecated to allow deprecated tests (which test deprecated functionality) without warnings")
static var allTests : [(String, (LoggingBaggageContextCarrierTests) -> () throws -> Void)] {
return [
("test_ContextWithLogger_dumpBaggage", test_ContextWithLogger_dumpBaggage),
("test_ContextWithLogger_log_withBaggage", test_ContextWithLogger_log_withBaggage),
]
}
}

View File

@ -72,7 +72,7 @@ public struct ExampleFrameworkContext: LoggingBaggageContextCarrier {
private var _logger: Logger
public var logger: Logger {
get {
self._logger.with(context: self.baggage)
return self._logger.with(context: self.baggage)
}
set {
self._logger = newValue
@ -89,7 +89,7 @@ struct CoolFrameworkContext: LoggingBaggageContextCarrier {
private var _logger: Logger = Logger(label: "some frameworks logger")
var logger: Logger {
get {
self._logger.with(context: self.baggage)
return self._logger.with(context: self.baggage)
}
set {
self._logger = newValue
@ -110,7 +110,7 @@ struct FakeEventLoop {}
private extension BaggageContextProtocol {
var testID: Int? {
get {
self[TestIDKey.self]
return self[TestIDKey.self]
}
set {
self[TestIDKey.self] = newValue
@ -119,7 +119,7 @@ private extension BaggageContextProtocol {
var secondTestID: String? {
get {
self[SecondTestIDKey.self]
return self[SecondTestIDKey.self]
}
set {
self[SecondTestIDKey.self] = newValue

View File

@ -35,11 +35,11 @@ internal struct TestLogging {
private let recorder = Recorder() // shared among loggers
func make(label: String) -> LogHandler {
TestLogHandler(label: label, config: self.config, recorder: self.recorder)
return TestLogHandler(label: label, config: self.config, recorder: self.recorder)
}
var config: Config { self._config }
var history: History { self.recorder }
var config: Config { return self._config }
var history: History { return self.recorder }
}
internal struct TestLogHandler: LogHandler {
@ -68,7 +68,7 @@ internal struct TestLogHandler: LogHandler {
var logLevel: Logger.Level {
get {
// get from config unless set
self.logLevelLock.withLock { self._logLevel } ?? self.config.get(key: self.label)
return self.logLevelLock.withLock { self._logLevel } ?? self.config.get(key: self.label)
}
set {
self.logLevelLock.withLock { self._logLevel = newValue }
@ -85,7 +85,7 @@ internal struct TestLogHandler: LogHandler {
public var metadata: Logger.Metadata {
get {
// return self.logger.metadata
self.metadataLock.withLock { self._metadata }
return self.metadataLock.withLock { self._metadata }
}
set {
// self.logger.metadata = newValue
@ -97,7 +97,7 @@ internal struct TestLogHandler: LogHandler {
subscript(metadataKey metadataKey: Logger.Metadata.Key) -> Logger.Metadata.Value? {
get {
// return self.logger[metadataKey: metadataKey]
self.metadataLock.withLock { self._metadata[metadataKey] }
return self.metadataLock.withLock { self._metadata[metadataKey] }
}
set {
// return logger[metadataKey: metadataKey] = newValue
@ -115,7 +115,7 @@ internal class Config {
private var storage = [String: Logger.Level]()
func get(key: String) -> Logger.Level {
self.get(key) ?? self.get(Config.ALL) ?? Logger.Level.debug
return self.get(key) ?? self.get(Config.ALL) ?? Logger.Level.debug
}
func get(_ key: String) -> Logger.Level? {
@ -145,7 +145,7 @@ internal class Recorder: History {
}
var entries: [LogEntry] {
self.lock.withLock { self._entries }
return self.lock.withLock { return self._entries }
}
}
@ -155,29 +155,29 @@ internal protocol History {
internal extension History {
func atLevel(level: Logger.Level) -> [LogEntry] {
self.entries.filter { entry in
return self.entries.filter { entry in
level == entry.level
}
}
var trace: [LogEntry] {
self.atLevel(level: .debug)
return self.atLevel(level: .debug)
}
var debug: [LogEntry] {
self.atLevel(level: .debug)
return self.atLevel(level: .debug)
}
var info: [LogEntry] {
self.atLevel(level: .info)
return self.atLevel(level: .info)
}
var warning: [LogEntry] {
self.atLevel(level: .warning)
return self.atLevel(level: .warning)
}
var error: [LogEntry] {
self.atLevel(level: .error)
return self.atLevel(level: .error)
}
}
@ -226,7 +226,7 @@ extension History {
}
func find(level: Logger.Level, message: String, metadata: Logger.Metadata? = nil, source: String) -> LogEntry? {
self.entries.first { entry in
return self.entries.first { entry in
entry.level == level &&
entry.message == message &&
entry.metadata ?? [:] == metadata ?? [:] &&
@ -245,8 +245,8 @@ public class MDC {
public subscript(metadataKey: String) -> Logger.Metadata.Value? {
get {
self.lock.withLock {
self.storage[self.threadId]?[metadataKey]
return self.lock.withLock {
return self.storage[self.threadId]?[metadataKey]
}
}
set {
@ -260,8 +260,8 @@ public class MDC {
}
public var metadata: Logger.Metadata {
self.lock.withLock {
self.storage[self.threadId] ?? [:]
return self.lock.withLock {
return self.storage[self.threadId] ?? [:]
}
}

View File

@ -0,0 +1,36 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift Baggage Context open source project
//
// Copyright (c) 2020 Moritz Lang and the Swift Baggage Context project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
//
// BaggageContextTests+XCTest.swift
//
import XCTest
///
/// NOTE: This file was generated by generate_linux_tests.rb
///
/// Do NOT edit this file directly as it will be regenerated automatically when needed.
///
extension BaggageContextTests {
@available(*, deprecated, message: "not actually deprecated. Just deprecated to allow deprecated tests (which test deprecated functionality) without warnings")
static var allTests : [(String, (BaggageContextTests) -> () throws -> Void)] {
return [
("testSubscriptAccess", testSubscriptAccess),
("testRecommendedConvenienceExtension", testRecommendedConvenienceExtension),
("testEmptyBaggageDescription", testEmptyBaggageDescription),
("testSingleKeyBaggageDescription", testSingleKeyBaggageDescription),
("testMultiKeysBaggageDescription", testMultiKeysBaggageDescription),
]
}
}

View File

@ -22,7 +22,7 @@ final class BaggageContextTests: XCTestCase {
XCTAssertNil(baggage[TestIDKey.self])
baggage[TestIDKey.self] = testID
XCTAssertEqual(baggage[TestIDKey], testID)
XCTAssertEqual(baggage[TestIDKey.self], testID)
baggage[TestIDKey.self] = nil
XCTAssertNil(baggage[TestIDKey.self])
@ -73,7 +73,7 @@ private enum TestIDKey: BaggageContextKey {
private extension BaggageContext {
var testID: Int? {
get {
self[TestIDKey.self]
return self[TestIDKey.self]
} set {
self[TestIDKey.self] = newValue
}

42
Tests/LinuxMain.swift Normal file
View File

@ -0,0 +1,42 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift Baggage Context open source project
//
// Copyright (c) 2020 Moritz Lang and the Swift Baggage Context project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
//
// LinuxMain.swift
//
import XCTest
///
/// NOTE: This file was generated by generate_linux_tests.rb
///
/// Do NOT edit this file directly as it will be regenerated automatically when needed.
///
#if os(Linux) || os(FreeBSD)
@testable import BaggageLoggingTests
@testable import BaggageTests
// This protocol is necessary to we can call the 'run' method (on an existential of this protocol)
// without the compiler noticing that we're calling a deprecated function.
// This hack exists so we can deprecate individual tests which test deprecated functionality without
// getting a compiler warning...
protocol LinuxMainRunner { func run() }
class LinuxMainRunnerImpl: LinuxMainRunner {
@available(*, deprecated, message: "not actually deprecated. Just deprecated to allow deprecated tests (which test deprecated functionality) without warnings")
func run() {
XCTMain([
testCase(BaggageContextTests.allTests),
testCase(LoggingBaggageContextCarrierTests.allTests),
])
}
}
(LinuxMainRunnerImpl() as LinuxMainRunner).run()
#endif

241
scripts/generate_linux_tests.rb Executable file
View File

@ -0,0 +1,241 @@
#!/usr/bin/env ruby
#
# process_test_files.rb
#
# Copyright 2016 Tony Stone
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Created by Tony Stone on 5/4/16.
#
require 'getoptlong'
require 'fileutils'
require 'pathname'
include FileUtils
#
# This ruby script will auto generate LinuxMain.swift and the +XCTest.swift extension files for Swift Package Manager on Linux platforms.
#
# See https://github.com/apple/swift-corelibs-xctest/blob/master/Documentation/Linux.md
#
def header(fileName)
string = <<-eos
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift Baggage Context open source project
//
// Copyright (c) 2020 Moritz Lang and the Swift Baggage Context project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
//
// <FileName>
//
import XCTest
///
/// NOTE: This file was generated by generate_linux_tests.rb
///
/// Do NOT edit this file directly as it will be regenerated automatically when needed.
///
eos
string
.sub('<FileName>', File.basename(fileName))
.sub('<Date>', Time.now.to_s)
end
def createExtensionFile(fileName, classes)
extensionFile = fileName.sub! '.swift', '+XCTest.swift'
print 'Creating file: ' + extensionFile + "\n"
File.open(extensionFile, 'w') do |file|
file.write header(extensionFile)
file.write "\n"
for classArray in classes
file.write 'extension ' + classArray[0] + " {\n\n"
file.write ' @available(*, deprecated, message: "not actually deprecated. Just deprecated to allow deprecated tests (which test deprecated functionality) without warnings")' +"\n"
file.write ' static var allTests : [(String, (' + classArray[0] + ") -> () throws -> Void)] {\n"
file.write " return [\n"
for funcName in classArray[1]
file.write ' ("' + funcName + '", ' + funcName + "),\n"
end
file.write " ]\n"
file.write " }\n"
file.write "}\n\n"
end
end
end
def createLinuxMain(testsDirectory, allTestSubDirectories, files)
fileName = testsDirectory + '/LinuxMain.swift'
print 'Creating file: ' + fileName + "\n"
File.open(fileName, 'w') do |file|
file.write header(fileName)
file.write "\n"
file.write "#if os(Linux) || os(FreeBSD)\n"
for testSubDirectory in allTestSubDirectories.sort { |x, y| x <=> y }
file.write ' @testable import ' + testSubDirectory + "\n"
end
file.write "\n"
file.write "// This protocol is necessary to we can call the 'run' method (on an existential of this protocol)\n"
file.write "// without the compiler noticing that we're calling a deprecated function.\n"
file.write "// This hack exists so we can deprecate individual tests which test deprecated functionality without\n"
file.write "// getting a compiler warning...\n"
file.write "protocol LinuxMainRunner { func run() }\n"
file.write "class LinuxMainRunnerImpl: LinuxMainRunner {\n"
file.write ' @available(*, deprecated, message: "not actually deprecated. Just deprecated to allow deprecated tests (which test deprecated functionality) without warnings")' + "\n"
file.write " func run() {\n"
file.write " XCTMain([\n"
testCases = []
for classes in files
for classArray in classes
testCases << classArray[0]
end
end
for testCase in testCases.sort { |x, y| x <=> y }
file.write ' testCase(' + testCase + ".allTests),\n"
end
file.write " ])\n"
file.write " }\n"
file.write "}\n"
file.write "(LinuxMainRunnerImpl() as LinuxMainRunner).run()\n"
file.write "#endif\n"
end
end
def parseSourceFile(fileName)
puts 'Parsing file: ' + fileName + "\n"
classes = []
currentClass = nil
inIfLinux = false
inElse = false
ignore = false
#
# Read the file line by line
# and parse to find the class
# names and func names
#
File.readlines(fileName).each do |line|
if inIfLinux
if /\#else/.match(line)
inElse = true
ignore = true
else
if /\#end/.match(line)
inElse = false
inIfLinux = false
ignore = false
end
end
else
if /\#if[ \t]+os\(Linux\)/.match(line)
inIfLinux = true
ignore = false
end
end
next if ignore
# Match class or func
match = line[/class[ \t]+[a-zA-Z0-9_]*(?=[ \t]*:[ \t]*XCTestCase)|func[ \t]+test[a-zA-Z0-9_]*(?=[ \t]*\(\))/, 0]
if match
if match[/class/, 0] == 'class'
className = match.sub(/^class[ \t]+/, '')
#
# Create a new class / func structure
# and add it to the classes array.
#
currentClass = [className, []]
classes << currentClass
else # Must be a func
funcName = match.sub(/^func[ \t]+/, '')
#
# Add each func name the the class / func
# structure created above.
#
currentClass[1] << funcName
end
end
end
classes
end
#
# Main routine
#
#
testsDirectory = 'Tests'
options = GetoptLong.new(['--tests-dir', GetoptLong::OPTIONAL_ARGUMENT])
options.quiet = true
begin
options.each do |option, value|
case option
when '--tests-dir'
testsDirectory = value
end
end
rescue GetoptLong::InvalidOption
end
allTestSubDirectories = []
allFiles = []
Dir[testsDirectory + '/*'].each do |subDirectory|
next unless File.directory?(subDirectory)
directoryHasClasses = false
Dir[subDirectory + '/*Test{s,}.swift'].each do |fileName|
next unless File.file? fileName
fileClasses = parseSourceFile(fileName)
#
# If there are classes in the
# test source file, create an extension
# file for it.
#
next unless fileClasses.count > 0
createExtensionFile(fileName, fileClasses)
directoryHasClasses = true
allFiles << fileClasses
end
if directoryHasClasses
allTestSubDirectories << Pathname.new(subDirectory).split.last.to_s
end
end
#
# Last step is the create a LinuxMain.swift file that
# references all the classes and funcs in the source files.
#
if allFiles.count > 0
createLinuxMain(testsDirectory, allTestSubDirectories, allFiles)
end
# eof

View File

@ -15,6 +15,18 @@
set -eu
here="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
printf "=> Checking linux tests... "
FIRST_OUT="$(git status --porcelain)"
ruby "$here/../scripts/generate_linux_tests.rb" > /dev/null
SECOND_OUT="$(git status --porcelain)"
if [[ "$FIRST_OUT" != "$SECOND_OUT" ]]; then
printf "\033[0;31mmissing changes!\033[0m\n"
git --no-pager diff
exit 1
else
printf "\033[0;32mokay.\033[0m\n"
fi
bash $here/validate_license_headers.sh
bash $here/validate_format.sh
bash $here/validate_naming.sh