Skip to content

Commit

Permalink
Merge pull request #27 from CodaFi/tests-mod-2
Browse files Browse the repository at this point in the history
New Modifiers
  • Loading branch information
CodaFi committed May 31, 2015
2 parents 5982494 + be37554 commit f3a2254
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 5 deletions.
14 changes: 10 additions & 4 deletions SwiftCheck/Arbitrary.swift
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,11 @@ extension UInt64 : Arbitrary {

extension Float : Arbitrary {
public static func arbitrary() -> Gen<Float> {
return Gen.sized({ (n : Int) in
return n == 0 ? Gen.pure(0.0) : Gen.pure(Float(-n) + Float(arc4random()) / Float(UINT32_MAX / UInt32((n)*2)))
return Gen.sized({ n in
if n == 0 {
return Gen<Float>.pure(0.0)
}
return Gen<Float>.pure(Float(-n) + Float(arc4random()) / Float(UINT32_MAX / UInt32((n)*2)))
})
}

Expand All @@ -193,8 +196,11 @@ extension Float : Arbitrary {

extension Double : Arbitrary {
public static func arbitrary() -> Gen<Double> {
return Gen.sized({ (n : Int) in
return n == 0 ? Gen.pure(0.0) : Gen.pure(Double(-n) + Double(arc4random()) / Double(UINT32_MAX / UInt32(n*2)))
return Gen.sized({ n in
if n == 0 {
return Gen<Double>.pure(0.0)
}
return Gen<Double>.pure(Double(-n) + Double(arc4random()) / Double(UINT32_MAX / UInt32(n*2)))
})
}

Expand Down
8 changes: 8 additions & 0 deletions SwiftCheck/Equatable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,18 @@ public func == <T : protocol<Arbitrary, Equatable>>(lhs : ArrayOf<T>, rhs : Arra
return lhs.getArray == rhs.getArray
}

public func == <K : protocol<Arbitrary, Equatable, Hashable>, V : protocol<Equatable, Arbitrary>>(lhs : DictionaryOf<K, V>, rhs : DictionaryOf<K, V>) -> Bool {
return lhs.getDictionary == rhs.getDictionary
}

public func == <T : protocol<Arbitrary, Equatable>>(lhs : OptionalOf<T>, rhs : OptionalOf<T>) -> Bool {
return lhs.getOptional == rhs.getOptional
}

public func == <T : protocol<Arbitrary, Equatable, Hashable>>(lhs : SetOf<T>, rhs : SetOf<T>) -> Bool {
return lhs.getSet == rhs.getSet
}

public func == <T : protocol<Arbitrary, SignedNumberType>>(lhs : Positive<T>, rhs : Positive<T>) -> Bool {
return lhs.getPositive == rhs.getPositive
}
Expand Down
80 changes: 79 additions & 1 deletion SwiftCheck/Modifiers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ public struct Static<A : Arbitrary> : Arbitrary, Printable {
/// Generates an array of arbitrary values of type A.
public struct ArrayOf<A : Arbitrary> : Arbitrary, Printable {
public let getArray : [A]
public var getContiguousArray : ContiguousArray<A> {
return ContiguousArray(self.getArray)
}

public init(_ array : [A]) {
self.getArray = array
Expand Down Expand Up @@ -128,6 +131,49 @@ func drop<T>(num : Int, xs : [T]) -> [T] {
return [T](xs[n..<xs.endIndex])
}

/// Generates an dictionary of arbitrary keys and values.
public struct DictionaryOf<K : protocol<Hashable, Arbitrary>, V : Arbitrary> : Arbitrary, Printable {
public let getDictionary : Dictionary<K, V>

public init(_ dict : Dictionary<K, V>) {
self.getDictionary = dict
}

public var description : String {
return "\(self.getDictionary)"
}

private static func create(dict : Dictionary<K, V>) -> DictionaryOf<K, V> {
return DictionaryOf(dict)
}

public static func arbitrary() -> Gen<DictionaryOf<K, V>> {
return ArrayOf<K>.arbitrary().bind { k in
return ArrayOf<V>.arbitrary().bind { v in
return Gen.pure(DictionaryOf(Dictionary<K, V>(Zip2(k.getArray, v.getArray))))
}
}
}

public static func shrink(d : DictionaryOf<K, V>) -> [DictionaryOf<K, V>] {
var xs = [DictionaryOf<K, V>]()
for (k, v) in d.getDictionary {
xs.append(DictionaryOf(Dictionary(Zip2(K.shrink(k), V.shrink(v)))))
}
return xs
}
}

extension Dictionary {
init<S : SequenceType where S.Generator.Element == Element>(_ pairs : S) {
self.init()
var g = pairs.generate()
while let (k : Key, v : Value) = g.next() {
self[k] = v
}
}
}

/// Generates an Optional of arbitrary values of type A.
public struct OptionalOf<A : Arbitrary> : Arbitrary, Printable {
public let getOptional : A?
Expand Down Expand Up @@ -159,6 +205,39 @@ public struct OptionalOf<A : Arbitrary> : Arbitrary, Printable {
}
}

/// Generates a set of arbitrary values of type A.
public struct SetOf<A : protocol<Hashable, Arbitrary>> : Arbitrary, Printable {
public let getSet : Set<A>

public init(_ set : Set<A>) {
self.getSet = set
}

public var description : String {
return "\(self.getSet)"
}

private static func create(set : Set<A>) -> SetOf<A>{
return SetOf(set)
}

public static func arbitrary() -> Gen<SetOf<A>> {
return Gen.sized { n in
return Gen<Int>.choose((0, n)).bind { k in
if k == 0 {
return Gen.pure(SetOf(Set([])))
}

return sequence(Array((0...k)).map { _ in A.arbitrary() }).fmap({ SetOf.create(Set($0)) })
}
}
}

public static func shrink(s : SetOf<A>) -> [SetOf<A>] {
return ArrayOf.shrink(ArrayOf([A](s.getSet))).map({ SetOf(Set($0.getArray)) })
}
}

/// Generates a Swift function from T to U.
public struct ArrowOf<T : CoArbitrary, U : Arbitrary> : Arbitrary, Printable {
public let getArrow : T -> U
Expand All @@ -184,7 +263,6 @@ public struct ArrowOf<T : CoArbitrary, U : Arbitrary> : Arbitrary, Printable {
}
}


/// Guarantees that every generated integer is greater than 0.
public struct Positive<A : protocol<Arbitrary, SignedNumberType>> : Arbitrary, Printable {
public let getPositive : A
Expand Down
7 changes: 7 additions & 0 deletions SwiftCheckTests/ShrinkSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,12 @@ class ShrinkSpec : XCTestCase {
return (ls.filter({ $0 == [] || $0 == [0] }).count >= 1)
}()
}

property["Shrunken sets of integers always contain [] or [0]"] = forAll { (s : SetOf<Int>) in
return (!s.getSet.isEmpty && s.getSet != Set([0])) ==> {
let ls = self.shrinkArbitrary(s).map { $0.getSet }
return (ls.filter({ $0 == [] || $0 == [0] }).count >= 1)
}()
}
}
}

0 comments on commit f3a2254

Please sign in to comment.