Swiftpack.co - justeattakeaway/Genything as Swift Package

Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
See all packages published by justeattakeaway.
justeattakeaway/Genything 0.0.2
Generate Anything
⭐️ 17
🕓 2 weeks ago
iOS macOS watchOS tvOS
.package(url: "https://github.com/justeattakeaway/Genything.git", from: "0.0.2")

Genything

Genything

Swift: 5.0 Platforms: iOS – tvOS – watchOS – macOS Cocoapods Compatible Swift Package Manager Compatible

Genything - Generate Anything

Genything is a library dedicated to easy and composable generation of random data, no matter how complex.

Genything can be combined with Trickery which provides a growing library of pre-made generators which mock real-world information.

Both of these libraries may be used for code testing, rapid prototyping, demo applications, ui testing, and much more. Be creative!

Why use Genything?

  • We do not include a dependency on XCTest
  • Controllable randomness that's deterministic by default
    • Produce the same results on CI, your colleagues machine, and your own
  • You can use these generators for anything!
    • Create dummy data for your example apps or to rapidly prototype features
    • Use them in your SwiftUI previews to rapidly discover edge cases
    • Run your screenshot tests with easy-to-use and predictable data
    • Use your generators to unit test with Property Based Testing
  • High test coverage
  • 100% Documented

Gen

The Gen type class is the core of Genything. It is nothing more than a generic container that stores a callback capable of generating a value from a Context.

struct Gen<T> {
    let generator: (Context) throws -> T
}

The Context contains configuration, and a Random Number Generator which you can customize.

So a generator of Booleans might look like this:

Gen<Bool> { context in
    Bool.random(using: &context.rng)
}

This is a good to understand, but in practice you can avoid Gen's initializer altogether and instead use the vast library of extensions to build, combine, and mutate Gens.

You can find out more about these extensions in the documentation!

Arbitrary

The Arbitary protocol allows a Type to define a generator suitable for generating all of it's values.

Take Swift's Bool as example, it's Arbitrary is defined as:

extension Bool: Arbitrary {
    public static var arbitrary: Gen<Bool> {
        Gen.of([true, false])
    }
}

We can now use this definition automatically when we are composing a more complex arbitrary type:

struct Transaction {
  let isComplete: Bool
  // ...
}

extension Transaction: Arbitrary {
    public static var arbitrary: Gen<Bool> {
        Gen.compose {
          Transaction(
            isComplete: $0.generate(), // Will equally generate True or False when the Transaction generator is run
            //...
          )
        }
    }
}

These can then be used for invariant tests, to stub an API response, as preview data, etc...

Trickery

Genything comes together with Trickery, a collection of generators suitable for producing pseudo-realistic data according to real-world-conditions rather than those enforced only by the type.

Consider a phone number. A phone number of type String has rules about length, formatting, allowable characters. Whereas the arbitrary type String contains contains at most a definition of it's length

Examples

Examples: Gen

import Genything

let cityGen = Gen.of(["Winnipeg","Calgary","Vancouver","Halifax"])

/// Generates 1 city
cityGen.generate()

/// Takes 100 random cities
cityGen.take(count: 100)

/// Prints values from the generator until the Context's max iterations is reached
cityGen.forEach { city in print(city) }

Examples: Arbitrary

Will print an arbitrary string with any number of random characters

import Genything
 
let arbitraryString = String.arbitrary.sample()
debugPring(arbitraryString)

Examples: Trickery

Trickery Example: Use fake data to create a Swift UI preview

import Trickery

struct PhoneBook_Previews: PreviewProvider {
    static var previews: some View {
        PhoneBook(
          Gen.zip(
            Fake.PersonNames.full, 
            Fake.PhoneNumbers.formatted
          ) { 
            PhoneBookRow(name: $0, number: $1) 
          }.samples()
        )
    }
}

Mixins

Genything & Trickery are also amazing when combined with other open source libraries!

SFSafeSymbols

Generate any SF Symbol

extension Fake {
    public enum SFSafeSymbols {
        @available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
        public static let any: Gen<SFSymbol> = .ofCases().map { $0.rawValue }
    }
}

Installation

Cocoapods

pod 'Genything'
pod 'Trickery'

Swift Package Manager

Create a Package.swift file in your root directory and add:

dependencies: [
    .package(url: "https://github.com/justeattakeaway/genything.git", .exact("0.0.1"))
]

Then install Genything and optionally Trickery by adding it to:

  • General -> "Frameworks and Libraries", for an application of framework target
  • Build Phases -> "Link Binary With Libraries", for a test target

Credits

The Genything and Trickery projects are owned and maintained by SkipTheDishes, a Just Eat Takeaway.com subsidiary.

Contributing

Please read the Contribution Guide

Inspiration

Genything stands on the shoulder of giants. Please check out these other libraries and resources!

License

See: License

Apache License Version 2.0, January 2004 http://www.apache.org/licenses/

GitHub

link
Stars: 17
Last commit: 18 minutes ago
jonrohan Something's broken? Yell at me @ptrpavlik. Praise and feedback (and money) is also welcome.

Release Notes

v0.0.2
2 weeks ago

What's Changed

Full Changelog: https://github.com/justeattakeaway/Genything/compare/0.0.1...0.0.2

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics