{"id":2119,"url":"https://github.com/Brightify/Cuckoo","last_synced_at":"2025-08-06T14:31:44.493Z","repository":{"id":37431192,"uuid":"49505307","full_name":"Brightify/Cuckoo","owner":"Brightify","description":"Boilerplate-free mocking framework for Swift!","archived":false,"fork":false,"pushed_at":"2024-05-21T20:55:02.000Z","size":2656,"stargazers_count":1641,"open_issues_count":36,"forks_count":168,"subscribers_count":34,"default_branch":"master","last_synced_at":"2024-05-21T23:47:10.073Z","etag":null,"topics":["cocoapods","cuckoo","matcher","mock","mocking","mockito","protocol","stub","swift","unit-testing"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Brightify.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-01-12T14:30:36.000Z","updated_at":"2024-06-15T21:22:20.715Z","dependencies_parsed_at":"2023-11-13T20:24:40.737Z","dependency_job_id":"593cf583-c9d2-4f7f-a6e6-298da6a0b13b","html_url":"https://github.com/Brightify/Cuckoo","commit_stats":{"total_commits":534,"total_committers":59,"mean_commits":9.05084745762712,"dds":0.7584269662921348,"last_synced_commit":"b1ff0383512f0ab954e673718098c6c68bdf57b1"},"previous_names":[],"tags_count":64,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Brightify%2FCuckoo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Brightify%2FCuckoo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Brightify%2FCuckoo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Brightify%2FCuckoo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Brightify","download_url":"https://codeload.github.com/Brightify/Cuckoo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":215780273,"owners_count":15929791,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cocoapods","cuckoo","matcher","mock","mocking","mockito","protocol","stub","swift","unit-testing"],"created_at":"2024-01-05T20:16:04.099Z","updated_at":"2025-08-06T14:31:44.457Z","avatar_url":"https://github.com/Brightify.png","language":"Swift","readme":"# Cuckoo\n## Mock your Swift objects!\n\n[![Platform](https://img.shields.io/cocoapods/p/Cuckoo.svg?style=flat)](http://cocoapods.org/pods/Cuckoo)\n[![CocoaPods ready](https://img.shields.io/badge/CocoaPods-ready-brightgreen?style=flat)](http://cocoapods.org/pods/Cuckoo)\n[![SPM ready](https://img.shields.io/badge/SwiftPM-ready-brightgreen?style=flat)](https://swift.org/package-manager)\n[![License](https://img.shields.io/cocoapods/l/Cuckoo.svg?style=flat)](http://cocoapods.org/pods/Cuckoo)\n\n## Introduction\nCuckoo was created due to lack of a proper Swift mocking framework. We built the DSL to be very similar to [Mockito](http://mockito.org/), so anyone coming from Java/Android can immediately pick it up and use it.\n\n## How does it work\nCuckoo has two parts. One is the **runtime** and the other one is an OS X command-line tool simply called **Cuckoonator**.\n\nUnfortunately Swift does not have a proper reflection, so we decided to use a compile-time generator to go through files you specify and generate supporting structs/classes that will be used by the runtime in your test target.\n\nThe generated files contain enough information to give you the right amount of power. They work based on inheritance and protocol adoption. This means that only overridable things can be mocked. Due to the complexity of Swift it is not easy to check for all edge cases so if you find some unexpected behavior, please file an issue.\n\n## Changelog\nList of all changes and new features can be found [here](CHANGELOG.md).\n\n## Features\nCuckoo is a powerful mocking framework that supports:\n\n- [x] inheritance (grandparent methods)\n- [x] generics\n- [x] simple type inference for instance variables (works with initializers, `as TYPE` notation, and can be overridden by specifying type explicitly)\n- [x] [Objective-C mocks utilizing OCMock](#objective-c-support)\n\n## What will not be supported\nDue to the limitations mentioned above, unoverridable code structures are not supportable by Cuckoo. This includes:\n- `struct` - workaround is to use a common protocol\n- everything with `final` or `private` modifier\n- global constants and functions\n- static properties and methods\n\n## Requirements\nCuckoo works on the following platforms:\n\n- **iOS 13+**\n- **macOS 10.15+**\n- **tvOS 13+**\n- **watchOS 8+**\n\n## Cuckoo\n### 1. Installation\n#### Swift Package Manager\n\nURL: `https://github.com/Brightify/Cuckoo.git`\n\n**WARNING**: Make sure to add Cuckoo to test targets only.\n\nWhen you're all set, go to your test target's Build Phases and add plug-in `CuckooPluginSingleFile` to the **Run Build Tool Plug-ins**.\n\n#### CocoaPods\nCuckoo runtime is available through [CocoaPods](http://cocoapods.org). To install it, simply add the following line to your **test target** in your Podfile:\n\n```ruby\npod 'Cuckoo', '~\u003e 2.0'\n```\n\nAnd add the following `Run script` build phase to your test target's `Build Phases` above the `Compile Sources` phase:\n\n```bash\n# Skip for indexing\nif [ $ACTION == \"indexbuild\" ]; then\n  exit 0\nfi\n\n# Skip for preview builds\nif [ \"${ENABLE_PREVIEWS}\" = \"YES\" ]; then\n  exit 0\nfi\n\n\"${PODS_ROOT}/Cuckoo/run\"\n```\n\nAfter running once, locate `GeneratedMocks.swift` and drag it into your Xcode test target group.\n\n**IMPORTANT**: To make your mocking journey easier, make absolutely sure that the run script is above the `Compile Sources` phase.\n\n**NOTE**: From Xcode 15 the flag `ENABLE_USER_SCRIPT_SANDBOXING` in Build Settings is `Yes` by default. That means Xcode will sandbox the script so reading input files and writing output file will be forbidden. As a result running above script may fail to access the files. To prevent Xcode from sandboxing the script, change this option to `No`.\n\nInput files can be also specified directly in `Run script` in `Input Files` form.\n\nNote: All paths in the Run script must be absolute. Variable `PROJECT_DIR` automatically points to your project directory.\n**Remember to include paths to inherited Classes and Protocols for mocking/stubbing parent and grandparents.**\n\n### 2. Cuckoofile customization\nAt the root of your project, create `Cuckoofile.toml` configuration file:\n\n```toml\n# You can define a fallback output for all modules that don't define their own.\noutput = \"Tests/Swift/Generated/GeneratedMocks.swift\"\n\n[modules.MyProject]\noutput = \"Tests/Swift/Generated/GeneratedMocks+MyProject.swift\"\n# Standard imports added to the generated file(s).\nimports = [\"Foundation\"]\n# Public imports if needed due to imports being internal by default from Swift 6.\npublicImports = [\"ExampleModule\"]\n# @testable imports if needed.\ntestableImports = [\"RxSwift\"]\nsources = [\n    \"Tests/Swift/Source/*.swift\",\n]\nexclude = [\"ExcludedTestClass\"]\n# Optionally you can use a regular expression to filter only specific classes/protocols.\n# regex = \"\"\n\n[modules.MyProject.options]\n# glob = false\n# Docstrings are preserved by default, comments are omitted.\nkeepDocumentation = false\n# enableInheritance = false\n# protocolsOnly = true\n# omitHeaders = true\n\n# If specified, Cuckoo can also get sources for the module from an Xcode target.\n[modules.MyProject.xcodeproj]\n# Path to folder with .xcodeproj, omit this if it's at the same level as Cuckoofile.\npath = \"Generator\"\ntarget = \"Cuckoonator\"\n\n# You can define as many modules as you need, each with different sources/options/output.\n[modules.AnotherProject]\n# ...\n```\n\n### 3. Usage\nUsage of Cuckoo is similar to [Mockito](http://mockito.org/) and [Hamcrest](http://hamcrest.org/). However, there are some differences and limitations caused by generating the mocks and Swift language itself. List of all the supported features can be found below. You can find complete examples in [tests](Tests).\n\n#### Mock initialization\nMocks can be created with the same constructors as the mocked type. Name of mock class always corresponds to the name of the mocked class/protocol with `Mock` prefix (e.g. mock of protocol `Greeter` is called `MockGreeter`).\n\n```swift\nlet mock = MockGreeter()\n```\n\n#### Spy\nSpies are a special type of Mocks where each call is forwarded to the victim by default. When you need a spy, give Cuckoo a class, then you'll then be able to call `enableSuperclassSpy()` (or `withEnabledSuperclassSpy()`) on a mock instance and it will behave like a spy for the parent class.\n\n```swift\nlet spy = MockGreeter().withEnabledSuperclassSpy()\n```\n\n#### Stubbing\nStubbing can be done by calling methods as a parameter of the `when` function. The stub call must be done on special stubbing object. You can get a reference to it with the `stub` function. This function takes an instance of the mock that you want to stub and a closure in which you can do the stubbing. The parameter of this closure is the stubbing object.\n\nNote: It is currently possible for the subbing object to escape from the closure. You can still use it to stub calls but it is not recommended in practice as the behavior of this may change in the future.\n\nAfter calling the `when` function you can specify what to do next with following methods:\n\n```swift\n/// Invokes `implementation` when invoked.\nthen(_ implementation: IN throws -\u003e OUT)\n\n/// Returns `output` when invoked.\nthenReturn(_ output: OUT, _ outputs: OUT...)\n\n/// Throws `error` when invoked.\nthenThrow(_ error: ErrorType, _ errors: Error...)\n\n/// Invokes real implementation when invoked.\nthenCallRealImplementation()\n\n/// Does nothing when invoked.\nthenDoNothing()\n```\n\nThe available methods depend on the stubbed method characteristics. For example, the `thenThrow` method isn't available for a method that isn't throwing or rethrowing.\n\nAn example of stubbing a method looks like this:\n\n```swift\nstub(mock) { stub in\n  when(stub.greetWithMessage(\"Hello world\")).then { message in\n    print(message)\n  }\n}\n```\n\nAs for a property:\n\n```swift\nstub(mock) { stub in\n  when(stub.readWriteProperty.get).thenReturn(10)\n  when(stub.readWriteProperty.set(anyInt())).then {\n    print($0)\n  }\n}\n```\n\nNotice the `get` and `set`, these will be used in verification later.\n\n##### Enabling default implementation\nIn addition to stubbing, you can enable default implementation using an instance of the original class that's being mocked. Every method/property that is not stubbed will behave according to the original implementation.\n\nEnabling the default implementation is achieved by simply calling the provided method:\n\n```swift\nlet original = OriginalClass\u003cInt\u003e(value: 12)\nmock.enableDefaultImplementation(original)\n```\n\nFor passing classes into the method, nothing changes whether you're mocking a class or a protocol. However, there is a difference if you're using a `struct` to conform to the original protocol we are mocking:\n\n```swift\nlet original = ConformingStruct\u003cString\u003e(value: \"Hello, Cuckoo!\")\nmock.enableDefaultImplementation(original)\n// or if you need to track changes:\nmock.enableDefaultImplementation(mutating: \u0026original)\n```\n\nNote that this only concerns `struct`s. `enableDefaultImplementation(_:)` and `enableDefaultImplementation(mutating:)` are different in state tracking.\n\nThe standard non-mutating method `enableDefaultImplementation(_:)` creates a copy of the `struct` for default implementation and works with that. However, the mutating method `enableDefaultImplementation(mutating:)` takes a reference to the struct and the changes of the `original` are reflected in the default implementation calls even after enabling default implementation.\n\nWe recommend using the non-mutating method for enabling default implementation unless you need to track the changes for consistency within your code.\n\n##### Chain stubbing\nIt is possible to chain stubbing. This is useful for when you need to define different behavior for multiple calls in order. The last behavior will be used for all calls after that. The syntax goes like this:\n\n```swift\nwhen(stub.readWriteProperty.get).thenReturn(10).thenReturn(20)\n```\n\nwhich is equivalent to:\n\n```swift\nwhen(stub.readWriteProperty.get).thenReturn(10, 20)\n```\n\nThe first call to `readWriteProperty` will return `10` and all calls after that will return `20`.\n\nYou can combine the stubbing methods as you like.\n\n##### Overriding of stubbing\nWhen looking for stub match Cuckoo gives the highest priority to the last call of `when`. This means that calling `when` multiple times with the same function and matchers effectively overrides the previous call. Also more general parameter matchers have to be used before specific ones.\n\n```swift\nwhen(stub.countCharacters(anyString())).thenReturn(10)\nwhen(stub.countCharacters(\"a\")).thenReturn(1)\n```\n\nIn this example calling `countCharacters` with `a` will return `1`. If you reversed the order of stubbing then the output would always be `10`.\n\n#### Usage in real code\nAfter previous steps the stubbed method can be called. It is up to you to inject this mock into your production code.\n\nNote: Call on mock which wasn't stubbed will cause an error. In case of a spy, the real code will execute.\n\n#### Verification\nFor verifying calls there is function `verify`. Its first parameter is the mocked object, optional second parameter is the call matcher. Then the call with its parameters follows.\n\n```swift\nverify(mock).greetWithMessage(\"Hello world\")\n```\n\nVerification of properties is similar to their stubbing.\n\nYou can check if there are no more interactions on mock with function `verifyNoMoreInteractions`.\n\nWith Swift's generic types, it is possible to use a generic parameter as the return type. To properly verify these methods, you need to be able to specify the return type.\n\n```swift\n// Given:\nfunc genericReturn\u003cT: Codable\u003e(for: String) -\u003e T? { ... }\n\n// Verify\nverify(mock).genericReturn(for: any()).with(returnType: String?.self)\n```\n\n##### Argument capture\nYou can use `ArgumentCaptor` to capture arguments in verification of calls (doing that in stubbing is not recommended). Here is an example code:\n\n```swift\nmock.readWriteProperty = 10\nmock.readWriteProperty = 20\nmock.readWriteProperty = 30\n\nlet argumentCaptor = ArgumentCaptor\u003cInt\u003e()\nverify(mock, times(3)).readWriteProperty.set(argumentCaptor.capture())\nargumentCaptor.value // Returns 30\nargumentCaptor.allValues // Returns [10, 20, 30]\n```\n\nAs you can see, method `capture()` is used to create matcher for the call and then you can get the arguments via properties `value` and `allValues`. `value` returns last captured argument or nil if none. `allValues` returns array with all captured values.\n\n### 3. Matchers\nCuckoo makes use of *matchers* to connect your mocks to your code under test.\n\n#### A) Automatic matchers for known types\nYou can mock any object that conforms to the `Matchable` protocol. Standard built-in types like `Int`, `String`, already conform thanks to Cuckoo. Automatic conformance synthesis applies for `Array` and the like.\n\n#### B) Custom matchers\nIf Cuckoo doesn't know the type you are trying to compare, you have to write your own method `equal(to:)` using a `ParameterMatcher`. Add this method to your test file:\n\n```swift\nfunc equal(to value: YourCustomType) -\u003e ParameterMatcher\u003cYourCustomType\u003e {\n  return ParameterMatcher { tested in\n    // Implementation of equality test for your custom type.\n\n  }\n}\n```\n\n⚠️ Trying to match an object with an unknown or non-`Matchable` type may lead to:\n\n```\nCommand failed due to signal: Segmentation fault: 11\n```\n\nFor details or an example (with Alamofire), see [this issue](https://github.com/Brightify/Cuckoo/issues/124).\n\n#### Parameter matchers\n`ParameterMatcher` itself also conforms to `Matchable`. You can create your own `ParameterMatcher` instances or if you want to directly use your custom types there is the `Matchable` protocol. Standard instances of `ParameterMatcher` can be obtained via these functions:\n\n```swift\n/// Returns an equality matcher.\nequal\u003cT: Equatable\u003e(to value: T)\n\n/// Returns an identity matcher.\nequal\u003cT: AnyObject\u003e(to value: T)\n\n/// Returns a matcher using the supplied function.\nequal\u003cT\u003e(to value: T, equalWhen equalityFunction: (T, T) -\u003e Bool)\n\n/// Returns a matcher matching any Int value.\nanyInt()\n\n/// Returns a matcher matching any String value.\nanyString()\n\n/// Returns a matcher matching any T value or nil.\nany\u003cT\u003e(type: T.Type = T.self)\n\n/// Returns a matcher matching any closure.\nanyClosure()\n\n/// Returns a matcher matching any throwing closure.\nanyThrowingClosure()\n\n/// Returns a matcher matching any non nil value.\nnotNil()\n```\n\nCuckoo also provides plenty of convenience matchers for sequences and dictionaries, allowing you to check if a sequence is a superset of a certain sequence, contains at least one of its elements, or is completely disjunct from it.\n\n`Matchable` can be chained with methods `or` and `and` like so:\n\n```swift\nverify(mock).greetWithMessage(\"Hello world\".or(\"Hallo Welt\"))\n```\n\n#### Call matchers\nAs a second parameter of the `verify` function you can use instances of `CallMatcher`. Its primary function is to assert how many times was the call made. But the `matches` function has a parameter of type `[StubCall]` which means you can use a custom `CallMatcher` to inspect the stub calls or for some side effect.\n\nNote: Call matchers are applied after the parameter matchers. So you get only stub calls of the desired method with correct arguments.\n\nStandard call matchers are:\n\n```swift\n/// Returns a matcher ensuring a call was made `count` times.\ntimes(_ count: Int)\n\n/// Returns a matcher ensuring no call was made.\nnever()\n\n/// Returns a matcher ensuring at least one call was made.\natLeastOnce()\n\n/// Returns a matcher ensuring call was made at least `count` times.\natLeast(_ count: Int)\n\n/// Returns a matcher ensuring call was made at most `count` times.\natMost(_ count: Int)\n```\n\nAs with `Matchable` you can chain `CallMatcher` with methods `or` and `and`. However, you can't mix `Matchable` and `CallMatcher` together.\n\n#### Resetting mocks\nFollowing functions are used to reset stubbing and/or invocations on mocks.\n\n```swift\n/// Clears all invocations and stubs of given mocks.\nreset\u003cM: Mock\u003e(_ mocks: M...)\n\n/// Clears all stubs of given mocks.\nclearStubs\u003cM: Mock\u003e(_ mocks: M...)\n\n/// Clears all invocations of given mocks.\nclearInvocations\u003cM: Mock\u003e(_ mocks: M...)\n```\n\n#### Stub objects\nStubs are used for suppressing real code. Stubs are different from Mocks in that they don't support stubbing nor verification. They can be created with the same constructors as the mocked type. Name of stub class always corresponds to name of the mocked class/protocol with `Stub` suffix (e.g. stub of protocol `Greeter` is called `GreeterStub`).\n\n```swift\nlet stub = GreeterStub()\n```\n\nWhen a method is called or a property accessed/set on a stub, nothing happens. If a value is to be returned from a method or a property, `DefaultValueRegistry` provides a default value. Stubs can be used to set implicit (no) behavior to mocks without the need to use `thenDoNothing()` like this: `MockGreeter().spy(on: GreeterStub())`.\n\n##### DefaultValueRegistry\n`DefaultValueRegistry` is used by Stubs to get default values for return types. It knows only default Swift types, sets, arrays, dictionaries, optionals, and tuples (up to 6 values). Tuples for more values can be added through extensions. Custom types must be registered before use with `DefaultValueRegistry.register\u003cT\u003e(value: T, forType: T.Type)`. Furthermore, default values set by Cuckoo can also be overridden by this method. Sets, arrays, etc. do not have to be registered if their generic type is already registered.\n\n`DefaultValueRegistry.reset()` returns the registry to its clean slate before the `register` method made any changes.\n\n##### Type inference\nCuckoo does a simple type inference on all variables which allows for much cleaner source code on your side. There are a total 3 ways the inference tries to extract the type name from a variable:\n\n```swift\n// From the explicitly declared type:\nlet constant1: MyType\n\n// From the initial value:\nlet constant2 = MyType(...)\n\n// From the explicitly specified type `as MyType`:\nlet constant3 = anything as MyType\n```\n\n## Cuckoo run script\n#### Build Options\nThese options are only used for downloading or building the generator and don't interfere with the result of the generated mocks.\n\nWhen the [run script](run) is executed without any parameters, it simply searches for the `cuckoonator` file and builds it from source code if it's missing, running the generator afterwards.\n\nTo download the generator from GitHub instead of building it, use the `--download` option as the first argument (i.e. `run --download`). If you're having issues with rather long build time (especially in CI), this might be the way to fix it.\n\n**NOTE**: If you encounter Github API rate limit using the `--download` option, the [run script](run) refers to the environment variable `GITHUB_ACCESS_TOKEN`.\nAdd this line (replacing the Xs with your [GitHub token](https://github.com/settings/tokens), no additional permissions are needed) to the script build phase above the `run` call:\n```bash\nexport GITHUB_ACCESS_TOKEN=\"XXXXXXX\"\n```\n\nThe build option `--clean` forces either build or download of the version specified even if the generator is present.\nThe run script also syncs the generator to the correct version (either by building from source or downloading with `--download`) if needed.\n\nWe recommend only using `--clean` when you're trying to fix a compile problem as it forces the build (or download) every time which makes the testing way longer than it needs to be.\n\n## Objective-C Support\nFor Objective-C support, Cuckoo wraps `OCMock` and uses its battle-tested functionality to bring support for mocking various Objective-C classes and protocols to Swift.\n\nFor example:\n```swift\nlet tableView = UITableView()\n// stubbing the class is very similar to stubbing with Cuckoo, note the `objcStub` method.\nlet mock = objcStub(for: UITableViewController.self) { stubber, mock in\n  stubber.when(mock.numberOfSections(in: tableView)).thenReturn(1)\n  stubber.when(mock.tableView(tableView, accessoryButtonTappedForRowWith: IndexPath(row: 14, section: 2))).then { args in\n    // An unfortunate drawback is that arguments will miss type information, so the closure needs to cast them manually.\n    let (tableView, indexPath) = (args[0] as! UITableView, args[1] as! IndexPath)\n    print(tableView, indexPath)\n  }\n}\n\n// Invoking is exactly the same as you'd expect.\nXCTAssertEqual(mock.numberOfSections(in: tableView), 1)\nmock.tableView(tableView, accessoryButtonTappedForRowWith: IndexPath(row: 14, section: 2))\n\n// `objcVerify` replaces `verify` to test the interaction with methods/variables.\nobjcVerify(mock.numberOfSections(in: tableView))\nobjcVerify(mock.tableView(tableView, accessoryButtonTappedForRowWith: IndexPath(row: 14, section: 2)))\n```\n\nDetailed usage is available in Cuckoo tests along with DOs and DON'Ts of this Swift-ObjC bridge.\n\n## Contribute\nCuckoo is open for everyone and we'd like you to help us make the best Swift mocking library. For Cuckoo development, follow these steps:\n1. Clone the **Cuckoo** repository.\n2. Make sure you have [Mise](https://mise.jdx.dev/getting-started.html) installed.\n3. Run `make` at the root of the repository. This will install dependencies, generate the project, and open it in Xcode.\n4. Select any scheme of `Cuckoo-iOS`, `Cuckoo-tvOS`, or `Cuckoo-macOS` and verify by running the tests (⌘+U).\n5. Peek around or file a pull request with your changes.\n\n**NOTE**: Make sure to run `make` again whenever you checkout another branch, the project utilizes [Tuist](https://github.com/tuist/tuist) for project generation.\n\nThe project consists of two parts - runtime and code generator. When you open the `Cuckoo.xcworkspace` in Xcode, you'll see these directories:\n    - `Source` - runtime sources\n    - `Tests` - tests for the runtime part\n    - `Generator.xcodeproj` - project containing generator source code (use the `Generator` scheme to run it)\n\nThank you for your help!\n\n## Inspiration\n- [Mockito](http://mockito.org/) - Mocking DSL\n- [Hamcrest](http://hamcrest.org/) - Matcher API\n\n## Used libraries\n- [ArgumentParser](https://github.com/apple/swift-argument-parser)\n- [FileKit](https://github.com/nvzqz/FileKit)\n- [SwiftSyntax](https://github.com/apple/swift-syntax)\n\n## License\nCuckoo is available under the [MIT License](LICENSE).\n","funding_links":[],"categories":["Testing","Libs","Swift","Testing [🔝](#readme)","🧪 Testing Architecture"],"sub_categories":["Other Testing","Testing","Other free courses","Testing Resources"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FBrightify%2FCuckoo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FBrightify%2FCuckoo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FBrightify%2FCuckoo/lists"}