diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bb460e7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.DS_Store +/.build +/Packages +/*.xcodeproj +xcuserdata/ +DerivedData/ +.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/Beton.iml b/.idea/Beton.iml new file mode 100644 index 0000000..97d3aaa --- /dev/null +++ b/.idea/Beton.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..edc9591 --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,50 @@ + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..79ee123 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/markdown.xml b/.idea/markdown.xml new file mode 100644 index 0000000..ec0b30f --- /dev/null +++ b/.idea/markdown.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7026b53 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,16 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..ce42929 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..fdfc178 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 21Gram Consulting + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/Package.swift b/Package.swift new file mode 100644 index 0000000..58b39a7 --- /dev/null +++ b/Package.swift @@ -0,0 +1,51 @@ +// swift-tools-version:5.5 + +import PackageDescription + +let package = Package( + name: "Beton", + defaultLocalization: LanguageTag("en_US"), + platforms: [ + .macOS(.v12) + ], + products: [ + .library(name: "Beton", targets: ["Beton"]), + ], + targets: [ + .target(name: "Beton"), + .target( + name: "XCTBeton", + dependencies: [ + .byName(name: "Beton") + ] + ), + .testTarget(type: .unit), + .testTarget(type: .component), + .testTarget(type: .integration), + .testTarget(type: .system), + .testTarget(type: .performance), + ] +) + +/// MARK: Convenience units + +extension PackageDescription.Target { + enum TestType: String { + case unit = "Unit" + case component = "Component" + case integration = "Integration" + case system = "System" + case performance = "Performance" + } + + static func testTarget(type: TestType) -> PackageDescription.Target { + .testTarget( + name: "\(type.rawValue)Tests", + dependencies: [ + .byName(name: "Beton"), + .byName(name: "XCTBeton") + ], + resources: [.process("Resources")] + ) + } +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..cea07b4 --- /dev/null +++ b/README.md @@ -0,0 +1,10 @@ +# Beton + +A description of this package. + +```bash + +docc convert --transform-for-static-hosting \ +--additional-symbol-graph-dir .build + +``` \ No newline at end of file diff --git a/Sources/Beton/Beton.swift b/Sources/Beton/Beton.swift new file mode 100644 index 0000000..ff2b4e2 --- /dev/null +++ b/Sources/Beton/Beton.swift @@ -0,0 +1 @@ +@_exported import Foundation diff --git a/Sources/Beton/Bundle/Bundle+localizationBundles.swift b/Sources/Beton/Bundle/Bundle+localizationBundles.swift new file mode 100644 index 0000000..38e564b --- /dev/null +++ b/Sources/Beton/Bundle/Bundle+localizationBundles.swift @@ -0,0 +1,17 @@ +import Foundation + +public extension Bundle { + var localizationBundles: [Locale: Bundle] { + localizations + .compactMap { [self] in + guard let path = path(forResource: $0, ofType: "lproj") else { return nil } + guard let bundle = Bundle(path: path) else { return nil } + return (key: Locale(identifier: $0), value: bundle) + } + .reduce([:]) { (bundles: [Locale: Bundle], entry: (key: Locale, value: Bundle)) in + var bundles = bundles + bundles[entry.key] = entry.value + return bundles + } + } +} diff --git a/Sources/Beton/Bundle/Bundle+localizedString.swift b/Sources/Beton/Bundle/Bundle+localizedString.swift new file mode 100644 index 0000000..2aa1d34 --- /dev/null +++ b/Sources/Beton/Bundle/Bundle+localizedString.swift @@ -0,0 +1,15 @@ +import Foundation + +public extension Bundle { + func localizedString(_ key: String) -> String { + self.localizedString(forKey: key, value: nil, table: nil) + } + + func localizedString(_ key: String, from table: String) -> String { + self.localizedString(forKey: key, value: nil, table: table) + } + + func localizedString(_ key: String, fallback: String) -> String { + self.localizedString(forKey: key, value: fallback, table: nil) + } +} \ No newline at end of file diff --git a/Sources/Beton/Math/pow.swift b/Sources/Beton/Math/pow.swift new file mode 100644 index 0000000..b1632c9 --- /dev/null +++ b/Sources/Beton/Math/pow.swift @@ -0,0 +1,8 @@ +import Foundation + +public func pow(_ x: Measurement, _ y: Double) -> Measurement { + Measurement( + value: pow(x.value, y), + unit: x.unit + ) +} \ No newline at end of file diff --git a/Sources/Beton/Math/sqrt.swift b/Sources/Beton/Math/sqrt.swift new file mode 100644 index 0000000..6003c97 --- /dev/null +++ b/Sources/Beton/Math/sqrt.swift @@ -0,0 +1,8 @@ +import Foundation + +public func sqrt(_ x: Measurement) -> Measurement { + Measurement( + value: sqrt(x.value), + unit: x.unit + ) +} \ No newline at end of file diff --git a/Sources/Beton/Measurement/Measurement+AdditiveArithmetic.swift b/Sources/Beton/Measurement/Measurement+AdditiveArithmetic.swift new file mode 100644 index 0000000..cccf148 --- /dev/null +++ b/Sources/Beton/Measurement/Measurement+AdditiveArithmetic.swift @@ -0,0 +1,5 @@ +import Foundation + +extension Measurement: AdditiveArithmetic where UnitType: Unit, UnitType.U == UnitType { + public static var zero: Self { Self.init(value: 0.0, unit: .default) } +} diff --git a/Sources/Beton/Measurement/Unit/Unit.swift b/Sources/Beton/Measurement/Unit/Unit.swift new file mode 100644 index 0000000..89e4efd --- /dev/null +++ b/Sources/Beton/Measurement/Unit/Unit.swift @@ -0,0 +1,6 @@ +import Foundation + +public protocol Unit: Foundation.Unit { + associatedtype U = Self + static var `default`: U { get } +} diff --git a/Sources/Beton/Measurement/Unit/UnitAcceleration+default.swift b/Sources/Beton/Measurement/Unit/UnitAcceleration+default.swift new file mode 100644 index 0000000..c14f447 --- /dev/null +++ b/Sources/Beton/Measurement/Unit/UnitAcceleration+default.swift @@ -0,0 +1,5 @@ +import Foundation + +extension UnitAcceleration: Unit { + public static var `default`: UnitAcceleration { .metersPerSecondSquared } +} \ No newline at end of file diff --git a/Sources/Beton/Measurement/Unit/UnitAngle+default.swift b/Sources/Beton/Measurement/Unit/UnitAngle+default.swift new file mode 100644 index 0000000..6d09204 --- /dev/null +++ b/Sources/Beton/Measurement/Unit/UnitAngle+default.swift @@ -0,0 +1,5 @@ +import Foundation + +extension UnitAngle: Unit { + public static var `default`: UnitAngle { .degrees } +} diff --git a/Sources/Beton/Measurement/Unit/UnitArea+default.swift b/Sources/Beton/Measurement/Unit/UnitArea+default.swift new file mode 100644 index 0000000..6fb3972 --- /dev/null +++ b/Sources/Beton/Measurement/Unit/UnitArea+default.swift @@ -0,0 +1,5 @@ +import Foundation + +extension UnitArea: Unit { + public static var `default`: UnitArea { .squareMeters } +} diff --git a/Sources/Beton/Measurement/Unit/UnitConcentrationMass+default.swift b/Sources/Beton/Measurement/Unit/UnitConcentrationMass+default.swift new file mode 100644 index 0000000..26d3a77 --- /dev/null +++ b/Sources/Beton/Measurement/Unit/UnitConcentrationMass+default.swift @@ -0,0 +1,5 @@ +import Foundation + +extension UnitConcentrationMass: Unit { + public static var `default`: UnitConcentrationMass { .gramsPerLiter } +} diff --git a/Sources/Beton/Measurement/Unit/UnitDispersion+default.swift b/Sources/Beton/Measurement/Unit/UnitDispersion+default.swift new file mode 100644 index 0000000..e8132e7 --- /dev/null +++ b/Sources/Beton/Measurement/Unit/UnitDispersion+default.swift @@ -0,0 +1,5 @@ +import Foundation + +extension UnitDispersion: Unit { + public static var `default`: UnitDispersion { .partsPerMillion } +} diff --git a/Sources/Beton/Measurement/Unit/UnitDuration+default.swift b/Sources/Beton/Measurement/Unit/UnitDuration+default.swift new file mode 100644 index 0000000..4519711 --- /dev/null +++ b/Sources/Beton/Measurement/Unit/UnitDuration+default.swift @@ -0,0 +1,5 @@ +import Foundation + +extension UnitDuration: Unit { + public static var `default`: UnitDuration { .seconds } +} \ No newline at end of file diff --git a/Sources/Beton/Measurement/Unit/UnitElectricCharge+default.swift b/Sources/Beton/Measurement/Unit/UnitElectricCharge+default.swift new file mode 100644 index 0000000..b1d16e7 --- /dev/null +++ b/Sources/Beton/Measurement/Unit/UnitElectricCharge+default.swift @@ -0,0 +1,5 @@ +import Foundation + +extension UnitElectricCharge: Unit { + public static var `default`: UnitElectricCharge { .ampereHours } +} diff --git a/Sources/Beton/Measurement/Unit/UnitElectricCurrent+default.swift b/Sources/Beton/Measurement/Unit/UnitElectricCurrent+default.swift new file mode 100644 index 0000000..eaf852a --- /dev/null +++ b/Sources/Beton/Measurement/Unit/UnitElectricCurrent+default.swift @@ -0,0 +1,5 @@ +import Foundation + +extension UnitElectricCurrent: Unit { + public static var `default`: UnitElectricCurrent { .amperes } +} diff --git a/Sources/Beton/Measurement/Unit/UnitElectricPotentialDifference+default.swift b/Sources/Beton/Measurement/Unit/UnitElectricPotentialDifference+default.swift new file mode 100644 index 0000000..af5d0bc --- /dev/null +++ b/Sources/Beton/Measurement/Unit/UnitElectricPotentialDifference+default.swift @@ -0,0 +1,5 @@ +import Foundation + +extension UnitElectricPotentialDifference: Unit { + public static var `default`: UnitElectricPotentialDifference { .volts } +} diff --git a/Sources/Beton/Measurement/Unit/UnitElectricResistance+default.swift b/Sources/Beton/Measurement/Unit/UnitElectricResistance+default.swift new file mode 100644 index 0000000..f9dbe71 --- /dev/null +++ b/Sources/Beton/Measurement/Unit/UnitElectricResistance+default.swift @@ -0,0 +1,5 @@ +import Foundation + +extension UnitElectricResistance: Unit { + public static var `default`: UnitElectricResistance { .ohms } +} diff --git a/Sources/Beton/Measurement/Unit/UnitEnergy+default.swift b/Sources/Beton/Measurement/Unit/UnitEnergy+default.swift new file mode 100644 index 0000000..e8ff819 --- /dev/null +++ b/Sources/Beton/Measurement/Unit/UnitEnergy+default.swift @@ -0,0 +1,5 @@ +import Foundation + +extension UnitEnergy: Unit { + public static var `default`: UnitEnergy { .joules } +} diff --git a/Sources/Beton/Measurement/Unit/UnitFrequency+default.swift b/Sources/Beton/Measurement/Unit/UnitFrequency+default.swift new file mode 100644 index 0000000..ffd2df5 --- /dev/null +++ b/Sources/Beton/Measurement/Unit/UnitFrequency+default.swift @@ -0,0 +1,5 @@ +import Foundation + +extension UnitFrequency: Unit { + public static var `default`: UnitFrequency { .hertz } +} \ No newline at end of file diff --git a/Sources/Beton/Measurement/Unit/UnitFuelEfficiency+default.swift b/Sources/Beton/Measurement/Unit/UnitFuelEfficiency+default.swift new file mode 100644 index 0000000..d10f464 --- /dev/null +++ b/Sources/Beton/Measurement/Unit/UnitFuelEfficiency+default.swift @@ -0,0 +1,5 @@ +import Foundation + +extension UnitFuelEfficiency: Unit { + public static var `default`: UnitFuelEfficiency { .litersPer100Kilometers } +} diff --git a/Sources/Beton/Measurement/Unit/UnitIlluminance+default.swift b/Sources/Beton/Measurement/Unit/UnitIlluminance+default.swift new file mode 100644 index 0000000..0325432 --- /dev/null +++ b/Sources/Beton/Measurement/Unit/UnitIlluminance+default.swift @@ -0,0 +1,5 @@ +import Foundation + +extension UnitIlluminance: Unit { + public static var `default`: UnitIlluminance { .lux } +} diff --git a/Sources/Beton/Measurement/Unit/UnitInformationStorage+default.swift b/Sources/Beton/Measurement/Unit/UnitInformationStorage+default.swift new file mode 100644 index 0000000..102ac59 --- /dev/null +++ b/Sources/Beton/Measurement/Unit/UnitInformationStorage+default.swift @@ -0,0 +1,5 @@ +import Foundation + +extension UnitInformationStorage: Unit { + public static var `default`: UnitInformationStorage { .bits } +} diff --git a/Sources/Beton/Measurement/Unit/UnitLength+default.swift b/Sources/Beton/Measurement/Unit/UnitLength+default.swift new file mode 100644 index 0000000..96a8831 --- /dev/null +++ b/Sources/Beton/Measurement/Unit/UnitLength+default.swift @@ -0,0 +1,5 @@ +import Foundation + +extension UnitLength: Unit { + public static var `default`: UnitLength { .meters } +} \ No newline at end of file diff --git a/Sources/Beton/Measurement/Unit/UnitMass+default.swift b/Sources/Beton/Measurement/Unit/UnitMass+default.swift new file mode 100644 index 0000000..02ed877 --- /dev/null +++ b/Sources/Beton/Measurement/Unit/UnitMass+default.swift @@ -0,0 +1,5 @@ +import Foundation + +extension UnitMass: Unit { + public static var `default`: UnitMass { .grams } +} diff --git a/Sources/Beton/Measurement/Unit/UnitPower+default.swift b/Sources/Beton/Measurement/Unit/UnitPower+default.swift new file mode 100644 index 0000000..cc9d8a6 --- /dev/null +++ b/Sources/Beton/Measurement/Unit/UnitPower+default.swift @@ -0,0 +1,5 @@ +import Foundation + +extension UnitPower: Unit { + public static var `default`: UnitPower { .watts } +} diff --git a/Sources/Beton/Measurement/Unit/UnitPressure+default.swift b/Sources/Beton/Measurement/Unit/UnitPressure+default.swift new file mode 100644 index 0000000..35a1e3f --- /dev/null +++ b/Sources/Beton/Measurement/Unit/UnitPressure+default.swift @@ -0,0 +1,5 @@ +import Foundation + +extension UnitPressure: Unit { + public static var `default`: UnitPressure { .bars } +} diff --git a/Sources/Beton/Measurement/Unit/UnitSpeed+default.swift b/Sources/Beton/Measurement/Unit/UnitSpeed+default.swift new file mode 100644 index 0000000..e3fcdde --- /dev/null +++ b/Sources/Beton/Measurement/Unit/UnitSpeed+default.swift @@ -0,0 +1,5 @@ +import Foundation + +extension UnitSpeed: Unit { + public static var `default`: UnitSpeed { .kilometersPerHour } +} diff --git a/Sources/Beton/Measurement/Unit/UnitTemperature+default.swift b/Sources/Beton/Measurement/Unit/UnitTemperature+default.swift new file mode 100644 index 0000000..7421bd5 --- /dev/null +++ b/Sources/Beton/Measurement/Unit/UnitTemperature+default.swift @@ -0,0 +1,5 @@ +import Foundation + +extension UnitTemperature: Unit { + public static var `default`: UnitTemperature { .celsius } +} diff --git a/Sources/Beton/Measurement/Unit/UnitVolume+default.swift b/Sources/Beton/Measurement/Unit/UnitVolume+default.swift new file mode 100644 index 0000000..7b046b1 --- /dev/null +++ b/Sources/Beton/Measurement/Unit/UnitVolume+default.swift @@ -0,0 +1,5 @@ +import Foundation + +extension UnitVolume: Unit { + public static var `default`: UnitVolume { .liters } +} diff --git a/Sources/Beton/Sequence/Sequence+sum.swift b/Sources/Beton/Sequence/Sequence+sum.swift new file mode 100644 index 0000000..fc3444a --- /dev/null +++ b/Sources/Beton/Sequence/Sequence+sum.swift @@ -0,0 +1,5 @@ +import Foundation + +public extension Sequence where Self.Element: AdditiveArithmetic { + func sum() -> Element { reduce(Element.zero, +) } +} diff --git a/Sources/XCTBeton/Performance/XCTMeasureOptions.swift b/Sources/XCTBeton/Performance/XCTMeasureOptions.swift new file mode 100644 index 0000000..3c3816f --- /dev/null +++ b/Sources/XCTBeton/Performance/XCTMeasureOptions.swift @@ -0,0 +1,4 @@ +import Beton +import class XCTest.XCTMeasureOptions + +open class XCTMeasureOptions: XCTest.XCTMeasureOptions {} diff --git a/Sources/XCTBeton/Performance/XCTMetric/XCTCPUMetric.swift b/Sources/XCTBeton/Performance/XCTMetric/XCTCPUMetric.swift new file mode 100644 index 0000000..3069f02 --- /dev/null +++ b/Sources/XCTBeton/Performance/XCTMetric/XCTCPUMetric.swift @@ -0,0 +1,15 @@ +import Beton +import class XCTest.XCTCPUMetric + +public class XCTCPUMetric: XCTest.XCTCPUMetric, XCTMetric { + deinit { forgetSelf() } + + public override func reportMeasurements(from startTime: XCTPerformanceMeasurementTimestamp, to endTime: XCTPerformanceMeasurementTimestamp) throws -> [XCTPerformanceMeasurement] { + storing(measurements: try super.reportMeasurements(from: startTime, to: endTime)) + } + + override public func copy(with zone: NSZone? = nil) -> Any { + remembering(copy: super.copy(with: zone)) + } + +} \ No newline at end of file diff --git a/Sources/XCTBeton/Performance/XCTMetric/XCTClockMetric.swift b/Sources/XCTBeton/Performance/XCTMetric/XCTClockMetric.swift new file mode 100644 index 0000000..5286e93 --- /dev/null +++ b/Sources/XCTBeton/Performance/XCTMetric/XCTClockMetric.swift @@ -0,0 +1,15 @@ +import Beton +import class XCTest.XCTClockMetric + +public class XCTClockMetric: XCTest.XCTClockMetric, XCTMetric { + deinit { forgetSelf() } + + public override func reportMeasurements(from startTime: XCTPerformanceMeasurementTimestamp, to endTime: XCTPerformanceMeasurementTimestamp) throws -> [XCTPerformanceMeasurement] { + storing(measurements: try super.reportMeasurements(from: startTime, to: endTime)) + } + + override public func copy(with zone: NSZone? = nil) -> Any { + remembering(copy: super.copy(with: zone)) + } + +} \ No newline at end of file diff --git a/Sources/XCTBeton/Performance/XCTMetric/XCTMemoryMetric.swift b/Sources/XCTBeton/Performance/XCTMetric/XCTMemoryMetric.swift new file mode 100644 index 0000000..9f6204c --- /dev/null +++ b/Sources/XCTBeton/Performance/XCTMetric/XCTMemoryMetric.swift @@ -0,0 +1,15 @@ +import Beton +import class XCTest.XCTMemoryMetric + +public class XCTMemoryMetric: XCTest.XCTMemoryMetric, XCTMetric { + deinit { forgetSelf() } + + public override func reportMeasurements(from startTime: XCTPerformanceMeasurementTimestamp, to endTime: XCTPerformanceMeasurementTimestamp) throws -> [XCTPerformanceMeasurement] { + storing(measurements: try super.reportMeasurements(from: startTime, to: endTime)) + } + + override public func copy(with zone: NSZone? = nil) -> Any { + remembering(copy: super.copy(with: zone)) + } + +} \ No newline at end of file diff --git a/Sources/XCTBeton/Performance/XCTMetric/XCTMetric+measurementStorage.swift b/Sources/XCTBeton/Performance/XCTMetric/XCTMetric+measurementStorage.swift new file mode 100644 index 0000000..267d977 --- /dev/null +++ b/Sources/XCTBeton/Performance/XCTMetric/XCTMetric+measurementStorage.swift @@ -0,0 +1,37 @@ +import Beton + +fileprivate var results: [ObjectIdentifier: [XCTPerformanceMeasurement]] = [:] +fileprivate var copyMap: [ObjectIdentifier: ObjectIdentifier] = [:] + +public extension XCTMetric { + var measurements: [XCTPerformanceMeasurement] { results[id] ?? [] } +} + +internal extension XCTMetric { + func storing(measurements: [XCTPerformanceMeasurement]) -> [XCTPerformanceMeasurement] { + if results[originId] == nil { results[originId] = [] } + results[originId]?.append(contentsOf: measurements) + return measurements + } + + func remembering(copy: Copy) -> Copy { + if let copy = copy as? Self { copyMap[copy.id] = id } + return copy + } + + func forgetSelf() { + results[id] = nil + copyMap[id] = nil + } +} + +fileprivate extension XCTMetric { + var id: ObjectIdentifier { ObjectIdentifier(self) } + + var originId: ObjectIdentifier { + var originId = id + while copyMap[originId] != nil { originId = copyMap[originId]! } + return originId + } + +} \ No newline at end of file diff --git a/Sources/XCTBeton/Performance/XCTMetric/XCTMetric.swift b/Sources/XCTBeton/Performance/XCTMetric/XCTMetric.swift new file mode 100644 index 0000000..1c4f768 --- /dev/null +++ b/Sources/XCTBeton/Performance/XCTMetric/XCTMetric.swift @@ -0,0 +1,7 @@ +import Beton +import protocol XCTest.XCTMetric +import class XCTest.XCTPerformanceMeasurement + +public protocol XCTMetric: XCTest.XCTMetric { + var measurements: [XCTPerformanceMeasurement] { get } +} diff --git a/Sources/XCTBeton/Performance/XCTMetric/XCTStorageMetric.swift b/Sources/XCTBeton/Performance/XCTMetric/XCTStorageMetric.swift new file mode 100644 index 0000000..8969d93 --- /dev/null +++ b/Sources/XCTBeton/Performance/XCTMetric/XCTStorageMetric.swift @@ -0,0 +1,16 @@ +import Beton +import class XCTest.XCTStorageMetric + +public class XCTStorageMetric: XCTest.XCTStorageMetric, XCTMetric { + + deinit { forgetSelf() } + + public override func reportMeasurements(from startTime: XCTPerformanceMeasurementTimestamp, to endTime: XCTPerformanceMeasurementTimestamp) throws -> [XCTPerformanceMeasurement] { + storing(measurements: try super.reportMeasurements(from: startTime, to: endTime)) + } + + override public func copy(with zone: NSZone? = nil) -> Any { + remembering(copy: super.copy(with: zone)) + } + +} \ No newline at end of file diff --git a/Sources/XCTBeton/XCTBeton.swift b/Sources/XCTBeton/XCTBeton.swift new file mode 100644 index 0000000..9c5629a --- /dev/null +++ b/Sources/XCTBeton/XCTBeton.swift @@ -0,0 +1,97 @@ +@_exported import func XCTest.XCTAssertEqual +@_exported import var XCTest.XCT_UI_TESTING_AVAILABLE +@_exported import let XCTest.XCTestErrorDomain +@_exported import struct XCTest.XCTestError +@_exported import class XCTest._XCTestCaseInterruptionException +@_exported import func XCTest._XCTPreformattedFailureHandler +@_exported import func XCTest.XCTAssertThrowsError +@_exported import class XCTest.XCUIElement +@_exported import func XCTest.XCTAssertNil +@_exported import class XCTest.XCTestObserver +@_exported import protocol XCTest.XCTestObservation +@_exported import class XCTest.XCTestObservationCenter +@_exported import class XCTest.XCTIssueReference +@_exported import enum XCTest.XCUIProtectedResource +@_exported import protocol XCTest.XCUIScreenshotProviding +@_exported import func XCTest.XCTAssertNotEqualWithAccuracy +@_exported import class XCTest.XCTExpectedFailure +@_exported import func XCTest.XCTAssertEqualWithAccuracy +@_exported import class XCTest.XCTKVOExpectation +@_exported import func XCTest.XCTAssertTrue +@_exported import class XCTest.XCTMutableIssue +@_exported import class XCTest.XCTDarwinNotificationExpectation +@_exported import class XCTest.XCTestLog +@_exported import protocol XCTest.XCUIElementAttributes +@_exported import class XCTest.XCTSourceCodeSymbolInfo +@_exported import func XCTest.XCTAssertNotIdentical +@_exported import typealias XCTest.XCWaitCompletionHandler +@_exported import let XCTest.XCTestScopeNone +@_exported import let XCTest.XCUIIdentifierCloseWindow +@_exported import struct XCTest.XCUIKeyboardKey +@_exported import class XCTest.XCUIScreenshot +@_exported import let XCTest.XCTestToolKey +@_exported import func XCTest.XCTSkipUnless +@_exported import class XCTest.XCTApplicationLaunchMetric +@_exported import struct XCTest.XCTSkip +@_exported import class XCTest.XCTPerformanceMeasurement +@_exported import let XCTest.XCUIIdentifierZoomWindow +@_exported import class XCTest.XCTNSNotificationExpectation +@_exported import func XCTest.XCTAssertIdentical +@_exported import let XCTest.XCTestScopeAll +@_exported import class XCTest.XCTSourceCodeLocation +@_exported import class XCTest.XCUIElementQuery +@_exported import func XCTest.XCTAssert +@_exported import func XCTest.XCTAssertNoThrow +@_exported import func XCTest.XCTAssertLessThan +@_exported import let XCTest.XCTestObserverClassKey +@_exported import func XCTest._XCTDescriptionForValue +@_exported import func XCTest.XCTAssertNotEqual +@_exported import protocol XCTest.XCUIElementTypeQueryProvider +@_exported import class XCTest.XCTPerformanceMeasurementTimestamp +@_exported import let XCTest.XCTestedUnitPath +@_exported import class XCTest.XCTestSuite +@_exported import func XCTest.XCTAssertNotNil +@_exported import class XCTest.XCUIApplication +@_exported import class XCTest.XCTNSPredicateExpectation +@_exported import class XCTest.XCTAttachment +@_exported import class XCTest.XCUICoordinate +@_exported import class XCTest.XCTOSSignpostMetric +@_exported import enum XCTest.XCUIRemoteButton +@_exported import let XCTest.XCUIIdentifierMinimizeWindow +@_exported import class XCTest.XCTestRun +@_exported import protocol XCTest.XCUIElementSnapshotProviding +@_exported import protocol XCTest.XCUIElementSnapshot +@_exported import func XCTest.XCTFail +@_exported import struct XCTest.XCTPerformanceMetric +@_exported import let XCTest.XCTestScopeKey +@_exported import class XCTest.XCTestProbe +@_exported import func XCTest.XCTAssertGreaterThan +@_exported import class XCTest.XCTestExpectation +@_exported import func XCTest.XCTExpectFailure +@_exported import struct XCTest.XCTIssue +@_exported import enum XCTest._XCTAssertionType +@_exported import func XCTest._XCTFailureFormat +@_exported import func XCTest.XCTAssertFalse +@_exported import func XCTest.XCTAssertGreaterThanOrEqual +@_exported import class XCTest.XCTSourceCodeContext +@_exported import class XCTest.XCTSourceCodeFrame +@_exported import class XCTest.XCTestSuiteRun +@_exported import class XCTest.XCTWaiter +@_exported import func XCTest.XCTSelfTestMain +@_exported import let XCTest.XCUIIdentifierFullScreenWindow +@_exported import protocol XCTest.XCTActivity +@_exported import func XCTest.XCTAssertLessThanOrEqual +@_exported import func XCTest.XCTSkipIf +@_exported import struct XCTest.XCUIGestureVelocity +@_exported import func XCTest.XCTUnwrap +@_exported import protocol XCTest.XCTWaiterDelegate +@_exported import class XCTest._XCTSkipFailureException +@_exported import let XCTest.XCTestScopeSelf +@_exported import class XCTest.XCTContext +@_exported import class XCTest.XCUIScreen +@_exported import class XCTest.XCTestCaseRun +@_exported import func XCTest.XCTAssertEqual + +import class XCTest.XCTest + +public typealias XCTBeton = XCTest \ No newline at end of file diff --git a/Sources/XCTBeton/XCTestCase/XCTAssertMetric/XCTAssertClockIdentifier.swift b/Sources/XCTBeton/XCTestCase/XCTAssertMetric/XCTAssertClockIdentifier.swift new file mode 100644 index 0000000..a4a8efc --- /dev/null +++ b/Sources/XCTBeton/XCTestCase/XCTAssertMetric/XCTAssertClockIdentifier.swift @@ -0,0 +1,15 @@ +import Beton + +public enum XCTAssertClockIdentifier { + case timeMonotonic +} + +extension XCTAssertClockIdentifier: XCTAssertMetricIdentifier { + public typealias RelatedMetric = XCTClockMetric + + public var identifier: String { + switch self { + case .timeMonotonic: return "com.apple.dt.XCTMetric_Clock.time.monotonic" + } + } +} diff --git a/Sources/XCTBeton/XCTestCase/XCTAssertMetric/XCTAssertCpuIdentifier.swift b/Sources/XCTBeton/XCTestCase/XCTAssertMetric/XCTAssertCpuIdentifier.swift new file mode 100644 index 0000000..4fea8ed --- /dev/null +++ b/Sources/XCTBeton/XCTestCase/XCTAssertMetric/XCTAssertCpuIdentifier.swift @@ -0,0 +1,19 @@ +import Beton + +public enum XCTAssertCpuIdentifier { + case time + case cycles + case instructionsRetired +} + +extension XCTAssertCpuIdentifier: XCTAssertMetricIdentifier { + public typealias RelatedMetric = XCTCPUMetric + + public var identifier: String { + switch self { + case .time: return "com.apple.dt.XCTMetric_CPU.time" + case .cycles: return "com.apple.dt.XCTMetric_CPU.cycles" + case .instructionsRetired: return "com.apple.dt.XCTMetric_CPU.instructions_retired" + } + } +} diff --git a/Sources/XCTBeton/XCTestCase/XCTAssertMetric/XCTAssertDiskIdentifier.swift b/Sources/XCTBeton/XCTestCase/XCTAssertMetric/XCTAssertDiskIdentifier.swift new file mode 100644 index 0000000..ff46274 --- /dev/null +++ b/Sources/XCTBeton/XCTestCase/XCTAssertMetric/XCTAssertDiskIdentifier.swift @@ -0,0 +1,15 @@ +import Beton + +public enum XCTAssertDiskIdentifier { + case logicalWrites +} + +extension XCTAssertDiskIdentifier: XCTAssertMetricIdentifier { + public typealias RelatedMetric = XCTStorageMetric + + public var identifier: String { + switch self { + case .logicalWrites: return "com.apple.dt.XCTMetric_Disk.logical_writes" + } + } +} diff --git a/Sources/XCTBeton/XCTestCase/XCTAssertMetric/XCTAssertMemoryIdentifier.swift b/Sources/XCTBeton/XCTestCase/XCTAssertMetric/XCTAssertMemoryIdentifier.swift new file mode 100644 index 0000000..29a19d0 --- /dev/null +++ b/Sources/XCTBeton/XCTestCase/XCTAssertMetric/XCTAssertMemoryIdentifier.swift @@ -0,0 +1,17 @@ +import Beton + +public enum XCTAssertMemoryIdentifier { + case physical + case physicalPeak +} + +extension XCTAssertMemoryIdentifier: XCTAssertMetricIdentifier { + public typealias RelatedMetric = XCTMemoryMetric + + public var identifier: String { + switch self { + case .physical: return "com.apple.dt.XCTMetric_Memory.physical" + case .physicalPeak: return "com.apple.dt.XCTMetric_Memory.physical_peak" + } + } +} diff --git a/Sources/XCTBeton/XCTestCase/XCTAssertMetric/XCTAssertMetric.swift b/Sources/XCTBeton/XCTestCase/XCTAssertMetric/XCTAssertMetric.swift new file mode 100644 index 0000000..ad292d6 --- /dev/null +++ b/Sources/XCTBeton/XCTestCase/XCTAssertMetric/XCTAssertMetric.swift @@ -0,0 +1,25 @@ +import Beton + +public struct XCTAssertMetric where Identifier: XCTAssertMetricIdentifier {} +public extension XCTAssertMetric { + static var cpu: XCTAssertMetric { .init() } + static var memory: XCTAssertMetric { .init() } + static var disk: XCTAssertMetric { .init() } + static var clock: XCTAssertMetric { .init() } +} + +public extension XCTAssertMetric { + enum Aspect { + case average(maximum: Double) + case relativeStandardDeviation(maximum: Double) + } +} + +internal extension XCTAssertMetric.Aspect { + var maximum: Double { + switch self { + case let .average(maximum): return maximum + case let .relativeStandardDeviation(maximum): return maximum + } + } +} \ No newline at end of file diff --git a/Sources/XCTBeton/XCTestCase/XCTAssertMetric/XCTestCase+XCTAssertMetric.swift b/Sources/XCTBeton/XCTestCase/XCTAssertMetric/XCTestCase+XCTAssertMetric.swift new file mode 100644 index 0000000..429b5ff --- /dev/null +++ b/Sources/XCTBeton/XCTestCase/XCTAssertMetric/XCTestCase+XCTAssertMetric.swift @@ -0,0 +1,67 @@ +import Beton +import XCTest + +extension XCTestCase { + public final func XCTAssertMetric( + _ metric: XCTAssertMetric, + _ identifier: Identifier, + _ aspect: XCTAssertMetric.Aspect, + _ message: @autoclosure () -> String = "", + file: StaticString = #filePath, + line: UInt = #line + ) { + let measurements: [Double] = fetchMeasurement(for: identifier).map(\.value).map(\.value) + XCTAssertLessThanOrEqual( + measurements[keyPath: aspect.measurementKeyPath], + aspect.maximum, + errorMessage(for: identifier, message: message()), + file: file, + line: line + ) + XCTAssertFalse( + measurements.isEmpty, + errorMessage( + for: identifier, + message: "No measurement results found." + ), + file: file, + line: line + ) + } + + private func errorMessage(for identifier: Identifier, message: String) -> String { + message.isEmpty + ? #"XCTAssertMetric<\#(Identifier.self).\#(identifier)>"# + : #"XCTAssertMetric<\#(Identifier.self).\#(identifier)> - \#(message)"# + } + + internal func fetchMeasurement(for identifier: Identifier) -> [XCTPerformanceMeasurement] where Identifier: XCTAssertMetricIdentifier { + lastRunMetrics + .compactMap { $0 as? Identifier.RelatedMetric } + .map(\.measurements) + .reduce([], +) + .filter { $0.identifier == identifier.identifier } // TODO: this naming is fucking dumb + } +} + +fileprivate extension Array where Element == Double { + var average: Element { sum() / Double(count) } + + var standardDeviation: Element { + let squaredDifferences = map { pow($0 - average, 2.0) } + let variance = squaredDifferences.reduce(.zero, +) / Double(count - 1) + return sqrt(variance) + } + + var relativeStandardDeviation: Double { standardDeviation / average } + +} + +fileprivate extension XCTAssertMetric.Aspect { + var measurementKeyPath: KeyPath<[Double], Double> { + switch self { + case .average: return \.average + case .relativeStandardDeviation: return \.relativeStandardDeviation + } + } +} \ No newline at end of file diff --git a/Sources/XCTBeton/XCTestCase/XCTAssertMetricIdentifier.swift b/Sources/XCTBeton/XCTestCase/XCTAssertMetricIdentifier.swift new file mode 100644 index 0000000..5280e19 --- /dev/null +++ b/Sources/XCTBeton/XCTestCase/XCTAssertMetricIdentifier.swift @@ -0,0 +1,6 @@ +import Beton + +public protocol XCTAssertMetricIdentifier { + associatedtype RelatedMetric: XCTMetric + var identifier: String { get } +} \ No newline at end of file diff --git a/Sources/XCTBeton/XCTestCase/XCTestCase+measure.swift b/Sources/XCTBeton/XCTestCase/XCTestCase+measure.swift new file mode 100644 index 0000000..2cf42b9 --- /dev/null +++ b/Sources/XCTBeton/XCTestCase/XCTestCase+measure.swift @@ -0,0 +1,17 @@ +import Beton + +extension XCTestCase { + @nonobjc open func measure(metrics: [XCTMetric], block: () -> Void) { + self.measure(metrics: metrics, options: Self.defaultMeasureOptions, block: block) + } + + @nonobjc open func measure(options: XCTMeasureOptions, block: () -> Void) { + self.measure(metrics: Self.defaultMetrics, options: options, block: block) + } + + @nonobjc open func measure(metrics: [XCTMetric], options: XCTMeasureOptions, block: () -> Void) { + super.measure(metrics: metrics, options: options, block: block) + precondition(lastRunMetrics.isEmpty, "Must not have performed measurements yet!") + lastRunMetrics = metrics + } +} \ No newline at end of file diff --git a/Sources/XCTBeton/XCTestCase/XCTestCase.swift b/Sources/XCTBeton/XCTestCase/XCTestCase.swift new file mode 100644 index 0000000..390c2f9 --- /dev/null +++ b/Sources/XCTBeton/XCTestCase/XCTestCase.swift @@ -0,0 +1,11 @@ +import Beton +import class XCTest.XCTestCase + +open class XCTestCase: XCTest.XCTestCase { + internal var lastRunMetrics: [XCTMetric] = [] +} + +extension XCTest.XCTestCase { + open class var defaultMetrics: [XCTMetric] { [XCTClockMetric()] } + open class var defaultMeasureOptions: XCTMeasureOptions { XCTMeasureOptions() } +} \ No newline at end of file diff --git a/Tests/ComponentTests/Resources/en_US.lproj/Test.strings b/Tests/ComponentTests/Resources/en_US.lproj/Test.strings new file mode 100644 index 0000000..85c3d86 --- /dev/null +++ b/Tests/ComponentTests/Resources/en_US.lproj/Test.strings @@ -0,0 +1 @@ +"Test" = "Test"; \ No newline at end of file diff --git a/Tests/ComponentTests/Resources/hu_HU.lproj/Test.strings b/Tests/ComponentTests/Resources/hu_HU.lproj/Test.strings new file mode 100644 index 0000000..eb55259 --- /dev/null +++ b/Tests/ComponentTests/Resources/hu_HU.lproj/Test.strings @@ -0,0 +1 @@ +"Test" = "Teszt"; \ No newline at end of file diff --git a/Tests/IntegrationTests/Resources/en_US.lproj/Test.strings b/Tests/IntegrationTests/Resources/en_US.lproj/Test.strings new file mode 100644 index 0000000..85c3d86 --- /dev/null +++ b/Tests/IntegrationTests/Resources/en_US.lproj/Test.strings @@ -0,0 +1 @@ +"Test" = "Test"; \ No newline at end of file diff --git a/Tests/IntegrationTests/Resources/hu_HU.lproj/Test.strings b/Tests/IntegrationTests/Resources/hu_HU.lproj/Test.strings new file mode 100644 index 0000000..eb55259 --- /dev/null +++ b/Tests/IntegrationTests/Resources/hu_HU.lproj/Test.strings @@ -0,0 +1 @@ +"Test" = "Teszt"; \ No newline at end of file diff --git a/Tests/PerformanceTests/Beton/Bundle/BundleTest.swift b/Tests/PerformanceTests/Beton/Bundle/BundleTest.swift new file mode 100644 index 0000000..e13fe20 --- /dev/null +++ b/Tests/PerformanceTests/Beton/Bundle/BundleTest.swift @@ -0,0 +1,51 @@ +import Beton +import XCTBeton + +class BundleTest: XCTestCase { + override func tearDown() { + super.tearDown() + XCTAssertMetric(.cpu, .cycles, .average(maximum: 5000)) + XCTAssertMetric(.cpu, .instructionsRetired, .average(maximum: 4500)) + XCTAssertMetric(.cpu, .time, .average(maximum: 0.002)) + XCTAssertMetric(.memory, .physical, .average(maximum: 60)) + XCTAssertMetric(.memory, .physicalPeak, .average(maximum: 0)) + XCTAssertMetric(.disk, .logicalWrites, .average(maximum: 0)) + XCTAssertMetric(.clock, .timeMonotonic, .average(maximum: 0.005)) + } + + func testLocalizationBundles() { + measure(metrics: .defaults) { + Bundle.module.localizationBundles + } + } + + func testLocalizedString_keyOnly() { + measure(metrics: .defaults) { + Bundle.module.localizedString("Test") + } + } + + func testLocalizedString_keyAndTableOnly() { + measure(metrics: .defaults) { + Bundle.module.localizedString("Test", from: "Test") + } + } + + func testLocalizedString_keyAndValueOnly() { + measure(metrics: .defaults) { + Bundle.module.localizedString("Test", fallback: "Test") + } + } + +} + +extension Array where Self.Element == XCTMetric { + static var defaults: [Element] { + [ + XCTCPUMetric(), + XCTMemoryMetric(), + XCTStorageMetric(), + XCTClockMetric(), + ] + } +} diff --git a/Tests/PerformanceTests/Resources/en_US.lproj/Test.strings b/Tests/PerformanceTests/Resources/en_US.lproj/Test.strings new file mode 100644 index 0000000..85c3d86 --- /dev/null +++ b/Tests/PerformanceTests/Resources/en_US.lproj/Test.strings @@ -0,0 +1 @@ +"Test" = "Test"; \ No newline at end of file diff --git a/Tests/PerformanceTests/Resources/hu_HU.lproj/Test.strings b/Tests/PerformanceTests/Resources/hu_HU.lproj/Test.strings new file mode 100644 index 0000000..eb55259 --- /dev/null +++ b/Tests/PerformanceTests/Resources/hu_HU.lproj/Test.strings @@ -0,0 +1 @@ +"Test" = "Teszt"; \ No newline at end of file diff --git a/Tests/SystemTests/Resources/en_US.lproj/Test.strings b/Tests/SystemTests/Resources/en_US.lproj/Test.strings new file mode 100644 index 0000000..85c3d86 --- /dev/null +++ b/Tests/SystemTests/Resources/en_US.lproj/Test.strings @@ -0,0 +1 @@ +"Test" = "Test"; \ No newline at end of file diff --git a/Tests/SystemTests/Resources/hu_HU.lproj/Test.strings b/Tests/SystemTests/Resources/hu_HU.lproj/Test.strings new file mode 100644 index 0000000..eb55259 --- /dev/null +++ b/Tests/SystemTests/Resources/hu_HU.lproj/Test.strings @@ -0,0 +1 @@ +"Test" = "Teszt"; \ No newline at end of file diff --git a/Tests/UnitTests/Beton/Bundle/BundleTest+localizedString.swift b/Tests/UnitTests/Beton/Bundle/BundleTest+localizedString.swift new file mode 100644 index 0000000..d1f3320 --- /dev/null +++ b/Tests/UnitTests/Beton/Bundle/BundleTest+localizedString.swift @@ -0,0 +1,26 @@ +import Foundation +import XCTest +@testable import Beton + +extension BundleTest { + func testLocalizedString_keyOnly() { + XCTAssertEqual( + Bundle.module.localizedString("Test"), + Bundle.module.localizedString(forKey: "Test", value: nil, table: nil) + ) + } + + func testLocalizedString_keyAndTableOnly() { + XCTAssertEqual( + Bundle.module.localizedString("Test", from: "Test"), + Bundle.module.localizedString(forKey: "Test", value: nil, table: "Test") + ) + } + + func testLocalizedString_keyAndValueOnly() { + XCTAssertEqual( + Bundle.module.localizedString("Test", fallback: "Test"), + Bundle.module.localizedString(forKey: "Test", value: "Test", table: nil) + ) + } +} diff --git a/Tests/UnitTests/Beton/Bundle/BundleTest+localiztationBundles.swift b/Tests/UnitTests/Beton/Bundle/BundleTest+localiztationBundles.swift new file mode 100644 index 0000000..95c30ed --- /dev/null +++ b/Tests/UnitTests/Beton/Bundle/BundleTest+localiztationBundles.swift @@ -0,0 +1,11 @@ +import Foundation +import XCTest +@testable import Beton + +extension BundleTest { + func testLocalizationBundles() { + XCTAssertTrue(Bundle.module.localizationBundles.keys.contains(Locale(identifier: "en_US"))) + XCTAssertTrue(Bundle.module.localizationBundles.keys.contains(Locale(identifier: "hu_HU"))) + XCTAssertFalse(Bundle.module.localizationBundles.keys.contains(Locale(identifier: "de_DE"))) + } +} \ No newline at end of file diff --git a/Tests/UnitTests/Beton/Bundle/BundleTest.swift b/Tests/UnitTests/Beton/Bundle/BundleTest.swift new file mode 100644 index 0000000..f499940 --- /dev/null +++ b/Tests/UnitTests/Beton/Bundle/BundleTest.swift @@ -0,0 +1,4 @@ +import Foundation +import XCTest + +class BundleTest: XCTestCase {} diff --git a/Tests/UnitTests/Beton/MathTest.swift b/Tests/UnitTests/Beton/MathTest.swift new file mode 100644 index 0000000..399cf6c --- /dev/null +++ b/Tests/UnitTests/Beton/MathTest.swift @@ -0,0 +1,20 @@ +import Foundation +import XCTest +@testable import Beton + +class MathTest: XCTestCase { + + func testPow() { + XCTAssertEqual( + pow(Measurement(value: 2, unit: .bits), 3), + Measurement(value: 1, unit: .bytes) + ) + } + + func testSqrt() { + XCTAssertEqual( + sqrt(Measurement(value: 8, unit: .bits)), + Measurement(value: sqrt(8), unit: .bits) + ) + } +} diff --git a/Tests/UnitTests/Beton/Measurement/MeasurementTest+AdditiveArithmetic.swift b/Tests/UnitTests/Beton/Measurement/MeasurementTest+AdditiveArithmetic.swift new file mode 100644 index 0000000..fd91d73 --- /dev/null +++ b/Tests/UnitTests/Beton/Measurement/MeasurementTest+AdditiveArithmetic.swift @@ -0,0 +1,30 @@ +import Foundation +import XCTest +@testable import Beton + +extension MeasurementTest { + func testZero() { + XCTAssertEqual(Measurement.zero, Measurement(value: 0, unit: UnitAcceleration.default)) + XCTAssertEqual(Measurement.zero, Measurement(value: 0, unit: UnitAngle.default)) + XCTAssertEqual(Measurement.zero, Measurement(value: 0, unit: UnitArea.default)) + XCTAssertEqual(Measurement.zero, Measurement(value: 0, unit: UnitConcentrationMass.default)) + XCTAssertEqual(Measurement.zero, Measurement(value: 0, unit: UnitDispersion.default)) + XCTAssertEqual(Measurement.zero, Measurement(value: 0, unit: UnitDuration.default)) + XCTAssertEqual(Measurement.zero, Measurement(value: 0, unit: UnitElectricCharge.default)) + XCTAssertEqual(Measurement.zero, Measurement(value: 0, unit: UnitElectricCurrent.default)) + XCTAssertEqual(Measurement.zero, Measurement(value: 0, unit: UnitElectricPotentialDifference.default)) + XCTAssertEqual(Measurement.zero, Measurement(value: 0, unit: UnitElectricResistance.default)) + XCTAssertEqual(Measurement.zero, Measurement(value: 0, unit: UnitEnergy.default)) + XCTAssertEqual(Measurement.zero, Measurement(value: 0, unit: UnitFrequency.default)) + XCTAssertEqual(Measurement.zero, Measurement(value: 0, unit: UnitFuelEfficiency.default)) + XCTAssertEqual(Measurement.zero, Measurement(value: 0, unit: UnitIlluminance.default)) + XCTAssertEqual(Measurement.zero, Measurement(value: 0, unit: UnitInformationStorage.default)) + XCTAssertEqual(Measurement.zero, Measurement(value: 0, unit: UnitLength.default)) + XCTAssertEqual(Measurement.zero, Measurement(value: 0, unit: UnitMass.default)) + XCTAssertEqual(Measurement.zero, Measurement(value: 0, unit: UnitPower.default)) + XCTAssertEqual(Measurement.zero, Measurement(value: 0, unit: UnitPressure.default)) + XCTAssertEqual(Measurement.zero, Measurement(value: 0, unit: UnitSpeed.default)) + XCTAssertEqual(Measurement.zero, Measurement(value: 0, unit: UnitTemperature.default)) + XCTAssertEqual(Measurement.zero, Measurement(value: 0, unit: UnitVolume.default)) + } +} \ No newline at end of file diff --git a/Tests/UnitTests/Beton/Measurement/MeasurementTest.swift b/Tests/UnitTests/Beton/Measurement/MeasurementTest.swift new file mode 100644 index 0000000..d54a7b4 --- /dev/null +++ b/Tests/UnitTests/Beton/Measurement/MeasurementTest.swift @@ -0,0 +1,6 @@ +import Foundation +import XCTest +@testable import Beton + +class MeasurementTest: XCTestCase { +} diff --git a/Tests/UnitTests/Beton/Measurement/Unit/UnitAccelerationTest.swift b/Tests/UnitTests/Beton/Measurement/Unit/UnitAccelerationTest.swift new file mode 100644 index 0000000..2e3f7d5 --- /dev/null +++ b/Tests/UnitTests/Beton/Measurement/Unit/UnitAccelerationTest.swift @@ -0,0 +1,9 @@ +import Foundation +import XCTest +@testable import Beton + +class UnitAccelerationTest: XCTestCase { + func testDefault() { + XCTAssertEqual(UnitAcceleration.default, .metersPerSecondSquared) + } +} \ No newline at end of file diff --git a/Tests/UnitTests/Beton/Measurement/Unit/UnitAngleTest.swift b/Tests/UnitTests/Beton/Measurement/Unit/UnitAngleTest.swift new file mode 100644 index 0000000..031e3e0 --- /dev/null +++ b/Tests/UnitTests/Beton/Measurement/Unit/UnitAngleTest.swift @@ -0,0 +1,9 @@ +import Foundation +import XCTest +@testable import Beton + +class UnitAngleTest: XCTestCase { + func testDefault() { + XCTAssertEqual(UnitAngle.default, .degrees) + } +} \ No newline at end of file diff --git a/Tests/UnitTests/Beton/Measurement/Unit/UnitAreaTest.swift b/Tests/UnitTests/Beton/Measurement/Unit/UnitAreaTest.swift new file mode 100644 index 0000000..4cae16e --- /dev/null +++ b/Tests/UnitTests/Beton/Measurement/Unit/UnitAreaTest.swift @@ -0,0 +1,9 @@ +import Foundation +import XCTest +@testable import Beton + +class UnitAreaTest: XCTestCase { + func testDefault() { + XCTAssertEqual(UnitArea.default, .squareMeters) + } +} \ No newline at end of file diff --git a/Tests/UnitTests/Beton/Measurement/Unit/UnitConcentrationMassTest.swift b/Tests/UnitTests/Beton/Measurement/Unit/UnitConcentrationMassTest.swift new file mode 100644 index 0000000..df4deb7 --- /dev/null +++ b/Tests/UnitTests/Beton/Measurement/Unit/UnitConcentrationMassTest.swift @@ -0,0 +1,9 @@ +import Foundation +import XCTest +@testable import Beton + +class UnitConcentrationMassTest: XCTestCase { + func testDefault() { + XCTAssertEqual(UnitConcentrationMass.default, .gramsPerLiter) + } +} \ No newline at end of file diff --git a/Tests/UnitTests/Beton/Measurement/Unit/UnitDispersionTest.swift b/Tests/UnitTests/Beton/Measurement/Unit/UnitDispersionTest.swift new file mode 100644 index 0000000..f233bbc --- /dev/null +++ b/Tests/UnitTests/Beton/Measurement/Unit/UnitDispersionTest.swift @@ -0,0 +1,9 @@ +import Foundation +import XCTest +@testable import Beton + +class UnitDispersionTest: XCTestCase { + func testDefault() { + XCTAssertEqual(UnitDispersion.default, .partsPerMillion) + } +} \ No newline at end of file diff --git a/Tests/UnitTests/Beton/Measurement/Unit/UnitDurationTest.swift b/Tests/UnitTests/Beton/Measurement/Unit/UnitDurationTest.swift new file mode 100644 index 0000000..3e1e760 --- /dev/null +++ b/Tests/UnitTests/Beton/Measurement/Unit/UnitDurationTest.swift @@ -0,0 +1,9 @@ +import Foundation +import XCTest +@testable import Beton + +class UnitDurationTest: XCTestCase { + func testDefault() { + XCTAssertEqual(UnitDuration.default, .seconds ) + } +} \ No newline at end of file diff --git a/Tests/UnitTests/Beton/Measurement/Unit/UnitElectricChargeTest.swift b/Tests/UnitTests/Beton/Measurement/Unit/UnitElectricChargeTest.swift new file mode 100644 index 0000000..028d93e --- /dev/null +++ b/Tests/UnitTests/Beton/Measurement/Unit/UnitElectricChargeTest.swift @@ -0,0 +1,9 @@ +import Foundation +import XCTest +@testable import Beton + +class UnitElectricChargeTest: XCTestCase { + func testDefault() { + XCTAssertEqual(UnitElectricCharge.default, .ampereHours) + } +} \ No newline at end of file diff --git a/Tests/UnitTests/Beton/Measurement/Unit/UnitElectricCurrentTest.swift b/Tests/UnitTests/Beton/Measurement/Unit/UnitElectricCurrentTest.swift new file mode 100644 index 0000000..bb8e9c6 --- /dev/null +++ b/Tests/UnitTests/Beton/Measurement/Unit/UnitElectricCurrentTest.swift @@ -0,0 +1,9 @@ +import Foundation +import XCTest +@testable import Beton + +class UnitElectricCurrentTest: XCTestCase { + func testDefault() { + XCTAssertEqual(UnitElectricCurrent.default, .default) + } +} \ No newline at end of file diff --git a/Tests/UnitTests/Beton/Measurement/Unit/UnitElectricPotentialDifferenceTest.swift b/Tests/UnitTests/Beton/Measurement/Unit/UnitElectricPotentialDifferenceTest.swift new file mode 100644 index 0000000..58ee257 --- /dev/null +++ b/Tests/UnitTests/Beton/Measurement/Unit/UnitElectricPotentialDifferenceTest.swift @@ -0,0 +1,9 @@ +import Foundation +import XCTest +@testable import Beton + +class UnitElectricPotentialDifferenceTest: XCTestCase { + func testDefault() { + XCTAssertEqual(UnitElectricPotentialDifference.default, .volts) + } +} \ No newline at end of file diff --git a/Tests/UnitTests/Beton/Measurement/Unit/UnitElectricResistanceTest.swift b/Tests/UnitTests/Beton/Measurement/Unit/UnitElectricResistanceTest.swift new file mode 100644 index 0000000..0a30a6d --- /dev/null +++ b/Tests/UnitTests/Beton/Measurement/Unit/UnitElectricResistanceTest.swift @@ -0,0 +1,9 @@ +import Foundation +import XCTest +@testable import Beton + +class UnitElectricResistanceTest: XCTestCase { + func testDefault() { + XCTAssertEqual(UnitElectricResistance.default, .ohms) + } +} \ No newline at end of file diff --git a/Tests/UnitTests/Beton/Measurement/Unit/UnitEnergyTest.swift b/Tests/UnitTests/Beton/Measurement/Unit/UnitEnergyTest.swift new file mode 100644 index 0000000..9c684d0 --- /dev/null +++ b/Tests/UnitTests/Beton/Measurement/Unit/UnitEnergyTest.swift @@ -0,0 +1,9 @@ +import Foundation +import XCTest +@testable import Beton + +class UnitEnergyTest: XCTestCase { + func testDefault() { + XCTAssertEqual(UnitEnergy.default, .joules) + } +} \ No newline at end of file diff --git a/Tests/UnitTests/Beton/Measurement/Unit/UnitFrequencyTest.swift b/Tests/UnitTests/Beton/Measurement/Unit/UnitFrequencyTest.swift new file mode 100644 index 0000000..379ab06 --- /dev/null +++ b/Tests/UnitTests/Beton/Measurement/Unit/UnitFrequencyTest.swift @@ -0,0 +1,9 @@ +import Foundation +import XCTest +@testable import Beton + +class UnitFrequencyTest: XCTestCase { + func testDefault() { + XCTAssertEqual(UnitFrequency.default, .hertz) + } +} \ No newline at end of file diff --git a/Tests/UnitTests/Beton/Measurement/Unit/UnitFuelEfficiencyTest.swift b/Tests/UnitTests/Beton/Measurement/Unit/UnitFuelEfficiencyTest.swift new file mode 100644 index 0000000..91f9734 --- /dev/null +++ b/Tests/UnitTests/Beton/Measurement/Unit/UnitFuelEfficiencyTest.swift @@ -0,0 +1,9 @@ +import Foundation +import XCTest +@testable import Beton + +class UnitFuelEfficiencyTest: XCTestCase { + func testDefault() { + XCTAssertEqual(UnitFuelEfficiency.default, .litersPer100Kilometers) + } +} \ No newline at end of file diff --git a/Tests/UnitTests/Beton/Measurement/Unit/UnitIlluminanceTest.swift b/Tests/UnitTests/Beton/Measurement/Unit/UnitIlluminanceTest.swift new file mode 100644 index 0000000..6bc9394 --- /dev/null +++ b/Tests/UnitTests/Beton/Measurement/Unit/UnitIlluminanceTest.swift @@ -0,0 +1,9 @@ +import Foundation +import XCTest +@testable import Beton + +class UnitIlluminanceTest: XCTestCase { + func testDefault() { + XCTAssertEqual(UnitIlluminance.default, .lux) + } +} \ No newline at end of file diff --git a/Tests/UnitTests/Beton/Measurement/Unit/UnitInformationStorageTest.swift b/Tests/UnitTests/Beton/Measurement/Unit/UnitInformationStorageTest.swift new file mode 100644 index 0000000..0a8cd8e --- /dev/null +++ b/Tests/UnitTests/Beton/Measurement/Unit/UnitInformationStorageTest.swift @@ -0,0 +1,9 @@ +import Foundation +import XCTest +@testable import Beton + +class UnitInformationStorageTest: XCTestCase { + func testDefault() { + XCTAssertEqual(UnitInformationStorage.default, .bits) + } +} \ No newline at end of file diff --git a/Tests/UnitTests/Beton/Measurement/Unit/UnitLengthTest.swift b/Tests/UnitTests/Beton/Measurement/Unit/UnitLengthTest.swift new file mode 100644 index 0000000..0dda942 --- /dev/null +++ b/Tests/UnitTests/Beton/Measurement/Unit/UnitLengthTest.swift @@ -0,0 +1,9 @@ +import Foundation +import XCTest +@testable import Beton + +class UnitLengthTest: XCTestCase { + func testDefault() { + XCTAssertEqual(UnitLength.default, .meters) + } +} \ No newline at end of file diff --git a/Tests/UnitTests/Beton/Measurement/Unit/UnitMassTest.swift b/Tests/UnitTests/Beton/Measurement/Unit/UnitMassTest.swift new file mode 100644 index 0000000..81b8527 --- /dev/null +++ b/Tests/UnitTests/Beton/Measurement/Unit/UnitMassTest.swift @@ -0,0 +1,9 @@ +import Foundation +import XCTest +@testable import Beton + +class UnitMassTest: XCTestCase { + func testDefault() { + XCTAssertEqual(UnitMass.default, .grams) + } +} \ No newline at end of file diff --git a/Tests/UnitTests/Beton/Measurement/Unit/UnitPowerTest.swift b/Tests/UnitTests/Beton/Measurement/Unit/UnitPowerTest.swift new file mode 100644 index 0000000..d7c28bf --- /dev/null +++ b/Tests/UnitTests/Beton/Measurement/Unit/UnitPowerTest.swift @@ -0,0 +1,9 @@ +import Foundation +import XCTest +@testable import Beton + +class UnitPowerTest: XCTestCase { + func testDefault() { + XCTAssertEqual(UnitPower.default, .watts) + } +} \ No newline at end of file diff --git a/Tests/UnitTests/Beton/Measurement/Unit/UnitPressureTest.swift b/Tests/UnitTests/Beton/Measurement/Unit/UnitPressureTest.swift new file mode 100644 index 0000000..ac97355 --- /dev/null +++ b/Tests/UnitTests/Beton/Measurement/Unit/UnitPressureTest.swift @@ -0,0 +1,9 @@ +import Foundation +import XCTest +@testable import Beton + +class UnitPressureTest: XCTestCase { + func testDefault() { + XCTAssertEqual(UnitPressure.default, .bars) + } +} \ No newline at end of file diff --git a/Tests/UnitTests/Beton/Measurement/Unit/UnitSpeedTest.swift b/Tests/UnitTests/Beton/Measurement/Unit/UnitSpeedTest.swift new file mode 100644 index 0000000..63f4f94 --- /dev/null +++ b/Tests/UnitTests/Beton/Measurement/Unit/UnitSpeedTest.swift @@ -0,0 +1,9 @@ +import Foundation +import XCTest +@testable import Beton + +class UnitSpeedTest: XCTestCase { + func testDefault() { + XCTAssertEqual(UnitSpeed.default, .kilometersPerHour) + } +} \ No newline at end of file diff --git a/Tests/UnitTests/Beton/Measurement/Unit/UnitTemperatureTest.swift b/Tests/UnitTests/Beton/Measurement/Unit/UnitTemperatureTest.swift new file mode 100644 index 0000000..a6a135a --- /dev/null +++ b/Tests/UnitTests/Beton/Measurement/Unit/UnitTemperatureTest.swift @@ -0,0 +1,9 @@ +import Foundation +import XCTest +@testable import Beton + +class UnitTemperatureTest: XCTestCase { + func testDefault() { + XCTAssertEqual(UnitTemperature.default, .celsius) + } +} \ No newline at end of file diff --git a/Tests/UnitTests/Beton/Measurement/Unit/UnitVolumeTest.swift b/Tests/UnitTests/Beton/Measurement/Unit/UnitVolumeTest.swift new file mode 100644 index 0000000..4101051 --- /dev/null +++ b/Tests/UnitTests/Beton/Measurement/Unit/UnitVolumeTest.swift @@ -0,0 +1,9 @@ +import Foundation +import XCTest +@testable import Beton + +class UnitVolumeTest: XCTestCase { + func testDefault() { + XCTAssertEqual(UnitVolume.default, .liters) + } +} \ No newline at end of file diff --git a/Tests/UnitTests/Beton/Sequence/SequenceTest+testSum.swift b/Tests/UnitTests/Beton/Sequence/SequenceTest+testSum.swift new file mode 100644 index 0000000..d9584ab --- /dev/null +++ b/Tests/UnitTests/Beton/Sequence/SequenceTest+testSum.swift @@ -0,0 +1,9 @@ +import Foundation +import XCTest +@testable import Beton + +extension SequenceTest { + func testSum() { + XCTAssertEqual([1, 2, 3, 4, 5, 6].sum(), 21) + } +} diff --git a/Tests/UnitTests/Beton/Sequence/SequenceTest.swift b/Tests/UnitTests/Beton/Sequence/SequenceTest.swift new file mode 100644 index 0000000..ab64307 --- /dev/null +++ b/Tests/UnitTests/Beton/Sequence/SequenceTest.swift @@ -0,0 +1,6 @@ +import Foundation +import XCTest +@testable import Beton + +class SequenceTest: XCTestCase { +} diff --git a/Tests/UnitTests/Resources/en_US.lproj/Test.strings b/Tests/UnitTests/Resources/en_US.lproj/Test.strings new file mode 100644 index 0000000..85c3d86 --- /dev/null +++ b/Tests/UnitTests/Resources/en_US.lproj/Test.strings @@ -0,0 +1 @@ +"Test" = "Test"; \ No newline at end of file diff --git a/Tests/UnitTests/Resources/hu_HU.lproj/Test.strings b/Tests/UnitTests/Resources/hu_HU.lproj/Test.strings new file mode 100644 index 0000000..eb55259 --- /dev/null +++ b/Tests/UnitTests/Resources/hu_HU.lproj/Test.strings @@ -0,0 +1 @@ +"Test" = "Teszt"; \ No newline at end of file diff --git a/Tests/UnitTests/XCTBeton/Performance/XCTAssertMetric/XCTAssertClockIdentifierTest.swift b/Tests/UnitTests/XCTBeton/Performance/XCTAssertMetric/XCTAssertClockIdentifierTest.swift new file mode 100644 index 0000000..6298bbe --- /dev/null +++ b/Tests/UnitTests/XCTBeton/Performance/XCTAssertMetric/XCTAssertClockIdentifierTest.swift @@ -0,0 +1,11 @@ +import Beton +@testable import XCTBeton + +class XCTAssertClockIdentifierTest: XCTestCase { + func testIdentifier() { + XCTAssertEqual( + XCTAssertClockIdentifier.timeMonotonic.identifier, + "com.apple.dt.XCTMetric_Clock.time.monotonic" + ) + } +} diff --git a/Tests/UnitTests/XCTBeton/Performance/XCTAssertMetric/XCTAssertCpuIdentifierTest.swift b/Tests/UnitTests/XCTBeton/Performance/XCTAssertMetric/XCTAssertCpuIdentifierTest.swift new file mode 100644 index 0000000..c0581f4 --- /dev/null +++ b/Tests/UnitTests/XCTBeton/Performance/XCTAssertMetric/XCTAssertCpuIdentifierTest.swift @@ -0,0 +1,10 @@ +import Beton +@testable import XCTBeton + +class XCTAssertCpuIdentifierTest: XCTestCase { + func testIdentifier() { + XCTAssertEqual(XCTAssertCpuIdentifier.time.identifier, "com.apple.dt.XCTMetric_CPU.time") + XCTAssertEqual(XCTAssertCpuIdentifier.cycles.identifier, "com.apple.dt.XCTMetric_CPU.cycles") + XCTAssertEqual(XCTAssertCpuIdentifier.instructionsRetired.identifier, "com.apple.dt.XCTMetric_CPU.instructions_retired") + } +} diff --git a/Tests/UnitTests/XCTBeton/Performance/XCTAssertMetric/XCTAssertDiskIdentifierTest.swift b/Tests/UnitTests/XCTBeton/Performance/XCTAssertMetric/XCTAssertDiskIdentifierTest.swift new file mode 100644 index 0000000..b6de2ba --- /dev/null +++ b/Tests/UnitTests/XCTBeton/Performance/XCTAssertMetric/XCTAssertDiskIdentifierTest.swift @@ -0,0 +1,8 @@ +import Beton +@testable import XCTBeton + +class XCTAssertDiskIdentifierTest: XCTestCase { + func testIdentifier() { + XCTAssertEqual(XCTAssertDiskIdentifier.logicalWrites.identifier, "com.apple.dt.XCTMetric_Disk.logical_writes") + } +} diff --git a/Tests/UnitTests/XCTBeton/Performance/XCTAssertMetric/XCTAssertMemoryIdentifierTest.swift b/Tests/UnitTests/XCTBeton/Performance/XCTAssertMetric/XCTAssertMemoryIdentifierTest.swift new file mode 100644 index 0000000..42a790b --- /dev/null +++ b/Tests/UnitTests/XCTBeton/Performance/XCTAssertMetric/XCTAssertMemoryIdentifierTest.swift @@ -0,0 +1,9 @@ +import Beton +@testable import XCTBeton + +class XCTAssertMemoryIdentifierTest: XCTestCase { + func testIdentifier() { + XCTAssertEqual(XCTAssertMemoryIdentifier.physical.identifier, "com.apple.dt.XCTMetric_Memory.physical") + XCTAssertEqual(XCTAssertMemoryIdentifier.physicalPeak.identifier, "com.apple.dt.XCTMetric_Memory.physical_peak") + } +} diff --git a/Tests/UnitTests/XCTBeton/Performance/XCTAssertMetric/XCTAssertMetric.AspectTest.swift b/Tests/UnitTests/XCTBeton/Performance/XCTAssertMetric/XCTAssertMetric.AspectTest.swift new file mode 100644 index 0000000..cfd2354 --- /dev/null +++ b/Tests/UnitTests/XCTBeton/Performance/XCTAssertMetric/XCTAssertMetric.AspectTest.swift @@ -0,0 +1,23 @@ +import Beton +@testable import XCTBeton + +class XCTAssertMetric_AspectTest: XCTestCase { + private func AssertMaximum( + of: XCTAssertMetric, + aspect: XCTAssertMetric.Aspect, + equals: Double + ) { + XCTAssertEqual(aspect.maximum, equals) + } + + func testMaximum() { + AssertMaximum(of: .clock, aspect: .relativeStandardDeviation(maximum: 123), equals: 123) + AssertMaximum(of: .clock, aspect: .average(maximum: 123), equals: 123) + AssertMaximum(of: .disk, aspect: .relativeStandardDeviation(maximum: 123), equals: 123) + AssertMaximum(of: .disk, aspect: .average(maximum: 123), equals: 123) + AssertMaximum(of: .memory, aspect: .relativeStandardDeviation(maximum: 123), equals: 123) + AssertMaximum(of: .memory, aspect: .average(maximum: 123), equals: 123) + AssertMaximum(of: .cpu, aspect: .relativeStandardDeviation(maximum: 123), equals: 123) + AssertMaximum(of: .cpu, aspect: .average(maximum: 123), equals: 123) + } +} \ No newline at end of file diff --git a/Tests/UnitTests/XCTBeton/Performance/XCTMetric/XCTCPUMetricTest.swift b/Tests/UnitTests/XCTBeton/Performance/XCTMetric/XCTCPUMetricTest.swift new file mode 100644 index 0000000..5ef1e7e --- /dev/null +++ b/Tests/UnitTests/XCTBeton/Performance/XCTMetric/XCTCPUMetricTest.swift @@ -0,0 +1,6 @@ +import Beton +import XCTBeton + +class XCTCPUMetricTest: XCTMetricTest { + override func setUp() { unit = .init() } +} diff --git a/Tests/UnitTests/XCTBeton/Performance/XCTMetric/XCTClockMetricTest.swift b/Tests/UnitTests/XCTBeton/Performance/XCTMetric/XCTClockMetricTest.swift new file mode 100644 index 0000000..9e977da --- /dev/null +++ b/Tests/UnitTests/XCTBeton/Performance/XCTMetric/XCTClockMetricTest.swift @@ -0,0 +1,6 @@ +import Beton +import XCTBeton + +class XCTClockMetricTest: XCTMetricTest { + override func setUp() { unit = .init() } +} diff --git a/Tests/UnitTests/XCTBeton/Performance/XCTMetric/XCTMemoryMetricTest.swift b/Tests/UnitTests/XCTBeton/Performance/XCTMetric/XCTMemoryMetricTest.swift new file mode 100644 index 0000000..563f9dc --- /dev/null +++ b/Tests/UnitTests/XCTBeton/Performance/XCTMetric/XCTMemoryMetricTest.swift @@ -0,0 +1,6 @@ +import Beton +import XCTBeton + +class XCTMemoryMetricTest: XCTMetricTest { + override func setUp() { unit = .init() } +} diff --git a/Tests/UnitTests/XCTBeton/Performance/XCTMetric/XCTMetricTest.swift b/Tests/UnitTests/XCTBeton/Performance/XCTMetric/XCTMetricTest.swift new file mode 100644 index 0000000..e57bd54 --- /dev/null +++ b/Tests/UnitTests/XCTBeton/Performance/XCTMetric/XCTMetricTest.swift @@ -0,0 +1,11 @@ +import Beton +import XCTBeton + +class XCTMetricTest: XCTestCase where Unit: XCTMetric { + var unit: Unit! = nil + + func testMeasurement_emptyByDefault() { + XCTAssertTrue(unit.measurements.isEmpty, "Measurements should be empty by default.") + } + +} diff --git a/Tests/UnitTests/XCTBeton/Performance/XCTMetric/XCTStorageMetricTest.swift b/Tests/UnitTests/XCTBeton/Performance/XCTMetric/XCTStorageMetricTest.swift new file mode 100644 index 0000000..e5a0e73 --- /dev/null +++ b/Tests/UnitTests/XCTBeton/Performance/XCTMetric/XCTStorageMetricTest.swift @@ -0,0 +1,6 @@ +import Beton +import XCTBeton + +class XCTStorageMetricTest: XCTMetricTest { + override func setUp() { unit = .init() } +} diff --git a/Tests/UnitTests/XCTBeton/XCTestCaseTest.swift b/Tests/UnitTests/XCTBeton/XCTestCaseTest.swift new file mode 100644 index 0000000..aa7e213 --- /dev/null +++ b/Tests/UnitTests/XCTBeton/XCTestCaseTest.swift @@ -0,0 +1,15 @@ +import Beton +@testable import XCTBeton + +class XCTestCaseTest: XCTestCase { + func testLastRunMetrics() { + let testCase = XCTestCase() + XCTAssertTrue(testCase.lastRunMetrics.isEmpty, "Should initially be empty.") + } + + func testDefaultMetrics() { + XCTAssertEqual(XCTestCase.defaultMetrics.count, 1, "Should have only one default metric.") + XCTAssertTrue(XCTestCase.defaultMetrics[0] is XCTClockMetric, "First item should be an XCTClockMetric.") + } + +}