Skip to content

Commit

Permalink
Merge pull request #264 from CodaFi/futureshock
Browse files Browse the repository at this point in the history
Try an update to Xcode 9.3
  • Loading branch information
CodaFi authored Apr 12, 2018
2 parents ae61bed + b6b4bc6 commit 43ffe7a
Show file tree
Hide file tree
Showing 24 changed files with 89 additions and 550 deletions.
2 changes: 1 addition & 1 deletion .swift-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4.0
4.1
27 changes: 9 additions & 18 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ matrix:
include:
- os: osx
language: objective-c
osx_image: xcode9
osx_image: xcode9.3
before_install:
- git submodule update --init --recursive
- pushd Utilities
Expand All @@ -16,7 +16,7 @@ matrix:
- carthage build --no-skip-current
- os: osx
language: objective-c
osx_image: xcode9
osx_image: xcode9.3
before_install:
- git submodule update --init --recursive
- pushd Utilities
Expand All @@ -25,29 +25,20 @@ matrix:
script:
- set -o pipefail
- xcodebuild test -scheme SwiftCheck | xcpretty -c
# -- Start iOS --
# !!!: Make sure desired device name & OS version are suitable for the Xcode version installed on osx_image
- iOS_DEVICE_NAME="iPad Pro (12.9-inch) (2nd generation)"
- iOS_RUNTIME_VERSION="11.0"
# Get simulator identifier for desired device/runtime pair
- SIMULATOR_ID=$(xcrun instruments -s | grep -o "${iOS_DEVICE_NAME} (${iOS_RUNTIME_VERSION}) \[.*\]" | grep -o "\[.*\]" | sed "s/^\[\(.*\)\]$/\1/")
- echo $SIMULATOR_ID
- echo $iOS_DEVICE_NAME
- echo $iOS_RUNTIME_VERSION
- xcodebuild build-for-testing -scheme SwiftCheck-iOS -destination "platform=iOS Simulator,name=${iOS_DEVICE_NAME},OS=${iOS_RUNTIME_VERSION}" | xcpretty -c
- xcodebuild test -scheme SwiftCheck-iOS -destination "platform=iOS Simulator,name=${iOS_DEVICE_NAME},OS=${iOS_RUNTIME_VERSION}" | xcpretty -c
- xcodebuild build-for-testing -scheme SwiftCheck-tvOS -destination 'platform=tvOS Simulator,name=Apple TV 1080p' | xcpretty -c
- xcodebuild test -scheme SwiftCheck-tvOS -destination 'platform=tvOS Simulator,name=Apple TV 1080p' | xcpretty -c
- xcodebuild build-for-testing -scheme SwiftCheck-iOS -destination "platform=iOS Simulator,name=iPad Pro (12.9-inch) (2nd generation)" | xcpretty -c
- xcodebuild test -scheme SwiftCheck-iOS -destination "platform=iOS Simulator,name=iPad Pro (12.9-inch) (2nd generation)" | xcpretty -c
- xcodebuild build-for-testing -scheme SwiftCheck-tvOS -destination 'platform=tvOS Simulator,name=Apple TV 4K (at 1080p)' | xcpretty -c
- xcodebuild test -scheme SwiftCheck-tvOS -destination 'platform=tvOS Simulator,name=Apple TV 4K (at 1080p)' | xcpretty -c
- os: linux
language: generic
sudo: required
dist: trusty
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-4.0-release/ubuntu1404/swift-4.0-RELEASE/swift-4.0-RELEASE-ubuntu14.04.tar.gz
- tar xzf swift-4.0-RELEASE-ubuntu14.04.tar.gz
- export PATH=${PWD}/swift-4.0-RELEASE-ubuntu14.04/usr/bin:"${PATH}"
- wget https://swift.org/builds/swift-4.1-release/ubuntu1404/swift-4.1-RELEASE/swift-4.1-RELEASE-ubuntu14.04.tar.gz
- tar xzf swift-4.1-RELEASE-ubuntu14.04.tar.gz
- export PATH=${PWD}/swift-4.1-RELEASE-ubuntu14.04/usr/bin:"${PATH}"
- pushd Utilities
- ./compile.sh
- popd
Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version:4.0
// swift-tools-version:4.1

import PackageDescription

Expand Down
15 changes: 6 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,7 @@ For a less contrived example, here is a program property that tests whether
Array identity holds under double reversal:

```swift
// Because Swift doesn't allow us to implement `Arbitrary` for certain types,
// SwiftCheck instead implements 'modifier' types that wrap them. Here,
// `ArrayOf<T : Arbitrary>` generates random arrays of values of type `T`.
property("The reverse of the reverse of an array is that array") <- forAll { (xs : ArrayOf<Int>) in
property("The reverse of the reverse of an array is that array") <- forAll { (xs : [Int]) in
// This property is using a number of SwiftCheck's more interesting
// features. `^&&^` is the conjunction operator for properties that turns
// both properties into a larger property that only holds when both sub-properties
Expand All @@ -56,22 +53,22 @@ property("The reverse of the reverse of an array is that array") <- forAll { (xs
// *** Passed 100 tests
// (100% , Right identity, Left identity)
return
(xs.getArray.reverse().reverse() == xs.getArray) <?> "Left identity"
(xs.reverse().reverse() == xs) <?> "Left identity"
^&&^
(xs.getArray == xs.getArray.reverse().reverse()) <?> "Right identity"
(xs == xs.reverse().reverse()) <?> "Right identity"
}
```

Because SwiftCheck doesn't require tests to return `Bool`, just `Testable`, we
can produce tests for complex properties with ease:

```swift
property("Shrunken lists of integers always contain [] or [0]") <- forAll { (l : ArrayOf<Int>) in
property("Shrunken lists of integers always contain [] or [0]") <- forAll { (l : [Int]) in
// Here we use the Implication Operator `==>` to define a precondition for
// this test. If the precondition fails the test is discarded. If it holds
// the test proceeds.
return (!l.getArray.isEmpty && l.getArray != [0]) ==> {
let ls = self.shrinkArbitrary(l).map { $0.getArray }
return (!l.isEmpty && l != [0]) ==> {
let ls = self.shrinkArbitrary(l)
return (ls.filter({ $0 == [] || $0 == [0] }).count >= 1)
}
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/SwiftCheck/Arbitrary.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
/// implementation of `shrink` is provided, SwiftCheck will default to an empty
/// one - that is, no shrinking will occur.
///
/// As an example, take the `ArrayOf` implementation of shrink:
/// As an example, take `Array`'s implementation of shrink:
///
/// Arbitrary.shrink(ArrayOf([1, 2, 3]))
/// Arbitrary.shrink([1, 2, 3])
/// > [[], [2,3], [1,3], [1,2], [0,2,3], [1,0,3], [1,1,3], [1,2,0], [1,2,2]]
///
/// SwiftCheck will search each case forward, one-by-one, and continue shrinking
Expand Down
173 changes: 2 additions & 171 deletions Sources/SwiftCheck/Modifiers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,6 @@
/// return xs.map(f.getArrow) == xs.map(f.getArrow)
/// }
/// }
///
/// Finally, modifiers nest to allow the generation of intricate structures that
/// would not otherwise be possible due to the limitations above. For example,
/// to generate an Array of Arrays of Dictionaries of Integers and Strings (a
/// type that normally looks like `Array<Array<Dictionary<String, Int>>>`),
/// would look like this:
///
/// property("Generating monstrous data types is possible") <- forAll { (xs : ArrayOf<ArrayOf<DictionaryOf<String, Int>>>) in
/// /// We're gonna need a bigger boat.
/// }

/// For types that either do not have a `CustomStringConvertible` instance or
/// that wish to have no description to print, Blind will create a default
Expand Down Expand Up @@ -115,48 +105,6 @@ extension Static : CoArbitrary {
}
}

/// Generates an array of arbitrary values of type A.
public struct ArrayOf<A : Arbitrary> : Arbitrary, CustomStringConvertible {
/// Retrieves the underlying array of values.
public let getArray : [A]

/// Retrieves the underlying array of values as a contiguous array.
public var getContiguousArray : ContiguousArray<A> {
return ContiguousArray(self.getArray)
}

/// Creates a new `ArrayOf` modifier from an underlying array of values.
public init(_ array : [A]) {
self.getArray = array
}

/// A textual representation of `self`.
public var description : String {
return "\(self.getArray)"
}

/// Returns a generator of `ArrayOf` values.
public static var arbitrary : Gen<ArrayOf<A>> {
return Array<A>.arbitrary.map(ArrayOf.init)
}

/// The default shrinking function for an `ArrayOf` values.
public static func shrink(_ bl : ArrayOf<A>) -> [ArrayOf<A>] {
return Array<A>.shrink(bl.getArray).map(ArrayOf.init)
}
}

extension ArrayOf : CoArbitrary {
/// Uses the underlying array of values to perturb a generator.
public static func coarbitrary<C>(_ x : ArrayOf) -> ((Gen<C>) -> Gen<C>) {
let a = x.getArray
if a.isEmpty {
return { $0.variant(0) }
}
return comp({ $0.variant(1) }, ArrayOf.coarbitrary(ArrayOf([A](a[1..<a.endIndex]))))
}
}

/// Generates a sorted array of arbitrary values of type A.
public struct OrderedArrayOf<A : Arbitrary & Comparable> : Arbitrary, CustomStringConvertible {
/// Retrieves the underlying sorted array of values.
Expand Down Expand Up @@ -193,121 +141,6 @@ public struct OrderedArrayOf<A : Arbitrary & Comparable> : Arbitrary, CustomStri
}
}


/// Generates an dictionary of arbitrary keys and values.
public struct DictionaryOf<K : Hashable & Arbitrary, V : Arbitrary> : Arbitrary, CustomStringConvertible {
/// Retrieves the underlying dictionary of values.
public let getDictionary : Dictionary<K, V>

/// Creates a new `DictionaryOf` modifier from an underlying dictionary of
/// key-value pairs.
public init(_ dict : Dictionary<K, V>) {
self.getDictionary = dict
}

/// A textual representation of `self`.
public var description : String {
return "\(self.getDictionary)"
}

/// Returns a generator for a `DictionaryOf` values.
public static var arbitrary : Gen<DictionaryOf<K, V>> {
return Dictionary<K, V>.arbitrary.map(DictionaryOf.init)
}

/// The default shrinking function for a `DictionaryOf` values.
public static func shrink(_ d : DictionaryOf<K, V>) -> [DictionaryOf<K, V>] {
return Dictionary.shrink(d.getDictionary).map(DictionaryOf.init)
}
}

extension DictionaryOf : CoArbitrary {
/// Uses the underlying array of values to perturb a generator.
public static func coarbitrary<C>(_ x : DictionaryOf) -> ((Gen<C>) -> Gen<C>) {
return Dictionary.coarbitrary(x.getDictionary)
}
}

/// Generates an Optional of arbitrary values of type A.
public struct OptionalOf<A : Arbitrary> : Arbitrary, CustomStringConvertible {
/// Retrieves the underlying optional value.
public let getOptional : A?

/// Creates a new `OptionalOf` modifier from an underlying `Optional` value.
public init(_ opt : A?) {
self.getOptional = opt
}

/// A textual representation of `self`.
public var description : String {
return "\(String(describing: self.getOptional))"
}

/// Returns a generator for `OptionalOf` values.
public static var arbitrary : Gen<OptionalOf<A>> {
return Optional<A>.arbitrary.map(OptionalOf.init)
}

/// The default shrinking function for `OptionalOf` values.
public static func shrink(_ bl : OptionalOf<A>) -> [OptionalOf<A>] {
return Optional<A>.shrink(bl.getOptional).map(OptionalOf.init)
}
}

extension OptionalOf : CoArbitrary {
/// Uses the underlying presence or lack of a value to perturb a generator.
public static func coarbitrary<C>(_ x : OptionalOf) -> ((Gen<C>) -> Gen<C>) {
if let _ = x.getOptional {
return { $0.variant(0) }
}
return { $0.variant(1) }
}
}

/// Generates a set of arbitrary values of type A.
public struct SetOf<A : Hashable & Arbitrary> : Arbitrary, CustomStringConvertible {
/// Retrieves the underlying set of values.
public let getSet : Set<A>

/// Creates a new `SetOf` modifier from an underlying set of values.
public init(_ set : Set<A>) {
self.getSet = set
}

/// A textual representation of `self`.
public var description : String {
return "\(self.getSet)"
}

/// Returns a generator for a `SetOf` values.
public static var arbitrary : Gen<SetOf<A>> {
return Gen.sized { n in
return Gen<Int>.choose((0, n)).flatMap { k in
if k == 0 {
return Gen.pure(SetOf(Set([])))
}

return sequence(Array((0...k)).map { _ in A.arbitrary }).map(comp(SetOf.init, Set.init))
}
}
}

/// The default shrinking function for a `SetOf` values.
public static func shrink(_ s : SetOf<A>) -> [SetOf<A>] {
return ArrayOf.shrink(ArrayOf([A](s.getSet))).map({ SetOf(Set($0.getArray)) })
}
}

extension SetOf : CoArbitrary {
/// Uses the underlying set of values to perturb a generator.
public static func coarbitrary<C>(_ x : SetOf) -> ((Gen<C>) -> Gen<C>) {
if x.getSet.isEmpty {
return { $0.variant(0) }
}
return { $0.variant(1) }
}
}

/// Generates pointers of varying size of random values of type T.
public struct PointerOf<T : Arbitrary> : Arbitrary, CustomStringConvertible {
fileprivate let _impl : PointerOfImpl<T>
Expand Down Expand Up @@ -663,10 +496,8 @@ private final class PointerOfImpl<T : Arbitrary> : Arbitrary {
}

deinit {
if self.size > 0 && self.ptr != nil {
self.ptr?.deallocate(capacity: self.size)
self.ptr = nil
}
self.ptr?.deallocate()
self.ptr = nil
}

static var arbitrary : Gen<PointerOfImpl<T>> {
Expand Down
2 changes: 1 addition & 1 deletion Sources/SwiftCheck/Testable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ extension Bool : Testable {
}
}

extension Gen /*: Testable*/ where A : Testable {
extension Gen : Testable where A : Testable {
public var property : Property {
return Property(self.flatMap { $0.property.unProperty })
}
Expand Down
Loading

0 comments on commit 43ffe7a

Please sign in to comment.