From cfaff58d9b341c6a755a82864475af9d15eb5544 Mon Sep 17 00:00:00 2001 From: Stefan van den Oord Date: Mon, 29 Jun 2020 17:30:53 +0200 Subject: [PATCH 1/4] Adds ability to generate arbitrary `Date`s and `UUID`s --- Sources/SwiftCheck/Arbitrary.swift | 56 +++++++++++++++++++++++ SwiftCheck.xcodeproj/project.pbxproj | 8 ++++ Tests/LinuxMain.swift | 1 + Tests/SwiftCheckTests/ArbitrarySpec.swift | 28 ++++++++++++ 4 files changed, 93 insertions(+) create mode 100644 Tests/SwiftCheckTests/ArbitrarySpec.swift diff --git a/Sources/SwiftCheck/Arbitrary.swift b/Sources/SwiftCheck/Arbitrary.swift index b4e8ca8..af21212 100644 --- a/Sources/SwiftCheck/Arbitrary.swift +++ b/Sources/SwiftCheck/Arbitrary.swift @@ -370,6 +370,62 @@ extension Mirror : Arbitrary { } } +import Foundation + +extension Date: Arbitrary { + public static var arbitrary: Gen { + return TimeInterval.arbitrary.map(Date.init(timeIntervalSinceNow:)) + } +} + +extension UUID: Arbitrary { + /// Returns a generator of `UUID` values. + public static var arbitrary: Gen { + return Gen.compose { composer in + var bytes = (0..<16).map { _ in composer.generate(using: UInt8.arbitrary) } + bytes[7] = bytes[7] | 0b01000000 // UUID version 4 + bytes[9] = bytes[9] | 0b01000000 // clock_seq_hi_and_reserved + + let part1 = Data(bytes[0..<4]).hexEncodedString() + let part2 = Data(bytes[4..<6]).hexEncodedString() + let part3 = Data(bytes[6..<8]).hexEncodedString() + let part4 = Data(bytes[8..<10]).hexEncodedString() + let part5 = Data(bytes[10..<16]).hexEncodedString() + + return UUID(uuidString: part1 + "-" + part2 + "-" + part3 + "-" + part4 + "-" + part5)! + } + } +} + +extension Data { + + /// Creates a new `Data` instance using the hexadecimal-encoded string. + /// + /// - Parameter string: A string with even non-zero length containing only digits or a/A through f/F. + public init?(hexEncoded string: String) { + if string.count == 0 || string.count % 2 != 0 { return nil } + + var bytes = [UInt8]() + var start = string.startIndex + while start < string.endIndex { + let chunkEnd = string.index(start, offsetBy: 2) + let chunk = string[start.. String { + return [UInt8](self).map { String(format: "%.2x", $0) }.reduce("", {$0+$1}) + } +} + #if os(Linux) import Glibc #else diff --git a/SwiftCheck.xcodeproj/project.pbxproj b/SwiftCheck.xcodeproj/project.pbxproj index 60aad52..e0a18f4 100644 --- a/SwiftCheck.xcodeproj/project.pbxproj +++ b/SwiftCheck.xcodeproj/project.pbxproj @@ -7,6 +7,9 @@ objects = { /* Begin PBXBuildFile section */ + 02135F9324AA3BB300E33BF1 /* ArbitrarySpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02135F9224AA3BA800E33BF1 /* ArbitrarySpec.swift */; }; + 02135F9424AA3BB300E33BF1 /* ArbitrarySpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02135F9224AA3BA800E33BF1 /* ArbitrarySpec.swift */; }; + 02135F9524AA3BB400E33BF1 /* ArbitrarySpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02135F9224AA3BA800E33BF1 /* ArbitrarySpec.swift */; }; 6A761B9E1F14E92100A7D74F /* Arbitrary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A761B771F14E91400A7D74F /* Arbitrary.swift */; }; 6A761B9F1F14E92100A7D74F /* Cartesian.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A761B781F14E91400A7D74F /* Cartesian.swift */; }; 6A761BA01F14E92100A7D74F /* Check.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A761B791F14E91400A7D74F /* Check.swift */; }; @@ -176,6 +179,7 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 02135F9224AA3BA800E33BF1 /* ArbitrarySpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArbitrarySpec.swift; sourceTree = ""; }; 6A761B751F14E91400A7D74F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 6A761B771F14E91400A7D74F /* Arbitrary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Arbitrary.swift; sourceTree = ""; }; 6A761B781F14E91400A7D74F /* Cartesian.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Cartesian.swift; sourceTree = ""; }; @@ -328,6 +332,7 @@ 6A761B8C1F14E91500A7D74F /* SwiftCheckTests */ = { isa = PBXGroup; children = ( + 02135F9224AA3BA800E33BF1 /* ArbitrarySpec.swift */, 6A761B8D1F14E91500A7D74F /* BooleanIdentitySpec.swift */, 6A761B8E1F14E91500A7D74F /* CartesianSpec.swift */, 6A761B8F1F14E91500A7D74F /* ComplexSpec.swift */, @@ -676,6 +681,7 @@ 8235D34C1F72DD0B00207FA1 /* Diagnostics.swift in Sources */, 8235D34D1F72DD0B00207FA1 /* EditDistance.swift in Sources */, 8235D34E1F72DD0B00207FA1 /* FileCheck.swift in Sources */, + 02135F9524AA3BB400E33BF1 /* ArbitrarySpec.swift in Sources */, 8235D34F1F72DD0B00207FA1 /* Pattern.swift in Sources */, 6A761C021F14E93B00A7D74F /* SimpleSpec.swift in Sources */, 6A761C031F14E93B00A7D74F /* TestSpec.swift in Sources */, @@ -727,6 +733,7 @@ 8235D3561F72DD2200207FA1 /* CheckString.swift in Sources */, 8235D3571F72DD2200207FA1 /* ColoredStream.swift in Sources */, 8235D3581F72DD2200207FA1 /* Diagnostics.swift in Sources */, + 02135F9324AA3BB300E33BF1 /* ArbitrarySpec.swift in Sources */, 8235D3591F72DD2200207FA1 /* EditDistance.swift in Sources */, 8235D35A1F72DD2200207FA1 /* FileCheck.swift in Sources */, 8235D35B1F72DD2200207FA1 /* Pattern.swift in Sources */, @@ -778,6 +785,7 @@ 8235D3501F72DD1B00207FA1 /* CheckString.swift in Sources */, 8235D3511F72DD1B00207FA1 /* ColoredStream.swift in Sources */, 8235D3521F72DD1B00207FA1 /* Diagnostics.swift in Sources */, + 02135F9424AA3BB300E33BF1 /* ArbitrarySpec.swift in Sources */, 8235D3531F72DD1B00207FA1 /* EditDistance.swift in Sources */, 8235D3541F72DD1B00207FA1 /* FileCheck.swift in Sources */, 8235D3551F72DD1B00207FA1 /* Pattern.swift in Sources */, diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift index fc2c0b5..b0a8ce4 100644 --- a/Tests/LinuxMain.swift +++ b/Tests/LinuxMain.swift @@ -12,6 +12,7 @@ import XCTest #if !os(macOS) XCTMain([ + ArbitrarySpec.allTests, BooleanIdentitySpec.allTests, ComplexSpec.allTests, DiscardSpec.allTests, diff --git a/Tests/SwiftCheckTests/ArbitrarySpec.swift b/Tests/SwiftCheckTests/ArbitrarySpec.swift new file mode 100644 index 0000000..a6c1d4f --- /dev/null +++ b/Tests/SwiftCheckTests/ArbitrarySpec.swift @@ -0,0 +1,28 @@ +import SwiftCheck +import XCTest +import Foundation +#if SWIFT_PACKAGE +import FileCheck +#endif + +class ArbitrarySpec : XCTestCase { + func testAll() { + XCTAssert(fileCheckOutput { + // CHECK: *** Passed 100 tests + // CHECK-NEXT: . + property("generates arbitrary `Date`s") <- forAll { (_ : Date) in + // The fact that we can return something here means that + // generating the Date succeeded + return true + } + + // CHECK: *** Passed 100 tests + // CHECK-NEXT: . + property("generates arbitrary `UUID`s") <- forAll { (_ : UUID) in + // The fact that we can return something here means that + // generating the UUID succeeded + return true + } + }) + } +} From b271d36ece155d348d433aff973d422be5db9fe0 Mon Sep 17 00:00:00 2001 From: Stefan van den Oord Date: Mon, 29 Jun 2020 18:43:03 +0200 Subject: [PATCH 2/4] Updates travis config for Swift tools version 5.2 --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3477e13..7b8c2f6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,9 +36,9 @@ matrix: before_install: - git submodule update --init --recursive - wget -q -O - https://swift.org/keys/all-keys.asc | gpg --import - - - wget https://swift.org/builds/swift-5.0-release/ubuntu1404/swift-5.0-RELEASE/swift-5.0-RELEASE-ubuntu14.04.tar.gz - - tar xzf swift-5.0-RELEASE-ubuntu14.04.tar.gz - - export PATH=${PWD}/swift-5.0-RELEASE-ubuntu14.04/usr/bin:"${PATH}" + - wget https://swift.org/builds/swift-5.2.4-release/ubuntu1604/swift-5.2.4-RELEASE/swift-5.2.4-RELEASE-ubuntu16.04.tar.gz + - tar xzf swift-5.2.4-RELEASE-ubuntu16.04.tar.gz + - export PATH=${PWD}/swift-5.2.4-RELEASE-ubuntu16.04/usr/bin:"${PATH}" - pushd Utilities - ./compile.sh - popd From 62f4d20f7d15ae809ebd55a4e8bff88d50b893b2 Mon Sep 17 00:00:00 2001 From: Stefan van den Oord Date: Mon, 29 Jun 2020 18:45:31 +0200 Subject: [PATCH 3/4] Updates Linux distro to match that expected by Swift release --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7b8c2f6..7a41ec2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,7 +32,7 @@ matrix: - os: linux language: generic sudo: required - dist: trusty + dist: xenial before_install: - git submodule update --init --recursive - wget -q -O - https://swift.org/keys/all-keys.asc | gpg --import - From 62c321014f3b10681339f0cb8fc0829a2ea018c4 Mon Sep 17 00:00:00 2001 From: Stefan van den Oord Date: Mon, 29 Jun 2020 21:05:18 +0200 Subject: [PATCH 4/4] Adds `allTests` member for Linux --- Tests/SwiftCheckTests/ArbitrarySpec.swift | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Tests/SwiftCheckTests/ArbitrarySpec.swift b/Tests/SwiftCheckTests/ArbitrarySpec.swift index a6c1d4f..ba07a25 100644 --- a/Tests/SwiftCheckTests/ArbitrarySpec.swift +++ b/Tests/SwiftCheckTests/ArbitrarySpec.swift @@ -25,4 +25,10 @@ class ArbitrarySpec : XCTestCase { } }) } + + #if !(os(macOS) || os(iOS) || os(watchOS) || os(tvOS)) + static var allTests = testCase([ + ("testAll", testAll), + ]) + #endif }