├── .github └── workflows │ └── master.yml ├── .gitignore ├── .jazzy.yaml ├── .legacy ├── .mocky.iOS.yml ├── .mocky.macOS.yml ├── .mocky.spm.yml └── .mocky.tvOS.yml ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── Makefile ├── Mintfile ├── Mockfile ├── Mocky_Example_iOS_15-Info.plist ├── Mocky_Tests_iOS_15-Info.plist ├── Package.resolved ├── Package.swift ├── Podfile ├── Podfile.lock ├── README.md ├── Rakefile ├── Sources ├── CLI │ ├── App │ │ └── main.swift │ └── Core │ │ ├── Application.swift │ │ ├── Assets │ │ ├── Assets.swift │ │ └── Messages.swift │ │ ├── Commands │ │ ├── GenerationController.swift │ │ ├── MacOS │ │ │ ├── InspectionController.swift │ │ │ ├── MigrationController.swift │ │ │ └── ProjectSetupController.swift │ │ └── MockfileInteractor.swift │ │ ├── Entities │ │ ├── MockConfiguration.swift │ │ ├── Mockfile.swift │ │ └── SourceryConfiguration.swift │ │ ├── InstanceFactory.swift │ │ ├── InteractiveOptions │ │ ├── AddingOption.swift │ │ ├── Booloption.swift │ │ ├── ProjectOption.swift │ │ └── SelectableOption.swift │ │ └── Utils │ │ ├── Global.swift │ │ ├── MacOS │ │ └── XCodeProj+Extensions.swift │ │ ├── Message.swift │ │ ├── PathKit+Extensions.swift │ │ ├── ProjectFile.swift │ │ ├── ShellOut+Extensions.swift │ │ └── WorkingDirectory.swift ├── Shared │ ├── Count.swift │ ├── Countable.swift │ ├── GenericAttribute.swift │ ├── Matcher.swift │ ├── Mock+Assertions.swift │ ├── Mock.swift │ ├── Parameter+Compare.swift │ ├── Parameter+Optionals.swift │ ├── Parameter.swift │ ├── Policies.swift │ ├── Stubbing.swift │ └── Utils.swift ├── SwiftyMocky │ ├── ArgumentCaptor.swift │ ├── CustomAssertions.swift │ ├── Mock.swifttemplate │ ├── MockyAssert.swift │ ├── Parameter+Literals.swift │ ├── Shared │ └── SwiftyMockyTestObserver.swift └── SwiftyPrototype │ ├── MockyAssert.swift │ ├── Prototype.swifttemplate │ ├── Shared │ └── SwiftyMockyTestObserver.swift ├── SwiftyMocky-Example ├── Shared │ ├── AssociatedTypes │ │ └── SuggestionRepository.swift │ ├── Example 1 │ │ ├── ProtocolsWithCollections.swift │ │ └── SimpleProtocols.swift │ ├── Example 10 │ │ └── ProtocolWithGenericConstraints.swift │ ├── Example 2 │ │ └── ProtocolWithThrowingMethods.swift │ ├── Example 3 │ │ └── ProtocolsWithCustomAttributes.swift │ ├── Example 4 │ │ └── ProtocolWithStaticMembers.swift │ ├── Example 5 │ │ └── ProtocolsWithClosures.swift │ ├── Example 6 │ │ └── ProtocolWithInitializers.swift │ ├── Example 7 │ │ └── ProtocolsWithGenerics.swift │ ├── Example 8 │ │ └── ProtocolWithProperties.swift │ ├── Example 9 │ │ └── ProtocolMethodsThatDifferOnlyInReturnType.swift │ ├── Model │ │ ├── Item.swift │ │ └── Models.swift │ ├── Other │ │ ├── AllLiteralsContainerProtocol.swift │ │ ├── EdgeCasesProtocols.swift │ │ ├── ExampleProtocols.swift │ │ ├── Excluded.generated.swift │ │ ├── GenericProtocols.swift │ │ ├── InoutParameterProtocols.swift │ │ ├── ItemsRepository.swift │ │ ├── MultiThreadAccess.swift │ │ ├── NonSwiftProtocol.swift │ │ ├── ProtocolWithAttributes.swift │ │ ├── ProtocolWithMethodWithManyParameters.swift │ │ ├── ProtocolWithSubscripts.swift │ │ ├── SampleService.swift │ │ ├── SelfConstrainedProtocol.swift │ │ ├── UnnamedAttributesProtocol.swift │ │ └── VariadicParametersProtocol.swift │ └── Swift5.5 │ │ ├── AsyncMethodsProtocol.swift │ │ └── ThrowingVarProtocol.swift ├── iOS │ ├── AppDelegate.swift │ ├── Base.lproj │ │ ├── LaunchScreen.xib │ │ └── Main.storyboard │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Info.plist │ └── ViewController.swift ├── macOS │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ └── Main.storyboard │ ├── Info.plist │ ├── Mocky_Example_macOS.entitlements │ └── ViewController.swift └── tvOS │ ├── AppDelegate.swift │ ├── Assets.xcassets │ └── Contents.json │ ├── Base.lproj │ └── Main.storyboard │ ├── Info.plist │ └── ViewController.swift ├── SwiftyMocky-Runtime ├── Info.plist ├── Prototyping.h └── SwiftyMocky.h ├── SwiftyMocky-Tests ├── Shared │ ├── AssociatedTypes │ │ └── SuggestionRepositoryTests.swift │ ├── Example 1 │ │ ├── ProtocolsWithCollectionsTests.swift │ │ └── SimpleProtocolsTests.swift │ ├── Example 10 │ │ └── ProtocolWithGenericConstraintsTests.swift │ ├── Example 2 │ │ └── ProtocolWithThrowingMehtodsTests.swift │ ├── Example 3 │ │ └── ProtocolsWithCustomAttributesTests.swift │ ├── Example 4 │ │ └── ProtocolWithStaticMembersTests.swift │ ├── Example 5 │ │ └── ProtocolWithClosuresTests.swift │ ├── Example 6 │ │ └── ProtocolWithInitializersTests.swift │ ├── Example 7 │ │ └── ProtocolsWithGenericsTests.swift │ ├── Example 8 │ │ └── ProtocolWithPropertiesTests.swift │ ├── Example 9 │ │ └── ProtocolMethodsThatDifferOnlyInReturnTypeTests.swift │ ├── Other │ │ ├── ComplicatedServiceTests.swift │ │ ├── ComposedServiceTests.swift │ │ ├── CustomAssertionsTests.swift │ │ ├── EdgeCasesTests.swift │ │ ├── ExampleTests.swift │ │ ├── ExpressibleByLiteralsTests.swift │ │ ├── GenericProtocolsTests.swift │ │ ├── InoutParameterTests.swift │ │ ├── MatcherTests.swift │ │ ├── MockClearTests.swift │ │ ├── MultiThreadAccessTests.swift │ │ ├── PropertiesHandlingTests.swift │ │ ├── ProtocolWithAttributesTests.swift │ │ ├── SampleServiceTests.swift │ │ ├── SelfConstrainedProtocolTests.swift │ │ ├── SimpleSequencingTests.swift │ │ ├── SubscriptsTests.swift │ │ ├── UnnamedAttributesTests.swift │ │ ├── VariadicParametersTests.swift │ │ └── VerifyMessagesTests.swift │ └── Swift5.5 │ │ ├── AsyncMethodsProtocolTests.swift │ │ └── ThrowingVarProtocolTests.swift ├── iOS │ ├── Info.plist │ └── Mocks │ │ ├── ItemsRepositoryMock.swift │ │ ├── Mock.15.generated.swift │ │ └── Mock.generated.swift ├── macOS │ ├── Info.plist │ ├── Mocks │ │ ├── ItemsRepositoryMock.swift │ │ └── Mock.generated.swift │ └── Mocky_Example_macOSTests.swift └── tvOS │ ├── Info.plist │ ├── Mocks │ ├── ItemsRepositoryMock.swift │ └── Mock.generated.swift │ └── Mocky_tvOS_Tests.swift ├── SwiftyMocky.podspec ├── SwiftyMocky.xcodeproj ├── project.pbxproj └── xcshareddata │ └── xcschemes │ ├── Mocky_Example_iOS.xcscheme │ ├── Mocky_Example_iOS_15.xcscheme │ ├── Mocky_Example_macOS.xcscheme │ ├── Mocky_Example_tvOS.xcscheme │ ├── Mocky_Tests_iOS.xcscheme │ ├── Mocky_Tests_iOS_15.xcscheme │ ├── Mocky_Tests_macOS.xcscheme │ ├── Mocky_Tests_tvOS.xcscheme │ ├── SwiftyMocky.xcscheme │ └── SwiftyPrototype.xcscheme ├── SwiftyMocky.xcworkspace └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── SwiftyPrototype.podspec ├── Templates ├── AllTypes.swifttemplate ├── ArgumentsHelper.swift ├── Assets.template ├── Current.swift ├── Header-Mock.swifttemplate ├── Header-Prototype.swifttemplate ├── Helpers.swift ├── Imports.swifttemplate ├── Main.swifttemplate ├── MethodWrapper.swift ├── ParameterWrapper.swift ├── SubscriptWrapper.swift ├── TemplateHelper.swift ├── TypeWrapper.swift └── VariableWrapper.swift ├── Tests ├── LinuxMain.swift ├── RuntimeLibaryTests │ ├── MatcherTests.swift │ └── XCTestManifests.swift ├── SwiftyMockyCLICoreTests │ ├── CommandLineInterfaceTests.swift │ ├── Mock.generated.swift │ └── XCTestManifests.swift └── SwiftyMockyTests │ ├── Mock.generated.swift │ ├── Shared │ └── XCTestManifests.swift ├── bin └── swiftymocky ├── docs ├── Additional Guides.html ├── Classes │ ├── ArgumentCaptor.html │ ├── Matcher.html │ ├── Matcher │ │ ├── ComparisonResult.html │ │ └── ParameterComparisonResult.html │ ├── MockyAssertion.html │ ├── StubbedMethod.html │ └── SwiftyMockyTestObserver.html ├── Configuration.html ├── Enums │ ├── Count.html │ ├── MockError.html │ ├── MockScope.html │ ├── Parameter.html │ ├── SequencingPolicy.html │ ├── StubProduct.html │ ├── StubbingPolicy.html │ └── Utils.html ├── Extensions │ ├── Int.html │ ├── Optional.html │ └── UInt.html ├── Generics.html ├── Global methods.html ├── Helpers.html ├── Internal.html ├── Main Guides.html ├── Other Classes.html ├── Other Enums.html ├── Other Guides.html ├── Other Protocols.html ├── Other Structs.html ├── Protocols │ ├── Countable.html │ ├── Mock.html │ ├── OptionalType.html │ ├── StaticMock.html │ ├── TypeErasedValue.html │ ├── WithSequencingPolicy.html │ ├── WithStaticSequencingPolicy.html │ └── WithStubbingPolicy.html ├── Structs │ ├── FatalErrorUtil.html │ ├── GenericAttribute.html │ ├── Stubber.html │ ├── StubberThrows.html │ └── TypeErasedAttribute.html ├── Types.html ├── add-xcode-generate-action.html ├── badge.svg ├── changelog.html ├── command-line-interface.html ├── contents.html ├── css │ ├── highlight.css │ └── jazzy.css ├── docsets │ ├── SwiftyMocky.docset │ │ └── Contents │ │ │ ├── Info.plist │ │ │ └── Resources │ │ │ ├── Documents │ │ │ ├── Additional Guides.html │ │ │ ├── Classes │ │ │ │ ├── ArgumentCaptor.html │ │ │ │ ├── Matcher.html │ │ │ │ ├── Matcher │ │ │ │ │ ├── ComparisonResult.html │ │ │ │ │ └── ParameterComparisonResult.html │ │ │ │ ├── MockyAssertion.html │ │ │ │ ├── StubbedMethod.html │ │ │ │ └── SwiftyMockyTestObserver.html │ │ │ ├── Configuration.html │ │ │ ├── Enums │ │ │ │ ├── Count.html │ │ │ │ ├── MockError.html │ │ │ │ ├── MockScope.html │ │ │ │ ├── Parameter.html │ │ │ │ ├── SequencingPolicy.html │ │ │ │ ├── StubProduct.html │ │ │ │ ├── StubbingPolicy.html │ │ │ │ └── Utils.html │ │ │ ├── Extensions │ │ │ │ ├── Int.html │ │ │ │ ├── Optional.html │ │ │ │ └── UInt.html │ │ │ ├── Generics.html │ │ │ ├── Global methods.html │ │ │ ├── Helpers.html │ │ │ ├── Internal.html │ │ │ ├── Main Guides.html │ │ │ ├── Other Classes.html │ │ │ ├── Other Enums.html │ │ │ ├── Other Guides.html │ │ │ ├── Other Protocols.html │ │ │ ├── Other Structs.html │ │ │ ├── Protocols │ │ │ │ ├── Countable.html │ │ │ │ ├── Mock.html │ │ │ │ ├── OptionalType.html │ │ │ │ ├── StaticMock.html │ │ │ │ ├── TypeErasedValue.html │ │ │ │ ├── WithSequencingPolicy.html │ │ │ │ ├── WithStaticSequencingPolicy.html │ │ │ │ └── WithStubbingPolicy.html │ │ │ ├── Structs │ │ │ │ ├── FatalErrorUtil.html │ │ │ │ ├── GenericAttribute.html │ │ │ │ ├── Stubber.html │ │ │ │ ├── StubberThrows.html │ │ │ │ └── TypeErasedAttribute.html │ │ │ ├── Types.html │ │ │ ├── add-xcode-generate-action.html │ │ │ ├── changelog.html │ │ │ ├── command-line-interface.html │ │ │ ├── contents.html │ │ │ ├── css │ │ │ │ ├── highlight.css │ │ │ │ └── jazzy.css │ │ │ ├── examples.html │ │ │ ├── handling-generics.html │ │ │ ├── img │ │ │ │ ├── carat.png │ │ │ │ ├── dash.png │ │ │ │ ├── gh.png │ │ │ │ └── spinner.gif │ │ │ ├── index.html │ │ │ ├── installation.html │ │ │ ├── js │ │ │ │ ├── jazzy.js │ │ │ │ ├── jazzy.search.js │ │ │ │ ├── jquery.min.js │ │ │ │ ├── lunr.min.js │ │ │ │ └── typeahead.jquery.js │ │ │ ├── known-issues.html │ │ │ ├── legacy.html │ │ │ ├── matcher-support-for-not-equatable.html │ │ │ ├── mockfile.html │ │ │ ├── overview.html │ │ │ ├── prototyping.html │ │ │ ├── search.json │ │ │ ├── setup-in-project.html │ │ │ └── supported-features.html │ │ │ └── docSet.dsidx │ └── SwiftyMocky.tgz ├── examples.html ├── handling-generics.html ├── img │ ├── carat.png │ ├── dash.png │ ├── gh.png │ └── spinner.gif ├── index.html ├── installation.html ├── js │ ├── jazzy.js │ ├── jazzy.search.js │ ├── jquery.min.js │ ├── lunr.min.js │ └── typeahead.jquery.js ├── known-issues.html ├── legacy.html ├── matcher-support-for-not-equatable.html ├── mockfile.html ├── overview.html ├── prototyping.html ├── search.json ├── setup-in-project.html ├── supported-features.html └── undocumented.json ├── fastlane ├── Fastfile ├── README.md └── certs.sh ├── guides ├── Add XCode generate action.md ├── CHANGELOG.md ├── Command Line Interface.md ├── Contents.md ├── Examples.md ├── Handling Generics.md ├── Installation.md ├── Known issues.md ├── Legacy.md ├── Matcher support for not Equatable.md ├── Mockfile.md ├── Overview.md ├── Prototyping.md ├── Setup in project.md ├── Supported features.md └── assets │ ├── add-framework-tocopy-files-phase.png │ ├── add-new-copy-files-phase.png │ ├── example-given.gif │ ├── example-verify.gif │ ├── example-watcher.gif │ ├── guide-add-generate.gif │ └── link-binary-with-libraries.png └── icon.png /.github/workflows/master.yml: -------------------------------------------------------------------------------- 1 | name: Build & Tests 2 | on: 3 | push: 4 | branches: 5 | - master 6 | pull_request: 7 | branches: 8 | - master 9 | jobs: 10 | SwiftyMocky-Tests: 11 | runs-on: macos-latest 12 | steps: 13 | - name: Check out repository code 14 | uses: actions/checkout@v2 15 | - name: Set Xcode version 16 | uses: maxim-lobanov/setup-xcode@v1 17 | with: 18 | xcode-version: '15.4' 19 | - name: Prepare for tests 20 | run: | 21 | rake pods 22 | rake mock 23 | - name: Run tests iOS 24 | run: | 25 | fastlane ios test 26 | - name: Run tests tvOS 27 | run: | 28 | fastlane tvos test 29 | - name: Run tests SwiftPM 30 | run: | 31 | swift test 32 | -------------------------------------------------------------------------------- /.jazzy.yaml: -------------------------------------------------------------------------------- 1 | author: Przemysław Wośko, Andrzej Michnia 2 | author_url: https://girappe.com 3 | module: SwiftyMocky 4 | sourcekitten_sourcefile: docs.json 5 | module_version: 4.2.0 6 | github_url: https://github.com/MakeAWishFoundation/SwiftyMocky 7 | copyright: 'Copyright © 2017 MakeAWishFoundation. All rights reserved.' 8 | readme: guides/Overview.md 9 | documentation: guides/*.md 10 | 11 | custom_categories: 12 | - name: Main Guides 13 | children: 14 | - Overview 15 | - Installation 16 | - Setup in project 17 | - Mockfile 18 | - Command Line Interface 19 | - Supported features 20 | - Prototyping 21 | 22 | - name: Additional Guides 23 | children: 24 | - Matcher support for not Equatable 25 | - Handling Generics 26 | - Examples 27 | - Legacy 28 | - Add XCode generate action 29 | - Known issues 30 | - CHANGELOG 31 | 32 | - name: Global methods 33 | children: 34 | - Given(_:_:_:) 35 | - Perform(_:_:) 36 | - Verify(_:_:file:line:) 37 | - Verify(_:_:_:file:line:) 38 | 39 | - name: Configuration 40 | children: 41 | - StubbingPolicy 42 | - SequencingPolicy 43 | 44 | - name: Types 45 | children: 46 | - Mock 47 | - StaticMock 48 | - Parameter 49 | - Matcher 50 | - Countable 51 | - Count 52 | - Stubber 53 | - StubberThrows 54 | 55 | - name: Generics 56 | children: 57 | - GenericAttribute 58 | - GenericAttributeType 59 | 60 | - name: Helpers 61 | children: 62 | - XCTAssertThrowsError(_:of:_:file:line:) 63 | - XCTAssertThrowsError(_:error:_:file:line:) 64 | - MockyAssertion 65 | 66 | - name: Internal 67 | children: 68 | - SwiftyMockyTestObserver 69 | - FatalErrorUtil 70 | - OptionalType 71 | - WithSequencingPolicy 72 | - WithStaticSequencingPolicy 73 | - WithStubbingPolicy 74 | - Int 75 | - Optional 76 | - UInt 77 | - MockError 78 | - StubProduct 79 | - StubbedMethod 80 | - Failure(_:) 81 | - MockyAssert(_:_:file:line:) 82 | -------------------------------------------------------------------------------- /.legacy/.mocky.iOS.yml: -------------------------------------------------------------------------------- 1 | sources: 2 | include: 3 | - ../SwiftyMocky-Example/Shared 4 | - ../SwiftyMocky-Example/iOS 5 | - ../SwiftyMocky-Tests/iOS 6 | exclude: 7 | - ../SwiftyMocky-Example/Shared/Other/Excluded.generated.swift 8 | templates: 9 | - ../Sources/SwiftyMocky 10 | output: 11 | ../SwiftyMocky-Tests/iOS/Mocks 12 | args: 13 | swiftyMocky: 14 | import: 15 | - CoreGraphics 16 | - Foundation 17 | - UIKit 18 | testable: 19 | - Mocky_Example_iOS 20 | excludedSwiftLintRules: 21 | - force_cast 22 | - function_body_length 23 | - line_length 24 | - vertical_whitespace 25 | -------------------------------------------------------------------------------- /.legacy/.mocky.macOS.yml: -------------------------------------------------------------------------------- 1 | sources: 2 | include: 3 | - ../SwiftyMocky-Example/Shared 4 | - ../SwiftyMocky-Example/macOS 5 | - ../SwiftyMocky-Tests/macOS 6 | exclude: 7 | - ../SwiftyMocky-Example/Shared/Other/Excluded.generated.swift 8 | templates: 9 | - ../Sources/SwiftyMocky 10 | output: 11 | ../SwiftyMocky-Tests/macOS/Mocks 12 | args: 13 | swiftyMocky: 14 | import: 15 | - Foundation 16 | testable: 17 | - Mocky_Example_macOS 18 | excludedSwiftLintRules: 19 | - force_cast 20 | - function_body_length 21 | - line_length 22 | - vertical_whitespace 23 | -------------------------------------------------------------------------------- /.legacy/.mocky.spm.yml: -------------------------------------------------------------------------------- 1 | sources: 2 | include: 3 | - ../SwiftyMocky-Example/Shared 4 | exclude: 5 | - ../SwiftyMocky-Example/Shared/Other/Excluded.generated.swift 6 | templates: 7 | - ../Sources/SwiftyMocky 8 | output: 9 | ../Tests/SwiftyMockyTests/ 10 | args: 11 | swiftyMocky: 12 | import: 13 | - Foundation 14 | testable: 15 | - Mocky_Example_macOS 16 | excludedSwiftLintRules: 17 | - force_cast 18 | - function_body_length 19 | - line_length 20 | - vertical_whitespace 21 | -------------------------------------------------------------------------------- /.legacy/.mocky.tvOS.yml: -------------------------------------------------------------------------------- 1 | sources: 2 | include: 3 | - ../SwiftyMocky-Example/Shared 4 | - ../SwiftyMocky-Example/tvOS 5 | - ../SwiftyMocky-Tests/tvOS 6 | exclude: 7 | - ../SwiftyMocky-Example/Shared/Other/Excluded.generated.swift 8 | templates: 9 | - ../Sources/SwiftyMocky 10 | output: 11 | ../SwiftyMocky-Tests/tvOS/Mocks 12 | args: 13 | swiftyMocky: 14 | import: 15 | - Foundation 16 | testable: 17 | - Mocky_Example_tvOS 18 | excludedSwiftLintRules: 19 | - force_cast 20 | - function_body_length 21 | - line_length 22 | - vertical_whitespace 23 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at wosko.przemyslaw@gmail.com, amichnia@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## About contributing 2 | 3 | There are multiple ways you can contribute to this project. 4 | 5 | The easiest way to contribute is to report possible bugs, request features, [discuss ideas](https://github.com/MakeAWishFoundation/SwiftyMocky/issues) and share excitement about this project. 6 | 7 | You can also make pull requests. 8 | 9 | There are some best practices that will be followed during the development of this project for common good ([Gitflow](http://nvie.com/posts/a-successful-git-branching-model/) branching model) 10 | 11 | So what does this mean in practice: 12 | 13 | * Please target your PR against the **master** branch 14 | * If you want to make a bigger contribution to the project, please [open an issue first](https://github.com/MakeAWishFoundation/SwiftyMocky/issues/new) so we can plan that work, discuss the architecture and brainstorm around that idea first. 15 | * Whenever possible - link your PR with issue if possible (by adding `Referencing: #` in your PR description). That will allow us to handle issues more easily. 16 | 17 | 18 | ## Developer's Certificate of Origin 1.1 19 | 20 | By making a contribution to this project, I certify that: 21 | 22 | - (a) The contribution was created in whole or in part by me and I 23 | have the right to submit it under the open source license 24 | indicated in the file; or 25 | 26 | - (b) The contribution is based upon previous work that, to the best 27 | of my knowledge, is covered under an appropriate open source 28 | license and I have the right under that license to submit that 29 | work with modifications, whether created in whole or in part 30 | by me, under the same open source license (unless I am 31 | permitted to submit under a different license), as indicated 32 | in the file; or 33 | 34 | - (c) The contribution was provided directly to me by some other 35 | person who certified (a), (b) or (c) and I have not modified 36 | it. 37 | 38 | - (d) I understand and agree that this project and the contribution 39 | are public and that a record of the contribution (including all 40 | personal information I submit with it, including my sign-off) is 41 | maintained indefinitely and may be redistributed consistent with 42 | this project or the open source license(s) involved. 43 | 44 | *Wording of statement copied from [elinux.org](http://elinux.org/Developer_Certificate_Of_Origin)* 45 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 Przemysław Wośko 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | EXECUTABLE_NAME = swiftymocky 2 | REPO = https://github.com/MakeAWishFoundation/SwiftyMocky 3 | VERSION = 4.2.0 4 | 5 | PREFIX = /usr/local 6 | INSTALL_PATH = $(PREFIX)/bin/$(EXECUTABLE_NAME) 7 | BUILD_PATH = .build/release/$(EXECUTABLE_NAME) 8 | CURRENT_PATH = $(PWD) 9 | RELEASE_TAR = $(REPO)/archive/$(VERSION).tar.gz 10 | 11 | .PHONY: install build uninstall clean 12 | 13 | install: build 14 | mkdir -p $(PREFIX)/bin 15 | cp -f $(BUILD_PATH) $(INSTALL_PATH) 16 | 17 | build: 18 | swift build --disable-sandbox -c release 19 | 20 | uninstall: 21 | rm -f $(INSTALL_PATH) 22 | 23 | clean: 24 | rm -rf .build 25 | -------------------------------------------------------------------------------- /Mintfile: -------------------------------------------------------------------------------- 1 | MakeAWishFoundation/SwiftyMocky@4.1.0 2 | krzysztofzablocki/Sourcery@1.8.0 3 | -------------------------------------------------------------------------------- /Mockfile: -------------------------------------------------------------------------------- 1 | sourceryCommand: null 2 | sourceryTemplate: ./Sources/SwiftyMocky/Mock.swifttemplate 3 | 4 | mocky.iOS: 5 | sources: 6 | include: 7 | - ./SwiftyMocky-Example/Shared 8 | - ./SwiftyMocky-Example/iOS 9 | - ./SwiftyMocky-Tests/iOS 10 | exclude: 11 | - ./SwiftyMocky-Example/Shared/Other/Excluded.generated.swift 12 | - ./SwiftyMocky-Example/Shared/Swift5.5 13 | output: ./SwiftyMocky-Tests/iOS/Mocks/Mock.generated.swift 14 | targets: 15 | - Mocky_Tests_iOS 16 | testable: 17 | - Mocky_Example_iOS 18 | import: 19 | - CoreGraphics 20 | - Foundation 21 | - UIKit 22 | 23 | mocky.iOS.15: 24 | sources: 25 | include: 26 | - ./SwiftyMocky-Example/Shared 27 | - ./SwiftyMocky-Example/iOS 28 | - ./SwiftyMocky-Tests/iOS 29 | exclude: 30 | - ./SwiftyMocky-Example/Shared/Other/Excluded.generated.swift 31 | output: ./SwiftyMocky-Tests/iOS/Mocks/Mock.15.generated.swift 32 | targets: 33 | - Mocky_Tests_iOS_15 34 | testable: 35 | - Mocky_Example_iOS_15 36 | import: 37 | - CoreGraphics 38 | - Foundation 39 | - UIKit 40 | 41 | mocky.macOS: 42 | sources: 43 | include: 44 | - ./SwiftyMocky-Example/Shared 45 | - ./SwiftyMocky-Example/macOS 46 | - ./SwiftyMocky-Tests/macOS 47 | exclude: 48 | - ./SwiftyMocky-Example/Shared/Other/Excluded.generated.swift 49 | - ./SwiftyMocky-Example/Shared/Swift5.5 50 | output: ./SwiftyMocky-Tests/macOS/Mocks/Mock.generated.swift 51 | targets: 52 | - Mocky_Tests_macOS 53 | testable: 54 | - Mocky_Example_macOS 55 | import: 56 | - Foundation 57 | 58 | mocky.tvOS: 59 | sources: 60 | include: 61 | - ./SwiftyMocky-Example/Shared 62 | - ./SwiftyMocky-Example/tvOS 63 | - ./SwiftyMocky-Tests/tvOS 64 | exclude: 65 | - ./SwiftyMocky-Example/Shared/Other/Excluded.generated.swift 66 | - ./SwiftyMocky-Example/Shared/Swift5.5 67 | output: ./SwiftyMocky-Tests/tvOS/Mocks/Mock.generated.swift 68 | targets: 69 | - Mocky_Tests_tvOS 70 | testable: 71 | - Mocky_Example_tvOS 72 | import: 73 | - Foundation 74 | 75 | mocky.spm: 76 | sources: 77 | include: 78 | - "./SwiftyMocky-Example/Shared" 79 | exclude: 80 | - ./SwiftyMocky-Example/Shared/Other/Excluded.generated.swift 81 | - ./SwiftyMocky-Example/Shared/Swift5.5 82 | output: ./Tests/SwiftyMockyTests/Mock.generated.swift 83 | targets: 84 | - SwiftyMockyTests 85 | testable: 86 | - Mocky_Example_macOS 87 | import: 88 | - Foundation 89 | 90 | cli.core.tests: 91 | sources: 92 | include: 93 | - ./Sources/CLI/Core 94 | exclude: 95 | - ./Sources/CLI/Core/Assets 96 | output: ./Tests/SwiftyMockyCLICoreTests/Mock.generated.swift 97 | targets: 98 | - Package.swift/SwiftyMockyCLICore 99 | testable: 100 | - SwiftyMockyCLICore 101 | import: 102 | - Foundation 103 | - PathKit 104 | -------------------------------------------------------------------------------- /Mocky_Example_iOS_15-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /Mocky_Tests_iOS_15-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "object": { 3 | "pins": [ 4 | { 5 | "package": "AEXML", 6 | "repositoryURL": "https://github.com/tadija/AEXML.git", 7 | "state": { 8 | "branch": null, 9 | "revision": "38f7d00b23ecd891e1ee656fa6aeebd6ba04ecc3", 10 | "version": "4.6.1" 11 | } 12 | }, 13 | { 14 | "package": "Chalk", 15 | "repositoryURL": "https://github.com/luoxiu/Chalk", 16 | "state": { 17 | "branch": null, 18 | "revision": "8a9d3373bd754fb62f7881d9f639d376f5e4d5a5", 19 | "version": "0.2.1" 20 | } 21 | }, 22 | { 23 | "package": "Commander", 24 | "repositoryURL": "https://github.com/kylef/Commander", 25 | "state": { 26 | "branch": null, 27 | "revision": "4a1f2fb82fb6cef613c4a25d2e38f702e4d812c2", 28 | "version": "0.9.2" 29 | } 30 | }, 31 | { 32 | "package": "PathKit", 33 | "repositoryURL": "https://github.com/kylef/PathKit", 34 | "state": { 35 | "branch": null, 36 | "revision": "3bfd2737b700b9a36565a8c94f4ad2b050a5e574", 37 | "version": "1.0.1" 38 | } 39 | }, 40 | { 41 | "package": "Rainbow", 42 | "repositoryURL": "https://github.com/luoxiu/Rainbow", 43 | "state": { 44 | "branch": null, 45 | "revision": "9d8fcb4c64e816a135c31162a0c319e9f1f09c35", 46 | "version": "0.1.1" 47 | } 48 | }, 49 | { 50 | "package": "ShellOut", 51 | "repositoryURL": "https://github.com/JohnSundell/ShellOut", 52 | "state": { 53 | "branch": null, 54 | "revision": "e1577acf2b6e90086d01a6d5e2b8efdaae033568", 55 | "version": "2.3.0" 56 | } 57 | }, 58 | { 59 | "package": "Spectre", 60 | "repositoryURL": "https://github.com/kylef/Spectre.git", 61 | "state": { 62 | "branch": null, 63 | "revision": "26cc5e9ae0947092c7139ef7ba612e34646086c7", 64 | "version": "0.10.1" 65 | } 66 | }, 67 | { 68 | "package": "XcodeProj", 69 | "repositoryURL": "https://github.com/tuist/xcodeproj", 70 | "state": { 71 | "branch": null, 72 | "revision": "446f3a0db73e141c7f57e26fcdb043096b1db52c", 73 | "version": "8.3.1" 74 | } 75 | }, 76 | { 77 | "package": "Yams", 78 | "repositoryURL": "https://github.com/jpsim/Yams", 79 | "state": { 80 | "branch": null, 81 | "revision": "01835dc202670b5bb90d07f3eae41867e9ed29f6", 82 | "version": "5.0.1" 83 | } 84 | } 85 | ] 86 | }, 87 | "version": 1 88 | } 89 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:4.2 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "swiftymocky", 8 | products: [ 9 | // XCTest Runtime libraries 10 | .library(name: "SwiftyMocky", targets: ["SwiftyMocky"]), 11 | .library(name: "SwiftyPrototype", targets: ["SwiftyPrototype"]), 12 | // CLI Executable 13 | .executable(name: "swiftymocky", targets: ["SwiftyMockyCLI"]), 14 | ], 15 | dependencies: [ 16 | .package(url: "https://github.com/JohnSundell/ShellOut", .upToNextMajor(from: "2.3.0")), 17 | .package(url: "https://github.com/tuist/xcodeproj", .upToNextMajor(from: "8.3.1")), 18 | .package(url: "https://github.com/luoxiu/Chalk", .exact("0.2.1")), 19 | .package(url: "https://github.com/kylef/Commander", .upToNextMajor(from: "0.9.1")), 20 | .package(url: "https://github.com/kylef/PathKit", .upToNextMajor(from: "1.0.1")), 21 | .package(url: "https://github.com/jpsim/Yams", .upToNextMajor(from: "5.0.1")), 22 | ], 23 | targets: [ 24 | // XCTest Runtime libraries 25 | .target( 26 | name: "SwiftyMocky", 27 | path: "./Sources/SwiftyMocky", 28 | exclude: ["Mock.swifttemplate"] 29 | ), 30 | .target( 31 | name: "SwiftyPrototype", 32 | path: "./Sources/SwiftyPrototype", 33 | exclude: ["Prototype.swifttemplate"] 34 | ), 35 | .target( 36 | name: "Shared", 37 | path: "./Sources/Shared" 38 | ), 39 | // Example and tests 40 | .target( 41 | name: "Mocky_Example_macOS", 42 | path: "./SwiftyMocky-Example/Shared", 43 | exclude: ["Swift5.5"] // TODO: remove when macOS 12 released 44 | ), 45 | .testTarget( 46 | name: "SwiftyMockyTests", 47 | dependencies: ["Mocky_Example_macOS", "SwiftyMocky"], 48 | path: "./Tests/SwiftyMockyTests", 49 | exclude: ["Shared/Swift5.5"] // TODO: remove when macOS 12 released 50 | ), 51 | .testTarget( 52 | name: "RuntimeLibaryTests", 53 | dependencies: ["SwiftyMocky"] 54 | ), 55 | // CLI Executable 56 | .target( 57 | name: "SwiftyMockyCLI", 58 | dependencies: [ 59 | "Commander", 60 | "SwiftyMockyCLICore", 61 | ], 62 | path: "./Sources/CLI/App" 63 | ), 64 | .target( 65 | name: "SwiftyMockyCLICore", 66 | dependencies: [ 67 | "ShellOut", 68 | "Chalk", 69 | "XcodeProj", 70 | "PathKit", 71 | "Yams", 72 | ], 73 | path: "./Sources/CLI/Core" 74 | ), 75 | .testTarget( 76 | name: "SwiftyMockyCLICoreTests", 77 | dependencies: [ 78 | "SwiftyMockyCLICore", 79 | "SwiftyMocky", 80 | ] 81 | ), 82 | ] 83 | ) 84 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | use_frameworks! 2 | 3 | def tests 4 | pod 'SwiftyMocky', :path => './' 5 | end 6 | 7 | target 'Mocky_Example_iOS' do 8 | platform :ios, '9.0' 9 | target 'Mocky_Tests_iOS' do 10 | inherit! :search_paths 11 | tests 12 | end 13 | end 14 | 15 | target 'Mocky_Example_iOS_15' do 16 | platform :ios, '15.0' 17 | target 'Mocky_Tests_iOS_15' do 18 | inherit! :search_paths 19 | tests 20 | end 21 | end 22 | 23 | target 'Mocky_Example_tvOS' do 24 | platform :tvos, '9.0' 25 | target 'Mocky_Tests_tvOS' do 26 | inherit! :search_paths 27 | tests 28 | end 29 | end 30 | 31 | target 'Mocky_Example_macOS' do 32 | platform :macos, '10.13' 33 | target 'Mocky_Tests_macOS' do 34 | inherit! :search_paths 35 | tests 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Sourcery (1.8.0): 3 | - Sourcery/CLI-Only (= 1.8.0) 4 | - Sourcery/CLI-Only (1.8.0) 5 | - SwiftyMocky (4.1.0): 6 | - Sourcery (= 1.8.0) 7 | 8 | DEPENDENCIES: 9 | - SwiftyMocky (from `./`) 10 | 11 | SPEC REPOS: 12 | trunk: 13 | - Sourcery 14 | 15 | EXTERNAL SOURCES: 16 | SwiftyMocky: 17 | :path: "./" 18 | 19 | SPEC CHECKSUMS: 20 | Sourcery: 6f5fe49b82b7e02e8c65560cbd52e1be67a1af2e 21 | SwiftyMocky: 308ec8314ed9a2f72e5b16537ffff046fec8779f 22 | 23 | PODFILE CHECKSUM: bdcefa827bbd4d82b3bb801ca8e42fd57d9afed5 24 | 25 | COCOAPODS: 1.11.3 26 | -------------------------------------------------------------------------------- /Sources/CLI/Core/Assets/Messages.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public struct Messages { 4 | public struct Setup { 5 | public static let initDescription = "Creates template of Mockfile to fill" 6 | public static let description = "if more than one xcodeproj in directory, add a selected project path: mocky setup .xcodeproj" 7 | } 8 | public struct Migrate { 9 | public static let description = "migrate existing SwiftyMocky yml configurations into Mockfile™" 10 | public static let noConfigurations = "No migration possible, not found any legacy yml configuration files in this directory." 11 | } 12 | public struct Autoimport { 13 | public static let description = "scans sources and automatically resolves imports for the mocks" 14 | } 15 | public struct Generate { 16 | public static let description = """ 17 | generate mocks. Usage 'swiftymocky ' 18 | Allowed flags: 19 | --disableCache \(Messages.Generate.disableCache) 20 | --verbose, -v \(Messages.Generate.verbose) 21 | --watch, -w \(Messages.Generate.watcher) 22 | """ 23 | public static let verbose = "additional sourcery debug info" 24 | public static let disableCache = "disables using cache" 25 | public static let watcher = "run in watcher mode, allowed only if mock name specified" 26 | } 27 | public struct Doctor { 28 | public static let description = "run to inspect status of SwiftyMocky setup" 29 | } 30 | public struct Tools { 31 | public static let assetizeDescription = "[internal] re-generates assets enum with templates." 32 | } 33 | 34 | public static func message(for error: MockyError) -> String { 35 | switch error { 36 | case .targetNotFound: 37 | return Errors.targetNotFound 38 | case .projectNotFound: 39 | return Errors.projectNotFound 40 | case .mockNotFound: 41 | return Errors.mockNotFound 42 | case .internalFailure: 43 | return Errors.internalFailure 44 | case .writingError: 45 | return Errors.writingError 46 | case .overrideWarning: 47 | return Errors.overrideWarning 48 | case .versionMismatch: 49 | return Errors.versionMismatch 50 | } 51 | } 52 | 53 | struct Errors { 54 | static let targetNotFound = "Specified target was not found!" 55 | static let projectNotFound = "Specified project was not found!" 56 | static let mockNotFound = "Mock with this name does not exist!" 57 | static let internalFailure = "SwiftyMocky: Internal error!" 58 | static let writingError = "SwiftyMocky: Internal writing error!" 59 | static let overrideWarning = "Already exists. Will not override." 60 | static let versionMismatch = "Template version seems to be mismatched, not matching CLI version!" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Sources/CLI/Core/Commands/MockfileInteractor.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import Yams 3 | import PathKit 4 | import Commander 5 | 6 | // MARK: - Mockfile Setup 7 | 8 | class MockfileInteractor { 9 | 10 | var mockfile: Mockfile 11 | let path: Path 12 | let existis: Bool 13 | 14 | init(path: Path) throws { 15 | self.path = path 16 | 17 | if let yaml: String = try? path.read() { 18 | mockfile = try YAMLDecoder().decode(from: yaml) 19 | existis = true 20 | } else { 21 | mockfile = Mockfile(sourceryCommand: nil, contents: [:]) 22 | existis = false 23 | } 24 | } 25 | 26 | init(path: Path, mockfile: Mockfile) { 27 | self.path = path 28 | self.mockfile = mockfile 29 | self.existis = true 30 | } 31 | 32 | func save() throws { 33 | try path.write(try YAMLEncoder().encode(mockfile)) 34 | } 35 | 36 | func isSetup(target: ProjectTarget) -> Bool { 37 | return mockfile.allMocks.contains(where: { $0.targets.contains(target.name) }) 38 | } 39 | 40 | func firstMockFor(target: ProjectTarget) -> String? { 41 | return mockfile.allMembers.first(where: { 42 | mockfile[dynamicMember: $0]?.targets.contains(target.name) ?? false 43 | }) 44 | } 45 | 46 | func add(mock: MockConfiguration, for name: String) { 47 | mockfile[dynamicMember: name] = mock 48 | } 49 | 50 | func remove(for name: String) { 51 | mockfile[dynamicMember: name] = nil 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Sources/CLI/Core/Entities/SourceryConfiguration.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import Yams 3 | import PathKit 4 | import Commander 5 | 6 | // MARK: - Legacy configuration 7 | 8 | /// Sourcery configuration - yaml file 9 | public struct LegacyConfiguration: Codable { 10 | 11 | public var sources: MockConfiguration.Sources 12 | public var templates: [String] 13 | public var output: String 14 | public var args: Arguments? 15 | } 16 | 17 | public extension LegacyConfiguration { 18 | 19 | init?(path: Path) { 20 | guard let contents: String = try? path.read() else { 21 | return nil 22 | } 23 | guard let config: LegacyConfiguration = try? YAMLDecoder().decode(from: contents) else { 24 | return nil 25 | } 26 | 27 | self = config 28 | } 29 | } 30 | 31 | public extension LegacyConfiguration { 32 | 33 | struct Arguments: Codable { 34 | public var swiftyMocky: Configuration? 35 | 36 | // Legacy from very old version of swifty mocky, needs for migration 37 | public var `import`: [String]? 38 | public var testable: [String]? 39 | } 40 | 41 | struct Configuration: Codable { 42 | public var `import`: [String]? 43 | public var testable: [String]? 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Sources/CLI/Core/InstanceFactory.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import PathKit 3 | 4 | public enum Instance { 5 | public internal(set) static var factory: InstanceFactory = InstanceFactoryConcrete() 6 | } 7 | 8 | public protocol InstanceFactory: AnyObject, AutoMockable { 9 | 10 | // MARK: - Generation 11 | func resolveGenerationCommand(root: Path) throws -> GenerationCommand 12 | func resolveGenerationCommand(root: Path, mockfile: Mockfile) -> GenerationCommand 13 | } 14 | 15 | public class InstanceFactoryConcrete: InstanceFactory { 16 | 17 | fileprivate init() { } 18 | 19 | // MARK: - Generation 20 | public func resolveGenerationCommand(root: Path) throws -> GenerationCommand { 21 | return try GenerationController(root: root) 22 | } 23 | 24 | public func resolveGenerationCommand(root: Path, mockfile: Mockfile) -> GenerationCommand { 25 | return GenerationController(root: root, mockfile: mockfile) 26 | } 27 | } -------------------------------------------------------------------------------- /Sources/CLI/Core/InteractiveOptions/AddingOption.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import Chalk 3 | 4 | // MARK: - Setup policy 5 | 6 | enum AddingPolicy { 7 | case addOnly 8 | case cancel 9 | case override 10 | case skipOverriding 11 | case onlyOverride(Int) 12 | } 13 | 14 | // MARK: - Selectable option 15 | 16 | enum AddingOption: RawRepresentable, SelectableOption { 17 | typealias RawValue = String 18 | 19 | case add 20 | case cancel 21 | case override 22 | case only(Int) 23 | 24 | var rawValue: String { 25 | switch self { 26 | case .add: return "add not defined" 27 | case .cancel: return "cancel" 28 | case .override: return "override all" 29 | case .only(let value): return "\(value)" 30 | } 31 | } 32 | var title: String { 33 | switch self { 34 | case .only(let value): 35 | return ck.underline.on("\(value)").string 36 | default: 37 | return ck.underline.on("\(rawValue.first!)".uppercased()).string + "\(rawValue.dropFirst())" 38 | } 39 | } 40 | 41 | var policy: AddingPolicy { 42 | switch self { 43 | case .add: return .skipOverriding 44 | case .cancel: return .cancel 45 | case .override: return .override 46 | case .only(let value): return .onlyOverride(value) 47 | } 48 | } 49 | 50 | init?(rawValue: String) { 51 | switch rawValue { 52 | case "A", "a", "Add", "add": 53 | self = .add 54 | case "C", "c", "Cancel", "cancel": 55 | self = .cancel 56 | case "O", "o", "Override", "override": 57 | self = .override 58 | case let n where Int(n) != nil: 59 | self = .only(Int(n)!) 60 | default: 61 | return nil 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Sources/CLI/Core/InteractiveOptions/Booloption.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import Chalk 3 | 4 | public enum BoolOption: RawRepresentable, SelectableOption { 5 | public typealias RawValue = String 6 | 7 | case yes 8 | case no 9 | 10 | public var rawValue: String { 11 | switch self { 12 | case .yes: return "yes" 13 | case .no: return "no" 14 | } 15 | } 16 | public var title: String { 17 | return ck.underline.on("\(rawValue.first!)".uppercased()).string + "\(rawValue.dropFirst())" 18 | } 19 | 20 | public init?(rawValue: String) { 21 | switch rawValue { 22 | case "Y", "y", "Yes", "yes": 23 | self = .yes 24 | case "N", "n", "No", "no": 25 | self = .no 26 | default: 27 | return nil 28 | } 29 | } 30 | 31 | public static func select() -> BoolOption { 32 | return select(from: [.yes, .no]) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Sources/CLI/Core/InteractiveOptions/ProjectOption.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import Chalk 3 | import PathKit 4 | 5 | public struct ProjectPathOption: RawRepresentable, SelectableOption { 6 | public typealias RawValue = String 7 | 8 | private static var projects: [Path] = [] 9 | 10 | public var rawValue: String 11 | public var title: String { 12 | if rawValue == ProjectPathOption.projects.first?.string { 13 | let formatted = ck.underline.on("\(Path(rawValue).lastComponentWithoutExtension)") 14 | return "\(formatted)" 15 | } 16 | return Path(rawValue).lastComponentWithoutExtension 17 | } 18 | 19 | public init?(rawValue: RawValue) { 20 | guard !ProjectPathOption.projects.isEmpty else { return nil } 21 | guard !rawValue.isEmpty else { 22 | self.rawValue = ProjectPathOption.projects.first!.string 23 | return 24 | } 25 | 26 | let matching = ProjectPathOption.projects.filter { $0.lastComponent.hasPrefix(rawValue) } 27 | guard !matching.isEmpty else { 28 | Message.warning("No project with that name!") 29 | return nil 30 | } 31 | guard matching.count == 1 else { 32 | Message.warning("Project name ambigious! Found:") 33 | Message.indent() 34 | matching.forEach { path in 35 | Message.infoPoint("\(path)") 36 | } 37 | Message.unindent() 38 | return nil 39 | } 40 | self.rawValue = matching[0].string 41 | } 42 | 43 | init(_ rawValue: RawValue) { 44 | self.rawValue = rawValue 45 | } 46 | 47 | static func select(project name: Path, at root: Path) throws -> Path { 48 | var paths = name.string.isEmpty ? root.glob("*.xcodeproj") : [name.xcproj(with: root)] 49 | paths = paths.map { $0.dropSlash() } 50 | 51 | guard !paths.isEmpty else { throw MockyError.projectNotFound } 52 | guard paths.count > 1 else { return paths[0] } 53 | ProjectPathOption.projects = paths 54 | 55 | Message.warning("Several projects found! Choose xcodeproj file.") 56 | 57 | let options = paths.map { ProjectPathOption($0.string) } 58 | let selected = Path(select(from: options).rawValue) 59 | 60 | Message.empty() 61 | Message.subheader("Selected: \(selected.lastComponent)\n") 62 | 63 | return selected 64 | } 65 | } 66 | 67 | private extension Path { 68 | func xcproj(with root: Path) -> Path { 69 | return (root + self).dropSlash() 70 | } 71 | 72 | func dropSlash() -> Path { 73 | return string.hasSuffix("/") ? Path(String(string.dropLast())) : self 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Sources/CLI/Core/InteractiveOptions/SelectableOption.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public protocol SelectableOption: RawRepresentable { 4 | var title: String { get } 5 | 6 | static func message(from options: [Self]) -> String 7 | static func select(from options: [Self]) -> Self 8 | } 9 | 10 | public extension SelectableOption where RawValue == String { 11 | 12 | static func message(from options: [Self]) -> String { 13 | let optionsString = options.map { $0.title }.joined(separator: ", ") 14 | return "> Please choose one of possible actions: (\(optionsString))" 15 | } 16 | 17 | static func select(from options: [Self]) -> Self { 18 | var option: Self? 19 | repeat { 20 | Message.empty() 21 | Message.subheader(message(from: options)) 22 | option = Self(rawValue: readLine() ?? "") 23 | } while option == nil 24 | return option! 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Sources/CLI/Core/Utils/Global.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import PathKit 3 | 4 | public var kSwiftyMockyCommand = Path("mocky") 5 | public var kSourceryVersion = "1.8.0" 6 | public var kDefaultSourceryCommand: (String) -> String = { version in "mint run krzysztofzablocki/Sourcery@\(version) sourcery"} 7 | 8 | public protocol AutoMockable {} 9 | 10 | public enum MockyError: Swift.Error { 11 | case targetNotFound 12 | case projectNotFound 13 | case mockNotFound 14 | case internalFailure 15 | case writingError 16 | case overrideWarning 17 | case versionMismatch 18 | } 19 | -------------------------------------------------------------------------------- /Sources/CLI/Core/Utils/MacOS/XCodeProj+Extensions.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import PathKit 3 | import XcodeProj 4 | 5 | extension PBXProj { 6 | 7 | var allTargets: [PBXTarget] { 8 | var all = [PBXTarget]() 9 | all.append(contentsOf: nativeTargets) 10 | all.append(contentsOf: legacyTargets) 11 | all.append(contentsOf: aggregateTargets) 12 | return all 13 | } 14 | var allUnitTestTargets: [PBXTarget] { 15 | return allTargets.filter { $0.productType == .unitTestBundle } 16 | } 17 | var allUITestTargets: [PBXTarget] { 18 | return allTargets.filter { $0.productType == .uiTestBundle } 19 | } 20 | } 21 | 22 | extension PBXTarget { 23 | 24 | /// Local path (relative to project root) for info plist file 25 | /// 26 | /// - Returns: Project root relative Info.plist path 27 | func infoPlistPath() -> Path? { 28 | guard let config = buildConfigurationList?.buildConfigurations.first else { 29 | return nil 30 | } 31 | guard let path = config.buildSettings["INFOPLIST_FILE"] as? String else { 32 | return nil 33 | } 34 | 35 | return Path(path) 36 | } 37 | 38 | /// Local path (relative to project root) for directory enclosing info plist file 39 | /// 40 | /// - Returns: Project root relative Info.plist enclosing directory path 41 | func infoPlistEnclosingDirectory() -> Path? { 42 | guard let path = infoPlistPath() else { return nil } 43 | return Path(components: path.components.dropLast()) 44 | } 45 | 46 | func commonSourcesEnclosingFolder() -> Path? { 47 | guard let sources = try? sourceFiles() else { return nil } 48 | 49 | let paths = sources.compactMap { file -> Path? in 50 | return file.relativePath() 51 | } 52 | 53 | return paths.commonPrefix() 54 | } 55 | 56 | func defaultSourcesFolder() -> Path { 57 | guard let path = commonSourcesEnclosingFolder() else { return Path(".") } 58 | return path 59 | } 60 | 61 | } 62 | 63 | extension PBXFileElement { 64 | func relativePath() -> Path? { 65 | guard let path = self.path else { return nil } 66 | 67 | if let parentPath = self.parent?.relativePath() { 68 | return parentPath + Path(path) 69 | } else { 70 | return Path(path) 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Sources/CLI/Core/Utils/PathKit+Extensions.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import PathKit 3 | 4 | extension Array where Element == Path { 5 | func commonPrefix() -> Path? { 6 | guard let first = self.first else { return nil } 7 | 8 | return self.reduce(first, { (result, current) -> Path in 9 | return result.commonPrefix(with: current) 10 | }) 11 | } 12 | } 13 | 14 | extension Path { 15 | 16 | func removingLastComponent() -> Path { 17 | return Path(components: components.dropLast()) 18 | } 19 | 20 | func commonPrefix(with other: Path) -> Path { 21 | var common = [String]() 22 | var lhs = self.components 23 | var rhs = other.components 24 | 25 | while !lhs.isEmpty, !rhs.isEmpty, rhs.first == lhs.first { 26 | common.append(lhs.first!) 27 | lhs.removeFirst() 28 | rhs.removeFirst() 29 | } 30 | 31 | return Path(components: common) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Sources/CLI/Core/Utils/ProjectFile.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | #if os(macOS) 4 | import XcodeProj 5 | 6 | extension PBXTarget: ProjectTarget { } 7 | #endif 8 | 9 | public protocol ProjectFile { 10 | 11 | } 12 | 13 | public protocol ProjectTarget { 14 | var name: String { get } 15 | } 16 | -------------------------------------------------------------------------------- /Sources/CLI/Core/Utils/ShellOut+Extensions.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | #if os(macOS) 4 | class ProxyFileHandle: FileHandle { 5 | override func write(_ data: Data) { 6 | FileHandle.standardOutput.write(data) 7 | } 8 | 9 | override func closeFile() { 10 | // empty on purpose 11 | } 12 | } 13 | #else 14 | class ProxyFileHandle { 15 | // empty for now, waiting for Foundation to have FileHandle on linux 16 | } 17 | #endif -------------------------------------------------------------------------------- /Sources/CLI/Core/Utils/WorkingDirectory.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import PathKit 3 | import Yams 4 | 5 | // MARK: - Temporary directory 6 | 7 | class WorkingDirectory { 8 | 9 | let identifier = UUID().uuidString 10 | var path: Path { return root + Path(".mocky\(identifier)") } 11 | var template: Path { return root + Path(".mocky\(identifier)/.template.swifttemplate") } 12 | var config: Path { return root + Path(".mocky\(identifier)/.config.yml.tmp") } 13 | 14 | private let root: Path 15 | 16 | // MARK: - Lifecycle 17 | 18 | init(root: Path) { 19 | self.root = root 20 | } 21 | 22 | // MARK: - Actions 23 | 24 | func createDirIfNeeded() throws { 25 | guard !path.exists else { return } 26 | try path.mkdir() 27 | } 28 | 29 | func create(config: LegacyConfiguration, output: String? = nil) throws { 30 | let includes = config.sources.include.map { ".\($0)" } 31 | let excludes = config.sources.exclude?.map { ".\($0)" } 32 | let templates = config.templates 33 | let updatedConfig = LegacyConfiguration( 34 | sources: MockConfiguration.Sources( 35 | include: includes, 36 | exclude: excludes 37 | ), 38 | templates: templates, 39 | output: output ?? ("." + config.output), 40 | args: config.args 41 | ) 42 | try? self.config.delete() 43 | let yaml: String = try YAMLEncoder().encode(updatedConfig) 44 | try self.config.write(yaml) 45 | } 46 | 47 | func cleanup() throws { 48 | try? config.delete() 49 | try? template.delete() 50 | try? path.delete() 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Sources/Shared/Countable.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// Allows matching count, verifying whether given count is right or not 4 | public protocol Countable { 5 | /// Returns whether given count matches countable case. 6 | /// 7 | /// - Parameter count: Given count 8 | /// - Returns: true, if it is within boundaries, false otherwise 9 | func matches(_ count: Int) -> Bool 10 | } 11 | 12 | extension UInt: Countable { 13 | /// Returns whether given count matches countable case. 14 | /// 15 | /// - Parameter count: Given count 16 | /// - Returns: true, if it is within boundaries, false otherwise 17 | public func matches(_ count: Int) -> Bool { 18 | return Int(self) == count 19 | } 20 | } 21 | 22 | extension Int: Countable { 23 | /// Returns whether given count matches countable case. 24 | /// 25 | /// - Parameter count: Given count 26 | /// - Returns: true, if it is within boundaries, false otherwise 27 | public func matches(_ count: Int) -> Bool { 28 | return self == count 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Sources/Shared/GenericAttribute.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// [Internal] Used as generic constraint for generic method stubs. 4 | public protocol TypeErasedValue { 5 | /// [internal] Returned value 6 | var value: Any { get } 7 | /// [internal] Used to describe attribute generocity (0 is general, 1 is specific) 8 | var intValue: Int { get } 9 | /// [internal] Used to compare with other generic attributes values 10 | var compare: (Any,Any,Matcher) -> Bool { get } 11 | /// [internal] Used for formatting messages. 12 | var shortDescription: String { get } 13 | } 14 | 15 | /// [Internal] Used to wrap generic parameters, for sake of generic method stubs. 16 | public struct GenericAttribute: TypeErasedValue { 17 | /// [internal] Returned value 18 | public let value: Any 19 | /// [internal] Used to describe attribute generocity (0 is general, 1 is specific) 20 | public var intValue: Int 21 | /// [internal] Used to compare with other generic attributes 22 | public let compare: (Any,Any,Matcher) -> Bool 23 | /// [internal] Used for formatting messages. 24 | public let shortDescription: String 25 | 26 | /// [internal] Creates new GenericAttribute instance, with specified return value and compare closure 27 | /// 28 | /// - Parameters: 29 | /// - value: Returned value 30 | /// - compare: Used to compare with other generic attributes values 31 | public init( 32 | value: Any, 33 | intValue: Int, 34 | shortDescription: String, 35 | compare: @escaping (Any,Any,Matcher) -> Bool 36 | ) { 37 | self.value = value 38 | self.intValue = intValue 39 | self.shortDescription = shortDescription 40 | self.compare = compare 41 | } 42 | } 43 | 44 | /// [Internal] Used to wrap availability constrained attributes, since enum cases used ubternally to 45 | /// represent method/variable/subscript invocation/stub cannot have availability clauses. 46 | public struct TypeErasedAttribute: TypeErasedValue { 47 | /// [internal] Returned value 48 | public let value: Any 49 | /// [internal] Used to describe attribute generocity (0 is general, 1 is specific) 50 | public var intValue: Int 51 | /// [internal] Used to compare with other attribute 52 | public let compare: (Any,Any,Matcher) -> Bool 53 | /// [internal] Used for formatting messages. 54 | public let shortDescription: String 55 | 56 | /// [internal] Creates new TypeErasedAttribute instance, with specified return value and compare closure 57 | /// 58 | /// - Parameters: 59 | /// - value: Returned value 60 | /// - compare: Used to compare with other attribute 61 | public init( 62 | value: Any, 63 | intValue: Int, 64 | shortDescription: String, 65 | compare: @escaping (Any,Any,Matcher) -> Bool 66 | ) { 67 | self.value = value 68 | self.intValue = intValue 69 | self.shortDescription = shortDescription 70 | self.compare = compare 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Sources/Shared/Parameter+Optionals.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | // MARK: - Optionality checks 4 | 5 | /// Protocol around Optional, allowing additional checks and features on `Paramater` where value is optional. 6 | public protocol OptionalType: ExpressibleByNilLiteral { 7 | var isNotNil: Bool { get } 8 | } 9 | 10 | extension Optional: OptionalType { 11 | public var isNotNil: Bool { 12 | switch self { 13 | case .some: return true 14 | case .none: return false 15 | } 16 | } 17 | } 18 | 19 | public extension Parameter where ValueType: OptionalType { 20 | static var notNil: Parameter { 21 | return Parameter.matching { $0.isNotNil } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Sources/Shared/Utils.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | extension Matcher { 4 | public struct ComparisonResult { 5 | public let matched: Int 6 | public let total: Int 7 | public let results: [ParameterComparisonResult] 8 | 9 | public var percentage: Float { return self.total != 0 ? (Float(matched) / Float(total)) * 100.0 : 0 } 10 | public var percentageString: String { return String(format: "%.2f", percentage) } 11 | public var isFullMatch: Bool { return matched == total && total != 0 } 12 | public var isMatch: Bool { return self.matched > 0 } 13 | 14 | public init(_ results: [ParameterComparisonResult]) { 15 | self.results = results 16 | // Add 1 to both for matching method. So methods with na params are 1/1 17 | self.matched = results.filter { $0.matches }.count + 1 18 | self.total = results.count + 1 19 | } 20 | 21 | public init(matched: Int, total: Int) { 22 | self.matched = matched 23 | self.total = total 24 | self.results = [] 25 | } 26 | 27 | public static var match: ComparisonResult { return ComparisonResult(matched: 1, total: 1) } 28 | public static var none: ComparisonResult { return ComparisonResult(matched: 0, total: 0) } 29 | 30 | public func resultString(_ index: Int, _ selectorName: String) -> String { 31 | let resultsString = self.results.map { " \($0.resultString)" }.joined(separator: "\n") 32 | return "\(index + 1)) \(selectorName) [\(self.percentageString)%]\n\(resultsString)" 33 | } 34 | } 35 | 36 | public struct ParameterComparisonResult { 37 | let matches: Bool 38 | let left: String 39 | let right: String 40 | let label: String 41 | 42 | public init(_ matches: Bool, _ left: Parameter, _ right: Parameter, _ label: String) { 43 | self.matches = matches 44 | self.left = left.shortDescription 45 | self.right = right.shortDescription 46 | self.label = label 47 | } 48 | 49 | public var resultString: String { 50 | if self.matches { 51 | return "- (ok) \(self.label): \(self.left) == \(self.right)" 52 | } else { 53 | return "- (fail) \(self.label): \(self.left) != \(self.right)" 54 | } 55 | } 56 | } 57 | } 58 | 59 | public enum Utils { 60 | 61 | public static func closestCallsMessage( 62 | for results: [Matcher.ComparisonResult], 63 | name assertionName: String 64 | ) -> String { 65 | let closestMisses = results 66 | .reversed() 67 | .filter { !$0.isFullMatch && $0.isMatch } 68 | .sorted { $0.percentage > $1.percentage } 69 | 70 | guard !closestMisses.isEmpty else { return "" } 71 | 72 | let message = closestMisses[.. { 4 | /// Last captured value (if any) 5 | public var value: ValueType? { 6 | return allValues.last 7 | } 8 | /// All captured values 9 | public private(set) var allValues = [ValueType]() 10 | 11 | public init() {} 12 | 13 | /// Return parameter matcher which captures the argument. 14 | public func capture(where matches: ((ValueType) -> Bool)? = nil) -> Parameter { 15 | return .matching { (value: ValueType) -> Bool in 16 | if let matchFunction = matches { 17 | let match = matchFunction(value) 18 | if match { 19 | self.allValues.append(value) 20 | } 21 | return match 22 | } 23 | self.allValues.append(value) 24 | return true 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Sources/SwiftyMocky/CustomAssertions.swift: -------------------------------------------------------------------------------- 1 | #if canImport(XCTest) 2 | import XCTest 3 | 4 | /// Allows to verify if error was thrown, and if it is of given type. 5 | /// 6 | /// - Parameters: 7 | /// - expression: Expression 8 | /// - error: Expected error type 9 | /// - message: Optional message 10 | /// - file: File (optional) 11 | /// - line: Line (optional) 12 | public func XCTAssertThrowsError( 13 | _ expression: @autoclosure () throws -> T, 14 | of error: E.Type, 15 | _ message: @autoclosure () -> String = "", 16 | file: StaticString = #file, 17 | line: UInt = #line 18 | ) { 19 | let throwMessage = message().isEmpty ? "Expected \(T.self) thrown" : message() 20 | XCTAssertThrowsError(try expression(), throwMessage, file: file, line: line) { errorThrown in 21 | let typeMessage = message().isEmpty ? "Expected \(T.self), got \(String(describing: errorThrown))" : message() 22 | XCTAssertTrue(errorThrown is E, typeMessage, file: file, line: line) 23 | } 24 | } 25 | 26 | /// Allows to verify if error was throws, and if its exactly the one expected. 27 | /// 28 | /// - Parameters: 29 | /// - expression: Expression 30 | /// - error: Expected error conforming to Equatable, Error 31 | /// - message: Optional message 32 | /// - file: File (optional) 33 | /// - line: Line (optional) 34 | public func XCTAssertThrowsError( 35 | _ expression: @autoclosure () throws -> T, 36 | error: E, _ message: @autoclosure () -> String = "", 37 | file: StaticString = #file, 38 | line: UInt = #line 39 | ) where E: Error, E: Equatable { 40 | let throwMessage = message().isEmpty ? "Expected \(error) thrown" : message() 41 | XCTAssertThrowsError(try expression(), throwMessage, file: file, line: line) { errorThrown in 42 | let typeMessage = message().isEmpty ? "Expected \(error), got \(String(describing: errorThrown))" : message() 43 | XCTAssertTrue((errorThrown as? E) == error, typeMessage, file: file, line: line) 44 | } 45 | } 46 | #endif 47 | -------------------------------------------------------------------------------- /Sources/SwiftyMocky/MockyAssert.swift: -------------------------------------------------------------------------------- 1 | #if canImport(XCTest) 2 | import XCTest 3 | #endif 4 | import Foundation 5 | 6 | /// You can use this class if there is need to define custom 7 | /// assertion handler. You can use its static handler closure to alter default 8 | /// behaviour. 9 | /// 10 | /// If it is `nil`, the default `assert` method would be used. 11 | public final class MockyAssertion { 12 | /// You can use it to define assertion behaviour. 13 | /// Leave blank to not assert at all. 14 | public static var handler: ((Bool, String, StaticString, UInt) -> Void)? 15 | } 16 | 17 | /// [internal] Assertion used by mocks and Verify methods 18 | /// 19 | /// - Parameters: 20 | /// - expression: Expression to assert on 21 | /// - message: Message 22 | /// - file: File name (levae default) 23 | /// - line: Line (levae default) 24 | public func MockyAssert( 25 | _ expression: @autoclosure () -> Bool, 26 | _ message: @autoclosure () -> String = "Verify failed", 27 | file: StaticString = #file, 28 | line: UInt = #line 29 | ) { 30 | guard let handler = MockyAssertion.handler else { 31 | return XCTMockyAssert(expression(), message(), file: file, line: line) 32 | } 33 | 34 | handler(expression(), message(), file, line) 35 | } 36 | 37 | 38 | /// [internal] Assertion used by mocks and Verify methods 39 | /// 40 | /// - Parameters: 41 | /// - expression: Expression to assert on 42 | /// - message: Message 43 | /// - file: File name (levae default) 44 | /// - line: Line (levae default) 45 | private func XCTMockyAssert( 46 | _ expression: @autoclosure () -> Bool, 47 | _ message: @autoclosure () -> String = "Verify failed", 48 | file: StaticString = #file, 49 | line: UInt = #line 50 | ) { 51 | #if canImport(XCTest) 52 | XCTAssert(expression(), message(), file: file, line: line) 53 | #else 54 | assert(expression(), message(), file: file, line: line) 55 | #endif 56 | } 57 | -------------------------------------------------------------------------------- /Sources/SwiftyMocky/Shared: -------------------------------------------------------------------------------- 1 | ../Shared/ -------------------------------------------------------------------------------- /Sources/SwiftyPrototype/MockyAssert.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// You can use this class if there is need to define custom 4 | /// assertion handler. You can use its static handler closure to alter default 5 | /// behaviour. 6 | /// 7 | /// If it is `nil`, the default `assert` method would be used. 8 | public final class MockyAssertion { 9 | /// You can use it to define assertion behaviour. 10 | /// Leave blank to not assert at all. 11 | public static var handler: ((Bool, String, StaticString, UInt) -> Void)? 12 | } 13 | 14 | /// [internal] Assertion used by mocks and Verify methods 15 | /// 16 | /// - Parameters: 17 | /// - expression: Expression to assert on 18 | /// - message: Message 19 | /// - file: File name (levae default) 20 | /// - line: Line (levae default) 21 | public func MockyAssert( 22 | _ expression: @autoclosure () -> Bool, 23 | _ message: @autoclosure () -> String = "Verify failed", 24 | file: StaticString = #file, 25 | line: UInt = #line 26 | ) { 27 | guard let handler = MockyAssertion.handler else { 28 | return assert(expression(), message(), file: file, line: line) 29 | } 30 | 31 | handler(expression(), message(), file, line) 32 | } 33 | -------------------------------------------------------------------------------- /Sources/SwiftyPrototype/Shared: -------------------------------------------------------------------------------- 1 | ../Shared/ -------------------------------------------------------------------------------- /Sources/SwiftyPrototype/SwiftyMockyTestObserver.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public class SwiftyMockyTestObserver: NSObject { 4 | /// [Internal] No setup whatsoever 5 | @objc public static func setup() { 6 | // Empty on purpose 7 | } 8 | 9 | public static func handleFatalError(message: String, file: StaticString, line: UInt) { 10 | // Empty on purpose 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/Shared/AssociatedTypes/SuggestionRepository.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SuggestionRepository.swift 3 | // SwiftyMocky 4 | // 5 | // Created by Andrzej Michnia on 11/11/2019. 6 | // Copyright © 2019 CocoaPods. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | //sourcery: AutoMockable 12 | //sourcery: typealias = "Entity = Suggestion" 13 | protocol SuggestionRepository: Repository where Entity == Suggestion {} 14 | 15 | //sourcery: AutoMockable 16 | //sourcery: associatedtype = "Entity: SuggestionProtocol" 17 | protocol SuggestionRepositoryConstrainedToProtocol: Repository where Entity: SuggestionProtocol {} 18 | 19 | protocol Repository { 20 | associatedtype Entity: EntityType 21 | 22 | func save(entity: Entity) -> Bool 23 | func save(entities: [Entity]) -> Bool 24 | 25 | func find( 26 | where predicate: NSPredicate, 27 | sortedBy sortDescriptors: [NSSortDescriptor] 28 | ) -> [Entity] 29 | 30 | func findOne(where predicate: NSPredicate) -> Entity 31 | func delete(entity: Entity) -> Bool 32 | func delete(entities: [Entity]) -> Bool 33 | } 34 | 35 | protocol EntityType {} 36 | 37 | protocol SuggestionProtocol: EntityType, AutoMockable { } 38 | 39 | class Suggestion: SuggestionProtocol { 40 | init() {} 41 | } 42 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/Shared/Example 1/ProtocolsWithCollections.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProtocolsWithCollections.swift 3 | // Mocky_Example 4 | // 5 | // Created by Andrzej Michnia on 16.11.2017. 6 | // Copyright © 2017 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | //sourcery: AutoMockable 12 | protocol SimpleProtocolUsingCollections { 13 | func getArray() -> [Int] 14 | func map(array: [String], param: Int) -> [Int: String] 15 | func use(dictionary: [Int: String]) -> [Int: String] 16 | func verify(set: Set) -> Bool 17 | } 18 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/Shared/Example 1/SimpleProtocols.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleProtocols.swift 3 | // Mocky_Example 4 | // 5 | // Created by Andrzej Michnia on 16.11.2017. 6 | // Copyright © 2017 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | //sourcery: AutoMockable 12 | protocol SimpleProtocolWithMethods { 13 | func simpleMethod() 14 | func simpleMehtodThatReturns() -> Int 15 | func simpleMehtodThatReturns(param: String) -> String 16 | func simpleMehtodThatReturns(optionalParam: String?) -> String? 17 | } 18 | 19 | //sourcery: AutoMockable 20 | protocol SimpleProtocolWithProperties { 21 | var property: String { get set } 22 | var weakProperty: AnyObject! { get set } 23 | var propertyGetOnly: String { get } 24 | var propertyOptional: Int? { get set } 25 | var propertyImplicit: Int! { get set } 26 | } 27 | 28 | //sourcery: AutoMockable 29 | protocol SimpleProtocolWithBothMethodsAndProperties { 30 | var property: String { get } 31 | func simpleMethod() -> String 32 | } 33 | 34 | //sourcery: AutoMockable 35 | protocol SimpleProtocolThatInheritsOtherProtocols: SimpleProtocolWithMethods, SimpleProtocolWithProperties { 36 | 37 | } 38 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/Shared/Example 10/ProtocolWithGenericConstraints.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProtocolWithGenericConstraints.swift 3 | // SwiftyMocky 4 | // 5 | // Created by Oleksandr Demishkevych on 7/17/19. 6 | // Copyright © 2018 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | // sourcery: AutoMockable 12 | // sourcery: associatedtype = "ContainedType" 13 | protocol ProtocolWithGenericConstraints { 14 | associatedtype ContainedType 15 | var value: ContainedType { get } 16 | 17 | func extractString() -> String? where ContainedType == Optional 18 | } 19 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/Shared/Example 2/ProtocolWithThrowingMethods.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProtocolWithThrowingMethods.swift 3 | // Mocky_Example 4 | // 5 | // Created by Andrzej Michnia on 16.11.2017. 6 | // Copyright © 2017 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | //sourcery: AutoMockable 12 | protocol ProtocolWithThrowingMethods { 13 | func methodThatThrows() throws 14 | func methodThatReturnsAndThrows(param: Int) throws -> Bool 15 | } 16 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/Shared/Example 3/ProtocolsWithCustomAttributes.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProtocolsWithCustomAttributes.swift 3 | // Mocky_Example 4 | // 5 | // Created by Andrzej Michnia on 16.11.2017. 6 | // Copyright © 2017 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct UserObject { 12 | let name: String 13 | let surname: String 14 | let age: Int 15 | } 16 | 17 | //sourcery: AutoMockable 18 | protocol ProtocolWithTuples { 19 | func methodThatTakesTuple(tuple: (String,Int)) -> Int 20 | } 21 | 22 | //sourcery: AutoMockable 23 | protocol ProtocolWithCustomAttributes { 24 | func methodThatTakesUser(user: UserObject) throws 25 | func methodThatTakesArrayOfUsers(array: [UserObject]) -> Int 26 | } 27 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/Shared/Example 4/ProtocolWithStaticMembers.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProtocolWithStaticMembers.swift 3 | // Mocky_Example 4 | // 5 | // Created by Andrzej Michnia on 16.11.2017. 6 | // Copyright © 2017 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | //sourcery: AutoMockable 12 | protocol ProtocolWithStaticMembers { 13 | static var staticProperty: String { get } 14 | static func staticMethod(param: Int) throws -> Int 15 | } 16 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/Shared/Example 5/ProtocolsWithClosures.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProtocolsWithClosures.swift 3 | // Mocky_Example 4 | // 5 | // Created by Andrzej Michnia on 17.11.2017. 6 | // Copyright © 2017 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | //sourcery: AutoMockable 12 | protocol ProtocolWithClosures { 13 | func methodThatTakes(closure: (Int) -> Int) 14 | func methodThatTakesEscaping(closure: @escaping (Int) -> Int) 15 | func methodThatTakesCompletionBlock(completion: (Bool,Error?) -> Void) 16 | } 17 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/Shared/Example 6/ProtocolWithInitializers.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProtocolWithInitializers.swift 3 | // Mocky_Example 4 | // 5 | // Created by Andrzej Michnia on 17.11.2017. 6 | // Copyright © 2017 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | //sourcery: AutoMockable 12 | protocol ProtocolWithInitializers { 13 | var param: Int { get } 14 | var other: String { get } 15 | 16 | init(param: Int, other: String) 17 | init(param: Int) 18 | } 19 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/Shared/Example 7/ProtocolsWithGenerics.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProtocolsWithGenerics.swift 3 | // Mocky_Example 4 | // 5 | // Created by Andrzej Michnia on 17.11.2017. 6 | // Copyright © 2017 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | //sourcery: AutoMockable 12 | protocol ProtocolWithGenericMethods { 13 | func methodWithGeneric(lhs: T, rhs: T) -> Bool 14 | func methodWithGenericConstraint(param: [U]) -> U where U: Equatable 15 | } 16 | 17 | struct Resource { } 18 | struct Response { } 19 | struct Observable { } 20 | //sourcery: AutoMockable 21 | protocol ProtocolWithGenericMethodsNested { 22 | func methodWithGeneric(resource: Resource) -> Observable> 23 | } 24 | 25 | //sourcery: AutoMockable 26 | //sourcery: associatedtype = "T: Sequence" 27 | protocol ProtocolWithAssociatedType { 28 | associatedtype T: Sequence 29 | 30 | var sequence: T { get } 31 | 32 | func methodWithType(t: T) -> Bool 33 | } 34 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/Shared/Example 8/ProtocolWithProperties.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProtocolWithProperties.swift 3 | // SwiftyMocky 4 | // 5 | // Created by Andrzej Michnia on 08.12.2017. 6 | // Copyright © 2017 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | //sourcery: AutoMockable 12 | protocol ProtocolWithProperties { 13 | var name: String { get set } 14 | static var name: String { get set } 15 | var email: String? { get set } 16 | static var defaultEmail: String? { get set } 17 | 18 | var internalProperty: InternalType { get set } 19 | 20 | // Methods cannot have labels called "set" 21 | func name(_ newValue: String) 22 | func email(_ newValue: String!) 23 | static func defaultEmail(_ newValue: String!) 24 | } 25 | 26 | internal struct InternalType { } 27 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/Shared/Example 9/ProtocolMethodsThatDifferOnlyInReturnType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProtocolWithSimilarMethods.swift 3 | // SwiftyMocky 4 | // 5 | // Created by Andrzej Michnia on 31.01.2018. 6 | // Copyright © 2018 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | //sourcery: AutoMockable 12 | protocol ProtocolMethodsThatDifferOnlyInReturnType { 13 | func foo(bar: String) -> String 14 | func foo(bar: String) -> Int 15 | } 16 | 17 | class A { 18 | let id: Int 19 | init(_ id: Int) { 20 | self.id = id 21 | } 22 | } 23 | class B { 24 | let id: Int 25 | init(_ id: Int) { 26 | self.id = id 27 | } 28 | } 29 | 30 | //sourcery: AutoMockable 31 | protocol ProtocolMethodsGenericThatDifferOnlyInReturnType { 32 | func foo(bar: T) -> String 33 | func foo(bar: T) -> Int 34 | func foo(bar: T) -> Float where T: A 35 | func foo(bar: T) -> Float where T: B 36 | func foo(bar: T) -> Double where T: B 37 | func foo(bar: String) -> Array 38 | func foo(bar: String) -> Set 39 | func foo(bar: Bool) -> T where T: A 40 | func foo(bar: Bool) -> T where T: B 41 | } 42 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/Shared/Model/Item.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Item.swift 3 | // Mocky 4 | // 5 | // Created by przemyslaw.wosko on 19/05/2017. 6 | // Copyright © 2017 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Item { 12 | let name: String 13 | let id: Int 14 | } 15 | 16 | struct ItemDetails { 17 | let item: Item 18 | let price: Decimal 19 | let description: [String: String] 20 | } 21 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/Shared/Model/Models.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Models.swift 3 | // Mocky_Example 4 | // 5 | // Created by Andrzej Michnia on 09.11.2017. 6 | // Copyright © 2017 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct User { 12 | let name: String 13 | } 14 | 15 | struct NetworkConfig { 16 | let baseUrl: String 17 | } 18 | 19 | class UsersViewModel { 20 | var usersStorage: UserStorageType! 21 | var userNetwork: UserNetworkType! 22 | 23 | var id: String = "someid" 24 | var error: Error? 25 | var user: User? 26 | 27 | func saveUser(name: String, surname: String) { 28 | usersStorage.storeUser(name: name, surname: surname) 29 | } 30 | 31 | func fetchUser(completion: @escaping () -> Void) { 32 | userNetwork.getUser(for: id) { user in 33 | self.user = user 34 | completion() 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/Shared/Other/AllLiteralsContainerProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AllLiteralsContainerProtocol.swift 3 | // SwiftyMocky 4 | // 5 | // Created by Andrzej Michnia on 20/09/2018. 6 | // Copyright © 2018 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | enum CustomString: ExpressibleByStringLiteral, Equatable { 12 | typealias StringLiteralType = String 13 | 14 | case a 15 | case b(String) 16 | 17 | init(stringLiteral value: StringLiteralType) { 18 | switch value { 19 | case "a": self = .a 20 | default: self = .b(value) 21 | } 22 | } 23 | } 24 | 25 | enum CustomInt: ExpressibleByIntegerLiteral, Equatable { 26 | typealias IntegerLiteralType = Int 27 | 28 | case zero 29 | case value(Int) 30 | 31 | init(integerLiteral value: IntegerLiteralType) { 32 | switch value { 33 | case 0: self = .zero 34 | default: self = .value(value) 35 | } 36 | } 37 | } 38 | 39 | class SomeClass: Equatable { 40 | static func == (lhs: SomeClass, rhs: SomeClass) -> Bool { 41 | return lhs.v == rhs.v 42 | } 43 | 44 | let v: Int 45 | init(v: Int) { 46 | self.v = v 47 | } 48 | } 49 | 50 | //sourcery: AutoMockable 51 | protocol AllLiteralsContainer { 52 | // ExpressibleByNilLiteral 53 | 54 | // ExpressibleByStringLiteral 55 | func methodWithStringParameter(p: String) -> Int 56 | func methodWithOtionalStringParameter(p: String?) -> Int 57 | func methodWithCustomStringParameter(p: CustomString) -> Int 58 | func methodWithCustomOptionalStringParameter(p: CustomString?) -> Int 59 | 60 | // ExpressibleByIntegerLiteral 61 | func methodWithIntParameter(p: Int) -> Int 62 | func methodWithCustomOptionalIntParameter(p: CustomInt?) -> Int 63 | 64 | // ExpressibleByBooleanLiteral 65 | func methodWithBool(p: Bool?) -> Int 66 | 67 | // ExpressibleByFloatLiteral 68 | func methodWithFloat(p: Float?) -> Int 69 | func methodWithDouble(p: Double?) -> Int 70 | 71 | // ExpressibleByArrayLiteral 72 | func methodWithArrayOfInt(p: [Int]) -> Int 73 | func methodWithArrayOfOther(p: [SomeClass]) -> Int 74 | func methodWithSetOfInt(p: Set) -> Int 75 | func methodWithOptionalSetOfInt(p: Set?) -> Int 76 | 77 | // ExpressibleByDictionaryLiteral 78 | func methodWithDict(p: [String: SomeClass]) -> Int 79 | } 80 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/Shared/Other/ExampleProtocols.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ExampleProtocols.swift 3 | // Mocky_Example 4 | // 5 | // Created by Andrzej Michnia on 25.10.2017. 6 | // Copyright © 2017 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | //sourcery: AutoMockable 12 | protocol UserStorageType { 13 | func surname(for name: String) -> String 14 | func storeUser(name: String, surname: String) 15 | } 16 | 17 | //sourcery: AutoMockable 18 | protocol UserNetworkType { 19 | init(config: NetworkConfig) 20 | init(baseUrl: String) 21 | 22 | func getUser(for id: String, completion: (User?) -> Void) 23 | func getUserEscaping(for id: String, completion: @escaping (User?,Error?) -> Void) 24 | func doSomething(prop: @autoclosure () -> String) 25 | func testDefaultValues(value: String) 26 | } 27 | 28 | extension UserNetworkType { 29 | func testDefaultValues(value: String = "asd") { 30 | 31 | } 32 | } 33 | 34 | //sourcery: AutoMockable 35 | protocol EmptyProtocol { } 36 | 37 | //sourcery: AutoMockable 38 | protocol AMassiveTestProtocol { 39 | var nonOptionalClosure: () -> Void { get set } 40 | var optionalClosure: (() -> Int)? { get set } 41 | var implicitelyUnwrappedClosure: (() -> Void)! { get set } 42 | 43 | static var optionalClosure: (() -> Int)? { get set } 44 | 45 | func methodThatThrows() throws 46 | func methodThatReturnsAndThrows(param: String) throws -> Int 47 | func methodThatRethrows(param: (String) throws -> Int) rethrows -> Int 48 | 49 | static func methodThatThrows() throws 50 | static func methodThatReturnsAndThrows(param: String) throws -> Int 51 | static func methodThatRethrows(param: (String) throws -> Int) rethrows -> Int 52 | 53 | init() 54 | init(_ sth: Int) 55 | } 56 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/Shared/Other/Excluded.generated.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Excluded.generated.swift 3 | // Mocky 4 | // 5 | // Created by Andrzej Michnia on 08.01.2018. 6 | // Copyright © 2018 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | //sourcery: AutoMockable 12 | protocol ProtocolNotToBeMocked { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/Shared/Other/GenericProtocols.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GenericProtocols.swift 3 | // Mocky_Example 4 | // 5 | // Created by Andrzej Michnia on 09.11.2017. 6 | // Copyright © 2017 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | //sourcery: AutoMockable 12 | public protocol DateSortable { 13 | var date: Date { get } 14 | } 15 | 16 | //sourcery: AutoMockable 17 | public protocol HistorySectionMapperType: AnyObject { 18 | func map(_ items: [T]) -> [(key: String, items: [T])] 19 | } 20 | 21 | //sourcery: AutoMockable 22 | public protocol AVeryGenericProtocol { 23 | func methodConstrained(param: A) -> (B,C) 24 | 25 | init(value: V) 26 | 27 | static func generic(lhs: Q, rhs: Q) -> Bool where Q: Equatable 28 | static func veryConstrained(lhs: Q, rhs: Q) -> Bool where Q: Equatable 29 | } 30 | 31 | //sourcery: AutoMockable 32 | //sourcery: associatedtype = "T1: Sequence" 33 | //sourcery: associatedtype = "T2: Comparable, EmptyProtocol" 34 | protocol AVeryAssociatedProtocol { 35 | associatedtype T1: Sequence 36 | associatedtype T2: Comparable, EmptyProtocol 37 | 38 | func fetch(for value: T2) -> T1 39 | } 40 | 41 | //sourcery: AutoMockable 42 | protocol GenericProtocolWithTypeConstraint { 43 | func decode(_ type: T.Type, from data: Data) -> T 44 | func test(_ type: FOO.Type) -> Int 45 | } 46 | 47 | //sourcery: AutoMockable 48 | //sourcery: associatedtype = "T: Sequence where T.Element: Equatable" 49 | protocol ProtocolWithWhereAfterDefinition { 50 | associatedtype T: Sequence where T.Element: Equatable 51 | 52 | var sequence: T { get } 53 | 54 | func methodWithType(t: T) -> Bool 55 | } 56 | 57 | protocol GenericProtocolReturningInt: AutoMockable { 58 | func value(for value: T) -> Int 59 | } 60 | 61 | protocol ProtocolWithMethodsWithGenericReturnTypeThatThrows: AutoMockable { 62 | func max( 63 | for attribute: Int, 64 | over samples: [Int], 65 | per aggregationUnit: String? 66 | ) throws -> [(date: String?, value: Type)] 67 | } 68 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/Shared/Other/InoutParameterProtocols.swift: -------------------------------------------------------------------------------- 1 | // 2 | // InoutParameterProtocols.swift 3 | // SwiftyMocky 4 | // 5 | // Created by Andrzej Michnia on 17/02/2019. 6 | // Copyright © 2019 CocoaPods. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | //sourcery: AutoMockable 12 | protocol InoutProtocol: AnyObject { 13 | func passThisAsInOut(value: inout URLRequest) 14 | func returnAndInOut(value: inout Int) -> String 15 | func genericInOutClosure(closure: (inout T) -> Void) 16 | } 17 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/Shared/Other/ItemsRepository.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ItemsRepository.swift 3 | // Mocky 4 | // 5 | // Created by przemyslaw.wosko on 19/05/2017. 6 | // Copyright © 2017 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol ItemsRepository { 12 | func storeItems(items: [Item]) 13 | func storeDetails(details: ItemDetails) 14 | func storedItems() -> [Item]? 15 | func storedDetails(item: Item) -> ItemDetails? 16 | } 17 | 18 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/Shared/Other/MultiThreadAccess.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | //sourcery: AutoMockable 4 | protocol Fetcher { 5 | func fetchProperty(with id: String) -> String 6 | } 7 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/Shared/Other/NonSwiftProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NonSwiftProtocol.swift 3 | // Mocky_Example 4 | // 5 | // Created by przemyslaw.wosko on 29/10/2017. 6 | // Copyright © 2017 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | //sourcery: AutoMockable 12 | @objc protocol NonSwiftProtocol { 13 | @objc optional func returnNoting() 14 | func someMethod() 15 | } 16 | 17 | //sourcery: AutoMockable 18 | @objc(PRProtocolWithObjc) public protocol ProtocolWithObjc { 19 | 20 | @objc(doStaticStuffWithParameter1: andParameter2:) 21 | static func doStaticStuff(parameter1: String, parameter2: String) 22 | 23 | @objc(doStuffWithParameter1: andParameter2:) 24 | func doStuff(parameter1: String, parameter2: String) 25 | } 26 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/Shared/Other/ProtocolWithAttributes.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | @available(iOS 14, *) @objc 4 | protocol ProtocolWithAttributes: AutoMockable { 5 | func funcA() 6 | } 7 | 8 | //sourcery: AutoMockable 9 | protocol ProtocolWithAttributesB { 10 | @available(iOS 14, *) 11 | func funcB(_ dependency: ProtocolWithAttributes) 12 | 13 | @available(iOS 14, *) 14 | func funcC(_ dependency: ProtocolWithAttributes) -> Bool 15 | 16 | @available(iOS 12, macOS 10.14, *) 17 | subscript (x: Int, y: Int) -> String { get set } 18 | 19 | mutating func mutatingFunc(param: Int) -> String 20 | 21 | @discardableResult @inlinable func inlinableFunc(_ val: Int) -> Int 22 | } 23 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/Shared/Other/ProtocolWithMethodWithManyParameters.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | protocol ProtocolWithMethodWithManyParameters: AutoMockable { 4 | func method(param1: Int, value: String, flagA: Bool, flagB: Bool, closure: () -> Void) 5 | } 6 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/Shared/Other/ProtocolWithSubscripts.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProtocolWithSubscripts.swift 3 | // SwiftyMocky 4 | // 5 | // Created by Andrzej Michnia on 26/09/2018. 6 | // Copyright © 2018 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | //sourcery: AutoMockable 12 | protocol ProtocolWithSubscripts { 13 | func aaa(_ value: Int) -> Bool 14 | var something: Any { get set } 15 | subscript (_ index: Int) -> String { get set } 16 | subscript (labeled index: Int) -> String { get set } 17 | subscript (x: Int, y: Int) -> String { get set } 18 | subscript (_ index: String) -> String { get set } 19 | subscript (label name: String) -> Int { get } 20 | //sourcery: associatedtype = "T: Sequence" 21 | //sourcery: where = "T.Element: Equatable" 22 | subscript(with generic: T) -> Bool where T.Element: Equatable { get set } 23 | //sourcery: associatedtype = "T" 24 | //sourcery: where = "T: FloatingPoint" 25 | subscript(with generic: T) -> Int where T: FloatingPoint { get set } 26 | //sourcery: associatedtype = "T" 27 | subscript(_ i: Int, type: T.Type) -> T { get set } 28 | subscript (closure c: @escaping (Int) -> Void) -> Bool { get set } 29 | 30 | subscript (same: Int) -> Bool { get set } 31 | subscript (same: Int) -> Int { get set } 32 | } 33 | 34 | //sourcery: AutoMockable 35 | protocol ProtocolWithDeprecatedMembers { 36 | func method(_ value: Int) -> Bool 37 | } 38 | 39 | //sourcery: AutoMockable 40 | protocol ProtocolWithConflictingMembers { 41 | func method(withLabel value: Int) -> Bool 42 | func method(_ value: Int) -> Bool 43 | func method(value: Int) -> Bool 44 | } 45 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/Shared/Other/SampleService.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SampleService.swift 3 | // Mocky 4 | // 5 | // Created by Andrzej Michnia on 24.09.2017. 6 | // Copyright © 2017 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | @objc public protocol AutoMockable { } 12 | 13 | struct Point { 14 | let x: Float 15 | let y: Float 16 | } 17 | 18 | typealias Scalar = Double 19 | typealias LinearFunction = ((Scalar) -> Scalar)? 20 | typealias ClosureFabric = () -> ((Int) -> Void) 21 | 22 | protocol SampleServiceType: AutoMockable { 23 | func serviceName() -> String 24 | func getPoint(from point: Point) -> Point 25 | func getPoint(from tuple: (Float,Float)) -> Point 26 | func similarMethodThatDiffersOnType(_ value: Float) -> Bool 27 | func similarMethodThatDiffersOnType(_ value: Point) -> Bool 28 | func methodWithTypedef(_ scalar: Scalar) 29 | func methodWithClosures(success function: LinearFunction) -> ClosureFabric 30 | func methodWithClosures(success function: ((Scalar,Scalar) -> Scalar)?) -> ((Int) -> Void) 31 | } 32 | 33 | protocol SimpleServiceType { 34 | var youCouldOnlyGetThis: String { get } 35 | func serviceName() -> String 36 | } 37 | 38 | // sourcery: AutoMockable 39 | protocol ComplicatedServiceType: SampleServiceType, SimpleServiceType { 40 | var youCouldOnlyGetThis:String { get } 41 | func serviceName() -> String 42 | func aNewWayToSayHooray() -> Void 43 | } 44 | 45 | typealias ComposedService = SampleServiceType & SimpleServiceType & AutoMockable 46 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/Shared/Other/SelfConstrainedProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SelfConstrainedProtocol.swift 3 | // Mocky 4 | // 5 | // Created by Andrzej Michnia on 09.01.2018. 6 | // Copyright © 2018 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | //sourcery: AutoMockable 12 | protocol SelfConstrainedProtocol { 13 | func methodReturningSelf() -> Self 14 | static func construct(param value: Int) -> Self 15 | func compare(with other: Self) -> Bool 16 | func genericMethodWithNestedSelf(param: Int, second: T, other: (Self,Self)) -> Self 17 | func configure(with secret: String) throws -> Self 18 | } 19 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/Shared/Other/UnnamedAttributesProtocol.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | //sourcery: AutoMockable 4 | protocol UnnamedAttributesProtocol { 5 | func methodWithUnnamedAttributes(_: Int) -> String 6 | func methodWithUnnamedAndNamedAttributes(at int: Int, _: Int) -> String 7 | } 8 | 9 | class UnnamedAtributesProtocolImpl: UnnamedAttributesProtocol { 10 | 11 | func methodWithUnnamedAttributes(_ name: Int) -> String { 12 | return "\(name)" 13 | } 14 | 15 | func methodWithUnnamedAndNamedAttributes(at int: Int, _ other: Int) -> String { 16 | return "\(int).\(other)" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/Shared/Other/VariadicParametersProtocol.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | //sourcery: AutoMockable 4 | protocol VariadicParametersProtocol { 5 | func methodThatTakesVariadic(numbers: Int...) -> Int 6 | func methodThatTakesVariadic(label numbers: Int...) -> Int 7 | } 8 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/Shared/Swift5.5/AsyncMethodsProtocol.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | //sourcery: AutoMockable 4 | protocol AsyncMethodsProtocol { 5 | @available(iOS 15.0.0, macOS 12.0.0, tvOS 15.0.0, *) 6 | func loadListOfItems() async -> [String] 7 | } 8 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/Shared/Swift5.5/ThrowingVarProtocol.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | //sourcery: AutoMockable 4 | protocol ThrowingVarProtocol { 5 | @available(iOS 15.0.0, macOS 12.0.0, tvOS 15.0.0, *) 6 | var testVariableThatThrow: Bool { get throws } 7 | } 8 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/iOS/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Mocky 4 | // 5 | // Created by Przemysław Wośko on 05/19/2017. 6 | // Copyright (c) 2017 Przemysław Wośko. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/iOS/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/iOS/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ios-marketing", 45 | "size" : "1024x1024", 46 | "scale" : "1x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } -------------------------------------------------------------------------------- /SwiftyMocky-Example/iOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/iOS/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Mocky 4 | // 5 | // Created by Przemysław Wośko on 05/19/2017. 6 | // Copyright (c) 2017 Przemysław Wośko. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import CoreGraphics 11 | 12 | class ViewController: UIViewController { 13 | 14 | override func viewDidLoad() { 15 | super.viewDidLoad() 16 | // Do any additional setup after loading the view, typically from a nib. 17 | } 18 | 19 | override func didReceiveMemoryWarning() { 20 | super.didReceiveMemoryWarning() 21 | // Dispose of any resources that can be recreated. 22 | } 23 | 24 | } 25 | 26 | protocol TestAutoImport: AutoMockable { } 27 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/macOS/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Mocky_Example_macOS 4 | // 5 | // Created by Andrzej Michnia on 27.11.2017. 6 | // Copyright © 2017 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | @NSApplicationMain 12 | class AppDelegate: NSObject, NSApplicationDelegate { 13 | 14 | func applicationDidFinishLaunching(_ aNotification: Notification) { 15 | // Insert code here to initialize your application 16 | } 17 | 18 | func applicationWillTerminate(_ aNotification: Notification) { 19 | // Insert code here to tear down your application 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/macOS/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /SwiftyMocky-Example/macOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2017 MakeAWishFoundation. All rights reserved. 27 | NSMainStoryboardFile 28 | Main 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/macOS/Mocky_Example_macOS.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/macOS/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Mocky_Example_macOS 4 | // 5 | // Created by Andrzej Michnia on 27.11.2017. 6 | // Copyright © 2017 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class ViewController: NSViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | 16 | // Do any additional setup after loading the view. 17 | } 18 | 19 | override var representedObject: Any? { 20 | didSet { 21 | // Update the view, if already loaded. 22 | } 23 | } 24 | 25 | 26 | } 27 | 28 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/tvOS/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Mocky 4 | // 5 | // Created by Przemysław Wośko on 05/19/2017. 6 | // Copyright (c) 2017 Przemysław Wośko. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/tvOS/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /SwiftyMocky-Example/tvOS/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/tvOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIMainStoryboardFile 24 | Main 25 | UIRequiredDeviceCapabilities 26 | 27 | arm64 28 | 29 | UIUserInterfaceStyle 30 | Automatic 31 | 32 | 33 | -------------------------------------------------------------------------------- /SwiftyMocky-Example/tvOS/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Mocky 4 | // 5 | // Created by Przemysław Wośko on 05/19/2017. 6 | // Copyright (c) 2017 Przemysław Wośko. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | // Do any additional setup after loading the view, typically from a nib. 16 | } 17 | 18 | override func didReceiveMemoryWarning() { 19 | super.didReceiveMemoryWarning() 20 | // Dispose of any resources that can be recreated. 21 | } 22 | 23 | } 24 | 25 | -------------------------------------------------------------------------------- /SwiftyMocky-Runtime/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 4.2.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /SwiftyMocky-Runtime/Prototyping.h: -------------------------------------------------------------------------------- 1 | // 2 | // Prototyping.h 3 | // Prototyping 4 | // 5 | // Created by Andrzej Michnia on 25/05/2019. 6 | // Copyright © 2019 CocoaPods. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for Prototyping. 12 | FOUNDATION_EXPORT double PrototypingVersionNumber; 13 | 14 | //! Project version string for Prototyping. 15 | FOUNDATION_EXPORT const unsigned char PrototypingVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /SwiftyMocky-Runtime/SwiftyMocky.h: -------------------------------------------------------------------------------- 1 | // 2 | // SwiftyMocky.h 3 | // SwiftyMocky 4 | // 5 | // Created by Andrzej Michnia on 05.11.2017. 6 | // Copyright © 2017 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for SwiftyMocky. 12 | FOUNDATION_EXPORT double SwiftyMockyVersionNumber; 13 | 14 | //! Project version string for SwiftyMocky. 15 | FOUNDATION_EXPORT const unsigned char SwiftyMockyVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | -------------------------------------------------------------------------------- /SwiftyMocky-Tests/Shared/AssociatedTypes/SuggestionRepositoryTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SuggestionRepositoryTests.swift 3 | // SwiftyMocky 4 | // 5 | // Created by Andrzej Michnia on 11/11/2019. 6 | // Copyright © 2019 CocoaPods. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import SwiftyMocky 11 | #if os(iOS) 12 | #if IOS15 13 | @testable import Mocky_Example_iOS_15 14 | #else 15 | @testable import Mocky_Example_iOS 16 | #endif 17 | #elseif os(tvOS) 18 | @testable import Mocky_Example_tvOS 19 | #else 20 | @testable import Mocky_Example_macOS 21 | #endif 22 | 23 | class SuggestionRepositoryTests: XCTestCase { 24 | 25 | func testSuggestionRepositoryMock() { 26 | let mock = SuggestionRepositoryMock() 27 | 28 | let a = Suggestion() 29 | let b = Suggestion() 30 | 31 | Given(mock, .save(entity: .any, willReturn: false)) 32 | Given(mock, .save(entity: .sameInstance(as: a), willReturn: true)) 33 | 34 | XCTAssertTrue(mock.save(entity: a)) 35 | XCTAssertFalse(mock.save(entity: b)) 36 | 37 | Verify(mock, 2, .save(entity: .any)) 38 | Verify(mock, 1, .save(entity: .sameInstance(as: a))) 39 | Verify(mock, 1, .save(entity: .sameInstance(as: b))) 40 | } 41 | 42 | func testSuggestionRepositoryConstrainedToProtocolMock() { 43 | let mock = SuggestionRepositoryConstrainedToProtocolMock() 44 | 45 | let a = Suggestion() 46 | let b = Suggestion() 47 | 48 | Given(mock, .save(entity: .any, willReturn: false)) 49 | Given(mock, .save(entity: .sameInstance(as: a), willReturn: true)) 50 | 51 | XCTAssertTrue(mock.save(entity: a)) 52 | XCTAssertFalse(mock.save(entity: b)) 53 | 54 | Verify(mock, 2, .save(entity: .any)) 55 | Verify(mock, 1, .save(entity: .sameInstance(as: a))) 56 | Verify(mock, 1, .save(entity: .sameInstance(as: b))) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /SwiftyMocky-Tests/Shared/Example 1/ProtocolsWithCollectionsTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProtocolsWithCollectionsTests.swift 3 | // Mocky_Tests 4 | // 5 | // Created by Andrzej Michnia on 16.11.2017. 6 | // Copyright © 2017 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import SwiftyMocky 11 | #if os(iOS) 12 | #if IOS15 13 | @testable import Mocky_Example_iOS_15 14 | #else 15 | @testable import Mocky_Example_iOS 16 | #endif 17 | #elseif os(tvOS) 18 | @testable import Mocky_Example_tvOS 19 | #else 20 | @testable import Mocky_Example_macOS 21 | #endif 22 | 23 | class ProtocolsWithCollectionsTests: XCTestCase { 24 | 25 | func test_protocol_with_array() { 26 | let mock = SimpleProtocolUsingCollectionsMock() 27 | 28 | // When handling sequence of equatable, all works by default 29 | Given(mock, .getArray(willReturn: [1,2,3])) 30 | XCTAssertEqual(mock.getArray(), [1,2,3]) 31 | Verify(mock, .getArray()) 32 | 33 | // First always handle most explicit given 34 | Given(mock, .map(array: .value(["a","b","c"]), param: .value(1), willReturn: [1:"1abc"])) 35 | // If two have same level of explicity, order of setup matters (LIFO) 36 | Given(mock, .map(array: .value(["a","b","c"]), param: .any, willReturn: [1:"abc"])) 37 | Given(mock, .map(array: .any, param: .value(1), willReturn: [1:"1"])) 38 | 39 | XCTAssertEqual(mock.map(array: ["a","b","c"], param: 1)[1], "1abc") 40 | XCTAssertEqual(mock.map(array: ["any array"], param: 1)[1], "1") 41 | XCTAssertEqual(mock.map(array: ["a","b","c"], param: 2)[1], "abc") 42 | 43 | Verify(mock, 3, .map(array: .any, param: .any)) // total three invocations should be performed 44 | } 45 | 46 | func test_protocol_with_set() { 47 | let mock = SimpleProtocolUsingCollectionsMock() 48 | 49 | // Set is a Sequence of equatable, so it should work by default 50 | Given(mock, .verify(set: .value(Set(arrayLiteral: 1,2,3)), willReturn: true)) 51 | Given(mock, .verify(set: .any, willReturn: false)) 52 | 53 | XCTAssertEqual(mock.verify(set: Set(arrayLiteral: 1,2,3)), true) 54 | XCTAssertEqual(mock.verify(set: Set(arrayLiteral: 1,2,4)), false) 55 | XCTAssertEqual(mock.verify(set: Set(arrayLiteral: 0)), false) 56 | 57 | Verify(mock, 3, .verify(set: .any)) 58 | } 59 | 60 | func test_protocol_with_dictionary() { 61 | let mock = SimpleProtocolUsingCollectionsMock() 62 | 63 | #if swift(>=4.1) 64 | #else 65 | Matcher.default.register([Int: String].Element.self) { $0 == $1 } 66 | #endif 67 | 68 | // Set is a Sequence of equatable, so it should work by default 69 | Given(mock, .use(dictionary: .value([1:"abc"]), willReturn: [2:"def"])) 70 | Given(mock, .use(dictionary: .any, willReturn: [0:""])) 71 | 72 | XCTAssertEqual(mock.use(dictionary: [1:"abc"]), [2:"def"]) 73 | XCTAssertEqual(mock.use(dictionary: [1:"abcd"]), [0:""]) 74 | XCTAssertEqual(mock.use(dictionary: [2:"qwert"]), [0:""]) 75 | 76 | Verify(mock, 3, .use(dictionary: .any)) 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /SwiftyMocky-Tests/Shared/Example 10/ProtocolWithGenericConstraintsTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProtocolWithGenericConstraintsTests.swift 3 | // SwiftyMocky 4 | // 5 | // Created by Oleksandr Demishkevych on 7/17/19. 6 | // Copyright © 2018 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import SwiftyMocky 11 | #if os(iOS) 12 | #if IOS15 13 | @testable import Mocky_Example_iOS_15 14 | #else 15 | @testable import Mocky_Example_iOS 16 | #endif 17 | #elseif os(tvOS) 18 | @testable import Mocky_Example_tvOS 19 | #else 20 | @testable import Mocky_Example_macOS 21 | #endif 22 | 23 | class ProtocolWithGenericConstraintsTests: XCTestCase { 24 | 25 | func test_get_value() { 26 | let mock = ProtocolWithGenericConstraintsMock() 27 | let expectedValue = UUID().uuidString 28 | mock.given(.value(getter: expectedValue)) 29 | XCTAssertEqual(mock.value, expectedValue) 30 | mock.verify(.value) 31 | } 32 | 33 | func test_extract_value_if_constrains_satisfied() { 34 | let mock = ProtocolWithGenericConstraintsMock() 35 | let expectedValue = UUID().uuidString 36 | mock.given(.extractString(willReturn: .some(expectedValue))) 37 | XCTAssertEqual(mock.extractString(), expectedValue) 38 | mock.verify(.extractString()) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /SwiftyMocky-Tests/Shared/Example 2/ProtocolWithThrowingMehtodsTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProtocolWithThrowingMehtodsTests.swift 3 | // Mocky_Tests 4 | // 5 | // Created by Andrzej Michnia on 16.11.2017. 6 | // Copyright © 2017 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import SwiftyMocky 11 | #if os(iOS) 12 | #if IOS15 13 | @testable import Mocky_Example_iOS_15 14 | #else 15 | @testable import Mocky_Example_iOS 16 | #endif 17 | #elseif os(tvOS) 18 | @testable import Mocky_Example_tvOS 19 | #else 20 | @testable import Mocky_Example_macOS 21 | #endif 22 | 23 | enum SimpleTestError: Error { 24 | case failure 25 | case other 26 | } 27 | 28 | class ProtocolWithThrowingMehtodsTests: XCTestCase { 29 | 30 | func test_will_throw() { 31 | let mock = ProtocolWithThrowingMethodsMock() 32 | 33 | XCTAssertNoThrow(try mock.methodThatThrows(), "Should not throw right now") 34 | 35 | Given(mock, .methodThatThrows(willThrow: SimpleTestError.failure)) 36 | XCTAssertThrowsError(try mock.methodThatThrows(), "Should throw error") { error in 37 | switch error { 38 | case SimpleTestError.failure: XCTAssert(true) 39 | default: XCTFail("Wrong error thrown - expected \(SimpleTestError.failure), got \(error)") 40 | } 41 | } 42 | 43 | Given(mock, .methodThatThrows(willThrow: SimpleTestError.other)) 44 | XCTAssertThrowsError(try mock.methodThatThrows(), "Should throw error") { error in 45 | switch error { 46 | case SimpleTestError.other: XCTAssert(true) 47 | default: XCTFail("Wrong error thrown - expected \(SimpleTestError.other), got \(error)") 48 | } 49 | } 50 | } 51 | 52 | func test_throw_or_return() { 53 | let mock = ProtocolWithThrowingMethodsMock() 54 | 55 | Given(mock, .methodThatReturnsAndThrows(param: .value(200), willReturn: true)) 56 | Given(mock, .methodThatReturnsAndThrows(param: .value(404), willThrow: SimpleTestError.failure)) 57 | Given(mock, .methodThatReturnsAndThrows(param: .any, willThrow: SimpleTestError.other)) 58 | 59 | XCTAssertNoThrow(try mock.methodThatReturnsAndThrows(param: 200), "Should not throw") 60 | XCTAssertThrowsError(try mock.methodThatReturnsAndThrows(param: 404)) 61 | XCTAssertThrowsError(try mock.methodThatReturnsAndThrows(param: 123)) 62 | 63 | Verify(mock, 3, .methodThatReturnsAndThrows(param: .any)) 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /SwiftyMocky-Tests/Shared/Example 3/ProtocolsWithCustomAttributesTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProtocolsWithCustomAttributesTests.swift 3 | // Mocky_Tests 4 | // 5 | // Created by Andrzej Michnia on 16.11.2017. 6 | // Copyright © 2017 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import SwiftyMocky 11 | #if os(iOS) 12 | #if IOS15 13 | @testable import Mocky_Example_iOS_15 14 | #else 15 | @testable import Mocky_Example_iOS 16 | #endif 17 | #elseif os(tvOS) 18 | @testable import Mocky_Example_tvOS 19 | #else 20 | @testable import Mocky_Example_macOS 21 | #endif 22 | 23 | enum UserVerifyError: Error { 24 | case tooYoung 25 | } 26 | 27 | class ProtocolsWithCustomAttributesTests: XCTestCase { 28 | 29 | func test_protocol_using_tuples() { 30 | let mock = ProtocolWithTuplesMock() 31 | 32 | // When using only .any - no matcher registering needed 33 | Given(mock, .methodThatTakesTuple(tuple: .any, willReturn: 0)) 34 | XCTAssertEqual(mock.methodThatTakesTuple(tuple: ("first",1)), 0) 35 | 36 | // When using custom attributes or tuples as .value(...) - registering comparator in Matcher is required! 37 | Matcher.default.register((String,Int).self) { (lhs, rhs) -> Bool in 38 | return lhs.0 == rhs.0 && lhs.1 == rhs.1 39 | } 40 | 41 | Given(mock, .methodThatTakesTuple(tuple: .value(("first",1)), willReturn: 1)) 42 | Given(mock, .methodThatTakesTuple(tuple: .value(("second",2)), willReturn: 2)) 43 | XCTAssertEqual(mock.methodThatTakesTuple(tuple: ("first",1)), 1) 44 | XCTAssertEqual(mock.methodThatTakesTuple(tuple: ("second",2)), 2) 45 | XCTAssertEqual(mock.methodThatTakesTuple(tuple: ("first",0)), 0) 46 | 47 | Verify(mock, 4, .methodThatTakesTuple(tuple: .any)) 48 | Verify(mock, 2, .methodThatTakesTuple(tuple: .value(("first",1)))) 49 | } 50 | 51 | func test_protocol_using_customAttributes() { 52 | let mock = ProtocolWithCustomAttributesMock() 53 | 54 | // Register comparing user object 55 | // We can use registration for Array of elements, which will compare value by value 56 | // Also, providing by default comparator for element type 57 | Matcher.default.register(UserObject.self) { (lhs, rhs) -> Bool in 58 | guard lhs.name == rhs.name else { return false } 59 | guard lhs.surname == rhs.surname else { return false } 60 | guard lhs.age == rhs.age else { return false } 61 | return true 62 | } 63 | 64 | let user1 = UserObject(name: "Karl", surname: "Gustav", age: 90) 65 | let user2 = UserObject(name: "Dan", surname: "Dannerson", age: 13) 66 | Given(mock, .methodThatTakesUser(user: .value(user2), willThrow: UserVerifyError.tooYoung)) 67 | Given(mock, .methodThatTakesArrayOfUsers(array: .any, willReturn: 0)) 68 | Given(mock, .methodThatTakesArrayOfUsers(array: .value([user1, user2]), willReturn: 2)) 69 | 70 | XCTAssertNoThrow(try mock.methodThatTakesUser(user: user1), "Should not throw") 71 | XCTAssertThrowsError(try mock.methodThatTakesUser(user: user2)) 72 | XCTAssertEqual(mock.methodThatTakesArrayOfUsers(array: [user1, user2]), 2) 73 | XCTAssertEqual(mock.methodThatTakesArrayOfUsers(array: [user1, user2, user1]), 0) 74 | XCTAssertEqual(mock.methodThatTakesArrayOfUsers(array: [user2, user1]), 0) 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /SwiftyMocky-Tests/Shared/Example 4/ProtocolWithStaticMembersTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProtocolWithStaticMembersTests.swift 3 | // Mocky_Tests 4 | // 5 | // Created by Andrzej Michnia on 17.11.2017. 6 | // Copyright © 2017 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import SwiftyMocky 11 | #if os(iOS) 12 | #if IOS15 13 | @testable import Mocky_Example_iOS_15 14 | #else 15 | @testable import Mocky_Example_iOS 16 | #endif 17 | #elseif os(tvOS) 18 | @testable import Mocky_Example_tvOS 19 | #else 20 | @testable import Mocky_Example_macOS 21 | #endif 22 | 23 | class ProtocolWithStaticMembersTests: XCTestCase { 24 | 25 | func test_protocol_with_static() { 26 | // Static members are handled similar way - but instead of instance 27 | // you pass its type to Verify and Given calls 28 | 29 | // Static properties should be set with default values - same as with instance ones 30 | Given(ProtocolWithStaticMembersMock.self, .staticProperty(getter: "value")) 31 | Given(ProtocolWithStaticMembersMock.self, .staticMethod(param: .value(0), willReturn: 1)) 32 | Given(ProtocolWithStaticMembersMock.self, .staticMethod(param: .value(1), willReturn: 2)) 33 | Given(ProtocolWithStaticMembersMock.self, .staticMethod(param: .any, willThrow: SimpleTestError.failure)) 34 | 35 | XCTAssertEqual(ProtocolWithStaticMembersMock.staticProperty, "value") 36 | XCTAssertEqual(try? ProtocolWithStaticMembersMock.staticMethod(param: 0), 1) 37 | XCTAssertEqual(try? ProtocolWithStaticMembersMock.staticMethod(param: 1), 2) 38 | XCTAssertThrowsError(try ProtocolWithStaticMembersMock.staticMethod(param: -3)) 39 | XCTAssertThrowsError(try ProtocolWithStaticMembersMock.staticMethod(param: 2)) 40 | 41 | Verify(ProtocolWithStaticMembersMock.self, 4, .staticMethod(param: .any)) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /SwiftyMocky-Tests/Shared/Example 5/ProtocolWithClosuresTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProtocolWithClosuresTests.swift 3 | // Mocky_Tests 4 | // 5 | // Created by Andrzej Michnia on 17.11.2017. 6 | // Copyright © 2017 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import SwiftyMocky 11 | #if os(iOS) 12 | #if IOS15 13 | @testable import Mocky_Example_iOS_15 14 | #else 15 | @testable import Mocky_Example_iOS 16 | #endif 17 | #elseif os(tvOS) 18 | @testable import Mocky_Example_tvOS 19 | #else 20 | @testable import Mocky_Example_macOS 21 | #endif 22 | 23 | class ProtocolWithClosuresTests: XCTestCase { 24 | 25 | func test_closures_not_escaping() { 26 | let mock = ProtocolWithClosuresMock() 27 | 28 | mock.methodThatTakes(closure: { $0 }) 29 | mock.methodThatTakes(closure: { $0 * 2 }) 30 | 31 | Verify(mock, 2, .methodThatTakes(closure: .any)) 32 | // For non escaping closures - every .value(...) is always treated as .any 33 | Verify(mock, 2, .methodThatTakes(closure: .value({ $0 }))) 34 | } 35 | 36 | func test_closures_escaping() { 37 | let mock = ProtocolWithClosuresMock() 38 | 39 | mock.methodThatTakesEscaping(closure: { $0 }) 40 | mock.methodThatTakesEscaping(closure: { $0 * 2 }) 41 | 42 | // It is possible to check based on .value(...) for escaping closures 43 | // It requires to register closure comparator to Matcher 44 | // Nevertheless - we have not found ane good reason to do that yet :) 45 | Matcher.default.register(((Int) -> Int).self) { (lhs, rhs) -> Bool in 46 | return lhs(1) == rhs(1) && lhs(2) == rhs(2) 47 | } 48 | 49 | Verify(mock, 2, .methodThatTakesEscaping(closure: .any)) 50 | Verify(mock, 1, .methodThatTakesEscaping(closure: .value({ $0 }))) 51 | } 52 | 53 | func test_completion_block_based_approach() { 54 | let mock = ProtocolWithClosuresMock() 55 | 56 | let calledCompletionBlock = expectation(description: "Should call completion block") 57 | 58 | // Perform allows to execute given closure, with all the method parameters, as soon as it is being called 59 | Perform(mock, .methodThatTakesCompletionBlock(completion: .any, perform: { (completion) in 60 | completion(true,nil) 61 | })) 62 | 63 | mock.methodThatTakesCompletionBlock { (success, error) in 64 | calledCompletionBlock.fulfill() 65 | XCTAssertTrue(success) 66 | XCTAssertNil(error) 67 | } 68 | 69 | waitForExpectations(timeout: 0.5) { (error) in 70 | guard let error = error else { return } 71 | XCTFail("Error: \(error)") 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /SwiftyMocky-Tests/Shared/Example 6/ProtocolWithInitializersTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProtocolWithInitializersTests.swift 3 | // Mocky_Tests 4 | // 5 | // Created by Andrzej Michnia on 17.11.2017. 6 | // Copyright © 2017 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import SwiftyMocky 11 | #if os(iOS) 12 | #if IOS15 13 | @testable import Mocky_Example_iOS_15 14 | #else 15 | @testable import Mocky_Example_iOS 16 | #endif 17 | #elseif os(tvOS) 18 | @testable import Mocky_Example_tvOS 19 | #else 20 | @testable import Mocky_Example_macOS 21 | #endif 22 | 23 | class ProtocolWithInitializersTests: XCTestCase { 24 | 25 | func test_protocol_with_initializers() { 26 | // You can use all defined initializers 27 | let mock1 = ProtocolWithInitializersMock(param: 1) 28 | let mock2 = ProtocolWithInitializersMock(param: 2, other: "something") 29 | 30 | // Please hav in mind, that they are only to satisfy protocol requirements 31 | // there is no logic behind that, and so all properties has to be set manually anyway 32 | Given(mock1, .param(getter: 1)) 33 | Given(mock1, .other(getter: "")) 34 | XCTAssertEqual(mock1.param, 1) 35 | XCTAssertEqual(mock1.other, "") 36 | Given(mock2, .param(getter: 2)) 37 | Given(mock2, .other(getter: "something")) 38 | XCTAssertEqual(mock2.param, 2) 39 | XCTAssertEqual(mock2.other, "something") 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /SwiftyMocky-Tests/Shared/Example 7/ProtocolsWithGenericsTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProtocolsWithGenericsTests.swift 3 | // Mocky_Tests 4 | // 5 | // Created by Andrzej Michnia on 17.11.2017. 6 | // Copyright © 2017 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import SwiftyMocky 11 | #if os(iOS) 12 | #if IOS15 13 | @testable import Mocky_Example_iOS_15 14 | #else 15 | @testable import Mocky_Example_iOS 16 | #endif 17 | #elseif os(tvOS) 18 | @testable import Mocky_Example_tvOS 19 | #else 20 | @testable import Mocky_Example_macOS 21 | #endif 22 | 23 | class ProtocolsWithGenericsTests: XCTestCase { 24 | 25 | func test_protocol_with_generic_methods() { 26 | let mock = ProtocolWithGenericMethodsMock() 27 | 28 | // For generics - you have to use .any(ValueType.Type) to avoid ambiguity 29 | Given(mock, .methodWithGeneric(lhs: .any(Int.self), rhs: .any(Int.self), willReturn: false)) 30 | Given(mock, .methodWithGeneric(lhs: .any(String.self), rhs: .any(String.self), willReturn: true)) 31 | // In that case it is enough to specify type for only one elemen, so the type inference could do the rest 32 | Given(mock, .methodWithGeneric(lhs: .value(1), rhs: .any, willReturn: true)) 33 | 34 | XCTAssertEqual(mock.methodWithGeneric(lhs: 1, rhs: 0), true) 35 | XCTAssertEqual(mock.methodWithGeneric(lhs: 0, rhs: 1), false) 36 | XCTAssertEqual(mock.methodWithGeneric(lhs: "0", rhs: "1"), true) 37 | 38 | // Same applies to verify - specify type to avoid ambiguity 39 | Verify(mock, 2, .methodWithGeneric(lhs: .any(Int.self), rhs: .any(Int.self))) 40 | Verify(mock, 1, .methodWithGeneric(lhs: .any(String.self), rhs: .any(String.self))) 41 | } 42 | 43 | func test_protocol_with_associated_types() { 44 | let mock = ProtocolWithAssociatedTypeMock<[Int]>() 45 | Given(mock, .sequence(getter: [1,2,3])) 46 | 47 | // There is autocomplete issue, so in order to get autocomplete for all available methods 48 | // Use full .Given. ... syntax 49 | Given(mock, ProtocolWithAssociatedTypeMock.Given.methodWithType(t: .any, willReturn: false)) 50 | // It works slightly better, when using given directly on mock instance 51 | mock.given(ProtocolWithAssociatedTypeMock<[Int]>.Given.methodWithType(t: .value([1,1,1]), willReturn: true)) 52 | 53 | XCTAssertTrue(mock.methodWithType(t: [1,1,1])) 54 | XCTAssertFalse(mock.methodWithType(t: [2,2])) 55 | 56 | // Similar here 57 | Verify(mock, ProtocolWithAssociatedTypeMock.Verify.methodWithType(t: .value([1,1,1]))) 58 | // And also here, using method on instance works slightly better when comes to types inference 59 | mock.verify(ProtocolWithAssociatedTypeMock<[Int]>.Verify.methodWithType(t: .value([2,2]))) 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /SwiftyMocky-Tests/Shared/Example 8/ProtocolWithPropertiesTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProtocolWithPropertiesTests.swift 3 | // SwiftyMocky 4 | // 5 | // Created by Andrzej Michnia on 08.12.2017. 6 | // Copyright © 2017 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import SwiftyMocky 11 | #if os(iOS) 12 | #if IOS15 13 | @testable import Mocky_Example_iOS_15 14 | #else 15 | @testable import Mocky_Example_iOS 16 | #endif 17 | #elseif os(tvOS) 18 | @testable import Mocky_Example_tvOS 19 | #else 20 | @testable import Mocky_Example_macOS 21 | #endif 22 | 23 | class ProtocolsWithPropertiesTests: XCTestCase { 24 | 25 | func test_properties_getters() { 26 | let mock = ProtocolWithPropertiesMock() 27 | 28 | Verify(mock, .never, .name) 29 | Verify(mock, .never, .name(set: .any)) 30 | 31 | mock.name = "danny_13" 32 | 33 | // Get properties randomly between 10 and 20 times 34 | let upper: Int = 10 + Int(arc4random_uniform(10)) 35 | for _ in 1...upper { 36 | XCTAssertEqual(mock.name, "danny_13") 37 | } 38 | 39 | Verify(mock, .from(10, to: 20), .name) 40 | } 41 | 42 | func test_properties_setters() { 43 | let mock = ProtocolWithPropertiesMock() 44 | 45 | Verify(mock, .never, .name) 46 | Verify(mock, .never, .name(set: .any)) 47 | 48 | // Get properties randomly between 10 and 20 times 49 | let upper: Int = 10 + Int(arc4random_uniform(10)) 50 | for i in 1...upper { 51 | mock.name = "danny_\(i)" 52 | } 53 | 54 | Verify(mock, .atLeastOnce, .name(set: .value("danny_1"))) 55 | Verify(mock, .from(10, to: 20), .name(set: .any)) 56 | } 57 | 58 | func test_static_properties_getters() { 59 | let mock = ProtocolWithPropertiesMock.self 60 | mock.resetMock() 61 | 62 | Verify(mock, .never, .name) 63 | Verify(mock, .never, .name(set: .any)) 64 | 65 | mock.name = "danny_13" 66 | 67 | // Get properties randomly between 10 and 20 times 68 | let upper: Int = 10 + Int(arc4random_uniform(10)) 69 | for _ in 1...upper { 70 | XCTAssertEqual(mock.name, "danny_13") 71 | } 72 | 73 | Verify(mock, .from(10, to: 20), .name) 74 | } 75 | 76 | func test_static_properties_setters() { 77 | let mock = ProtocolWithPropertiesMock.self 78 | mock.resetMock() 79 | 80 | Verify(mock, .never, .name) 81 | Verify(mock, .never, .name(set: .any)) 82 | 83 | // Get properties randomly between 10 and 20 times 84 | let upper: Int = 10 + Int(arc4random_uniform(10)) 85 | for i in 1...upper { 86 | mock.name = "danny_\(i)" 87 | } 88 | 89 | Verify(mock, .atLeastOnce, .name(set: .value("danny_1"))) 90 | Verify(mock, .from(10, to: 20), .name(set: .any)) 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /SwiftyMocky-Tests/Shared/Example 9/ProtocolMethodsThatDifferOnlyInReturnTypeTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProtocolMethodsThatDifferOnlyInReturnTypeTests.swift 3 | // Mocky 4 | // 5 | // Created by Andrzej Michnia on 31.01.2018. 6 | // Copyright © 2018 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import SwiftyMocky 11 | #if os(iOS) 12 | #if IOS15 13 | @testable import Mocky_Example_iOS_15 14 | #else 15 | @testable import Mocky_Example_iOS 16 | #endif 17 | #elseif os(tvOS) 18 | @testable import Mocky_Example_tvOS 19 | #else 20 | @testable import Mocky_Example_macOS 21 | #endif 22 | 23 | class ProtocolMethodsThatDifferOnlyInReturnTypeTests: XCTestCase { 24 | 25 | func test_simple_case() { 26 | let mock = ProtocolMethodsThatDifferOnlyInReturnTypeMock() 27 | 28 | Given(mock, .foo(bar: .any, willReturn: 1)) 29 | Given(mock, .foo(bar: .value("sth"), willReturn: 2)) 30 | Given(mock, .foo(bar: .any, willReturn: "any")) 31 | 32 | Verify(mock, .never, .foo(bar: .any, returning: Int.self)) 33 | Verify(mock, .never, .foo(bar: .any, returning: String.self)) 34 | 35 | XCTAssertEqual(mock.foo(bar: "aaa"), 1) 36 | 37 | Verify(mock, 1, .foo(bar: .any, returning: Int.self)) 38 | Verify(mock, .never, .foo(bar: .any, returning: String.self)) 39 | 40 | XCTAssertEqual(mock.foo(bar: "sth"), 2) 41 | XCTAssertEqual(mock.foo(bar: "sth"), "any") 42 | 43 | Verify(mock, 2, .foo(bar: .any, returning: Int.self)) 44 | Verify(mock, 1, .foo(bar: .any, returning: String.self)) 45 | } 46 | 47 | func test_generic_case() { 48 | let mock = ProtocolMethodsGenericThatDifferOnlyInReturnTypeMock() 49 | 50 | Matcher.default.register(A.self) { lhs,rhs in 51 | return lhs.id == rhs.id 52 | } 53 | Matcher.default.register(B.self) { lhs,rhs in 54 | return lhs.id == rhs.id 55 | } 56 | 57 | Given(mock, .foo(bar: .any(A.self), willReturn: Float(0))) 58 | Given(mock, .foo(bar: .any(B.self), willReturn: Double(1))) 59 | Given(mock, .foo(bar: .any(Int.self), willReturn: 3)) 60 | Given(mock, .foo(bar: .any(String.self), willReturn: [1, 2])) 61 | Given(mock, .foo(bar: .any(String.self), willReturn: [1, 2, 3] as Set)) 62 | 63 | Verify(mock, .never, .foo(bar: .any(A.self), returning: Float.self)) 64 | Verify(mock, .never, .foo(bar: .any(Int.self), returning: Int.self)) 65 | Verify(mock, .never, .foo(bar: .any(String.self), returning: [Int].self)) 66 | Verify(mock, .never, .foo(bar: .any(String.self), returning: Set.self)) 67 | 68 | let v1: Float = mock.foo(bar: A(0)) 69 | XCTAssertEqual(v1, 0) 70 | let v2: Double = mock.foo(bar: B(1)) 71 | XCTAssertEqual(v2, 1) 72 | let v3: Set = mock.foo(bar: "0") 73 | XCTAssertEqual(v3, [1, 2, 3]) 74 | 75 | Verify(mock, 1, .foo(bar: .any(A.self), returning: Float.self)) 76 | Verify(mock, .never, .foo(bar: .any(Int.self), returning: Int.self)) 77 | Verify(mock, .never, .foo(bar: .any(String.self), returning: [Int].self)) 78 | Verify(mock, 1, .foo(bar: .any(String.self), returning: Set.self)) 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /SwiftyMocky-Tests/Shared/Other/ComplicatedServiceTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ComplicatedServiceTests.swift 3 | // Mocky_Example 4 | // 5 | // Created by Andrzej Michnia on 24.10.2017. 6 | // Copyright © 2017 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import SwiftyMocky 11 | #if os(iOS) 12 | #if IOS15 13 | @testable import Mocky_Example_iOS_15 14 | #else 15 | @testable import Mocky_Example_iOS 16 | #endif 17 | #elseif os(tvOS) 18 | @testable import Mocky_Example_tvOS 19 | #else 20 | @testable import Mocky_Example_macOS 21 | #endif 22 | 23 | class ComplicatedServiceTests: XCTestCase { 24 | 25 | var service: ComplicatedServiceTypeMock! 26 | 27 | override func setUp() { 28 | super.setUp() 29 | 30 | service = ComplicatedServiceTypeMock() 31 | } 32 | 33 | override func tearDown() { 34 | service = nil 35 | 36 | super.tearDown() 37 | } 38 | 39 | func test_something() { 40 | service.matcher.register(Point.self) { p1,p2 -> Bool in 41 | return p1.x == p2.x && p1.y == p2.y 42 | } 43 | 44 | service.matcher.register((Float,Float).self) { (t0, t1) -> Bool in 45 | return t0.0 == t1.0 && t0.1 == t1.1 46 | } 47 | 48 | Given(service,.getPoint(from: .any(Point.self), willReturn: Point(x: 0, y: 0))) 49 | Given(service,.getPoint(from: .value((0.0,0.0)), willReturn: Point(x: 1, y: 1))) 50 | 51 | let first = service.getPoint(from: Point(x: 1332, y: 1231)) 52 | XCTAssertEqual(first.x, 0) 53 | XCTAssertEqual(first.y, 0) 54 | 55 | let second = service.getPoint(from: (0.0,0.0)) 56 | XCTAssertEqual(second.x, 1) 57 | XCTAssertEqual(second.y, 1) 58 | } 59 | 60 | func test_closures() { 61 | var calls = 0 62 | 63 | service.given(.methodWithClosures(success: Parameter<((Scalar, Scalar) -> Scalar)?>.any, willReturn: { _ in })) 64 | 65 | service.perform(.methodWithClosures(success: Parameter<((Scalar, Scalar) -> Scalar)?>.any, 66 | perform: { function in 67 | _ = function?(Scalar(1),Scalar(2)) 68 | })) 69 | 70 | _ = service.methodWithClosures { (a, b) -> Scalar in 71 | calls += 1 72 | return a + b 73 | } 74 | 75 | XCTAssertEqual(calls, 1) 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /SwiftyMocky-Tests/Shared/Other/ComposedServiceTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ComposedServiceTests.swift 3 | // SwiftyMocky 4 | // 5 | // Created by Ernesto Cambuston on 3/1/21. 6 | // Copyright © 2021 CocoaPods. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import SwiftyMocky 11 | #if os(iOS) 12 | #if IOS15 13 | @testable import Mocky_Example_iOS_15 14 | #else 15 | @testable import Mocky_Example_iOS 16 | #endif 17 | #elseif os(tvOS) 18 | @testable import Mocky_Example_tvOS 19 | #else 20 | @testable import Mocky_Example_macOS 21 | #endif 22 | 23 | class ComposedServiceTests: XCTestCase { 24 | 25 | var service: ComposedServiceMock! 26 | 27 | override func setUp() { 28 | super.setUp() 29 | 30 | service = ComposedServiceMock() 31 | } 32 | 33 | override func tearDown() { 34 | service = nil 35 | 36 | super.tearDown() 37 | } 38 | 39 | func test_something() { 40 | service.matcher.register(Point.self) { p1,p2 -> Bool in 41 | return p1.x == p2.x && p1.y == p2.y 42 | } 43 | 44 | service.matcher.register((Float,Float).self) { (t0, t1) -> Bool in 45 | return t0.0 == t1.0 && t0.1 == t1.1 46 | } 47 | 48 | Given(service,.getPoint(from: .any(Point.self), willReturn: Point(x: 0, y: 0))) 49 | Given(service,.getPoint(from: .value((0.0,0.0)), willReturn: Point(x: 1, y: 1))) 50 | 51 | let first = service.getPoint(from: Point(x: 1332, y: 1231)) 52 | XCTAssertEqual(first.x, 0) 53 | XCTAssertEqual(first.y, 0) 54 | 55 | let second = service.getPoint(from: (0.0,0.0)) 56 | XCTAssertEqual(second.x, 1) 57 | XCTAssertEqual(second.y, 1) 58 | } 59 | 60 | func test_closures() { 61 | var calls = 0 62 | 63 | service.given(.methodWithClosures(success: Parameter<((Scalar, Scalar) -> Scalar)?>.any, willReturn: { _ in })) 64 | 65 | service.perform(.methodWithClosures(success: Parameter<((Scalar, Scalar) -> Scalar)?>.any, 66 | perform: { function in 67 | _ = function?(Scalar(1),Scalar(2)) 68 | })) 69 | 70 | _ = service.methodWithClosures { (a, b) -> Scalar in 71 | calls += 1 72 | return a + b 73 | } 74 | 75 | XCTAssertEqual(calls, 1) 76 | } 77 | } 78 | 79 | -------------------------------------------------------------------------------- /SwiftyMocky-Tests/Shared/Other/CustomAssertionsTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CustomAssertionsTests.swift 3 | // SwiftyMocky 4 | // 5 | // Created by Andrzej Michnia on 24/06/2019. 6 | // Copyright © 2019 CocoaPods. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import SwiftyMocky 11 | #if os(iOS) 12 | #if IOS15 13 | @testable import Mocky_Example_iOS_15 14 | #else 15 | @testable import Mocky_Example_iOS 16 | #endif 17 | #elseif os(tvOS) 18 | @testable import Mocky_Example_tvOS 19 | #else 20 | @testable import Mocky_Example_macOS 21 | #endif 22 | 23 | class CustomAssertionsTests: XCTestCase { 24 | 25 | func test_throws_error_of_type_success() { 26 | XCTAssertThrowsError(try throwErrorA(), of: TestError.self) 27 | } 28 | 29 | func test_throws_error_equatable_success() { 30 | XCTAssertThrowsError(try throwErrorA(), error: TestError.a) 31 | XCTAssertThrowsError(try throwErrorB(), error: TestError.b) 32 | } 33 | 34 | private enum TestError: Error, Equatable { 35 | case a 36 | case b 37 | } 38 | 39 | private func throwErrorA() throws -> Bool { 40 | throw TestError.a 41 | } 42 | 43 | private func throwErrorB() throws -> Bool { 44 | throw TestError.b 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /SwiftyMocky-Tests/Shared/Other/InoutParameterTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // InoutParameterTests.swift 3 | // Mocky 4 | // 5 | // Created by Andrzej Michnia on 17/02/2019. 6 | // Copyright © 2019 CocoaPods. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import SwiftyMocky 11 | #if os(iOS) 12 | #if IOS15 13 | @testable import Mocky_Example_iOS_15 14 | #else 15 | @testable import Mocky_Example_iOS 16 | #endif 17 | #elseif os(tvOS) 18 | @testable import Mocky_Example_tvOS 19 | #else 20 | @testable import Mocky_Example_macOS 21 | #endif 22 | 23 | class InoutParameterTests: XCTestCase { 24 | 25 | func testBaseInoutTest() { 26 | let mock = InoutProtocolMock() 27 | 28 | Given(mock, .returnAndInOut(value: .any, willReturn: "0")) 29 | Given(mock, .returnAndInOut(value: 1, willReturn: "1")) 30 | Given(mock, .returnAndInOut(value: 2, willReturn: "2")) 31 | 32 | Verify(mock, .never, .returnAndInOut(value: .any)) 33 | 34 | var value = 0 35 | XCTAssertEqual("0", mock.returnAndInOut(value: &value)) 36 | value = 1 37 | XCTAssertEqual("1", mock.returnAndInOut(value: &value)) 38 | value = 2 39 | XCTAssertEqual("2", mock.returnAndInOut(value: &value)) 40 | value = 3 41 | XCTAssertEqual("0", mock.returnAndInOut(value: &value)) 42 | 43 | Verify(mock, 4, .returnAndInOut(value: .any)) 44 | Verify(mock, .once, .returnAndInOut(value: 2)) 45 | Verify(mock, .never, .returnAndInOut(value: 5)) 46 | } 47 | 48 | func testPerformWithInoutParams() { 49 | let mock = InoutProtocolMock() 50 | 51 | Given(mock, .returnAndInOut(value: .any, willReturn: "A")) 52 | Perform(mock, .returnAndInOut(value: .any, perform: { (value: inout Int) in 53 | value += 1 54 | })) 55 | 56 | var value = 0 57 | XCTAssertEqual(value, 0) 58 | XCTAssertEqual(mock.returnAndInOut(value: &value), "A") 59 | XCTAssertEqual(value, 1) 60 | XCTAssertEqual(mock.returnAndInOut(value: &value), "A") 61 | XCTAssertEqual(value, 2) 62 | XCTAssertEqual(mock.returnAndInOut(value: &value), "A") 63 | XCTAssertEqual(value, 3) 64 | } 65 | 66 | typealias IntClosure = (inout Int) -> Void 67 | 68 | func testPerformWithGenericInoutClosure() { 69 | let mock = InoutProtocolMock() 70 | 71 | var value = 0 72 | Perform(mock, .genericInOutClosure(closure: .any(IntClosure.self), perform: { closure in 73 | closure(&value) 74 | })) 75 | 76 | mock.genericInOutClosure { value in 77 | value += 1 78 | } 79 | XCTAssertEqual(value, 1) 80 | mock.genericInOutClosure { value in 81 | value += 10 82 | } 83 | XCTAssertEqual(value, 11) 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /SwiftyMocky-Tests/Shared/Other/MultiThreadAccessTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MultiThreadAccessTests.swift 3 | // SwiftyMocky 4 | // 5 | // Created by Andrzej Michnia on 05/03/2021. 6 | // Copyright © 2021 CocoaPods. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import SwiftyMocky 11 | #if os(iOS) 12 | #if IOS15 13 | @testable import Mocky_Example_iOS_15 14 | #else 15 | @testable import Mocky_Example_iOS 16 | #endif 17 | #elseif os(tvOS) 18 | @testable import Mocky_Example_tvOS 19 | #else 20 | @testable import Mocky_Example_macOS 21 | #endif 22 | 23 | class CombinedFetcher { 24 | let fetcher: Fetcher 25 | var count = 0 26 | 27 | init(fetcher: Fetcher) { 28 | self.fetcher = fetcher 29 | } 30 | 31 | func fetch(forIds ids: [String], _ completion: @escaping () -> Void) { 32 | let queue = DispatchQueue(label: "test", attributes: .concurrent) 33 | let group = DispatchGroup() 34 | 35 | ids.forEach { id in 36 | group.enter() 37 | queue.async { 38 | _ = self.fetcher.fetchProperty(with: id) 39 | group.leave() 40 | } 41 | } 42 | 43 | group.notify(queue: DispatchQueue.main) { 44 | self.count += 1 45 | completion() 46 | } 47 | } 48 | } 49 | 50 | class CombinedFetcherTests: XCTestCase { 51 | 52 | func test_fetch() { 53 | let id1 = "id1" 54 | let id2 = "id2" 55 | let fetcher = FetcherMock() 56 | Given(fetcher, .fetchProperty(with: .value(id1), willReturn: "")) 57 | Given(fetcher, .fetchProperty(with: .value(id2), willReturn: "")) 58 | let sut = CombinedFetcher(fetcher: fetcher) 59 | let range = 1...100 60 | range.forEach { _ in 61 | let exp = expectation(description: "Fetch complete") 62 | sut.fetch(forIds: [id1, id2]) { exp.fulfill() } 63 | waitForExpectations(timeout: 2) 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /SwiftyMocky-Tests/Shared/Other/PropertiesHandlingTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PropertiesHandlingTests.swift 3 | // Mocky 4 | // 5 | // Created by Andrzej Michnia on 25/09/2018. 6 | // Copyright © 2018 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import SwiftyMocky 11 | #if os(iOS) 12 | #if IOS15 13 | @testable import Mocky_Example_iOS_15 14 | #else 15 | @testable import Mocky_Example_iOS 16 | #endif 17 | #elseif os(tvOS) 18 | @testable import Mocky_Example_tvOS 19 | #else 20 | @testable import Mocky_Example_macOS 21 | #endif 22 | 23 | class PropertiesHandlingTests: XCTestCase { 24 | 25 | override func setUp() { 26 | super.setUp() 27 | } 28 | 29 | override func tearDown() { 30 | super.tearDown() 31 | } 32 | 33 | func test_simple_given_scenario() { 34 | let mock = SimpleProtocolWithBothMethodsAndPropertiesMock() 35 | 36 | Verify(mock, .never, .property) // Verify we start with fresh counter 37 | Given(mock, .property(getter: "1","2","3")) 38 | Verify(mock, .never, .property) // Check if given do not change count 39 | XCTAssertEqual(mock.property, "1") 40 | Verify(mock, 1, .property) 41 | XCTAssertEqual(mock.property, "2") 42 | XCTAssertEqual(mock.property, "3") 43 | XCTAssertEqual(mock.property, "1") 44 | Verify(mock, 4, .property) 45 | } 46 | 47 | func test_property_drop_policy_fails() { 48 | let mock = SimpleProtocolWithPropertiesMock() 49 | 50 | Given(mock, .property(getter: "1", "2", "nextWillFail"), .drop) 51 | 52 | XCTAssertFalse(mock.property.isEmpty) 53 | XCTAssertFalse(mock.property.isEmpty) 54 | XCTAssertFalse(mock.property.isEmpty) 55 | // XCTAssertFalse(mock.property.isEmpty) // if uncommented this will fail - that's correct behaviour 56 | } 57 | 58 | func test_property_given_policy() { 59 | let mock = SimpleProtocolWithPropertiesMock(stubbing: .drop) 60 | 61 | Given(mock, .weakProperty(getter: nil), .wrap) 62 | Verify(mock, .never, .weakProperty) 63 | 64 | for _ in 1...20 { 65 | XCTAssert(mock.weakProperty == nil) 66 | } 67 | 68 | Verify(mock, 20, .weakProperty) 69 | } 70 | 71 | func test_property_setter_always_overrides_given() { 72 | let mock = SimpleProtocolWithPropertiesMock() 73 | 74 | Given(mock, .property(getter: "a", "b", "never here")) 75 | 76 | XCTAssertEqual(mock.property, "a") 77 | XCTAssertEqual(mock.property, "b") 78 | mock.property = "if set, always override given. That's how properties work. Set is set" 79 | XCTAssertNotEqual(mock.property, "never here") 80 | XCTAssertNotEqual(mock.property, "never here") 81 | XCTAssertNotEqual(mock.property, "never here") 82 | XCTAssertNotEqual(mock.property, "never here") 83 | XCTAssertNotEqual(mock.property, "never here") 84 | XCTAssertNotEqual(mock.property, "never here") 85 | 86 | Verify(mock, 1, .property(set: .any)) 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /SwiftyMocky-Tests/Shared/Other/ProtocolWithAttributesTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import SwiftyMocky 3 | #if os(iOS) 4 | #if IOS15 5 | @testable import Mocky_Example_iOS_15 6 | #else 7 | @testable import Mocky_Example_iOS 8 | #endif 9 | #elseif os(tvOS) 10 | @testable import Mocky_Example_tvOS 11 | #else 12 | @testable import Mocky_Example_macOS 13 | #endif 14 | 15 | class ProtocolWithAttributesTests: XCTestCase { 16 | 17 | @available(iOS 14, *) 18 | func testThatItWorks() { 19 | let mock = ProtocolWithAttributesMock() 20 | Verify(mock, .never, .funcA()) 21 | mock.funcA() 22 | Verify(mock, .once, .funcA()) 23 | } 24 | 25 | func testProtocolB() { 26 | let mock = ProtocolWithAttributesBMock() 27 | 28 | Given(mock, .inlinableFunc(.any, willReturn: 2,1,4)) 29 | Verify(mock, .never, .inlinableFunc(.any)) 30 | 31 | mock.inlinableFunc(0) 32 | 33 | Verify(mock, .once, .inlinableFunc(.any)) 34 | 35 | if #available(iOS 14, *) { 36 | let dep = ProtocolWithAttributesMock() 37 | Verify(mock, .never, .funcB(.any)) 38 | mock.funcB(dep) 39 | Verify(mock, .once, .funcB(.any)) 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /SwiftyMocky-Tests/Shared/Other/SampleServiceTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SampleServiceTests.swift 3 | // Mocky 4 | // 5 | // Created by Andrzej Michnia on 25.09.2017. 6 | // Copyright © 2017 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import SwiftyMocky 11 | #if os(iOS) 12 | #if IOS15 13 | @testable import Mocky_Example_iOS_15 14 | #else 15 | @testable import Mocky_Example_iOS 16 | #endif 17 | #elseif os(tvOS) 18 | @testable import Mocky_Example_tvOS 19 | #else 20 | @testable import Mocky_Example_macOS 21 | #endif 22 | 23 | class SampleServiceTests: XCTestCase { 24 | 25 | var service: SampleServiceTypeMock! 26 | 27 | override func setUp() { 28 | super.setUp() 29 | 30 | service = SampleServiceTypeMock() 31 | } 32 | 33 | override func tearDown() { 34 | service = nil 35 | 36 | super.tearDown() 37 | } 38 | 39 | func test_something() { 40 | service.matcher.register(Point.self) { p1,p2 -> Bool in 41 | return p1.x == p2.x && p1.y == p2.y 42 | } 43 | 44 | service.matcher.register((Float,Float).self) { (t0, t1) -> Bool in 45 | return t0.0 == t1.0 && t0.1 == t1.1 46 | } 47 | 48 | Given(service,.getPoint(from: .any(Point.self), willReturn: Point(x: 0, y: 0))) 49 | Given(service,.getPoint(from: .value((0.0,0.0)), willReturn: Point(x: 1, y: 1))) 50 | 51 | let first = service.getPoint(from: Point(x: 1332, y: 1231)) 52 | XCTAssertEqual(first.x, 0) 53 | XCTAssertEqual(first.y, 0) 54 | 55 | let second = service.getPoint(from: (0.0,0.0)) 56 | XCTAssertEqual(second.x, 1) 57 | XCTAssertEqual(second.y, 1) 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /SwiftyMocky-Tests/Shared/Other/SelfConstrainedProtocolTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SelfConstrainedProtocolTests.swift 3 | // Mocky 4 | // 5 | // Created by Andrzej Michnia on 10.01.2018. 6 | // Copyright © 2018 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import SwiftyMocky 11 | #if os(iOS) 12 | #if IOS15 13 | @testable import Mocky_Example_iOS_15 14 | #else 15 | @testable import Mocky_Example_iOS 16 | #endif 17 | #elseif os(tvOS) 18 | @testable import Mocky_Example_tvOS 19 | #else 20 | @testable import Mocky_Example_macOS 21 | #endif 22 | 23 | class SelfConstrainedProtocolTests: XCTestCase { 24 | 25 | override func setUp() { 26 | super.setUp() 27 | } 28 | 29 | override func tearDown() { 30 | super.tearDown() 31 | } 32 | 33 | func test_self_constrained() { 34 | let mock = SelfConstrainedProtocolMock() 35 | let other = SelfConstrainedProtocolMock() 36 | 37 | Matcher.default.register(SelfConstrainedProtocolMock.self) { (a, b) -> Bool in 38 | return a === b 39 | } 40 | 41 | Given(mock, .methodReturningSelf(willReturn: mock)) 42 | Given(mock, .compare(with: .any, willReturn: false)) 43 | Given(mock, .compare(with: .value(mock), willReturn: true)) 44 | 45 | XCTAssert(mock.methodReturningSelf() === mock) 46 | XCTAssertTrue(mock.compare(with: mock)) 47 | XCTAssertFalse(mock.compare(with: other)) 48 | } 49 | 50 | func test_self_constrained_when_throwing() { 51 | let mock = SelfConstrainedProtocolMock() 52 | 53 | Matcher.default.register(SelfConstrainedProtocolMock.self) { (a, b) -> Bool in 54 | return a === b 55 | } 56 | 57 | Given(mock, .configure(with: "throw", willThrow: TestError.first)) 58 | Given(mock, .configure(with: "notthrow", willReturn: mock)) 59 | 60 | XCTAssertNoThrow(try mock.configure(with: "notthrow")) 61 | XCTAssertThrowsError(try mock.configure(with: "throw")) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /SwiftyMocky-Tests/Shared/Other/UnnamedAttributesTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import SwiftyMocky 3 | #if os(iOS) 4 | #if IOS15 5 | @testable import Mocky_Example_iOS_15 6 | #else 7 | @testable import Mocky_Example_iOS 8 | #endif 9 | #elseif os(tvOS) 10 | @testable import Mocky_Example_tvOS 11 | #else 12 | @testable import Mocky_Example_macOS 13 | #endif 14 | 15 | class UnnamedAttributesTests: XCTestCase { 16 | 17 | func testThatItWorks() { 18 | let mock = UnnamedAttributesProtocolMock() 19 | 20 | Given(mock, .methodWithUnnamedAttributes(willReturn: "a")) 21 | Given(mock, .methodWithUnnamedAndNamedAttributes(at: .any, willReturn: "a")) 22 | Given(mock, .methodWithUnnamedAndNamedAttributes(at: 1, willReturn: "1")) 23 | Given(mock, .methodWithUnnamedAndNamedAttributes(at: 2, willReturn: "2")) 24 | 25 | XCTAssertEqual(mock.methodWithUnnamedAttributes(0), "a") 26 | XCTAssertEqual(mock.methodWithUnnamedAttributes(1), "a") 27 | XCTAssertEqual(mock.methodWithUnnamedAttributes(2), "a") 28 | XCTAssertEqual(mock.methodWithUnnamedAttributes(3), "a") 29 | 30 | XCTAssertEqual(mock.methodWithUnnamedAndNamedAttributes(at: 0, 0), "a") 31 | XCTAssertEqual(mock.methodWithUnnamedAndNamedAttributes(at: 0, 1), "a") 32 | XCTAssertEqual(mock.methodWithUnnamedAndNamedAttributes(at: 0, 2), "a") 33 | XCTAssertEqual(mock.methodWithUnnamedAndNamedAttributes(at: 1, 0), "1") 34 | XCTAssertEqual(mock.methodWithUnnamedAndNamedAttributes(at: 1, 1), "1") 35 | XCTAssertEqual(mock.methodWithUnnamedAndNamedAttributes(at: 1, 2), "1") 36 | XCTAssertEqual(mock.methodWithUnnamedAndNamedAttributes(at: 2, 0), "2") 37 | XCTAssertEqual(mock.methodWithUnnamedAndNamedAttributes(at: 2, 1), "2") 38 | XCTAssertEqual(mock.methodWithUnnamedAndNamedAttributes(at: 2, 2), "2") 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /SwiftyMocky-Tests/Shared/Other/VariadicParametersTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import SwiftyMocky 3 | #if os(iOS) 4 | #if IOS15 5 | @testable import Mocky_Example_iOS_15 6 | #else 7 | @testable import Mocky_Example_iOS 8 | #endif 9 | #elseif os(tvOS) 10 | @testable import Mocky_Example_tvOS 11 | #else 12 | @testable import Mocky_Example_macOS 13 | #endif 14 | 15 | class VariadicParametersTests: XCTestCase { 16 | 17 | // MARK: - Tests 18 | 19 | func testVariadicPatametersWorks() { 20 | let mock = VariadicParametersProtocolMock() 21 | 22 | Given(mock, .methodThatTakesVariadic(numbers: .any, willReturn: -1)) 23 | Given(mock, .methodThatTakesVariadic(numbers: .value([1,2,3]), willReturn: 3)) 24 | 25 | XCTAssertEqual(mock.methodThatTakesVariadic(numbers:1,2,3), 3) 26 | XCTAssertEqual(mock.methodThatTakesVariadic(numbers:2,2,2), -1) 27 | XCTAssertEqual(mock.methodThatTakesVariadic(numbers:0), -1) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /SwiftyMocky-Tests/Shared/Swift5.5/AsyncMethodsProtocolTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import SwiftyMocky 3 | #if os(iOS) 4 | #if IOS15 5 | @testable import Mocky_Example_iOS_15 6 | #else 7 | @testable import Mocky_Example_iOS 8 | #endif 9 | #elseif os(tvOS) 10 | @testable import Mocky_Example_tvOS 11 | #else 12 | @testable import Mocky_Example_macOS 13 | #endif 14 | 15 | class AsyncMethodsProtocolTests: XCTestCase { 16 | 17 | // MARK: - Tests 18 | 19 | @available(iOS 15.0.0, macOS 12.0.0, tvOS 15.0.0, *) 20 | func testAsyncMethod() async { 21 | let mock = AsyncMethodsProtocolMock() 22 | 23 | Given(mock, .loadListOfItems(willReturn: ["aaa", "bbb"])) 24 | 25 | // Async keyword is not yet supported by sourcery, but casting to protocol silences warning about missing async. 26 | let result = await (mock as AsyncMethodsProtocol).loadListOfItems() 27 | XCTAssertEqual(result, ["aaa", "bbb"]) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /SwiftyMocky-Tests/Shared/Swift5.5/ThrowingVarProtocolTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import SwiftyMocky 3 | #if os(iOS) 4 | #if IOS15 5 | @testable import Mocky_Example_iOS_15 6 | #else 7 | @testable import Mocky_Example_iOS 8 | #endif 9 | #elseif os(tvOS) 10 | @testable import Mocky_Example_tvOS 11 | #else 12 | @testable import Mocky_Example_macOS 13 | #endif 14 | 15 | class ThrowingVarProtocolTests: XCTestCase { 16 | 17 | // MARK: - Tests 18 | 19 | @available(iOS 15.0.0, macOS 12.0.0, tvOS 15.0.0, *) 20 | func testThrowingVariableMethod() throws { 21 | let mock = ThrowingVarProtocolMock() 22 | 23 | // We can't specify throw value yet, since it is not supported 24 | Given(mock, .testVariableThatThrow(getter: true)) 25 | 26 | // // Async keyword is not yet supported by sourcery, but casting to protocol silences warning about missing async. 27 | let result = try (mock as ThrowingVarProtocol).testVariableThatThrow 28 | XCTAssertTrue(result) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /SwiftyMocky-Tests/iOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /SwiftyMocky-Tests/macOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /SwiftyMocky-Tests/macOS/Mocky_Example_macOSTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Mocky_Example_macOSTests.swift 3 | // Mocky_Example_macOSTests 4 | // 5 | // Created by Andrzej Michnia on 27.11.2017. 6 | // Copyright © 2017 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import SwiftyMocky 11 | @testable import Mocky_Example_macOS 12 | 13 | class Mocky_Example_macOSTests: XCTestCase { 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | 18 | } 19 | 20 | override func tearDown() { 21 | // Put teardown code here. This method is called after the invocation of each test method in the class. 22 | super.tearDown() 23 | } 24 | 25 | func testExample() { 26 | // This is an example of a functional test case. 27 | // Use XCTAssert and related functions to verify your tests produce the correct results. 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /SwiftyMocky-Tests/tvOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /SwiftyMocky-Tests/tvOS/Mocky_tvOS_Tests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Mocky_tvOS_Tests.swift 3 | // Mocky_tvOS_Tests 4 | // 5 | // Created by Siarhei Fedartsou on 11/20/17. 6 | // Copyright © 2017 MakeAWishFoundation. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import SwiftyMocky 11 | 12 | class Mocky_tvOS_Tests: XCTestCase { 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | func testExample() { 24 | // This is an example of a functional test case. 25 | // Use XCTAssert and related functions to verify your tests produce the correct results. 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /SwiftyMocky.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'SwiftyMocky' 3 | s.version = '4.2.0' 4 | s.summary = 'Unit testing library for Swift, with mock generation. Adds a set of handy methods, simplifying testing.' 5 | s.description = <<-DESC 6 | Library that uses metaprogramming technique to generate mocks based on sources, that makes testing for Swift Mockito-like. 7 | DESC 8 | 9 | s.homepage = 'https://github.com/MakeAWishFoundation/SwiftyMocky' 10 | s.screenshots = 'https://raw.githubusercontent.com/MakeAWishFoundation/SwiftyMocky/1.0.0/icon.png' 11 | s.license = { :type => 'MIT', :file => 'LICENSE' } 12 | s.author = { 'Przemysław Wośko' => 'przemyslaw.wosko@intive.com', 'Andrzej Michnia' => 'amichnia@gmail.com' } 13 | s.source = { :git => 'https://github.com/MakeAWishFoundation/SwiftyMocky.git', :tag => s.version.to_s } 14 | 15 | s.swift_versions = ['4.2', '5.0', '5.1', '5.1.2', '5.2', '5.3', '5.4', '5.5'] 16 | s.ios.deployment_target = '9.0' 17 | s.tvos.deployment_target = '9.0' 18 | s.macos.deployment_target = '10.10' 19 | s.preserve_paths = '*' 20 | 21 | s.source_files = 'Sources/{SwiftyMocky,Shared}/**/*.swift' 22 | s.resources = '{Sources/SwiftyMocky/Mock.swifttemplate}' 23 | s.frameworks = 'Foundation' 24 | s.weak_framework = "XCTest" 25 | s.dependency 'Sourcery', '1.8.0' 26 | s.pod_target_xcconfig = { 27 | 'APPLICATION_EXTENSION_API_ONLY' => 'YES', 28 | 'ENABLE_BITCODE' => 'NO', 29 | 'OTHER_LDFLAGS' => '$(inherited) -weak-lXCTestSwiftSupport -Xlinker -no_application_extension', 30 | 'OTHER_SWIFT_FLAGS' => '$(inherited) -suppress-warnings', 31 | 'FRAMEWORK_SEARCH_PATHS' => '$(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks"', 32 | 'DEFINES_MODULE' => 'YES' 33 | } 34 | s.user_target_xcconfig = { 'FRAMEWORK_SEARCH_PATHS' => '$(PLATFORM_DIR)/Developer/Library/Frameworks' } 35 | end 36 | -------------------------------------------------------------------------------- /SwiftyMocky.xcodeproj/xcshareddata/xcschemes/SwiftyPrototype.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 50 | 51 | 52 | 53 | 59 | 60 | 66 | 67 | 68 | 69 | 71 | 72 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /SwiftyMocky.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /SwiftyPrototype.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'SwiftyPrototype' 3 | s.version = '4.2.0' 4 | s.summary = 'Prototyping/Faking library for Swift, with code generation. Auto-generates fakes/prototypes based on protocol definitions.' 5 | s.description = <<-DESC 6 | Library that uses metaprogramming technique to generate fakes/prototypes based on sources, makin it easier to prototype app. 7 | DESC 8 | 9 | s.homepage = 'https://github.com/MakeAWishFoundation/SwiftyMocky' 10 | s.screenshots = 'https://raw.githubusercontent.com/MakeAWishFoundation/SwiftyMocky/1.0.0/icon.png' 11 | s.license = { :type => 'MIT', :file => 'LICENSE' } 12 | s.author = { 'Przemysław Wośko' => 'przemyslaw.wosko@intive.com', 'Andrzej Michnia' => 'amichnia@gmail.com' } 13 | s.source = { :git => 'https://github.com/MakeAWishFoundation/SwiftyMocky.git', :tag => s.version.to_s } 14 | 15 | s.swift_versions = ['4.2', '5.0', '5.1', '5.1.2', '5.2', '5.3', '5.4', '5.5'] 16 | s.ios.deployment_target = '9.0' 17 | s.tvos.deployment_target = '9.0' 18 | s.macos.deployment_target = '10.10' 19 | s.preserve_paths = '*' 20 | 21 | s.source_files = 'Sources/{SwiftyPrototype,Shared}/**/*.swift' 22 | s.resources = '{Sources/SwiftyPrototype/Prototype.swifttemplate}' 23 | s.frameworks = 'Foundation' 24 | s.dependency 'Sourcery', '~> 1.8.0' 25 | end 26 | -------------------------------------------------------------------------------- /Templates/AllTypes.swifttemplate: -------------------------------------------------------------------------------- 1 | types: 2 | <%_ var all = types.all 3 | all += types.protocols.map { $0 } 4 | all += types.protocolCompositions.map { $0 } -%> 5 | <%_ for type in all { -%><%_ -%> 6 | <%_ let autoMockable: Bool = type.inheritedTypes.contains("AutoMockable") || type.annotations["AutoMockable"] != nil -%> 7 | <%_ if autoMockable { -%> 8 | - <%= type.name %> 9 | <%_ } -%> 10 | <%_ } -%> 11 | -------------------------------------------------------------------------------- /Templates/ArgumentsHelper.swift: -------------------------------------------------------------------------------- 1 | func swiftLintRules(_ arguments: [String: Any]) -> [String] { 2 | return stringArray(fromArguments: arguments, forKey: "excludedSwiftLintRules").map { rule in 3 | return "//swiftlint:disable \(rule)" 4 | } 5 | } 6 | 7 | func projectImports(_ arguments: [String: Any]) -> [String] { 8 | return imports(arguments) + testableImports(arguments) 9 | } 10 | 11 | func imports(_ arguments: [String: Any]) -> [String] { 12 | return stringArray(fromArguments: arguments, forKey: "import") 13 | .map { return "import \($0)" } 14 | } 15 | 16 | func testableImports(_ arguments: [String: Any]) -> [String] { 17 | return stringArray(fromArguments: arguments, forKey: "testable") 18 | .map { return "@testable import \($0)" } 19 | } 20 | 21 | /// [Internal] Get value from dictionary 22 | /// - Parameters: 23 | /// - fromArguments: dictionary 24 | /// - forKey: dictionary key 25 | /// - Returns: array of strings, if key not found, returns empty array. 26 | /// - Note: If sourcery arguments containts only one element, then single value is stored, otherwise array of elements. This method always gets array of elements. 27 | func stringArray(fromArguments arguments: [String: Any], forKey key: String) -> [String] { 28 | 29 | if let argument = arguments[key] as? String { 30 | return [argument] 31 | } else if let manyArguments = arguments[key] as? [String] { 32 | return manyArguments 33 | } else { 34 | return [] 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Templates/Assets.template: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import PathKit 3 | 4 | public enum Assets { 5 | 6 | public enum swifttemplate { 7 | public static let allTypes: AssetFile = Files.allTypes 8 | public static let mock: AssetFile = Files.mock 9 | public static let prototype: AssetFile = Files.prototype 10 | } 11 | 12 | public static var mockfileTemplate: String { return """ 13 | # Mockfile is a SwiftyMocky YAML configuration file 14 | sourceryCommand: null 15 | unit.tests.mock: # Name of your mock 16 | sources: 17 | include: # All swift files here would be scanned for AutoMockable types 18 | - ./MyApp 19 | exclude: [] # You can exclude files as well 20 | output: # Generated mock file location and name 21 | ./MyAppUnitTests/Mocks/Mock.generated.swift 22 | targets: # Specify XCodeproj targets for your mock. Used for linting 23 | - MyAppUnitTests 24 | testable: [] # Specify list of imported/@testable modules referenced in mock 25 | import: [] # You can use 'swiftymocky autoimport' to update it automatically 26 | """ 27 | } 28 | } 29 | 30 | public protocol AssetFile { 31 | 32 | var name: String { get } 33 | var data: Data { get } 34 | 35 | func write(to path: Path) throws 36 | } 37 | 38 | private struct File: AssetFile { 39 | 40 | let name: String 41 | let contents: String 42 | var data: Data { return Data(base64Encoded: contents) ?? Data() } 43 | 44 | func write(to path: Path) throws { 45 | try path.write(data) 46 | } 47 | } 48 | 49 | private enum Files { 50 | static let allTypes = File( 51 | name: "AllTypes.swifttemplate", 52 | contents: "{{ AllTypes.swifttemplate }}" 53 | ) 54 | static let mock = File( 55 | name: "Mock.swifttemplate", 56 | contents: "{{ Mock.swifttemplate }}" 57 | ) 58 | static let prototype = File( 59 | name: "Mock.swifttemplate", 60 | contents: "{{ Prototype.swifttemplate }}" 61 | ) 62 | } 63 | -------------------------------------------------------------------------------- /Templates/Current.swift: -------------------------------------------------------------------------------- 1 | class Current { 2 | static var selfType: String = "Self" 3 | static var accessModifier: String = "open" 4 | } 5 | -------------------------------------------------------------------------------- /Templates/Header-Mock.swifttemplate: -------------------------------------------------------------------------------- 1 | // Generated with SwiftyMocky 4.2.0 2 | // Required Sourcery: 1.8.0 3 | 4 | <%_ for rule in swiftLintRules(argument) { -%> 5 | <%_ %><%= rule %> 6 | <%_ } -%> 7 | 8 | import SwiftyMocky 9 | import XCTest 10 | -------------------------------------------------------------------------------- /Templates/Header-Prototype.swifttemplate: -------------------------------------------------------------------------------- 1 | // Generated with SwiftyPrototype 4.2.0 2 | // Required Sourcery: 1.8.0 3 | 4 | <%_ for rule in swiftLintRules(argument) { -%> 5 | <%_ %><%= rule %> 6 | <%_ } -%> 7 | 8 | import SwiftyPrototype 9 | -------------------------------------------------------------------------------- /Templates/Imports.swifttemplate: -------------------------------------------------------------------------------- 1 | <%# ================================================== IMPORTS -%><%_ -%> 2 | <%_ for projectImport in projectImports(argument) { -%> 3 | <%_ %><%= projectImport %> 4 | <%_ } -%> 5 | <%# ============================ IMPORTS InAPP (aggregated argument) -%><%_ -%> 6 | <%_ if let swiftyMockyArgs = argument["swiftyMocky"] as? [String: Any] { -%> 7 | <%_ for projectImport in projectImports(swiftyMockyArgs) { -%> 8 | <%_ %><%= projectImport %> 9 | <%_ } -%> 10 | <%_ } -%> 11 | -------------------------------------------------------------------------------- /Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import SwiftyMockyCLICoreTests 3 | 4 | var tests = [XCTestCaseEntry]() 5 | tests += SwiftyMockyCLICoreTests.allTests() 6 | XCTMain(tests) -------------------------------------------------------------------------------- /Tests/RuntimeLibaryTests/XCTestManifests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | #if !os(macOS) 4 | public func allTests() -> [XCTestCaseEntry] { 5 | return [ 6 | // TODO: Insert all tests to run on linux 7 | ] 8 | } 9 | #endif -------------------------------------------------------------------------------- /Tests/SwiftyMockyCLICoreTests/XCTestManifests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | #if !os(macOS) 4 | public func allTests() -> [XCTestCaseEntry] { 5 | return [ 6 | testCase(CommandLineInterfaceTests.allTests), 7 | ] 8 | } 9 | #endif 10 | -------------------------------------------------------------------------------- /Tests/SwiftyMockyTests/Shared: -------------------------------------------------------------------------------- 1 | ../../SwiftyMocky-Tests/Shared/ -------------------------------------------------------------------------------- /Tests/SwiftyMockyTests/XCTestManifests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | #if !os(macOS) 4 | public func allTests() -> [XCTestCaseEntry] { 5 | return [ 6 | // TODO: Insert all tests to run on linux 7 | ] 8 | } 9 | #endif -------------------------------------------------------------------------------- /bin/swiftymocky: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MakeAWishFoundation/SwiftyMocky/3672eea08c7098214ac54ee26c7a7e39ea01a2f1/bin/swiftymocky -------------------------------------------------------------------------------- /docs/badge.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | documentation 17 | 18 | 19 | documentation 20 | 21 | 22 | 86% 23 | 24 | 25 | 86% 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /docs/docsets/SwiftyMocky.docset/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleIdentifier 6 | com.jazzy.swiftymocky 7 | CFBundleName 8 | SwiftyMocky 9 | DocSetPlatformFamily 10 | swiftymocky 11 | isDashDocset 12 | 13 | dashIndexFilePath 14 | index.html 15 | isJavaScriptEnabled 16 | 17 | DashDocSetFamily 18 | dashtoc 19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/docsets/SwiftyMocky.docset/Contents/Resources/Documents/img/carat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MakeAWishFoundation/SwiftyMocky/3672eea08c7098214ac54ee26c7a7e39ea01a2f1/docs/docsets/SwiftyMocky.docset/Contents/Resources/Documents/img/carat.png -------------------------------------------------------------------------------- /docs/docsets/SwiftyMocky.docset/Contents/Resources/Documents/img/dash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MakeAWishFoundation/SwiftyMocky/3672eea08c7098214ac54ee26c7a7e39ea01a2f1/docs/docsets/SwiftyMocky.docset/Contents/Resources/Documents/img/dash.png -------------------------------------------------------------------------------- /docs/docsets/SwiftyMocky.docset/Contents/Resources/Documents/img/gh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MakeAWishFoundation/SwiftyMocky/3672eea08c7098214ac54ee26c7a7e39ea01a2f1/docs/docsets/SwiftyMocky.docset/Contents/Resources/Documents/img/gh.png -------------------------------------------------------------------------------- /docs/docsets/SwiftyMocky.docset/Contents/Resources/Documents/img/spinner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MakeAWishFoundation/SwiftyMocky/3672eea08c7098214ac54ee26c7a7e39ea01a2f1/docs/docsets/SwiftyMocky.docset/Contents/Resources/Documents/img/spinner.gif -------------------------------------------------------------------------------- /docs/docsets/SwiftyMocky.docset/Contents/Resources/Documents/js/jazzy.js: -------------------------------------------------------------------------------- 1 | // Jazzy - https://github.com/realm/jazzy 2 | // Copyright Realm Inc. 3 | // SPDX-License-Identifier: MIT 4 | 5 | window.jazzy = {'docset': false} 6 | if (typeof window.dash != 'undefined') { 7 | document.documentElement.className += ' dash' 8 | window.jazzy.docset = true 9 | } 10 | if (navigator.userAgent.match(/xcode/i)) { 11 | document.documentElement.className += ' xcode' 12 | window.jazzy.docset = true 13 | } 14 | 15 | function toggleItem($link, $content) { 16 | var animationDuration = 300; 17 | $link.toggleClass('token-open'); 18 | $content.slideToggle(animationDuration); 19 | } 20 | 21 | function itemLinkToContent($link) { 22 | return $link.parent().parent().next(); 23 | } 24 | 25 | // On doc load + hash-change, open any targetted item 26 | function openCurrentItemIfClosed() { 27 | if (window.jazzy.docset) { 28 | return; 29 | } 30 | var $link = $(`a[name="${location.hash.substring(1)}"]`).nextAll('.token'); 31 | $content = itemLinkToContent($link); 32 | if ($content.is(':hidden')) { 33 | toggleItem($link, $content); 34 | } 35 | } 36 | 37 | $(openCurrentItemIfClosed); 38 | $(window).on('hashchange', openCurrentItemIfClosed); 39 | 40 | // On item link ('token') click, toggle its discussion 41 | $('.token').on('click', function(event) { 42 | if (window.jazzy.docset) { 43 | return; 44 | } 45 | var $link = $(this); 46 | toggleItem($link, itemLinkToContent($link)); 47 | 48 | // Keeps the document from jumping to the hash. 49 | var href = $link.attr('href'); 50 | if (history.pushState) { 51 | history.pushState({}, '', href); 52 | } else { 53 | location.hash = href; 54 | } 55 | event.preventDefault(); 56 | }); 57 | 58 | // Clicks on links to the current, closed, item need to open the item 59 | $("a:not('.token')").on('click', function() { 60 | if (location == this.href) { 61 | openCurrentItemIfClosed(); 62 | } 63 | }); 64 | 65 | // KaTeX rendering 66 | if ("katex" in window) { 67 | $($('.math').each( (_, element) => { 68 | katex.render(element.textContent, element, { 69 | displayMode: $(element).hasClass('m-block'), 70 | throwOnError: false, 71 | trust: true 72 | }); 73 | })) 74 | } 75 | -------------------------------------------------------------------------------- /docs/docsets/SwiftyMocky.docset/Contents/Resources/Documents/js/jazzy.search.js: -------------------------------------------------------------------------------- 1 | // Jazzy - https://github.com/realm/jazzy 2 | // Copyright Realm Inc. 3 | // SPDX-License-Identifier: MIT 4 | 5 | $(function(){ 6 | var $typeahead = $('[data-typeahead]'); 7 | var $form = $typeahead.parents('form'); 8 | var searchURL = $form.attr('action'); 9 | 10 | function displayTemplate(result) { 11 | return result.name; 12 | } 13 | 14 | function suggestionTemplate(result) { 15 | var t = '
'; 16 | t += '' + result.name + ''; 17 | if (result.parent_name) { 18 | t += '' + result.parent_name + ''; 19 | } 20 | t += '
'; 21 | return t; 22 | } 23 | 24 | $typeahead.one('focus', function() { 25 | $form.addClass('loading'); 26 | 27 | $.getJSON(searchURL).then(function(searchData) { 28 | const searchIndex = lunr(function() { 29 | this.ref('url'); 30 | this.field('name'); 31 | this.field('abstract'); 32 | for (const [url, doc] of Object.entries(searchData)) { 33 | this.add({url: url, name: doc.name, abstract: doc.abstract}); 34 | } 35 | }); 36 | 37 | $typeahead.typeahead( 38 | { 39 | highlight: true, 40 | minLength: 3, 41 | autoselect: true 42 | }, 43 | { 44 | limit: 10, 45 | display: displayTemplate, 46 | templates: { suggestion: suggestionTemplate }, 47 | source: function(query, sync) { 48 | const lcSearch = query.toLowerCase(); 49 | const results = searchIndex.query(function(q) { 50 | q.term(lcSearch, { boost: 100 }); 51 | q.term(lcSearch, { 52 | boost: 10, 53 | wildcard: lunr.Query.wildcard.TRAILING 54 | }); 55 | }).map(function(result) { 56 | var doc = searchData[result.ref]; 57 | doc.url = result.ref; 58 | return doc; 59 | }); 60 | sync(results); 61 | } 62 | } 63 | ); 64 | $form.removeClass('loading'); 65 | $typeahead.trigger('focus'); 66 | }); 67 | }); 68 | 69 | var baseURL = searchURL.slice(0, -"search.json".length); 70 | 71 | $typeahead.on('typeahead:select', function(e, result) { 72 | window.location = baseURL + result.url; 73 | }); 74 | }); 75 | -------------------------------------------------------------------------------- /docs/docsets/SwiftyMocky.docset/Contents/Resources/docSet.dsidx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MakeAWishFoundation/SwiftyMocky/3672eea08c7098214ac54ee26c7a7e39ea01a2f1/docs/docsets/SwiftyMocky.docset/Contents/Resources/docSet.dsidx -------------------------------------------------------------------------------- /docs/docsets/SwiftyMocky.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MakeAWishFoundation/SwiftyMocky/3672eea08c7098214ac54ee26c7a7e39ea01a2f1/docs/docsets/SwiftyMocky.tgz -------------------------------------------------------------------------------- /docs/img/carat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MakeAWishFoundation/SwiftyMocky/3672eea08c7098214ac54ee26c7a7e39ea01a2f1/docs/img/carat.png -------------------------------------------------------------------------------- /docs/img/dash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MakeAWishFoundation/SwiftyMocky/3672eea08c7098214ac54ee26c7a7e39ea01a2f1/docs/img/dash.png -------------------------------------------------------------------------------- /docs/img/gh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MakeAWishFoundation/SwiftyMocky/3672eea08c7098214ac54ee26c7a7e39ea01a2f1/docs/img/gh.png -------------------------------------------------------------------------------- /docs/img/spinner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MakeAWishFoundation/SwiftyMocky/3672eea08c7098214ac54ee26c7a7e39ea01a2f1/docs/img/spinner.gif -------------------------------------------------------------------------------- /docs/js/jazzy.js: -------------------------------------------------------------------------------- 1 | // Jazzy - https://github.com/realm/jazzy 2 | // Copyright Realm Inc. 3 | // SPDX-License-Identifier: MIT 4 | 5 | window.jazzy = {'docset': false} 6 | if (typeof window.dash != 'undefined') { 7 | document.documentElement.className += ' dash' 8 | window.jazzy.docset = true 9 | } 10 | if (navigator.userAgent.match(/xcode/i)) { 11 | document.documentElement.className += ' xcode' 12 | window.jazzy.docset = true 13 | } 14 | 15 | function toggleItem($link, $content) { 16 | var animationDuration = 300; 17 | $link.toggleClass('token-open'); 18 | $content.slideToggle(animationDuration); 19 | } 20 | 21 | function itemLinkToContent($link) { 22 | return $link.parent().parent().next(); 23 | } 24 | 25 | // On doc load + hash-change, open any targetted item 26 | function openCurrentItemIfClosed() { 27 | if (window.jazzy.docset) { 28 | return; 29 | } 30 | var $link = $(`a[name="${location.hash.substring(1)}"]`).nextAll('.token'); 31 | $content = itemLinkToContent($link); 32 | if ($content.is(':hidden')) { 33 | toggleItem($link, $content); 34 | } 35 | } 36 | 37 | $(openCurrentItemIfClosed); 38 | $(window).on('hashchange', openCurrentItemIfClosed); 39 | 40 | // On item link ('token') click, toggle its discussion 41 | $('.token').on('click', function(event) { 42 | if (window.jazzy.docset) { 43 | return; 44 | } 45 | var $link = $(this); 46 | toggleItem($link, itemLinkToContent($link)); 47 | 48 | // Keeps the document from jumping to the hash. 49 | var href = $link.attr('href'); 50 | if (history.pushState) { 51 | history.pushState({}, '', href); 52 | } else { 53 | location.hash = href; 54 | } 55 | event.preventDefault(); 56 | }); 57 | 58 | // Clicks on links to the current, closed, item need to open the item 59 | $("a:not('.token')").on('click', function() { 60 | if (location == this.href) { 61 | openCurrentItemIfClosed(); 62 | } 63 | }); 64 | 65 | // KaTeX rendering 66 | if ("katex" in window) { 67 | $($('.math').each( (_, element) => { 68 | katex.render(element.textContent, element, { 69 | displayMode: $(element).hasClass('m-block'), 70 | throwOnError: false, 71 | trust: true 72 | }); 73 | })) 74 | } 75 | -------------------------------------------------------------------------------- /docs/js/jazzy.search.js: -------------------------------------------------------------------------------- 1 | // Jazzy - https://github.com/realm/jazzy 2 | // Copyright Realm Inc. 3 | // SPDX-License-Identifier: MIT 4 | 5 | $(function(){ 6 | var $typeahead = $('[data-typeahead]'); 7 | var $form = $typeahead.parents('form'); 8 | var searchURL = $form.attr('action'); 9 | 10 | function displayTemplate(result) { 11 | return result.name; 12 | } 13 | 14 | function suggestionTemplate(result) { 15 | var t = '
'; 16 | t += '' + result.name + ''; 17 | if (result.parent_name) { 18 | t += '' + result.parent_name + ''; 19 | } 20 | t += '
'; 21 | return t; 22 | } 23 | 24 | $typeahead.one('focus', function() { 25 | $form.addClass('loading'); 26 | 27 | $.getJSON(searchURL).then(function(searchData) { 28 | const searchIndex = lunr(function() { 29 | this.ref('url'); 30 | this.field('name'); 31 | this.field('abstract'); 32 | for (const [url, doc] of Object.entries(searchData)) { 33 | this.add({url: url, name: doc.name, abstract: doc.abstract}); 34 | } 35 | }); 36 | 37 | $typeahead.typeahead( 38 | { 39 | highlight: true, 40 | minLength: 3, 41 | autoselect: true 42 | }, 43 | { 44 | limit: 10, 45 | display: displayTemplate, 46 | templates: { suggestion: suggestionTemplate }, 47 | source: function(query, sync) { 48 | const lcSearch = query.toLowerCase(); 49 | const results = searchIndex.query(function(q) { 50 | q.term(lcSearch, { boost: 100 }); 51 | q.term(lcSearch, { 52 | boost: 10, 53 | wildcard: lunr.Query.wildcard.TRAILING 54 | }); 55 | }).map(function(result) { 56 | var doc = searchData[result.ref]; 57 | doc.url = result.ref; 58 | return doc; 59 | }); 60 | sync(results); 61 | } 62 | } 63 | ); 64 | $form.removeClass('loading'); 65 | $typeahead.trigger('focus'); 66 | }); 67 | }); 68 | 69 | var baseURL = searchURL.slice(0, -"search.json".length); 70 | 71 | $typeahead.on('typeahead:select', function(e, result) { 72 | window.location = baseURL + result.url; 73 | }); 74 | }); 75 | -------------------------------------------------------------------------------- /fastlane/Fastfile: -------------------------------------------------------------------------------- 1 | fastlane_version "2.51.0" 2 | 3 | default_platform :ios 4 | 5 | platform :ios do 6 | desc "Runs all the tests" 7 | lane :test do 8 | scan( 9 | scheme: "Mocky_Tests_iOS", 10 | workspace: "./SwiftyMocky.xcworkspace", 11 | devices: ["iPhone 11 Pro"] 12 | ) 13 | end 14 | end 15 | 16 | platform :tvos do 17 | desc "Runs all the tests" 18 | lane :test do 19 | scan( 20 | scheme: "Mocky_Tests_tvOS", 21 | workspace: "./SwiftyMocky.xcworkspace", 22 | devices: ["Apple TV"] 23 | ) 24 | end 25 | end 26 | 27 | platform :mac do 28 | desc "Runs all the tests" 29 | lane :test do 30 | scan(scheme: "Mocky_Tests_macOS") 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /fastlane/README.md: -------------------------------------------------------------------------------- 1 | fastlane documentation 2 | ================ 3 | # Installation 4 | 5 | Make sure you have the latest version of the Xcode command line tools installed: 6 | 7 | ``` 8 | xcode-select --install 9 | ``` 10 | 11 | Install _fastlane_ using 12 | ``` 13 | [sudo] gem install fastlane -NV 14 | ``` 15 | or alternatively using `brew install fastlane` 16 | 17 | # Available Actions 18 | ## iOS 19 | ### ios test 20 | ``` 21 | fastlane ios test 22 | ``` 23 | Runs all the tests 24 | 25 | ---- 26 | 27 | ## tvos 28 | ### tvos test 29 | ``` 30 | fastlane tvos test 31 | ``` 32 | Runs all the tests 33 | 34 | ---- 35 | 36 | ## Mac 37 | ### mac test 38 | ``` 39 | fastlane mac test 40 | ``` 41 | Runs all the tests 42 | 43 | ---- 44 | 45 | This README.md is auto-generated and will be re-generated every time [fastlane](https://fastlane.tools) is run. 46 | More information about fastlane can be found on [fastlane.tools](https://fastlane.tools). 47 | The documentation of fastlane can be found on [docs.fastlane.tools](https://docs.fastlane.tools). 48 | -------------------------------------------------------------------------------- /fastlane/certs.sh: -------------------------------------------------------------------------------- 1 | openssl aes-256-cbc -k "$SECURITY_PASSWORD" -in certs/swifty-mocky-mac-dev.enc -d -a -out certs/swifty-mocky-mac-dev.p12 2 | security create-keychain -p $SECURITY_PASSWORD mac-build.keychain 3 | security default-keychain -s mac-build.keychain 4 | security unlock-keychain -p $SECURITY_PASSWORD mac-build.keychain 5 | security set-keychain-settings -t 600 -l ~/Library/Keychains/mac-build.keychain 6 | security import ./certs/swifty-mocky-mac-dev.p12 -k mac-build.keychain -P $SECURITY_PASSWORD -A 7 | security set-key-partition-list -S apple-tool:,apple: -s -k $SECURITY_PASSWORD mac-build.keychain > /dev/null 8 | -------------------------------------------------------------------------------- /guides/Add XCode generate action.md: -------------------------------------------------------------------------------- 1 | # Adding generate action to XCode 2 | 3 | Following these few simple steps, you can integrate mock generation with XCode, triggering it by key shortcut. 4 | 5 | ## 1. Prepare mock shell script 6 | 7 | Create `mock.sh` file in project root directory, that will execute mock generation. We are wrapping all mock tasks in Rakefile, so we can just trigger `rake mock`. 8 | 9 | // mock.sh 10 | ```bash 11 | #!/bin/sh 12 | 13 | swiftymocky generate 14 | ``` 15 | 16 | Make it executable, by executing in terminal: 17 | 18 | ``` 19 | chmod +x mock.sh 20 | ``` 21 | 22 | ## 2. Add XCode behavior with key bindings 23 | 24 | 1. Open settings (`⌘ ,`) 25 | 1. Navigate to `Behaviors` tab 26 | 1. Tap little `+` on bottom of the behaviors list 27 | 1. Name your behavior (like "Generate Mock") 28 | 1. Press `⌘` (cmd) icon on the right part of added behavior entry. 29 | 1. Record shortcut 30 | 1. Select `Run` checkbox 31 | 1. Choose script from disk (If it is grayed out - it means it is not enabled to be executed. Look to step 1) 32 | 1. [optional] change sound notification, which will play when mock generation is finished 33 | 34 | ![Adding generate behavior][guide-add-generate] 35 | 36 | ## 3. Useage 37 | 38 | Execute recorded shortcut, and watch stuff being done :) 39 | 40 | 41 | 42 | [guide-add-generate]: ../guides/assets/guide-add-generate.gif "Adding generation behavior" 43 | -------------------------------------------------------------------------------- /guides/Command Line Interface.md: -------------------------------------------------------------------------------- 1 | # Command Line Interface 2 | 3 | **SwiftyMocky CLI** is a custom command line tool, writtten in swift, that will simplify setting up mock configuration, validating and troubleshooting configuration and simplify mocks generation. 4 | 5 | CLI is hosted at: [https://github.com/MakeAWishFoundation/SwiftyMocky](https://github.com/MakeAWishFoundation/SwiftyMockyCLI) 6 | 7 | ## Installation: 8 | 9 | Please refer to [Guides/Installation.md](./Installation.md#installation-cli) 10 | 11 | ## Usage: 12 | 13 | ```bash 14 | // From cloned repo main dir 15 | $ swift run swiftymocky 16 | 17 | // From Pods 18 | $ ./Pods/SwiftyMocky/bin/swiftymocky 19 | 20 | // Using mint 21 | $ mint run MakeAWishFoundation/SwiftyMocky 22 | ``` 23 | 24 | ## Commands: 25 | 26 | + `init` - Creates template of Mockfile to fill 27 | + `generate` - generate mocks. Usage 'swiftymocky options optional-mock-name'. Allowed flags: 28 | + `--disableCache`: disables using cahche 29 | + `--verbose`, `-v`: additional sourcery debug info 30 | + `--watch`, `-w`: run in watcher mode, allowed only if mock name specified 31 | + `watch` - run in watcher mode, allowed only if mock name specified 32 | + `setup` - if more than one xcodeproj in directory, add a selected project path: `mocky setup .xcodeproj` 33 | + `migrate` - migrate existing SwiftyMocky yml configurations into Mockfile™ 34 | + `autoimport` - scans sources and automatically resolves imports for the mocks 35 | + `doctor` - run to inspect status of SwiftyMocky setup 36 | 37 | -------------------------------------------------------------------------------- /guides/Contents.md: -------------------------------------------------------------------------------- 1 | # SwiftyMocky 2 | 3 | ## Main guides 4 | 5 | 1. [Overview](./Overview.md) 6 | 1. [Installation](./Installation.md) 7 | 1. [Setup in project](./Setup%20in%20project.md) 8 | 1. [Command Line Interface](./Command%20Line%20Interface.md) 9 | 1. [Mockfile](./Mockfile.md) 10 | 1. [Supported Features](./Supported%20features.md) 11 | 1. [Prototyping](./Prototyping.md) 12 | 13 | ## Other: 14 | 15 | 1. [Changelog](./CHANGELOG.md) 16 | 1. [Legacy setup](./Legacy.md) 17 | 1. [Matcher - support for not Equatable](./Matcher%20support%20for%20not%20Equatable.md) 18 | 1. [Handling Generics](./Handling%20Generics.md) 19 | 1. [Custom subspec - for non XCTest dependent targets](./Custom%20Subspec.md) 20 | 1. [Examples](./Examples.md) 21 | 1. [Add generate action to XCode](./Add%20XCode%20generate%20action.md) 22 | 1. [Known issues](./Known%20issues.md) 23 | -------------------------------------------------------------------------------- /guides/Installation.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # SwiftyMocky CLI 4 | 5 | CLI will help you with project setup and mocks generation. Also, it supports new **Mockfile** format. 6 | 7 | To install it: 8 | 9 | **[Mint 🌱](https://github.com/yonaskolb/Mint)**: 10 | 11 | ```bash 12 | > brew install mint 13 | > mint install MakeAWishFoundation/SwiftyMocky 14 | ``` 15 | 16 | **[Marathon 🏃](https://github.com/JohnSundell/Marathon)**: 17 | 18 | ```bash 19 | > marathon install MakeAWishFoundation/SwiftyMocky 20 | ``` 21 | 22 | **Make**: 23 | 24 | Clone from https://github.com/MakeAWishFoundation/SwiftyMockyCLI and run `make` in the root directory. 25 | 26 | > More information about **CLI** you will fund in "Command Line Interface" section. 27 | 28 | 29 | 30 | # SwiftyMocky Runtime installation 31 | 32 | SwiftyMocky Runtime is available through: 33 | 34 | ## 1. [CocoaPods](http://cocoapods.org). 35 | 36 | To install it, simply add the following line to your Podfile: 37 | 38 | ```ruby 39 | pod "SwiftyMocky" 40 | ``` 41 | 42 | Then execute `pod install` 43 | 44 | The integration part is described in setup page. 45 | 46 | 47 | 48 | ## 2. [Carthage](https://github.com/Carthage/Carthage). 49 | 50 | To install, add following to you Cartfile: 51 | 52 | ```ruby 53 | github "MakeAWishFoundation/SwiftyMocky" 54 | ``` 55 | 56 | Then execute `carthage update` 57 | 58 | For Carthage, few additional steps are required: 59 | 60 | 1. In your test target, add SwiftyMocky to linked libraries: 61 | 62 | ![Link binary][example-link] 63 | 64 | 2. In your test target, add new copy files phase: 65 | 66 | ![Link binary][example-add] 67 | 68 | 3. Select destination to frameworks, and add SwiftyMocky: 69 | 70 | ![Link binary][example-copy] 71 | 72 | The integration part is described in setup page. 73 | 74 | 75 | ## 3. **[Ice Package Manager ❄️](https://github.com/jakeheis/Ice)**: 76 | 77 | ```bash 78 | > ice add MakeAWishFoundation/SwiftyMocky 79 | ``` 80 | 81 | > It will be supported when Ice reviews PR, fallback to SwiftPM if any issues. 82 | 83 | ## 4. **[Swift Package Manager](https://swift.org/package-manager/)**: 84 | 85 | Add **SwiftyMocky** to you **Package.swift** dependencies: 86 | 87 | ```swift 88 | dependencies: [ 89 | .package(url: "https://github.com/MakeAWishFoundation/SwiftyMocky", from: "4.2.0"), 90 | ] 91 | ``` 92 | 93 | And add `SwiftyMocky` to your test target dependencies. 94 | 95 | ## Support for other swift versions 96 | 97 | Download/build Sourcery binary manually, or use prebuilt sourcery versions from: `https://github.com/MakeAWishFoundation/SwiftyMocky.wiki.git` 98 | 99 | Currentyly we support: 100 | - 5.0 101 | - 4.2 102 | - 4.1 103 | 104 | 105 | 106 | [example-link]: https://raw.githubusercontent.com/MakeAWishFoundation/SwiftyMocky/3.2.0/guides/assets/link-binary-with-libraries.png "Example - link binary" 107 | [example-add]: https://raw.githubusercontent.com/MakeAWishFoundation/SwiftyMocky/3.2.0/guides/assets/add-new-copy-files-phase.png "Example - add copy files phase" 108 | [example-copy]: https://raw.githubusercontent.com/MakeAWishFoundation/SwiftyMocky/3.2.0/guides/assets/add-framework-tocopy-files-phase.png "Example - add SwiftyMocky to copy frameworks" 109 | -------------------------------------------------------------------------------- /guides/Known issues.md: -------------------------------------------------------------------------------- 1 | # Known issues 2 | 3 | **Please always check, if your problem is not related to feature being not supported** - for that we have **"Supported Features"** section. 4 | 5 | ----- 6 | 7 | ## 1. Ambiguity caused by multiple modules 8 | 9 | Considering situation as following: 10 | 11 | 12 | ```swift 13 | // Module A 14 | class Entity { /*..*/ } 15 | ``` 16 | 17 | ```swift 18 | // Module B 19 | class Entity { /*..*/ } 20 | ``` 21 | 22 | ```swift 23 | // App 24 | import A 25 | 26 | class Entity { /*..*/ } // Shadows entity 27 | 28 | protocol ToBeMocked { 29 | func convert(_ entity: Entity) -> A.Entity // It is App.Entity -> A.Entity 30 | } 31 | ``` 32 | 33 | ```swift 34 | import B 35 | 36 | protocol OtherProtocol { 37 | func isValid(_ entity: Entity) -> Bool // It is B.Entity 38 | } 39 | ``` 40 | 41 | In the generated mock, `Entity` would be on "the same level" as `A.Entity` and `B.Entity`, so generated mocks would have ambigious types. Similar happend if two There are two ways to resolve that: 42 | 43 | 1. Use full names if possible, so `B.Entity` instead of just `Entity` 44 | 2. Use additional annotation above protocol or method, to tell SwiftyMocky to translate types: `//sourcery: typealias = "Entity = B.Entity"` for example. 45 | 46 | ## 1. When triggering generation - error about modules in different swift versions appears 47 | 48 | This seems to be a problem with Swift abi. Either download/build Sourcery binary manually, or use prebuilt sourcery versions from: `https://github.com/MakeAWishFoundation/SwiftyMocky.wiki.git` 49 | 50 | The best solution is to install **SwiftyMocky CLI** and **mint**, and generate with `swiftymocky generate` 51 | 52 | ## 2. Matcher [FATAL] error for Equatable / Sequence types 53 | 54 | This happens usually for generic mocks - seems that wrapping generic methods causes breaking default resolving of generic contraints, and you might end up seeing something like `[FATAL] No registered matcher comparator for ` even when ValueType conforms to Equatable, or is a Collection of objects conforming to Equatable. 55 | 56 | As for now - the only valid solution is to add comparators for these types. There are convenience methods on matcher, that allows simple adding of comparators for types conforming to Equatable or Sequence. 57 | 58 | See **Generics** section for more informations. 59 | 60 | ## 3. Generated Mock breaks 61 | 62 | When methods has labels or attributes names that are either escaped using \`, or are matching Swift keywords like `for, while, guard ...`. For now - we advise not to use that. It will be resolved in the future. 63 | -------------------------------------------------------------------------------- /guides/Matcher support for not Equatable.md: -------------------------------------------------------------------------------- 1 | # Matcher - handling parameters that are not Equatable 2 | 3 | In some cases there is a need to specify return value (by `Given`) for a method, which parameters are not __*Equatable*__, or check (by Verify), whether a method was called with specific attribute which is not __*Equatable*__. 4 | 5 | If you try to perform Given or Verify for explicit parameter, whereas its type is not Equatable, **fatalError** will occur. There are two options to handle attributes types, that are not __*Equatable*__: 6 | 7 | **1) Use only wildcard .any parameters, or adopt Equatable** 8 | 9 | Sometimes .any is enough, or you can provide Equatable implementation. 10 | 11 | **2) Register comparator for that type in Matcher** 12 | 13 | Every Mock has `matcher` variable, which is `Matcher.default` singleton instance by default. 14 | 15 | Usage of **Matcher**: 16 | 17 | ```swift 18 | struct User { 19 | let id: String 20 | let name: String 21 | } 22 | 23 | // ... 24 | 25 | override func setUp() { 26 | // register all comparators for custom, non equatable attributes 27 | Matcher.default.register(User.self) { lhs,rhs -> Bool in 28 | return lhs.id == rhs.id 29 | } 30 | } 31 | 32 | func testFetchUserDetails() { 33 | //... 34 | let john = User(id: "Johny123", name: "Johny") 35 | // now we can safely verify explicit parameter 36 | Verify(mockNetwork, .fetchUserDetails(for: .value(john))) 37 | } 38 | ``` 39 | 40 | In most cases, you don't have to register comparators for Equatable and Sequence types (as long as Sequence Elememnt is Equatable) 41 | 42 | ## Matcher for generic methods in Mocks 43 | 44 | As generic methods and mocks are breaking generic constraints, for that particular case you also have to register comparators for Equatable / Sequence types. 45 | 46 | There are bunch of convenience registration methods, that will simplify registrations for that case. 47 | 48 | See **Generics** section for more information. 49 | -------------------------------------------------------------------------------- /guides/Mockfile.md: -------------------------------------------------------------------------------- 1 | # **Mockfile** format 2 | 3 | Mockfile is a YAML configuration, allowing to define what gets mocked. It simplifies including and excluding sources, as well as defining what should be imported or `@testable` imported. 4 | 5 | It also ties generated **Mock** configuration with a specific target, allowing to lint it agains most common issues. 6 | 7 | Every generated file have its own section, following pattern below: 8 | 9 | ```yaml 10 | sourceryCommand: null # 1. (optional) 11 | sourceryTemplate: null # 1. (optional) 12 | 13 | mock1: # 2. 14 | sources: # 2.1. 15 | include: # 2.1.1 16 | - ./MyApp 17 | exclude: [] # 2.1.2 (optional) 18 | output: # 2.2 19 | ./MyAppUnitTests/Mocks/Mock.generated.swift 20 | targets: # 2.3 (optional) 21 | - MyAppUnitTests 22 | testable: [] # 2.4 (optional) 23 | import: [] # 2.5 (optional) 24 | prototype: false # 2.6 (optional) 25 | sourcery: # 2.7 (optional) 26 | - ./path/to/custom/sourcery.yml # (optional) 27 | 28 | mock2: # 2. 29 | ... 30 | ``` 31 | 32 | 1. `sourceryCommand` is by default `nil`. You can use it to select custom Sourcery version/command/binary, instead of using default one bundled with SwiftyMocky CLI via `mint`. `sourceryTemplate` is custpom template location to use instead of default one. Default template would be derived from Pods,Carthage,SPM directory. If not found, CLI would use bundled template. 33 | 2. **Distinctive name** of your mock configuration. You can define as much **configurations** as you want. Each of them represents one generated file. That allows to have a separate mocks for a separate targets (you usually need that if you have more than one test target) 34 | 1. `sources` defines what files/directories would be scanned for `AutoMockable` types. 35 | 1. `include` list of included files/directories relative to project root 36 | 2. `exclude` list of excluded files/directories relative to project root 37 | 2. `output` location and name of generated mocks file. If no name specified "Mock.generated.swift" would be used 38 | 3. `targets` list of targets names. It should match the test targets that are using generated mocks file. Used to determine if your setup is correct. 39 | 4. `testable` list of testable modules imports. By default, if you generate mocks for `YourApp`, it should contain `YourApp`. Would be placed at the top of the generated file. 40 | 5. `import` list of modules imports. Would be placed at the top of the generated file. 41 | 6. `prototype` default is `false`. Set `true` if you are going to use Carthage `SwiftyPrototype` library 42 | 7. `sourcery` list of paths to additional Sourcery configurations, if you want to execute them alongside the mock generation. 43 | 44 | > **Note 1:** Calling `swiftymocky setup` will launch an interactive tool helping you to create and prefill the **Mockfile**. You can also use `swiftymocky init` if you want a placeholder you can fill manually. 45 | 46 | > **Note 2:** To evaluate your **Mockfile** setup, as well as other things, run `swiftmocky doctor`. 47 | 48 | > **Note 3:** You can use `swiftymocky autoimport` to prefill `testable` and `import` in your configurations. -------------------------------------------------------------------------------- /guides/Prototyping.md: -------------------------------------------------------------------------------- 1 | # **Prototyping** 2 | 3 | It is possible to use **SwiftyMocky** not in tests, but to fake/prototype inside application (works on device). 4 | 5 | For this reason, there is an additional library extracted from **Swiftymocky**, that does not rely on XCTest framework. 6 | 7 | Installation and generation is exactly same as with **SwiftyMocky**. Install CLI and inegrate runtime, via one of the options below, and mark target in [Mockfile](./Mockfile.md) with `prototype: true` 8 | 9 | ## Installation 10 | 11 | ## 1. [CocoaPods](http://cocoapods.org). 12 | 13 | To install it, simply add the following line to your Podfile: 14 | 15 | ```ruby 16 | pod "SwiftyPrototype" 17 | ``` 18 | 19 | Then execute `pod install` 20 | 21 | ## 2. [Carthage](https://github.com/Carthage/Carthage). 22 | 23 | To install, add following to you Cartfile: 24 | 25 | ```ruby 26 | github "MakeAWishFoundation/SwiftyMocky" 27 | ``` 28 | 29 | Then execute `carthage update` and add `SwiftyPrototype` to your target. 30 | 31 | ### 3. **[Swift Package Manager](https://swift.org/package-manager/)**: 32 | 33 | Add **SwiftyPrototype** to you **Package.swift** dependencies: 34 | 35 | ```swift 36 | dependencies: [ 37 | .package(url: "https://github.com/MakeAWishFoundation/SwiftyMocky", from: "4.0.1"), 38 | ] 39 | ``` 40 | 41 | And add `SwiftyPrototype` to your target dependencies. 42 | -------------------------------------------------------------------------------- /guides/Setup in project.md: -------------------------------------------------------------------------------- 1 | # How to setup SwiftyMocky 2 | 3 | First, install **CLI** as described in "Command Line Interface" section. 4 | 5 | Then, you can use: 6 | 7 | ```bash 8 | > swiftymocky setup # For automatic setup (preferred) 9 | ``` 10 | 11 | or 12 | 13 | ```bash 14 | > swiftymocky init # Just generate placeholder for Mockfile you can fill manually 15 | ``` 16 | 17 | > It is also worth to look into "Mockfile" section. 18 | 19 | ## Generate mocks: 20 | 21 | [Annotate your protocols](#mock-annotate) that are going to be mocked, making them adopt `AutoMockable` protocol, or adding annotation comment above their definition in the source code. 22 | 23 | Mocks are generated from your project root directory, based on configuration inside **Mockfile**. 24 | 25 | ```bash 26 | > swiftymocky doctor # validate your setup 27 | > swiftymocky generate # generate mocks 28 | ``` 29 | 30 | **Don't forget** to add generated files like `Mock.generated.swift` to your test target :) 31 | 32 | 33 | 34 | ## Marking protocols to be mocked 35 | 36 | ### **1. AutoMockable protocol** 37 | 38 | Create dummy protocol for you project: 39 | 40 | ```swift 41 | protocol AutoMockable { } 42 | ``` 43 | 44 | Every protocol in source directories, inheriting (directly!) from AutoMockable, will be added to `Mock.generated.swift`, like: 45 | 46 | ```swift 47 | protocol ToBeMocked: AutoMockable { 48 | // ... 49 | } 50 | ``` 51 | 52 | ### **2. AutoMockable annotation** 53 | 54 | Mark protocols that are meant to be mocked with sourcery annotation as following: 55 | 56 | ```swift 57 | //sourcery: AutoMockable 58 | protocol ToBeMocked { 59 | // ... 60 | } 61 | ``` 62 | 63 | Every protocol in source directories, having this annotation, will be added to `Mock.generated.swift` 64 | 65 | @objc protocols are also supported, but needs to be explicitly marked with ObjcProtocol annotation: 66 | 67 | ```swift 68 | //sourcery: AutoMockable 69 | //sourcery: ObjcProtocol 70 | @objc protocol NonSwiftProtocol { 71 | // ... 72 | } 73 | ``` 74 | 75 | ### **3. Manual annotation** 76 | 77 | In some rare cases, when you don't want to use `Mock.generated.swift`, or need to add some additional code to generated mock, you can create base for mock implementation yourself. It will look something like following: 78 | 79 | ```swift 80 | import Foundation 81 | import SwiftyMocky 82 | import XCTest 83 | @testable import TestedApp 84 | 85 | // sourcery: mock = "ToBeMocked" 86 | class SomeCustomMock: ToBeMocked, Mock { 87 | Your custom code can go here 88 | 89 | // sourcery:inline:auto:ToBeMocked.autoMocked 90 | 91 | Generated code goes here... 92 | 93 | // sourcery:end 94 | } 95 | ``` 96 | 97 | > __Note:__ 98 | > Please have in mind, that definition of MockyAssert used in generated mocks is placed in `Mock.generated.swift`. Even when using only manual annotations, please add this file to your target. 99 | -------------------------------------------------------------------------------- /guides/assets/add-framework-tocopy-files-phase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MakeAWishFoundation/SwiftyMocky/3672eea08c7098214ac54ee26c7a7e39ea01a2f1/guides/assets/add-framework-tocopy-files-phase.png -------------------------------------------------------------------------------- /guides/assets/add-new-copy-files-phase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MakeAWishFoundation/SwiftyMocky/3672eea08c7098214ac54ee26c7a7e39ea01a2f1/guides/assets/add-new-copy-files-phase.png -------------------------------------------------------------------------------- /guides/assets/example-given.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MakeAWishFoundation/SwiftyMocky/3672eea08c7098214ac54ee26c7a7e39ea01a2f1/guides/assets/example-given.gif -------------------------------------------------------------------------------- /guides/assets/example-verify.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MakeAWishFoundation/SwiftyMocky/3672eea08c7098214ac54ee26c7a7e39ea01a2f1/guides/assets/example-verify.gif -------------------------------------------------------------------------------- /guides/assets/example-watcher.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MakeAWishFoundation/SwiftyMocky/3672eea08c7098214ac54ee26c7a7e39ea01a2f1/guides/assets/example-watcher.gif -------------------------------------------------------------------------------- /guides/assets/guide-add-generate.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MakeAWishFoundation/SwiftyMocky/3672eea08c7098214ac54ee26c7a7e39ea01a2f1/guides/assets/guide-add-generate.gif -------------------------------------------------------------------------------- /guides/assets/link-binary-with-libraries.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MakeAWishFoundation/SwiftyMocky/3672eea08c7098214ac54ee26c7a7e39ea01a2f1/guides/assets/link-binary-with-libraries.png -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MakeAWishFoundation/SwiftyMocky/3672eea08c7098214ac54ee26c7a7e39ea01a2f1/icon.png --------------------------------------------------------------------------------