Repository: Skyscanner/Dixie Branch: master Commit: 292923f6802c Files: 193 Total size: 1004.8 KB Directory structure: gitextract_dxkqxvqx/ ├── .gitignore ├── .travis.yml ├── CONTRIBUTING.md ├── Dixie/ │ ├── Dixie/ │ │ ├── ChaosProvider/ │ │ │ ├── BlockChaosProvider/ │ │ │ │ ├── DixieBlockChaosProvider.h │ │ │ │ └── DixieBlockChaosProvider.m │ │ │ ├── CompositeChaosProvider/ │ │ │ │ ├── DixieCompositeChaosProvider.h │ │ │ │ ├── DixieCompositeChaosProvider.m │ │ │ │ ├── DixieCompositeCondition.h │ │ │ │ └── DixieCompositeCondition.m │ │ │ ├── ConstantChaosProvider/ │ │ │ │ ├── DixieConstantChaosProvider.h │ │ │ │ └── DixieConstantChaosProvider.m │ │ │ ├── DixieBaseChaosProvider.h │ │ │ ├── DixieBaseChaosProvider.m │ │ │ ├── DixieChaosContext.h │ │ │ ├── DixieChaosContext.m │ │ │ ├── ExceptionChaosProvider/ │ │ │ │ ├── DixieExceptionChaosProvider.h │ │ │ │ └── DixieExceptionChaosProvider.m │ │ │ ├── NilChaosProvider/ │ │ │ │ ├── DixieNilChaosProvider.h │ │ │ │ └── DixieNilChaosProvider.m │ │ │ ├── NonChaosProvider/ │ │ │ │ ├── DixieNonChaosProvider.h │ │ │ │ └── DixieNonChaosProvider.m │ │ │ ├── RandomChaosProvider/ │ │ │ │ ├── DixieRandomChaosProvider.h │ │ │ │ └── DixieRandomChaosProvider.m │ │ │ └── SequentialChaosProvider/ │ │ │ ├── DixieSequentialChaosProvider.h │ │ │ └── DixieSequentialChaosProvider.m │ │ ├── Dixie+Fluent/ │ │ │ ├── Dixie+Fluent.h │ │ │ └── Dixie+Fluent.m │ │ ├── Dixie.h │ │ ├── Dixie.m │ │ ├── DixieHeaders.h │ │ ├── DixieLogger/ │ │ │ ├── DixieLogger.h │ │ │ ├── DixieLogger.m │ │ │ └── SimpleLogger/ │ │ │ ├── DixieSimpleLogger.h │ │ │ └── DixieSimpleLogger.m │ │ ├── MethodInfo/ │ │ │ ├── DixieMethodInfo.h │ │ │ └── DixieMethodInfo.m │ │ ├── ParamProvider/ │ │ │ ├── DixieBaseParamProvider.h │ │ │ ├── DixieBaseParamProvider.m │ │ │ └── RandomParamProvider/ │ │ │ ├── DixieRandomParamProvider.h │ │ │ └── DixieRandomParamProvider.m │ │ ├── ProfileEntry/ │ │ │ ├── DixieProfileEntry.h │ │ │ └── DixieProfileEntry.m │ │ ├── PuppetMaker/ │ │ │ ├── DixieDefaultPuppetMaker.h │ │ │ ├── DixieDefaultPuppetMaker.m │ │ │ └── DixiePuppetMaking.h │ │ └── Runtime/ │ │ ├── DixieCallEnvironment.h │ │ ├── DixieCallEnvironment.m │ │ ├── DixieRunTimeHelper.h │ │ ├── DixieRunTimeHelper.m │ │ ├── NSObject+DixieRunTimeHelper.h │ │ └── NSObject+DixieRunTimeHelper.m │ ├── Dixie.xcodeproj/ │ │ ├── project.pbxproj │ │ ├── project.xcworkspace/ │ │ │ └── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── xcschemes/ │ │ ├── Dixie.xcscheme │ │ └── DixieTests.xcscheme │ └── DixieTests/ │ ├── Helpers/ │ │ ├── ChaosProviderTestClass.h │ │ ├── ChaosProviderTestClass.m │ │ ├── SubTestClass.h │ │ ├── SubTestClass.m │ │ ├── TestClass.h │ │ ├── TestClass.m │ │ ├── TestPuppetMaker.h │ │ └── TestPuppetMaker.m │ ├── Info.plist │ ├── Predefined profiles/ │ │ ├── NSDateProfile.h │ │ ├── NSDateProfile.m │ │ ├── NSURLConnectionProfile.h │ │ ├── NSURLConnectionProfile.m │ │ ├── NSURLProfile.h │ │ └── NSURLProfile.m │ └── Units/ │ ├── DixieAPITests.m │ ├── DixieChaosProviderTests.m │ ├── ProfileEntryTests.m │ ├── RandomParamProviderTests.m │ └── RunTimeHelperTests.m ├── Dixie.podspec ├── DixieBasicChaos.codesnippet ├── DixieExampleApp/ │ ├── DixieExampleApp/ │ │ ├── AppDelegate.h │ │ ├── AppDelegate.m │ │ ├── Base.lproj/ │ │ │ ├── LaunchScreen.xib │ │ │ └── Main.storyboard │ │ ├── CountDownViewController.h │ │ ├── CountDownViewController.m │ │ ├── Images.xcassets/ │ │ │ └── AppIcon.appiconset/ │ │ │ └── Contents.json │ │ ├── Info.plist │ │ ├── MapViewController.h │ │ ├── MapViewController.m │ │ ├── WeatherModel.h │ │ ├── WeatherModel.m │ │ ├── WeatherViewController.h │ │ ├── WeatherViewController.m │ │ └── main.m │ ├── DixieExampleApp.xcodeproj/ │ │ ├── project.pbxproj │ │ └── project.xcworkspace/ │ │ └── contents.xcworkspacedata │ ├── DixieExampleApp.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── Podfile ├── Documentation/ │ ├── docset/ │ │ └── Contents/ │ │ ├── Info.plist │ │ └── Resources/ │ │ ├── Documents/ │ │ │ ├── Blocks/ │ │ │ │ ├── DixieCustomChaosBlock.html │ │ │ │ └── DixieImplementationBlock.html │ │ │ ├── Categories/ │ │ │ │ └── NSObject+DixieRunTimeHelper.html │ │ │ ├── Classes/ │ │ │ │ ├── Dixie.html │ │ │ │ ├── DixieBaseChaosProvider.html │ │ │ │ ├── DixieBaseParamProvider.html │ │ │ │ ├── DixieBlockChaosProvider.html │ │ │ │ ├── DixieCallEnvironment.html │ │ │ │ ├── DixieChaosContext.html │ │ │ │ ├── DixieCompositeChaosProvider.html │ │ │ │ ├── DixieCompositeCondition.html │ │ │ │ ├── DixieConstantChaosProvider.html │ │ │ │ ├── DixieDefaultPuppetMaker.html │ │ │ │ ├── DixieExceptionChaosProvider.html │ │ │ │ ├── DixieLogger.html │ │ │ │ ├── DixieMethodInfo.html │ │ │ │ ├── DixieNilChaosProvider.html │ │ │ │ ├── DixieNonChaosProvider.html │ │ │ │ ├── DixieProfileEntry.html │ │ │ │ ├── DixieRandomChaosProvider.html │ │ │ │ ├── DixieRandomParamProvider.html │ │ │ │ ├── DixieRunTimeHelper.html │ │ │ │ ├── DixieSequentialChaosProvider.html │ │ │ │ └── DixieSimpleLogger.html │ │ │ ├── Protocols/ │ │ │ │ └── DixiePuppetMaking.html │ │ │ ├── css/ │ │ │ │ ├── styles.css │ │ │ │ └── stylesPrint.css │ │ │ ├── hierarchy.html │ │ │ └── index.html │ │ ├── Nodes.xml │ │ ├── Tokens1.xml │ │ ├── Tokens10.xml │ │ ├── Tokens11.xml │ │ ├── Tokens12.xml │ │ ├── Tokens13.xml │ │ ├── Tokens14.xml │ │ ├── Tokens15.xml │ │ ├── Tokens16.xml │ │ ├── Tokens17.xml │ │ ├── Tokens18.xml │ │ ├── Tokens19.xml │ │ ├── Tokens2.xml │ │ ├── Tokens20.xml │ │ ├── Tokens21.xml │ │ ├── Tokens22.xml │ │ ├── Tokens23.xml │ │ ├── Tokens24.xml │ │ ├── Tokens25.xml │ │ ├── Tokens3.xml │ │ ├── Tokens4.xml │ │ ├── Tokens5.xml │ │ ├── Tokens6.xml │ │ ├── Tokens7.xml │ │ ├── Tokens8.xml │ │ ├── Tokens9.xml │ │ ├── docSet.dsidx │ │ ├── docSet.dsidx-shm │ │ ├── docSet.dsidx-wal │ │ ├── docSet.mom │ │ ├── docSet.skidx │ │ ├── docSet.toc │ │ └── docSet.tokencache │ ├── docset-installed.txt │ └── html/ │ ├── Blocks/ │ │ ├── DixieCustomChaosBlock.html │ │ └── DixieImplementationBlock.html │ ├── Categories/ │ │ └── NSObject+DixieRunTimeHelper.html │ ├── Classes/ │ │ ├── Dixie.html │ │ ├── DixieBaseChaosProvider.html │ │ ├── DixieBaseParamProvider.html │ │ ├── DixieBlockChaosProvider.html │ │ ├── DixieCallEnvironment.html │ │ ├── DixieChaosContext.html │ │ ├── DixieCompositeChaosProvider.html │ │ ├── DixieCompositeCondition.html │ │ ├── DixieConstantChaosProvider.html │ │ ├── DixieDefaultPuppetMaker.html │ │ ├── DixieExceptionChaosProvider.html │ │ ├── DixieLogger.html │ │ ├── DixieMethodInfo.html │ │ ├── DixieNilChaosProvider.html │ │ ├── DixieNonChaosProvider.html │ │ ├── DixieProfileEntry.html │ │ ├── DixieRandomChaosProvider.html │ │ ├── DixieRandomParamProvider.html │ │ ├── DixieRunTimeHelper.html │ │ ├── DixieSequentialChaosProvider.html │ │ └── DixieSimpleLogger.html │ ├── Protocols/ │ │ └── DixiePuppetMaking.html │ ├── css/ │ │ ├── styles.css │ │ └── stylesPrint.css │ ├── hierarchy.html │ └── index.html ├── LICENSE ├── README.md ├── deploy_docs.sh └── documentation.sh ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ build/ *.pbxuser !default.pbxuser *.mode1v3 !default.mode1v3 *.mode2v3 !default.mode2v3 *.perspectivev3 !default.perspectivev3 xcuserdata *.xccheckout *.moved-aside DerivedData *.hmap *.ipa *.xcuserstate # CocoaPods # # We recommend against adding the Pods directory to your .gitignore. However # you should judge for yourself, the pros and cons are mentioned at: # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control? # Pods/ DixieExampleApp/Pods/ ================================================ FILE: .travis.yml ================================================ language: objective-c script: - xctool -project Dixie/Dixie.xcodeproj -scheme Dixie -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO - xctool test -project Dixie/Dixie.xcodeproj -scheme DixieTests -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO ================================================ FILE: CONTRIBUTING.md ================================================ # Contributing to Dixie If you would like to contribute code you can do so through GitHub by forking the repository and sending a pull request. When submitting code, please make every effort to follow existing conventions and style in order to keep the code as readable as possible. ## Pull requests Before creating a pull request please make sure the following steps are completed: * Make sure to update to the latest version of the master branch and branch out from that to avoid conflicts. * Check that both the Dixie and DixieTests schemes compile successfully. * Check that the unit tests included in the DixieTests scheme all execute successfully. * Check that all use cases in the sample project using the modified version of Dixie are still functioning correctly. * In the case of a new feature all the relevant use cases are covered with new unit tests. * In the case of a bug fix a new unit test covers the use case, which should execute successfully with the fix in place. * New files contain the common license header (please see below). * New classes and methods contain enough documentation to understand their purpose. * Please make sure the pull request contains a meaningful description explaining the problem the change solves and how the solution works. * Please also check that the created pull request's state is green after the validation is completed by Travis CI. ## Issues If you find a bug in the project (and you don’t know how to fix it), have trouble following the documentation or have a question about the project, then please create an issue! Some tips [from the GitHub Guide](https://guides.github.com/activities/contributing-to-open-source/): * Please check existing issues for the problem you're seeing. Duplicating an issue is slower for both parties so search through open and closed issues to see if what you’re running in to has been addressed already. * Be clear about what your problem is: what was the expected outcome, what happened instead? Detail how someone else can recreate the problem. * Include system details like the browser, library or operating system you’re using and its version. * Paste error output or logs in your issue or in a Gist. If pasting them in the issue, wrap it in three backticks: ``` so that it renders nicely. ## Contact In case of major changes please feel free to reach out to the maintainers of the project at any time, so we can figure out the best approach together: * Peter Wiesner (peter.wiesner@skyscanner.net, @WiesnerPeti) * Zsolt Varnai (zsolt.varnai@skyscanner.net, @zsoltvarnai) * Csaba Szabo (csaba.szabo@skyscanner.net, @CsabaSzabo) * Zsombor Fuszenecker (zsombor.fuszenecker@skyscanner.net, @zsbee) ## License By contributing your code, you agree to license your contribution under the terms of the APLv2: https://github.com/Skyscanner/Dixie/blob/master/LICENSE All files are released with the Apache 2.0 license. If you are adding a new file it should have a header like this: ``` // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. ``` ================================================ FILE: Dixie/Dixie/ChaosProvider/BlockChaosProvider/DixieBlockChaosProvider.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "DixieBaseChaosProvider.h" /** * Block type, that can describe a method implementation * * @param chaosProvider The DixieBaseChaosProvider, who is calling this block (to avoid retain cycles) * @param victim The class or instance of the class, that's method chould be changed * @param environment A DixieCallEnvironment, that describes the arguments and return value */ typedef void(^DixieCustomChaosBlock)(DixieBaseChaosProvider* chaosProvider,id victim, DixieCallEnvironment* environment); /** * Provides a behaviour, where the original method's implementation can be replaced by a custom block */ @interface DixieBlockChaosProvider : DixieBaseChaosProvider /** * Creates an instance of DixieBlockChaosProvider * * @param block The block, that should be called as the method's implementation * * @return a new instance of DixieBlockChaosProvider */ +(instancetype) block:(DixieCustomChaosBlock)block; @end ================================================ FILE: Dixie/Dixie/ChaosProvider/BlockChaosProvider/DixieBlockChaosProvider.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "DixieBlockChaosProvider.h" @interface DixieBlockChaosProvider (/*Private*/) @property (nonatomic, copy) DixieCustomChaosBlock block; @end @implementation DixieBlockChaosProvider +(instancetype) block:(DixieCustomChaosBlock)block; { DixieBlockChaosProvider* provider = [DixieBlockChaosProvider new]; provider.block = block; return provider; } -(void) chaosImplementationFor:(id)victim environment:(DixieCallEnvironment *)environment { self.block(self,victim, environment); } @end ================================================ FILE: Dixie/Dixie/ChaosProvider/CompositeChaosProvider/DixieCompositeChaosProvider.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "DixieBaseChaosProvider.h" #import "DixieCompositeCondition.h" /** * Provides a behaviour, where the method's implementation can be changed according the passed arguments */ @interface DixieCompositeChaosProvider : DixieBaseChaosProvider /** * Creates a new instance of DixieCompositeChaosProvider * * @param arrayOfConditions an array of DixieCompositeConditions * * @return a new instance of DixieCompositeChaosProvider */ +(instancetype) conditions:(NSArray*)arrayOfConditions; @end ================================================ FILE: Dixie/Dixie/ChaosProvider/CompositeChaosProvider/DixieCompositeChaosProvider.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "DixieCompositeChaosProvider.h" #import "DixieNonChaosProvider.h" @interface DixieCompositeChaosProvider (/*Private*/) @property (nonatomic, strong) NSArray* conditions; @end @implementation DixieCompositeChaosProvider +(instancetype) conditions:(NSArray*)arrayOfConditions { DixieCompositeChaosProvider* provider = [DixieCompositeChaosProvider new]; provider.conditions = arrayOfConditions; return provider; } -(void) setContext:(DixieChaosContext *)context { [super setContext:context]; for (DixieCompositeCondition* condition in self.conditions) { [condition.chaosProvider setContext:context]; } } -(void) chaosImplementationFor:(id)victim environment:(DixieCallEnvironment *)environment { for (DixieCompositeCondition* condition in self.conditions) { id param = environment.arguments[condition.index]; if ([param isEqual:condition.value]) { [self forwardChaosOf:victim environment:environment to:condition.chaosProvider]; return; } } //No condition matched any arguments, so fallback to the original implementation [self forwardChaosOf:victim environment:environment to:[DixieNonChaosProvider new]]; } @end ================================================ FILE: Dixie/Dixie/ChaosProvider/CompositeChaosProvider/DixieCompositeCondition.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. @import Foundation; #import "DixieBaseChaosProvider.h" /** * Describes which chaosProvider should define the method's behaviour if the argument at index, matches the given value. DixieCompositeChaosProvider uses this object to delegate the implementation to different providers. */ @interface DixieCompositeCondition : NSObject /** * The index of the argument to check */ @property (readonly) NSInteger index; /** * The value of the argument we wish to compare */ @property (readonly) id value; /** * The ChaosProvider to apply */ @property (readonly) DixieBaseChaosProvider* chaosProvider; /** * Creates a DixieCompositeCondition * * @param index The index of the argument to check * @param value The value to compare the argument against * @param chaosProvider The DixieChaosProvider to apply, if the argument matches the value * * @return a DixieCompositeCondition */ +(instancetype) condition:(NSInteger)index value:(id)value chaosProvider:(DixieBaseChaosProvider*)chaosProvider; @end ================================================ FILE: Dixie/Dixie/ChaosProvider/CompositeChaosProvider/DixieCompositeCondition.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "DixieCompositeCondition.h" @interface DixieCompositeCondition(/*Private*/) @property NSInteger index; @property id value; @property DixieBaseChaosProvider* chaosProvider; @end @implementation DixieCompositeCondition +(instancetype) condition:(NSInteger)index value:(id)value chaosProvider:(DixieBaseChaosProvider*)chaosProvider { DixieCompositeCondition* condition = [DixieCompositeCondition new]; condition.index = index; condition.value = value; condition.chaosProvider = chaosProvider; return condition; } @end ================================================ FILE: Dixie/Dixie/ChaosProvider/ConstantChaosProvider/DixieConstantChaosProvider.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "DixieBaseChaosProvider.h" /** * Provides a behaviour, where a given constant will be returned from the method's implementation */ @interface DixieConstantChaosProvider : DixieBaseChaosProvider /** * The constant value to return */ @property (readonly) id constant; /** * Creates a DixieConstantChaosProvider * * @param constant The value the DixieConstantChaosProvider will return * * @return a DixieConstantChaosProvider */ +(instancetype) constant:(id)constant; @end ================================================ FILE: Dixie/Dixie/ChaosProvider/ConstantChaosProvider/DixieConstantChaosProvider.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "DixieConstantChaosProvider.h" #import "NSObject+DixieRunTimeHelper.h" @interface DixieConstantChaosProvider() @property (nonatomic, strong) id constant; @end @implementation DixieConstantChaosProvider +(instancetype) constant:(id)constant { DixieConstantChaosProvider* provider = [DixieConstantChaosProvider new]; provider.constant = constant; return provider; } -(void) chaosImplementationFor:(id)victim environment:(DixieCallEnvironment *)environment { if(isType(self.context.methodInfo.signature.methodReturnType, void) == NO) { if(isType(self.context.methodInfo.signature.methodReturnType, id) || strcmp(self.context.methodInfo.signature.methodReturnType, "@?") == 0) { environment.returnValue = (__bridge void *)(self.constant); } else{ environment.returnValue = [(NSObject *)self.constant originalValue]; } } } @end ================================================ FILE: Dixie/Dixie/ChaosProvider/DixieBaseChaosProvider.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. @import Foundation; #import "DixieChaosContext.h" #import "DixieRunTimeHelper.h" @interface DixieBaseChaosProvider : NSObject @property (nonatomic, strong) DixieChaosContext* context; /** * Returns a new behaviour implementation * * @return An implementation pointer */ -(IMP) chaos; /** * Will forward the result of one DixieChaosProvider to the next. * * @param victim The class or instance of the class, that's method should be changed * @param environment A DixieCallEnvironment, that describes the arguments and return value * @param chaosProvider The target DixieBaseChaosProvider, who should provider the behaviour */ -(void) forwardChaosOf:(id)victim environment:(DixieCallEnvironment*)environment to:(DixieBaseChaosProvider*)chaosProvider; /** * The behaviour implementation * * @param victim The class or instance of the class, that's method should be changed * @param environment A DixieCallEnvironment, that describes the arguments and return value */ -(void) chaosImplementationFor:(id) victim environment:(DixieCallEnvironment*)environment; @end ================================================ FILE: Dixie/Dixie/ChaosProvider/DixieBaseChaosProvider.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "DixieBaseChaosProvider.h" #import "DixieLogger.h" @implementation DixieBaseChaosProvider -(IMP) chaos { return [DixieRunTimeHelper implementationWithChaosContext:self.context environment:^(id victim, DixieCallEnvironment *environment) { [self chaosImplementationFor:victim environment:environment]; if(isType(self.context.methodInfo.signature.methodReturnType, id)) { [[DixieLogger defaultLogger] log:@"Puppet %@: %@ used %@ to return %@", NSStringFromClass([victim class]), NSStringFromSelector(self.context.methodInfo.selector), [self class], environment.returnValue]; } }]; } -(void) forwardChaosOf:(id)victim environment:(DixieCallEnvironment*)environment to:(DixieBaseChaosProvider*)chaosProvider { [chaosProvider setContext:self.context]; IMP chaosIMP = [chaosProvider chaos]; SEL selector; if (chaosIMP == self.context.originalIMP) { selector = NSSelectorFromString([DixieMethodPrefix stringByAppendingString:NSStringFromSelector(self.context.methodInfo.selector)]); } else { selector = self.context.methodInfo.selector; } [DixieRunTimeHelper callImplementation:chaosIMP on:victim chaosContext:self.context environment:environment]; } -(void) chaosImplementationFor:(id)victim environment:(DixieCallEnvironment *)environment { @throw [NSException exceptionWithName:@"Method not overriden" reason:@"DixieBaseChaosProvider subclasses should override [BaseChaosProvider chaosImpl:]" userInfo:nil]; } @end ================================================ FILE: Dixie/Dixie/ChaosProvider/DixieChaosContext.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. @import Foundation; #import "DixieMethodInfo.h" /** * Defining the context for the DixieChaosProviders */ @interface DixieChaosContext : NSObject /** * A seed for deterministic behaviour. */ @property (readonly) NSInteger seed; /** * A DixieMethodInfo, that describes the class and one of its method */ @property (readonly) DixieMethodInfo* methodInfo; /** * The original implementation of the class method, described in the methodInfo property. */ @property IMP originalIMP; /** * Creates a DixieChaosContext with a given seed and methodInfo * * @param seed A seed for deterministic behaviour. * @param methodInfo A DixieMethodInfo, that describes the class and one of its method * * @return A DixieChaosContext */ -(instancetype) init:(NSInteger)seed methodInfo:(DixieMethodInfo*)methodInfo; @end ================================================ FILE: Dixie/Dixie/ChaosProvider/DixieChaosContext.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "DixieChaosContext.h" @interface DixieChaosContext(/*Private*/) @property NSInteger seed; @property (nonatomic, strong) DixieMethodInfo* methodInfo; @end @implementation DixieChaosContext -(instancetype) init:(NSInteger)seed methodInfo:(DixieMethodInfo*)methodInfo { if (self = [super init]) { self.seed = seed; self.methodInfo = methodInfo; } return self; } @end ================================================ FILE: Dixie/Dixie/ChaosProvider/ExceptionChaosProvider/DixieExceptionChaosProvider.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "DixieBaseChaosProvider.h" /** * Provides a behaviour, where the method's implementation will always crash on calling */ @interface DixieExceptionChaosProvider : DixieBaseChaosProvider /** * The exception to raise */ @property (readonly) NSException* exception; /** * Creates an DixieExceptionChaosProvider * * @param exception The exception to raise * * @return an DixieExceptionChaosProvider */ +(instancetype) exception:(NSException*)exception; @end ================================================ FILE: Dixie/Dixie/ChaosProvider/ExceptionChaosProvider/DixieExceptionChaosProvider.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "DixieExceptionChaosProvider.h" @interface DixieExceptionChaosProvider() @property (nonatomic, strong) NSException* exception; @end @implementation DixieExceptionChaosProvider +(instancetype) exception:(NSException*)exception { DixieExceptionChaosProvider* provider = [DixieExceptionChaosProvider new]; provider.exception = exception; return provider; } -(void) chaosImplementationFor:(id)victim environment:(DixieCallEnvironment *)environment { [_exception raise]; } @end ================================================ FILE: Dixie/Dixie/ChaosProvider/NilChaosProvider/DixieNilChaosProvider.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "DixieBaseChaosProvider.h" /** * Provides a behaviour, where the method's implementation always returns nil; */ @interface DixieNilChaosProvider : DixieBaseChaosProvider @end ================================================ FILE: Dixie/Dixie/ChaosProvider/NilChaosProvider/DixieNilChaosProvider.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "DixieNilChaosProvider.h" @implementation DixieNilChaosProvider -(void) chaosImplementationFor:(id)victim environment:(DixieCallEnvironment *)environment { environment.returnValue = nil; } @end ================================================ FILE: Dixie/Dixie/ChaosProvider/NonChaosProvider/DixieNonChaosProvider.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "DixieBaseChaosProvider.h" /** * Provides the original behaviour */ @interface DixieNonChaosProvider : DixieBaseChaosProvider @end ================================================ FILE: Dixie/Dixie/ChaosProvider/NonChaosProvider/DixieNonChaosProvider.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "DixieNonChaosProvider.h" @implementation DixieNonChaosProvider -(IMP) chaos { return self.context.originalIMP; } -(void) chaosImplementationFor:(id)victim environment:(DixieCallEnvironment *)environment { [DixieRunTimeHelper callImplementation:self.context.originalIMP on:victim chaosContext:self.context environment:environment]; } @end ================================================ FILE: Dixie/Dixie/ChaosProvider/RandomChaosProvider/DixieRandomChaosProvider.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "DixieBaseChaosProvider.h" #import "DixieRandomParamProvider.h" /** * Provides a behaviour, where the method's implementation returns a random object, generated with a DixieRandomParamProvider */ @interface DixieRandomChaosProvider : DixieBaseChaosProvider /** * Creates a DixieRandomChaosProvider * * @param paramProvider The DixieRandomParamProvider to use as the random object generator * * @return a DixieRandomChaosProvider */ +(instancetype) randomProvider:(DixieRandomParamProvider*)paramProvider; @end ================================================ FILE: Dixie/Dixie/ChaosProvider/RandomChaosProvider/DixieRandomChaosProvider.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "DixieRandomChaosProvider.h" @interface DixieRandomChaosProvider (/*Private*/) @property (nonatomic, strong) DixieRandomParamProvider* paramProvider; @end @implementation DixieRandomChaosProvider +(instancetype) randomProvider:(DixieRandomParamProvider*)paramProvider { DixieRandomChaosProvider* provider = [DixieRandomChaosProvider new]; provider.paramProvider = paramProvider; return provider; } -(void) setContext:(DixieChaosContext *)context { [super setContext:context]; [self.paramProvider setSeed:context.seed]; } -(void) chaosImplementationFor:(id)victim environment:(DixieCallEnvironment *)environment { environment.returnValue = (__bridge void *)([self.paramProvider parameter]); } @end ================================================ FILE: Dixie/Dixie/ChaosProvider/SequentialChaosProvider/DixieSequentialChaosProvider.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "DixieBaseChaosProvider.h" /** * Provides a behaviour, where the method's implementation behaves differently for a new call. The different behaviours depend on the defined different DixieChaosProviders of the class */ @interface DixieSequentialChaosProvider : DixieBaseChaosProvider /** * Creates a DixieSequentialChaosProvider * * @param sequenceOfChaosProviders Array of DixieBaseChaosProvider, the order of the array defines, how the method's implementation will behave for a new call. * * @return a DixieSequentialChaosProvider */ +(instancetype) sequence:(NSArray*)sequenceOfChaosProviders; @end ================================================ FILE: Dixie/Dixie/ChaosProvider/SequentialChaosProvider/DixieSequentialChaosProvider.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "DixieSequentialChaosProvider.h" #import "DixieNonChaosProvider.h" @interface DixieSequentialChaosProvider (/*Private*/) @property (nonatomic) NSInteger callCount; @property (nonatomic, strong) NSArray* sequence; @end @implementation DixieSequentialChaosProvider -(id) init { if (self = [super init]) { self.callCount = 0; self.sequence = @[]; } return self; } +(instancetype) sequence:(NSArray*)sequenceOfChaosProviders { DixieSequentialChaosProvider* provider = [DixieSequentialChaosProvider new]; provider.sequence = sequenceOfChaosProviders; return provider; } -(void) setContext:(DixieChaosContext *)context { [super setContext:context]; for (DixieBaseChaosProvider* provider in self.sequence) { [provider setContext:context]; } } -(void) chaosImplementationFor:(id)victim environment:(DixieCallEnvironment *)environment { DixieBaseChaosProvider* current; //If we are not out of bounds, then use chaos provider mathcing the call count if (self.callCount < self.sequence.count) { current = self.sequence[self.callCount]; } //Else use always the last one else { current = [self.sequence lastObject]; } //Only increamenet callcount if its less than NSIntegerMax so prevent overflows if (self.callCount < NSIntegerMax) { self.callCount++; } //If the current is a BaseChaosProvider, then forward the chaos to it if ([current isKindOfClass:[DixieBaseChaosProvider class]]) { [self forwardChaosOf:victim environment:environment to:current]; } //If it is of different class, do nothing else { [self forwardChaosOf:victim environment:environment to:[DixieNonChaosProvider new]]; } } @end ================================================ FILE: Dixie/Dixie/Dixie+Fluent/Dixie+Fluent.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "Dixie.h" /** * Fluent API of Dixie for easier configuration * @code [Dixie new].Profile(aProfile).Apply(); */ @interface Dixie (Fluent) @property (nonatomic, readonly) Dixie*(^PuppetMaker)(id puppetMaker); @property (nonatomic, readonly) Dixie*(^Profile)(DixieProfileEntry* profile); @property (nonatomic, readonly) Dixie*(^Profiles)(NSArray* arrayOfEntries); @property (nonatomic, readonly) void(^Apply)(); @property (nonatomic, readonly) void(^ApplyWith)(NSInteger seed); @property (nonatomic, readonly) void(^Revert)(); @property (nonatomic, readonly) void(^RevertIt)(DixieProfileEntry* entry); @end ================================================ FILE: Dixie/Dixie/Dixie+Fluent/Dixie+Fluent.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "Dixie+Fluent.h" @implementation Dixie (Fluent) -(Dixie*(^)(id)) PuppetMaker { return ^Dixie*(id puppetMaker) { return [self puppetMaker:puppetMaker]; }; } -(Dixie*(^)(DixieProfileEntry*)) Profile { return ^Dixie*(DixieProfileEntry* profile) { return [self profile:profile]; }; } -(Dixie*(^)(NSArray*)) Profiles { return ^Dixie*(NSArray* arrayOfEntries) { return [self profiles:arrayOfEntries]; }; } -(void(^)()) Apply { return ^void(){ [self apply]; }; } -(void(^)(NSInteger)) ApplyWith { return ^void(NSInteger seed){ [self apply:seed]; }; } -(void(^)()) Revert { return ^void(){ [self revert]; }; } -(void(^)(DixieProfileEntry* entry)) RevertIt { return ^void(DixieProfileEntry* entry){ [self revert:entry]; }; } @end ================================================ FILE: Dixie/Dixie/Dixie.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. @import Foundation; #import "DixiePuppetMaking.h" #import "DixieProfileEntry.h" /** * Represents a Dixie configuration. */ @interface Dixie : NSObject /** * Sets the default puppetmaker * * @param puppetMaker An object that conforms to the PuppetMaking protocol. * * @return The active Dixie object */ -(instancetype) puppetMaker:(id)puppetMaker; /** * Registers a single profiles. * * @param profile A DixieProfileEntry objects. * * @return Same Dixie object. */ -(instancetype) profile:(DixieProfileEntry*)profile; /** * Registers profiles. * * @param arrayOfEntries Collection of DixieProfileEntry objects. * * @return Same Dixie object. */ -(instancetype) profiles:(NSArray*)arrayOfEntries; /** * Applies the Dixie configuration. */ -(void) apply; /** * Applies the Dixie configuration with the specified seed (used for random generation). * * @param seed The seed for random generation */ -(void) apply:(NSInteger)seed; /** * Reverts the Dixie configuration. */ -(void) revert; /** * Reverts one DixieProfileEntry from the Dixie configuration. * * @param entry The profile to revert */ -(void) revert:(DixieProfileEntry*)entry; @end ================================================ FILE: Dixie/Dixie/Dixie.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "Dixie.h" #import "DixieDefaultPuppetMaker.h" #import "DixieLogger.h" @interface Dixie(/*Private*/) @property (atomic) NSLock* lock; @property (nonatomic, strong) NSMutableArray* profiles; @property (nonatomic, strong) id puppetMaker; @end @implementation Dixie -(id) init { if (self = [super init]) { self.lock = [NSLock new]; self.profiles = [@[] mutableCopy]; self.puppetMaker = [DixieDefaultPuppetMaker new]; } return self; } -(instancetype) puppetMaker:(id)puppetMaker { [self.lock lock]; self.puppetMaker = puppetMaker; [self.lock unlock]; return self; } -(instancetype) profile:(DixieProfileEntry*)profile { NSAssert(profile != nil, @"DixieProfileEntry should not be nil"); return [self profiles:@[ profile ]]; } -(instancetype) profiles:(NSArray*)arrayOfEntries { [self.lock lock]; [self.profiles addObjectsFromArray:arrayOfEntries]; [self.lock unlock]; return self; } -(void) apply { [self apply:0]; } -(void) apply:(NSInteger)seed { [self.lock lock]; for (DixieProfileEntry* entry in self.profiles) { [self.puppetMaker createPuppet:entry seed:seed]; } [self.lock unlock]; } -(void) revert { for (DixieProfileEntry* entry in self.profiles.copy) { [self revert:entry]; } } -(void) revert:(DixieProfileEntry*)entry { [self.lock lock]; [self.puppetMaker dismissPuppet:entry]; [self.profiles removeObject:entry]; [self.lock unlock]; } @end ================================================ FILE: Dixie/Dixie/DixieHeaders.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "Dixie.h" #import "Dixie+Fluent.h" #import "DixieProfileEntry.h" #import "DixieBaseChaosProvider.h" #import "DixieNilChaosProvider.h" #import "DixieNonChaosProvider.h" #import "DixieConstantChaosProvider.h" #import "DixieCompositeChaosProvider.h" #import "DixieBlockChaosProvider.h" #import "DixieRandomChaosProvider.h" #import "DixieExceptionChaosProvider.h" #import "DixieSequentialChaosProvider.h" ================================================ FILE: Dixie/Dixie/DixieLogger/DixieLogger.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. @import Foundation; /** * Base class for logging */ @interface DixieLogger : NSObject /** * Returns default logger. * * @return The logger. */ + (instancetype)defaultLogger; /** * Changes the default logger. * * @param logger The logger. */ + (void) setDefaultLogger:(DixieLogger*)logger; /** * Logs a message. * * @param format The format of the message. It can be followed by variadic arguments. */ - (void)log:(NSString*)format,...; @end ================================================ FILE: Dixie/Dixie/DixieLogger/DixieLogger.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #include "DixieLogger.h" #include "DixieSimpleLogger.h" @implementation DixieLogger static DixieLogger* _logger; + (instancetype)defaultLogger { return _logger; } + (void) setDefaultLogger:(DixieLogger*)logger { if (logger == nil) @throw [NSException exceptionWithName:@"ArgumentNil" reason:@"logger is nil" userInfo: nil]; _logger = logger; } +(void) load { [super load]; _logger = [DixieSimpleLogger new]; } - (void)log:(NSString*)format,... { @throw [NSException exceptionWithName:@"Method not overriden" reason:@"DixLogger subclasses should override [DixLogger log:]" userInfo: nil]; } @end ================================================ FILE: Dixie/Dixie/DixieLogger/SimpleLogger/DixieSimpleLogger.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. @import Foundation; #import "DixieLogger.h" /** * Default subclass of DixieLogger,that uses NSLog */ @interface DixieSimpleLogger : DixieLogger @end ================================================ FILE: Dixie/Dixie/DixieLogger/SimpleLogger/DixieSimpleLogger.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #include "DixieSimpleLogger.h" @implementation DixieSimpleLogger - (void)log:(NSString*)format,... { va_list argumentList; va_start(argumentList, format); NSMutableString * message = [[NSMutableString alloc] initWithFormat:format arguments:argumentList]; NSMutableString * res = [[NSMutableString alloc] initWithString:@"Dixie "]; [res appendString:message]; NSLog(res, nil); va_end(argumentList); } @end ================================================ FILE: Dixie/Dixie/MethodInfo/DixieMethodInfo.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. @import Foundation; /** * Describes a class and one of its method */ @interface DixieMethodInfo : NSObject /** * Owner of the method. */ @property (readonly) Class targetClass; /** * Selector of the method. */ @property (readonly) SEL selector; /** * The string representation of the method encoding */ @property (readonly) const char* methodTypeEncoding; /** * Indicates whether the method is a class method. */ @property (readonly) BOOL isClassMethod; /** * Signature of the method. */ @property (readonly) NSMethodSignature* signature; /** * Creates a new MethodInfo instance. * * @param targetClass The owner of the method. * @param selector The selector of the method. * * @return A MethodInfo instance. */ +(instancetype) infoWithClass:(Class)targetClass selector:(SEL)selector; @end ================================================ FILE: Dixie/Dixie/MethodInfo/DixieMethodInfo.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "DixieMethodInfo.h" #import "DixieRunTimeHelper.h" @interface DixieMethodInfo() @property Class targetClass; @property SEL selector; @property BOOL isClassMethod; @property (nonatomic, strong) NSMethodSignature* signature; @property const char* methodTypeEncoding; @end @implementation DixieMethodInfo +(instancetype) infoWithClass:(Class)targetClass selector:(SEL)selector; { DixieMethodInfo* method = [DixieMethodInfo new]; method.targetClass = targetClass; method.selector = selector; method.isClassMethod = [targetClass respondsToSelector:selector]; if (method.isClassMethod) { method.signature = [targetClass methodSignatureForSelector:selector]; } else { method.signature = [targetClass instanceMethodSignatureForSelector:selector]; } method.methodTypeEncoding = [DixieRunTimeHelper methodTypeEncodingForMethodInfo:method]; return method; } @end ================================================ FILE: Dixie/Dixie/ParamProvider/DixieBaseParamProvider.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. @import Foundation; /** * Base class for objects, that can return an object */ @interface DixieBaseParamProvider : NSObject /** * Returns an object * * @return an object */ -(id) parameter; @end ================================================ FILE: Dixie/Dixie/ParamProvider/DixieBaseParamProvider.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "DixieBaseParamProvider.h" @implementation DixieBaseParamProvider -(id) parameter; { @throw [NSException exceptionWithName:@"Method not overriden" reason:@"BaseParamProvider subclasses should override [BaseParamProvider aParameter]" userInfo:nil]; } @end ================================================ FILE: Dixie/Dixie/ParamProvider/RandomParamProvider/DixieRandomParamProvider.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "DixieBaseParamProvider.h" /** * Provides a random number object */ @interface DixieRandomParamProvider : DixieBaseParamProvider /** * Creates a DixieRandomParamProvider with a given uppper bound * * @param upperBound The upper limit to the random numbers, the numbers can be only lower than this * * @return a DixieRandomParamProvider */ +(instancetype) providerWithUpperBound:(unsigned int)upperBound; /** * Set the seed for the random generator * * @param seed A seed for deterministic behaviour */ -(void) setSeed:(unsigned long long)seed; @end ================================================ FILE: Dixie/Dixie/ParamProvider/RandomParamProvider/DixieRandomParamProvider.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. /* A C-program for MT19937-64 (2004/9/29 version). Coded by Takuji Nishimura and Makoto Matsumoto. This is a 64-bit version of Mersenne Twister pseudorandom number generator. Before using, initialize the state by using init_genrand64(seed) or init_by_array64(init_key, key_length). Copyright (C) 2004, Makoto Matsumoto and Takuji Nishimura, All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The names of its contributors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. References: T. Nishimura, ``Tables of 64-bit Mersenne Twisters'' ACM Transactions on Modeling and Computer Simulation 10. (2000) 348--357. M. Matsumoto and T. Nishimura, ``Mersenne Twister: a 623-dimensionally equidistributed uniform pseudorandom number generator'' ACM Transactions on Modeling and Computer Simulation 8. (Jan. 1998) 3--30. Any feedback is very welcome. http://www.math.hiroshima-u.ac.jp/~m-mat/MT/emt.html email: m-mat @ math.sci.hiroshima-u.ac.jp (remove spaces) */ #import "DixieRandomParamProvider.h" #define NN 312 #define MM 156 #define MATRIX_A 0xB5026F5AA96619E9ULL #define UM 0xFFFFFFFF80000000ULL /* Most significant 33 bits */ #define LM 0x7FFFFFFFULL /* Least significant 31 bits */ @interface DixieRandomParamProvider() { /* The array for the state vector */ unsigned long long _mt[NN]; int _mti; unsigned int _upperBound; } @end @implementation DixieRandomParamProvider +(instancetype) providerWithUpperBound:(unsigned int)upperBound { DixieRandomParamProvider* paramProvider = [DixieRandomParamProvider new]; paramProvider->_upperBound = upperBound; return paramProvider; } -(instancetype) init { self = [super init]; if(self) { /* mti==NN+1 means mt[NN] is not initialized */ _mti = NN+1; _upperBound = 100; [self setSeed:[[NSDate date] timeIntervalSince1970]]; } return self; } -(void) setSeed:(unsigned long long)seed { _mt[0] = seed; for (_mti=1; _mti> 62)) + _mti); } -(id) parameter { return @((unsigned int)([self generateRealNumber] * _upperBound)); } /* generates a random number on [0,1]-real-interval */ -(double) generateRealNumber { return ([self generateRandomUnsignedLongLong] >> 11) * (1.0/9007199254740991.0); } -(unsigned long long) generateRandomUnsignedLongLong { int i; unsigned long long x; static unsigned long long mag01[2]={0ULL, MATRIX_A}; if (_mti >= NN) { /* generate NN words at one time */ /* if init_genrand64() has not been called, */ /* a default initial seed is used */ if (_mti == NN+1) [self setSeed:5489ULL]; for (i=0;i>1) ^ mag01[(int)(x&1ULL)]; } for (;i>1) ^ mag01[(int)(x&1ULL)]; } x = (_mt[NN-1]&UM)|(_mt[0]&LM); _mt[NN-1] = _mt[MM-1] ^ (x>>1) ^ mag01[(int)(x&1ULL)]; _mti = 0; } x = _mt[_mti++]; x ^= (x >> 29) & 0x5555555555555555ULL; x ^= (x << 17) & 0x71D67FFFEDA60000ULL; x ^= (x << 37) & 0xFFF7EEE000000000ULL; x ^= (x >> 43); return x; } @end ================================================ FILE: Dixie/Dixie/ProfileEntry/DixieProfileEntry.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. @import Foundation; #import "DixieBaseChaosProvider.h" #import "DixieMethodInfo.h" /** * Describe the target class, selector and the desired behaviour */ @interface DixieProfileEntry : NSObject /** * Uniquely identifies the entry */ @property (readonly) NSString* entryID; /** * The DixieMethodInfo object, that describes the class and its method */ @property (nonatomic, readonly) DixieMethodInfo* methodInfo; /** * The ChaosProvider which will provide the new implementation */ @property (nonatomic, strong) DixieBaseChaosProvider* chaosProvider; /** * Creates a DixieProfileEntry with the main properties set * * @param victim The victim whose method we wish to override * @param selector The selector for the method we wish to override * @param chaosProvider The ChaosProvider which will provide the new implementation * * @return a new DixieProfileEntry with the properties set */ +(instancetype) entry:(Class)victim selector:(SEL)selector chaosProvider:(DixieBaseChaosProvider*)chaosProvider; /** * Creates an array of DixieProfileEntry. * The DixieProfileEntry array consists of all selectors on the victim EXCEPT those defined in the klass * * @param victim The victim whose method we wish to override * @param klass Tha class, whose selectors should not be added to the list of entries * @param chaosProvider The ChaosProvider which will provide the new implementation * * @return an array of DixieProfileEntries representing all available selectors on the victim EXCEPT those defined in the excludeClass */ +(NSArray*) entries:(Class)victim excludeSelectorsOfClass:(Class)excludeClass chaosProvider:(DixieBaseChaosProvider *)chaosProvider; /** * Creates an array of DixieProfileEntries * The DixieProfileEntries array consists of all selectors on the victim EXCEPT those specified in excludedSelectorNames * * @param victim The victim whose method we wish to override * @param excludedSelectorNames The selectors we do NOT wish to include in the return calue * @param chaosProvider The ChaosProvider which will provide the new implementation * * @return an array of DixieProfileEntries representing all available selectors on the victim EXCEPT those specified */ +(NSArray*) entries:(Class)victim excludes:(NSArray*)excludedSelectorNames chaosProvider:(DixieBaseChaosProvider*)chaosProvider; @end ================================================ FILE: Dixie/Dixie/ProfileEntry/DixieProfileEntry.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "DixieProfileEntry.h" #import "DixieRunTimeHelper.h" @interface DixieProfileEntry(/*Private*/) @property (nonatomic, strong) NSString* entryID; @property (nonatomic, strong) DixieMethodInfo* methodInfo; @end @implementation DixieProfileEntry -(instancetype) init { if (self = [super init]) { self.entryID = [[NSUUID UUID] UUIDString]; } return self; } +(instancetype) entry:(Class)victim selector:(SEL)selector chaosProvider:(DixieBaseChaosProvider*)chaosProvider { DixieProfileEntry* entry = [DixieProfileEntry new]; entry.methodInfo = [DixieMethodInfo infoWithClass:victim selector:selector]; entry.chaosProvider = chaosProvider; entry.entryID = [NSString stringWithFormat:@"%@%@", NSStringFromClass(victim), NSStringFromSelector(selector)]; return entry; } +(NSArray*) entries:(Class)victim excludeSelectorsOfClass:(Class)excludeClass chaosProvider:(DixieBaseChaosProvider *)chaosProvider { NSArray* selectorsToExclude = [DixieRunTimeHelper selectorsForClass:excludeClass]; return [self entries:victim excludes:selectorsToExclude chaosProvider:chaosProvider]; } +(NSArray*) entries:(Class)victim excludes:(NSArray*)excludedSelectorNames chaosProvider:(DixieBaseChaosProvider*)chaosProvider { NSArray* selectorNames = [DixieRunTimeHelper selectorsForClass:victim]; NSMutableArray* profileEntries = [@[] mutableCopy]; for (NSString* selectorName in selectorNames) { if (![excludedSelectorNames containsObject:selectorName]) { DixieProfileEntry* entry = [DixieProfileEntry entry:victim selector:NSSelectorFromString(selectorName) chaosProvider:chaosProvider]; if (entry) { [profileEntries addObject:entry]; } } } return profileEntries; } @end ================================================ FILE: Dixie/Dixie/PuppetMaker/DixieDefaultPuppetMaker.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. @import Foundation; #import "DixiePuppetMaking.h" /** * Default implementation of the DixiePuppetMaking interface */ @interface DixieDefaultPuppetMaker : NSObject @end ================================================ FILE: Dixie/Dixie/PuppetMaker/DixieDefaultPuppetMaker.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "DixieDefaultPuppetMaker.h" #import @interface DixieDefaultPuppetMaker(/*Private*/) @property (nonatomic, strong) NSMutableDictionary* victims; @end @implementation DixieDefaultPuppetMaker -(instancetype) init { if (self = [super init]) { self.victims = [@{} mutableCopy]; } return self; } -(void) createPuppet:(DixieProfileEntry*)entry seed:(NSInteger)seed { //If already a puppet, dismiss it if (self.victims[entry.entryID]) { [self dismissPuppet:entry]; } DixieMethodInfo* methodInfo = entry.methodInfo; //Get the victim class (class or meta class) Class victim = [DixieRunTimeHelper classForMethodInfo:methodInfo]; //Create the context for the behaviour replacement DixieChaosContext* context = [[DixieChaosContext alloc] init:seed methodInfo:methodInfo]; [entry.chaosProvider setContext:context]; context.originalIMP = method_getImplementation([DixieRunTimeHelper methodForMethodInfo:methodInfo]); //Retrieve the new behaviour from the provider IMP chaos = [entry.chaosProvider chaos]; //Add the original implementation to the class with a new selector, dixie_[originalSelectorName] class_addMethod(victim, NSSelectorFromString([DixieMethodPrefix stringByAppendingString:NSStringFromSelector(methodInfo.selector)]), context.originalIMP, methodInfo.methodTypeEncoding); //Replace the original behaviour with the new one class_replaceMethod(victim, methodInfo.selector, chaos, methodInfo.methodTypeEncoding); //Store original implementation self.victims[entry.entryID] = [NSValue valueWithPointer:context.originalIMP]; } -(void) dismissPuppet:(DixieProfileEntry*)entry { DixieMethodInfo* methodInfo = entry.methodInfo; NSValue* value = self.victims[entry.entryID]; if (!value) return; //Retrieve original implementation IMP originalIMP = [value pointerValue]; Class victim = [DixieRunTimeHelper classForMethodInfo:methodInfo]; //Put back original implementation class_replaceMethod(victim, methodInfo.selector, originalIMP, methodInfo.methodTypeEncoding); //No need to store it [self.victims removeObjectForKey:entry.entryID]; } @end ================================================ FILE: Dixie/Dixie/PuppetMaker/DixiePuppetMaking.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. @import Foundation; #import "DixieProfileEntry.h" /** * Interface to objects, that can change the behaviour of a class' method. */ @protocol DixiePuppetMaking /** * Creates puppet according to a given entry for the specified seed, by replacing the original behaviour with a new * * @param entry The entry specifying the victim class, selector and behaviour * @param seed An integer value to make the invocations on the puppets deterministic */ -(void) createPuppet:(DixieProfileEntry*)entry seed:(NSInteger)seed; /** * Dismisses the puppets for a given entry * * @param entry The entry specifying the victim class, selector and behaviour */ -(void) dismissPuppet:(DixieProfileEntry*)entry; @end ================================================ FILE: Dixie/Dixie/Runtime/DixieCallEnvironment.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import /** * Describes the environment of a method's implementation */ @interface DixieCallEnvironment : NSObject /** * Arguments of the method call converted into objects */ @property (strong) NSArray* arguments; /** * The return value of a method's implementation */ @property (nonatomic) void *returnValue; /** * Creates a DixieCallEnvironment with the arguments * * @param arguments Arguments of the method call converted into objects * * @return a DixieCallEnvironment */ -(instancetype) initWithArguments:(NSArray*)arguments; @end ================================================ FILE: Dixie/Dixie/Runtime/DixieCallEnvironment.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "DixieCallEnvironment.h" @implementation DixieCallEnvironment -(instancetype) initWithArguments:(NSArray*)arguments { if (self = [super init]) { self.arguments = arguments; } return self; } @end ================================================ FILE: Dixie/Dixie/Runtime/DixieRunTimeHelper.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. @import Foundation; #import #import "DixieCallEnvironment.h" #import "DixieChaosContext.h" #import "DixieMethodInfo.h" #define DixieMethodPrefix @"dixie_" #define isType(typeEncoding, type2) (strcmp(typeEncoding, @encode(type2)) == 0) /** * Block type to describe a method's concrete implementation * * @param victim The receiver of the ObjC message * @param environment The environment of the call */ typedef void(^DixieImplementationBlock)(id victim, DixieCallEnvironment* environment); /** * Helper to generate behaviour implementation, transparently call implementations and provide Runtime informations */ @interface DixieRunTimeHelper : NSObject /** * Generates an implementation pointer that confirms to the chaosContext and block * * @param chaosContext The context of the implementation * @param block Block for the body of the implementation pointer * * @return the implementation pointer */ +(IMP) implementationWithChaosContext:(DixieChaosContext*)chaosContext environment:(DixieImplementationBlock)block; /** * Calls the implementation pointer * * @param implementation The IMP pointer to call * @param puppet The receiver of the ObjC message * @param chaosContext The context of the behaviour * @param environment The environment of the method's implementation call */ +(void) callImplementation:(IMP)implementation on:(id)puppet chaosContext:(DixieChaosContext*)chaosContext environment:(DixieCallEnvironment*)environment; /** * Collects the runtime public methodnames for a given class * * @param targetClass The class * * @return Array of public selector strings */ +(NSArray*) selectorsForClass:(Class)targetClass; /** * Returns the Method pointer for a given MethodInfo object * * @param methodInfo Describes the target class and it's method * * @return The Method pointer */ +(Method) methodForMethodInfo:(DixieMethodInfo*)methodInfo; /** * Returns the string representation of the method encoding describes by the MethodInfo object * * @param methodInfo Describes the target class and it's method * * @return the string representation of the method encoding */ +(const char*) methodTypeEncodingForMethodInfo:(DixieMethodInfo*)methodInfo; /** * Returns the class for the method described in the MethodInfo. * * @param methodInfo Describes the target class and it's method * * @return A Class object for instance methods and meta class object for class methods */ +(Class) classForMethodInfo:(DixieMethodInfo*)methodInfo; @end ================================================ FILE: Dixie/Dixie/Runtime/DixieRunTimeHelper.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "DixieRunTimeHelper.h" #import "NSObject+DixieRunTimeHelper.h" @interface NSInvocation (PrivateHack) - (void)invokeUsingIMP: (IMP)imp; @end struct BlockDescriptor { unsigned long reserved; unsigned long size; void *rest[1]; }; struct Block { void *isa; int flags; int reserved; void *invoke; struct BlockDescriptor *descriptor; }; @implementation DixieRunTimeHelper #pragma mark - IMPLEMENTATION HELPERS +(IMP) implementationWithChaosContext:(DixieChaosContext*)chaosContext environment:(DixieImplementationBlock)block; { struct Block *blockWrapper = (__bridge void*)[self blockForSignature:chaosContext.methodInfo.signature block:block]; struct BlockDescriptor *descriptor = blockWrapper->descriptor; int copyDisposeFlag = 1 << 25; int signatureFlag = 1 << 30; assert(blockWrapper->flags & signatureFlag); int index = 0; if(blockWrapper->flags & copyDisposeFlag) index += 2; //Make the block fit for any need descriptor->rest[index] = (void*)chaosContext.methodInfo.methodTypeEncoding; return imp_implementationWithBlock((__bridge id)(blockWrapper)); } /** * Returns a block implementation for a given signature * * @param signature The method signature * @param block The body of the block implementation * * @return A block, that matches the signature and calls the block */ +(id) blockForSignature:(NSMethodSignature*)signature block:(DixieImplementationBlock)block { #define BLOCK_ID \ ^id(id victim, ...){ \ va_list args; \ va_start(args, victim); \ \ NSArray* arguments = [self argumentsFor:signature originalArguments:args]; \ DixieCallEnvironment* environment = [[DixieCallEnvironment alloc] initWithArguments:arguments]; \ block(victim, environment); \ return environment.returnValue; \ } #define BLOCK(TYPE) \ ^TYPE(id victim, ...){ \ va_list args; \ va_start(args, victim); \ \ NSArray* arguments = [self argumentsFor:signature originalArguments:args]; \ DixieCallEnvironment* environment = [[DixieCallEnvironment alloc] initWithArguments:arguments]; \ block(victim, environment); \ return *(TYPE *)environment.returnValue; \ } const char* rType = signature.methodReturnType; if (isType(rType, void)) return BLOCK(void); if (isType(rType, BOOL)) return BLOCK(BOOL); if (isType(rType, int)) return BLOCK(int); if (isType(rType, char)) return BLOCK(char); if (isType(rType, double)) return BLOCK(double); if (isType(rType, float)) return BLOCK(float); if (isType(rType, long)) return BLOCK(long); if (isType(rType, short)) return BLOCK(short); if (isType(rType, unsigned int)) return BLOCK(unsigned int); return BLOCK_ID; } /** * Parses a variadic list into array of objects @note The current solution handles only object,selector,BOOL and char types. * * @param signature The signature to determine the type of parameters in the variadic list * @param arguments The variadic list * * @return Array of parsed objects */ +(NSArray*) argumentsFor:(NSMethodSignature*)signature originalArguments:(va_list)arguments { //Ignore self and _cmd NSInteger numberOfParameters = signature.numberOfArguments-2; NSMutableArray* parameters = [NSMutableArray arrayWithCapacity:numberOfParameters]; va_list iteratorList; __va_copy(iteratorList, arguments); for (NSInteger index = 0; index < numberOfParameters; index++) { //Only read argument after self and _cmd const char* argTyp = [signature getArgumentTypeAtIndex:index + 2]; //Convert to object id parameter = [self objectFromNext:iteratorList type:argTyp outputArgumentList:&iteratorList]; //Fill the unparsed value with NSNull parameter = parameter ? :[NSNull null]; [parameters addObject:parameter]; } return parameters; } +(void) callImplementation:(IMP)implementation on:(id)puppet chaosContext:(DixieChaosContext*)chaosContext environment:(DixieCallEnvironment*)environment { NSMethodSignature* signature = chaosContext.methodInfo.signature; NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:signature]; [invocation setTarget:puppet]; [invocation setSelector:chaosContext.methodInfo.selector]; //We are ignoring the index of self and _cmd for (NSInteger i = 2; i < signature.numberOfArguments; i++) { const char* encoding = [signature getArgumentTypeAtIndex:i]; if (isType(encoding, NSObject*) || isType(encoding, void*) || strcmp(encoding, "@?") == 0 ) { id value = environment.arguments[i-2]; if (value == [NSNull null]) { value = nil; } [invocation setArgument:&value atIndex:i]; } else { void* value = [environment.arguments[i-2] originalValue]; [invocation setArgument:value atIndex:i]; } } [invocation invokeUsingIMP:implementation]; if (!isType(chaosContext.methodInfo.signature.methodReturnType, void)) { if(isType(chaosContext.methodInfo.signature.methodReturnType, id)) { id returnValue; [invocation getReturnValue:&returnValue]; environment.returnValue = (void*)CFBridgingRetain(returnValue); } else { void *returnValue = malloc(chaosContext.methodInfo.signature.methodReturnLength); environment.returnValue = returnValue; } } } #pragma mark - CONVERT OBJECT /** * Converts the next item in the variadic arguments list into subclass of NSObjects * @note We are using core foundation factories here, NSNumber, NSString might be swizzled * * @param arguments The variadic list * @param argType The expected type of the next item * @param ova_List The current state of the variadic list after the current value is read from it * * @return An NSObject subclass that represents the argument */ +(NSObject *) objectFromNext:(va_list)arguments type:(const char*)argType outputArgumentList:(out void *)ova_List { NSObject* object; //char //int //short //unsgined char //unsgined short //BOOL if (isType(argType, char) || isType(argType, int) || isType(argType, short) || isType(argType, unsigned char) || isType(argType, unsigned short) || isType(argType, BOOL)) { int i = va_arg(arguments, int); object = CFBridgingRelease(CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &i)); storeOriginal(object, int, i); } //long else if (isType(argType, long)) { long l = va_arg(arguments, long); object = CFBridgingRelease(CFNumberCreate(kCFAllocatorDefault, kCFNumberLongType, &l)); object.originalValue = &l; } //long long else if (isType(argType, long long)) { long long ll = va_arg(arguments, long long); object = CFBridgingRelease(CFNumberCreate(kCFAllocatorDefault, kCFNumberLongLongType, &ll)); object.originalValue = ≪ } //unsgined int else if (isType(argType, unsigned int)) { unsigned int ui = va_arg(arguments, unsigned int); object = CFBridgingRelease(CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &ui)); storeOriginal(object, unsigned int, ui); } //unsgined long else if (isType(argType, unsigned long)) { unsigned long ul = va_arg(arguments, unsigned long); object = CFBridgingRelease(CFNumberCreate(kCFAllocatorDefault, kCFNumberLongType, &ul)); storeOriginal(object, unsigned long, ul); } //unsgined long long else if (isType(argType, unsigned long long)) { unsigned long long ull = va_arg(arguments, unsigned long long); object = CFBridgingRelease(CFNumberCreate(kCFAllocatorDefault, kCFNumberLongLongType, &ull)); storeOriginal(object, unsigned long long, ull); } //float //double else if (isType(argType, float) || isType(argType, double) ) { double real = va_arg(arguments, double); object = CFBridgingRelease(CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &real)); storeOriginal(object, double, real); } //char string else if (isType(argType, char*)) { char* string = va_arg(arguments, char*); object = CFBridgingRelease(CFStringCreateWithCString(NULL, string, kCFStringEncodingUTF8)); object.originalValue = string; } //Object else if (strcmp(argType, "@") == 0 ||//NSObject strcmp(argType, "no@") == 0 || //NSObject? strcmp(argType, "@?") == 0 //Block ) { id data = va_arg(arguments, id); object = strcmp(argType, "@?") == 0 ? [data copy] : data; } //class else if (isType(argType, Class)) { Class klass = va_arg(arguments, Class); object = NSStringFromClass(klass); storeOriginal(object, Class, klass); } //SEL else if (isType(argType, SEL)) { SEL selector = va_arg(arguments, SEL); object = NSStringFromSelector(selector); storeOriginal(object, SEL, selector); } //Output pointer else if (argType[0] == '^') { void* outputParam = va_arg(arguments, void*); object = [NSValue valueWithPointer:outputParam]; } //Set the original encoding on the object [object setEncoding:[NSString stringWithUTF8String:argType]]; ova_List = &arguments; return object; } #pragma mark - INFO HELPER +(NSArray*) selectorsForClass:(Class)targetClass { unsigned int count; Method* methods = class_copyMethodList(targetClass, &count); NSMutableArray* selectorNames = [@[] mutableCopy]; for (NSInteger i = 0; i < count; i++) { Method method = methods[i]; SEL selector = method_getName(method); NSString* selectorName = NSStringFromSelector(selector); if (selectorName) { [selectorNames addObject:selectorName]; } } free(methods); return selectorNames; } +(Method) methodForMethodInfo:(DixieMethodInfo*)methodInfo { if (methodInfo.isClassMethod) { return class_getClassMethod(methodInfo.targetClass, methodInfo.selector); } else { return class_getInstanceMethod(methodInfo.targetClass, methodInfo.selector); } } +(const char*) methodTypeEncodingForMethodInfo:(DixieMethodInfo*)methodInfo { Method method = [self methodForMethodInfo:methodInfo]; return method_getTypeEncoding(method); } +(Class) classForMethodInfo:(DixieMethodInfo*)methodInfo { if (methodInfo.isClassMethod) { return object_getClass((id)methodInfo.targetClass); } else { return methodInfo.targetClass; } } @end ================================================ FILE: Dixie/Dixie/Runtime/NSObject+DixieRunTimeHelper.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. @import Foundation; #define storeOriginal(object , type, original) \ ({ \ object.originalValue = (void*)malloc(sizeof(type)); \ ((type*)object.originalValue)[0] = original; \ }) \ /** * Helper category on NSObject to store the original type encoding and value if the object was converted from non-object type */ @interface NSObject (DixieRunTimeHelper) @property (nonatomic, strong) NSString* encoding; @property void* originalValue; @end ================================================ FILE: Dixie/Dixie/Runtime/NSObject+DixieRunTimeHelper.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "NSObject+DixieRunTimeHelper.h" #import #import "DixieRunTimeHelper.h" static char encodingKey; static char originalValueKey; @interface NSObject () @property (nonatomic, strong) NSValue* wrapper; @end @implementation NSObject (encoding) #pragma mark - Encoding -(void) setEncoding:(NSString*)encoding { objc_setAssociatedObject(self, &encodingKey, encoding, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } -(NSString*) encoding { return objc_getAssociatedObject(self, &encodingKey); } #pragma mark - Original value -(void) setOriginalValue:(void *)originalValue { NSValue* value = [NSValue valueWithPointer:originalValue]; objc_setAssociatedObject(self, &originalValueKey, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } -(void*) originalValue { NSValue* value = objc_getAssociatedObject(self, &originalValueKey); return [value pointerValue]; } #pragma mark - Dealloc //Do not forget to dealloc the original value + (void)load { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ Class class = [self class]; SEL originalSelector = NSSelectorFromString(@"dealloc"); SEL swizzledSelector = NSSelectorFromString([DixieMethodPrefix stringByAppendingString:@"dealloc"]); Method originalMethod = class_getInstanceMethod(class, originalSelector); Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector); BOOL didAddMethod = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod)); if (didAddMethod) { class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); } else { method_exchangeImplementations(originalMethod, swizzledMethod); } }); } - (void)dixie_dealloc{ [self dixie_dealloc]; void* original = self.originalValue; if (original) { free(original); } } @end ================================================ FILE: Dixie/Dixie.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ F53EBAC21A1007AF004FAC40 /* RunTimeHelperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F53EBAC11A1007AF004FAC40 /* RunTimeHelperTests.m */; }; F54F5AA819E83346002EFAEA /* DixieBaseChaosProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5A4E19E83346002EFAEA /* DixieBaseChaosProvider.m */; }; F54F5AA919E83346002EFAEA /* DixieBaseChaosProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5A4E19E83346002EFAEA /* DixieBaseChaosProvider.m */; }; F54F5AAA19E83346002EFAEA /* DixieBlockChaosProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5A5119E83346002EFAEA /* DixieBlockChaosProvider.m */; }; F54F5AAB19E83346002EFAEA /* DixieBlockChaosProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5A5119E83346002EFAEA /* DixieBlockChaosProvider.m */; }; F54F5AAC19E83346002EFAEA /* DixieChaosContext.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5A5319E83346002EFAEA /* DixieChaosContext.m */; }; F54F5AAD19E83346002EFAEA /* DixieChaosContext.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5A5319E83346002EFAEA /* DixieChaosContext.m */; }; F54F5AAE19E83346002EFAEA /* DixieCompositeChaosProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5A5619E83346002EFAEA /* DixieCompositeChaosProvider.m */; }; F54F5AAF19E83346002EFAEA /* DixieCompositeChaosProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5A5619E83346002EFAEA /* DixieCompositeChaosProvider.m */; }; F54F5AB019E83346002EFAEA /* DixieCompositeCondition.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5A5819E83346002EFAEA /* DixieCompositeCondition.m */; }; F54F5AB119E83346002EFAEA /* DixieCompositeCondition.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5A5819E83346002EFAEA /* DixieCompositeCondition.m */; }; F54F5AB219E83346002EFAEA /* DixieConstantChaosProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5A5B19E83346002EFAEA /* DixieConstantChaosProvider.m */; }; F54F5AB319E83346002EFAEA /* DixieConstantChaosProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5A5B19E83346002EFAEA /* DixieConstantChaosProvider.m */; }; F54F5AB419E83346002EFAEA /* DixieExceptionChaosProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5A5E19E83346002EFAEA /* DixieExceptionChaosProvider.m */; }; F54F5AB519E83346002EFAEA /* DixieExceptionChaosProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5A5E19E83346002EFAEA /* DixieExceptionChaosProvider.m */; }; F54F5AB619E83346002EFAEA /* DixieNilChaosProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5A6119E83346002EFAEA /* DixieNilChaosProvider.m */; }; F54F5AB719E83346002EFAEA /* DixieNilChaosProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5A6119E83346002EFAEA /* DixieNilChaosProvider.m */; }; F54F5AB819E83346002EFAEA /* DixieNonChaosProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5A6419E83346002EFAEA /* DixieNonChaosProvider.m */; }; F54F5AB919E83346002EFAEA /* DixieNonChaosProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5A6419E83346002EFAEA /* DixieNonChaosProvider.m */; }; F54F5ABC19E83346002EFAEA /* DixieSequentialChaosProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5A6A19E83346002EFAEA /* DixieSequentialChaosProvider.m */; }; F54F5ABD19E83346002EFAEA /* DixieSequentialChaosProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5A6A19E83346002EFAEA /* DixieSequentialChaosProvider.m */; }; F54F5ABE19E83346002EFAEA /* Dixie+Fluent.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5A6D19E83346002EFAEA /* Dixie+Fluent.m */; }; F54F5ABF19E83346002EFAEA /* Dixie+Fluent.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5A6D19E83346002EFAEA /* Dixie+Fluent.m */; }; F54F5AC019E83346002EFAEA /* Dixie.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5A6F19E83346002EFAEA /* Dixie.m */; }; F54F5AC119E83346002EFAEA /* Dixie.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5A6F19E83346002EFAEA /* Dixie.m */; }; F54F5AC219E83346002EFAEA /* DixieLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5A7319E83346002EFAEA /* DixieLogger.m */; }; F54F5AC319E83346002EFAEA /* DixieLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5A7319E83346002EFAEA /* DixieLogger.m */; }; F54F5AC419E83346002EFAEA /* DixieSimpleLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5A7619E83346002EFAEA /* DixieSimpleLogger.m */; }; F54F5AC519E83346002EFAEA /* DixieSimpleLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5A7619E83346002EFAEA /* DixieSimpleLogger.m */; }; F54F5AD019E83346002EFAEA /* DixieMethodInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5A8719E83346002EFAEA /* DixieMethodInfo.m */; }; F54F5AD119E83346002EFAEA /* DixieMethodInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5A8719E83346002EFAEA /* DixieMethodInfo.m */; }; F54F5AE419E83346002EFAEA /* DixieProfileEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5AA319E83346002EFAEA /* DixieProfileEntry.m */; }; F54F5AE519E83346002EFAEA /* DixieProfileEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5AA319E83346002EFAEA /* DixieProfileEntry.m */; }; F54F5AE619E83346002EFAEA /* DixieDefaultPuppetMaker.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5AA619E83346002EFAEA /* DixieDefaultPuppetMaker.m */; }; F54F5AE719E83346002EFAEA /* DixieDefaultPuppetMaker.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5AA619E83346002EFAEA /* DixieDefaultPuppetMaker.m */; }; F54F5B1119E835B7002EFAEA /* TestPuppetMaker.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5B0719E835B7002EFAEA /* TestPuppetMaker.m */; }; F54F5B1319E835B7002EFAEA /* DixieAPITests.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5B0A19E835B7002EFAEA /* DixieAPITests.m */; }; F54F5B1419E835B7002EFAEA /* DixieChaosProviderTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5B0B19E835B7002EFAEA /* DixieChaosProviderTests.m */; }; F54F5B1719E835B7002EFAEA /* ProfileEntryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F54F5B0E19E835B7002EFAEA /* ProfileEntryTests.m */; }; F5529F9F1AFD3C52002D2004 /* DixieRandomParamProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = F5529F9E1AFD3C52002D2004 /* DixieRandomParamProvider.m */; }; F5529FA01AFD3C52002D2004 /* DixieRandomParamProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = F5529F9E1AFD3C52002D2004 /* DixieRandomParamProvider.m */; }; F5529FA31AFD3C96002D2004 /* DixieBaseParamProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = F5529FA21AFD3C96002D2004 /* DixieBaseParamProvider.m */; }; F5529FA41AFD3C96002D2004 /* DixieBaseParamProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = F5529FA21AFD3C96002D2004 /* DixieBaseParamProvider.m */; }; F5529FA91AFD3E12002D2004 /* TestClass.m in Sources */ = {isa = PBXBuildFile; fileRef = F5529FA61AFD3E12002D2004 /* TestClass.m */; }; F5529FAA1AFD3E12002D2004 /* SubTestClass.m in Sources */ = {isa = PBXBuildFile; fileRef = F5529FA81AFD3E12002D2004 /* SubTestClass.m */; }; F5529FC51AFD4A82002D2004 /* DixieCallEnvironment.m in Sources */ = {isa = PBXBuildFile; fileRef = F5529FBA1AFD4A82002D2004 /* DixieCallEnvironment.m */; }; F5529FC61AFD4A82002D2004 /* DixieCallEnvironment.m in Sources */ = {isa = PBXBuildFile; fileRef = F5529FBA1AFD4A82002D2004 /* DixieCallEnvironment.m */; }; F5529FCB1AFD4A82002D2004 /* NSObject+DixieRunTimeHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = F5529FC01AFD4A82002D2004 /* NSObject+DixieRunTimeHelper.m */; }; F5529FCC1AFD4A82002D2004 /* NSObject+DixieRunTimeHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = F5529FC01AFD4A82002D2004 /* NSObject+DixieRunTimeHelper.m */; }; F5529FCD1AFD4A82002D2004 /* DixieRunTimeHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = F5529FC21AFD4A82002D2004 /* DixieRunTimeHelper.m */; }; F5529FCE1AFD4A82002D2004 /* DixieRunTimeHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = F5529FC21AFD4A82002D2004 /* DixieRunTimeHelper.m */; }; F5529FD81B010F0A002D2004 /* NSDateProfile.m in Sources */ = {isa = PBXBuildFile; fileRef = F5529FD31B010F0A002D2004 /* NSDateProfile.m */; }; F5529FDA1B010F0A002D2004 /* NSURLProfile.m in Sources */ = {isa = PBXBuildFile; fileRef = F5529FD71B010F0A002D2004 /* NSURLProfile.m */; }; F56C7E191A5EFBFD004B946F /* DixieRandomChaosProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = F56C7E181A5EFBFD004B946F /* DixieRandomChaosProvider.m */; }; F56C7E1A1A5EFBFD004B946F /* DixieRandomChaosProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = F56C7E181A5EFBFD004B946F /* DixieRandomChaosProvider.m */; }; F573658A1A2A737200D684CE /* ChaosProviderTestClass.m in Sources */ = {isa = PBXBuildFile; fileRef = F57365891A2A737200D684CE /* ChaosProviderTestClass.m */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ F5965A4219C0796C00ED0A6A /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = "include/$(PRODUCT_NAME)"; dstSubfolderSpec = 16; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ F53EBAC11A1007AF004FAC40 /* RunTimeHelperTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RunTimeHelperTests.m; sourceTree = ""; }; F54F5A4D19E83346002EFAEA /* DixieBaseChaosProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DixieBaseChaosProvider.h; sourceTree = ""; }; F54F5A4E19E83346002EFAEA /* DixieBaseChaosProvider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DixieBaseChaosProvider.m; sourceTree = ""; }; F54F5A5019E83346002EFAEA /* DixieBlockChaosProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DixieBlockChaosProvider.h; sourceTree = ""; }; F54F5A5119E83346002EFAEA /* DixieBlockChaosProvider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DixieBlockChaosProvider.m; sourceTree = ""; }; F54F5A5219E83346002EFAEA /* DixieChaosContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DixieChaosContext.h; sourceTree = ""; }; F54F5A5319E83346002EFAEA /* DixieChaosContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DixieChaosContext.m; sourceTree = ""; }; F54F5A5519E83346002EFAEA /* DixieCompositeChaosProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DixieCompositeChaosProvider.h; sourceTree = ""; }; F54F5A5619E83346002EFAEA /* DixieCompositeChaosProvider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DixieCompositeChaosProvider.m; sourceTree = ""; }; F54F5A5719E83346002EFAEA /* DixieCompositeCondition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DixieCompositeCondition.h; sourceTree = ""; }; F54F5A5819E83346002EFAEA /* DixieCompositeCondition.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DixieCompositeCondition.m; sourceTree = ""; }; F54F5A5A19E83346002EFAEA /* DixieConstantChaosProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DixieConstantChaosProvider.h; sourceTree = ""; }; F54F5A5B19E83346002EFAEA /* DixieConstantChaosProvider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DixieConstantChaosProvider.m; sourceTree = ""; }; F54F5A5D19E83346002EFAEA /* DixieExceptionChaosProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DixieExceptionChaosProvider.h; sourceTree = ""; }; F54F5A5E19E83346002EFAEA /* DixieExceptionChaosProvider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DixieExceptionChaosProvider.m; sourceTree = ""; }; F54F5A6019E83346002EFAEA /* DixieNilChaosProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DixieNilChaosProvider.h; sourceTree = ""; }; F54F5A6119E83346002EFAEA /* DixieNilChaosProvider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DixieNilChaosProvider.m; sourceTree = ""; }; F54F5A6319E83346002EFAEA /* DixieNonChaosProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DixieNonChaosProvider.h; sourceTree = ""; }; F54F5A6419E83346002EFAEA /* DixieNonChaosProvider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DixieNonChaosProvider.m; sourceTree = ""; }; F54F5A6919E83346002EFAEA /* DixieSequentialChaosProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DixieSequentialChaosProvider.h; sourceTree = ""; }; F54F5A6A19E83346002EFAEA /* DixieSequentialChaosProvider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DixieSequentialChaosProvider.m; sourceTree = ""; }; F54F5A6C19E83346002EFAEA /* Dixie+Fluent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Dixie+Fluent.h"; sourceTree = ""; }; F54F5A6D19E83346002EFAEA /* Dixie+Fluent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "Dixie+Fluent.m"; sourceTree = ""; }; F54F5A6E19E83346002EFAEA /* Dixie.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Dixie.h; sourceTree = ""; }; F54F5A6F19E83346002EFAEA /* Dixie.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Dixie.m; sourceTree = ""; }; F54F5A7019E83346002EFAEA /* DixieHeaders.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DixieHeaders.h; sourceTree = ""; }; F54F5A7219E83346002EFAEA /* DixieLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DixieLogger.h; sourceTree = ""; }; F54F5A7319E83346002EFAEA /* DixieLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DixieLogger.m; sourceTree = ""; }; F54F5A7519E83346002EFAEA /* DixieSimpleLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DixieSimpleLogger.h; sourceTree = ""; }; F54F5A7619E83346002EFAEA /* DixieSimpleLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DixieSimpleLogger.m; sourceTree = ""; }; F54F5A8619E83346002EFAEA /* DixieMethodInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DixieMethodInfo.h; sourceTree = ""; }; F54F5A8719E83346002EFAEA /* DixieMethodInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DixieMethodInfo.m; sourceTree = ""; }; F54F5AA219E83346002EFAEA /* DixieProfileEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DixieProfileEntry.h; sourceTree = ""; }; F54F5AA319E83346002EFAEA /* DixieProfileEntry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DixieProfileEntry.m; sourceTree = ""; }; F54F5AA519E83346002EFAEA /* DixieDefaultPuppetMaker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DixieDefaultPuppetMaker.h; sourceTree = ""; }; F54F5AA619E83346002EFAEA /* DixieDefaultPuppetMaker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DixieDefaultPuppetMaker.m; sourceTree = ""; }; F54F5AA719E83346002EFAEA /* DixiePuppetMaking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DixiePuppetMaking.h; sourceTree = ""; }; F54F5B0619E835B7002EFAEA /* TestPuppetMaker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestPuppetMaker.h; sourceTree = ""; }; F54F5B0719E835B7002EFAEA /* TestPuppetMaker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TestPuppetMaker.m; sourceTree = ""; }; F54F5B0819E835B7002EFAEA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; F54F5B0A19E835B7002EFAEA /* DixieAPITests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DixieAPITests.m; sourceTree = ""; }; F54F5B0B19E835B7002EFAEA /* DixieChaosProviderTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DixieChaosProviderTests.m; sourceTree = ""; }; F54F5B0E19E835B7002EFAEA /* ProfileEntryTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProfileEntryTests.m; sourceTree = ""; }; F5529F9D1AFD3C52002D2004 /* DixieRandomParamProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DixieRandomParamProvider.h; sourceTree = ""; }; F5529F9E1AFD3C52002D2004 /* DixieRandomParamProvider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DixieRandomParamProvider.m; sourceTree = ""; }; F5529FA11AFD3C96002D2004 /* DixieBaseParamProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DixieBaseParamProvider.h; sourceTree = ""; }; F5529FA21AFD3C96002D2004 /* DixieBaseParamProvider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DixieBaseParamProvider.m; sourceTree = ""; }; F5529FA51AFD3E12002D2004 /* TestClass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestClass.h; sourceTree = ""; }; F5529FA61AFD3E12002D2004 /* TestClass.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TestClass.m; sourceTree = ""; }; F5529FA71AFD3E12002D2004 /* SubTestClass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SubTestClass.h; sourceTree = ""; }; F5529FA81AFD3E12002D2004 /* SubTestClass.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SubTestClass.m; sourceTree = ""; }; F5529FB91AFD4A82002D2004 /* DixieCallEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DixieCallEnvironment.h; sourceTree = ""; }; F5529FBA1AFD4A82002D2004 /* DixieCallEnvironment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DixieCallEnvironment.m; sourceTree = ""; }; F5529FBF1AFD4A82002D2004 /* NSObject+DixieRunTimeHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+DixieRunTimeHelper.h"; sourceTree = ""; }; F5529FC01AFD4A82002D2004 /* NSObject+DixieRunTimeHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+DixieRunTimeHelper.m"; sourceTree = ""; }; F5529FC11AFD4A82002D2004 /* DixieRunTimeHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DixieRunTimeHelper.h; sourceTree = ""; }; F5529FC21AFD4A82002D2004 /* DixieRunTimeHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DixieRunTimeHelper.m; sourceTree = ""; }; F5529FD21B010F0A002D2004 /* NSDateProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSDateProfile.h; sourceTree = ""; }; F5529FD31B010F0A002D2004 /* NSDateProfile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSDateProfile.m; sourceTree = ""; }; F5529FD61B010F0A002D2004 /* NSURLProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSURLProfile.h; sourceTree = ""; }; F5529FD71B010F0A002D2004 /* NSURLProfile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSURLProfile.m; sourceTree = ""; }; F552A0411B01CDB8002D2004 /* RandomParamProviderTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RandomParamProviderTests.m; sourceTree = ""; }; F56C7E171A5EFBFD004B946F /* DixieRandomChaosProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DixieRandomChaosProvider.h; sourceTree = ""; }; F56C7E181A5EFBFD004B946F /* DixieRandomChaosProvider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DixieRandomChaosProvider.m; sourceTree = ""; }; F57365881A2A737200D684CE /* ChaosProviderTestClass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChaosProviderTestClass.h; sourceTree = ""; }; F57365891A2A737200D684CE /* ChaosProviderTestClass.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ChaosProviderTestClass.m; sourceTree = ""; }; F5965A4419C0796C00ED0A6A /* libDixie.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libDixie.a; sourceTree = BUILT_PRODUCTS_DIR; }; F5965A4F19C0796C00ED0A6A /* DixieTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DixieTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ F5965A4119C0796C00ED0A6A /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; F5965A4C19C0796C00ED0A6A /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ F54F5A4B19E83346002EFAEA /* Dixie */ = { isa = PBXGroup; children = ( F54F5A7019E83346002EFAEA /* DixieHeaders.h */, F54F5A6E19E83346002EFAEA /* Dixie.h */, F54F5A6F19E83346002EFAEA /* Dixie.m */, F54F5A6B19E83346002EFAEA /* Dixie+Fluent */, F54F5AA419E83346002EFAEA /* PuppetMaker */, F54F5A9A19E83346002EFAEA /* ProfileEntry */, F54F5A8519E83346002EFAEA /* MethodInfo */, F54F5A4C19E83346002EFAEA /* ChaosProvider */, F5529F9B1AFD3C52002D2004 /* ParamProvider */, F54F5A7119E83346002EFAEA /* DixieLogger */, F5529FB81AFD4A82002D2004 /* Runtime */, ); path = Dixie; sourceTree = ""; }; F54F5A4C19E83346002EFAEA /* ChaosProvider */ = { isa = PBXGroup; children = ( F54F5A5219E83346002EFAEA /* DixieChaosContext.h */, F54F5A5319E83346002EFAEA /* DixieChaosContext.m */, F54F5A4D19E83346002EFAEA /* DixieBaseChaosProvider.h */, F54F5A4E19E83346002EFAEA /* DixieBaseChaosProvider.m */, F54F5A4F19E83346002EFAEA /* BlockChaosProvider */, F54F5A5419E83346002EFAEA /* CompositeChaosProvider */, F54F5A5919E83346002EFAEA /* ConstantChaosProvider */, F54F5A5C19E83346002EFAEA /* ExceptionChaosProvider */, F54F5A5F19E83346002EFAEA /* NilChaosProvider */, F54F5A6219E83346002EFAEA /* NonChaosProvider */, F56C7E161A5EFBFD004B946F /* RandomChaosProvider */, F54F5A6819E83346002EFAEA /* SequentialChaosProvider */, ); path = ChaosProvider; sourceTree = ""; }; F54F5A4F19E83346002EFAEA /* BlockChaosProvider */ = { isa = PBXGroup; children = ( F54F5A5019E83346002EFAEA /* DixieBlockChaosProvider.h */, F54F5A5119E83346002EFAEA /* DixieBlockChaosProvider.m */, ); path = BlockChaosProvider; sourceTree = ""; }; F54F5A5419E83346002EFAEA /* CompositeChaosProvider */ = { isa = PBXGroup; children = ( F54F5A5719E83346002EFAEA /* DixieCompositeCondition.h */, F54F5A5819E83346002EFAEA /* DixieCompositeCondition.m */, F54F5A5519E83346002EFAEA /* DixieCompositeChaosProvider.h */, F54F5A5619E83346002EFAEA /* DixieCompositeChaosProvider.m */, ); path = CompositeChaosProvider; sourceTree = ""; }; F54F5A5919E83346002EFAEA /* ConstantChaosProvider */ = { isa = PBXGroup; children = ( F54F5A5A19E83346002EFAEA /* DixieConstantChaosProvider.h */, F54F5A5B19E83346002EFAEA /* DixieConstantChaosProvider.m */, ); path = ConstantChaosProvider; sourceTree = ""; }; F54F5A5C19E83346002EFAEA /* ExceptionChaosProvider */ = { isa = PBXGroup; children = ( F54F5A5D19E83346002EFAEA /* DixieExceptionChaosProvider.h */, F54F5A5E19E83346002EFAEA /* DixieExceptionChaosProvider.m */, ); path = ExceptionChaosProvider; sourceTree = ""; }; F54F5A5F19E83346002EFAEA /* NilChaosProvider */ = { isa = PBXGroup; children = ( F54F5A6019E83346002EFAEA /* DixieNilChaosProvider.h */, F54F5A6119E83346002EFAEA /* DixieNilChaosProvider.m */, ); path = NilChaosProvider; sourceTree = ""; }; F54F5A6219E83346002EFAEA /* NonChaosProvider */ = { isa = PBXGroup; children = ( F54F5A6319E83346002EFAEA /* DixieNonChaosProvider.h */, F54F5A6419E83346002EFAEA /* DixieNonChaosProvider.m */, ); path = NonChaosProvider; sourceTree = ""; }; F54F5A6819E83346002EFAEA /* SequentialChaosProvider */ = { isa = PBXGroup; children = ( F54F5A6919E83346002EFAEA /* DixieSequentialChaosProvider.h */, F54F5A6A19E83346002EFAEA /* DixieSequentialChaosProvider.m */, ); path = SequentialChaosProvider; sourceTree = ""; }; F54F5A6B19E83346002EFAEA /* Dixie+Fluent */ = { isa = PBXGroup; children = ( F54F5A6C19E83346002EFAEA /* Dixie+Fluent.h */, F54F5A6D19E83346002EFAEA /* Dixie+Fluent.m */, ); path = "Dixie+Fluent"; sourceTree = ""; }; F54F5A7119E83346002EFAEA /* DixieLogger */ = { isa = PBXGroup; children = ( F54F5A7219E83346002EFAEA /* DixieLogger.h */, F54F5A7319E83346002EFAEA /* DixieLogger.m */, F54F5A7419E83346002EFAEA /* SimpleLogger */, ); path = DixieLogger; sourceTree = ""; }; F54F5A7419E83346002EFAEA /* SimpleLogger */ = { isa = PBXGroup; children = ( F54F5A7519E83346002EFAEA /* DixieSimpleLogger.h */, F54F5A7619E83346002EFAEA /* DixieSimpleLogger.m */, ); path = SimpleLogger; sourceTree = ""; }; F54F5A8519E83346002EFAEA /* MethodInfo */ = { isa = PBXGroup; children = ( F54F5A8619E83346002EFAEA /* DixieMethodInfo.h */, F54F5A8719E83346002EFAEA /* DixieMethodInfo.m */, ); path = MethodInfo; sourceTree = ""; }; F54F5A9A19E83346002EFAEA /* ProfileEntry */ = { isa = PBXGroup; children = ( F54F5AA219E83346002EFAEA /* DixieProfileEntry.h */, F54F5AA319E83346002EFAEA /* DixieProfileEntry.m */, ); path = ProfileEntry; sourceTree = ""; }; F54F5AA419E83346002EFAEA /* PuppetMaker */ = { isa = PBXGroup; children = ( F54F5AA719E83346002EFAEA /* DixiePuppetMaking.h */, F54F5AA519E83346002EFAEA /* DixieDefaultPuppetMaker.h */, F54F5AA619E83346002EFAEA /* DixieDefaultPuppetMaker.m */, ); path = PuppetMaker; sourceTree = ""; }; F54F5B0019E835B7002EFAEA /* DixieTests */ = { isa = PBXGroup; children = ( F5529FD11B010F0A002D2004 /* Predefined profiles */, F54F5B0119E835B7002EFAEA /* Helpers */, F54F5B0819E835B7002EFAEA /* Info.plist */, F54F5B0919E835B7002EFAEA /* Units */, ); path = DixieTests; sourceTree = ""; }; F54F5B0119E835B7002EFAEA /* Helpers */ = { isa = PBXGroup; children = ( F5529FA51AFD3E12002D2004 /* TestClass.h */, F5529FA61AFD3E12002D2004 /* TestClass.m */, F5529FA71AFD3E12002D2004 /* SubTestClass.h */, F5529FA81AFD3E12002D2004 /* SubTestClass.m */, F54F5B0619E835B7002EFAEA /* TestPuppetMaker.h */, F54F5B0719E835B7002EFAEA /* TestPuppetMaker.m */, F57365881A2A737200D684CE /* ChaosProviderTestClass.h */, F57365891A2A737200D684CE /* ChaosProviderTestClass.m */, ); path = Helpers; sourceTree = ""; }; F54F5B0919E835B7002EFAEA /* Units */ = { isa = PBXGroup; children = ( F53EBAC11A1007AF004FAC40 /* RunTimeHelperTests.m */, F54F5B0A19E835B7002EFAEA /* DixieAPITests.m */, F54F5B0B19E835B7002EFAEA /* DixieChaosProviderTests.m */, F54F5B0E19E835B7002EFAEA /* ProfileEntryTests.m */, F552A0411B01CDB8002D2004 /* RandomParamProviderTests.m */, ); path = Units; sourceTree = ""; }; F5529F9B1AFD3C52002D2004 /* ParamProvider */ = { isa = PBXGroup; children = ( F5529FA11AFD3C96002D2004 /* DixieBaseParamProvider.h */, F5529FA21AFD3C96002D2004 /* DixieBaseParamProvider.m */, F5529F9C1AFD3C52002D2004 /* RandomParamProvider */, ); path = ParamProvider; sourceTree = ""; }; F5529F9C1AFD3C52002D2004 /* RandomParamProvider */ = { isa = PBXGroup; children = ( F5529F9D1AFD3C52002D2004 /* DixieRandomParamProvider.h */, F5529F9E1AFD3C52002D2004 /* DixieRandomParamProvider.m */, ); path = RandomParamProvider; sourceTree = ""; }; F5529FB81AFD4A82002D2004 /* Runtime */ = { isa = PBXGroup; children = ( F5529FB91AFD4A82002D2004 /* DixieCallEnvironment.h */, F5529FBA1AFD4A82002D2004 /* DixieCallEnvironment.m */, F5529FBF1AFD4A82002D2004 /* NSObject+DixieRunTimeHelper.h */, F5529FC01AFD4A82002D2004 /* NSObject+DixieRunTimeHelper.m */, F5529FC11AFD4A82002D2004 /* DixieRunTimeHelper.h */, F5529FC21AFD4A82002D2004 /* DixieRunTimeHelper.m */, ); path = Runtime; sourceTree = ""; }; F5529FD11B010F0A002D2004 /* Predefined profiles */ = { isa = PBXGroup; children = ( F5529FD21B010F0A002D2004 /* NSDateProfile.h */, F5529FD31B010F0A002D2004 /* NSDateProfile.m */, F5529FD61B010F0A002D2004 /* NSURLProfile.h */, F5529FD71B010F0A002D2004 /* NSURLProfile.m */, ); path = "Predefined profiles"; sourceTree = ""; }; F56C7E161A5EFBFD004B946F /* RandomChaosProvider */ = { isa = PBXGroup; children = ( F56C7E171A5EFBFD004B946F /* DixieRandomChaosProvider.h */, F56C7E181A5EFBFD004B946F /* DixieRandomChaosProvider.m */, ); path = RandomChaosProvider; sourceTree = ""; }; F5965A3B19C0796C00ED0A6A = { isa = PBXGroup; children = ( F54F5A4B19E83346002EFAEA /* Dixie */, F54F5B0019E835B7002EFAEA /* DixieTests */, F5965A4519C0796C00ED0A6A /* Products */, ); sourceTree = ""; }; F5965A4519C0796C00ED0A6A /* Products */ = { isa = PBXGroup; children = ( F5965A4419C0796C00ED0A6A /* libDixie.a */, F5965A4F19C0796C00ED0A6A /* DixieTests.xctest */, ); name = Products; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ F5965A4319C0796C00ED0A6A /* Dixie */ = { isa = PBXNativeTarget; buildConfigurationList = F5965A5519C0796C00ED0A6A /* Build configuration list for PBXNativeTarget "Dixie" */; buildPhases = ( F5965A4019C0796C00ED0A6A /* Sources */, F5965A4119C0796C00ED0A6A /* Frameworks */, F5965A4219C0796C00ED0A6A /* CopyFiles */, ); buildRules = ( ); dependencies = ( ); name = Dixie; productName = Dix; productReference = F5965A4419C0796C00ED0A6A /* libDixie.a */; productType = "com.apple.product-type.library.static"; }; F5965A4E19C0796C00ED0A6A /* DixieTests */ = { isa = PBXNativeTarget; buildConfigurationList = F5965A5819C0796C00ED0A6A /* Build configuration list for PBXNativeTarget "DixieTests" */; buildPhases = ( F5965A4B19C0796C00ED0A6A /* Sources */, F5965A4C19C0796C00ED0A6A /* Frameworks */, F5965A4D19C0796C00ED0A6A /* Resources */, ); buildRules = ( ); dependencies = ( ); name = DixieTests; productName = DixTests; productReference = F5965A4F19C0796C00ED0A6A /* DixieTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ F5965A3C19C0796C00ED0A6A /* Project object */ = { isa = PBXProject; attributes = { LastUpgradeCheck = 0600; ORGANIZATIONNAME = "Distinction Ltd."; TargetAttributes = { F5965A4319C0796C00ED0A6A = { CreatedOnToolsVersion = 6.0; }; F5965A4E19C0796C00ED0A6A = { CreatedOnToolsVersion = 6.0; }; }; }; buildConfigurationList = F5965A3F19C0796C00ED0A6A /* Build configuration list for PBXProject "Dixie" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( en, ); mainGroup = F5965A3B19C0796C00ED0A6A; productRefGroup = F5965A4519C0796C00ED0A6A /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( F5965A4319C0796C00ED0A6A /* Dixie */, F5965A4E19C0796C00ED0A6A /* DixieTests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ F5965A4D19C0796C00ED0A6A /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ F5965A4019C0796C00ED0A6A /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( F54F5AA819E83346002EFAEA /* DixieBaseChaosProvider.m in Sources */, F54F5AE619E83346002EFAEA /* DixieDefaultPuppetMaker.m in Sources */, F54F5AB619E83346002EFAEA /* DixieNilChaosProvider.m in Sources */, F54F5ABC19E83346002EFAEA /* DixieSequentialChaosProvider.m in Sources */, F54F5AB419E83346002EFAEA /* DixieExceptionChaosProvider.m in Sources */, F54F5AAC19E83346002EFAEA /* DixieChaosContext.m in Sources */, F5529F9F1AFD3C52002D2004 /* DixieRandomParamProvider.m in Sources */, F54F5AC219E83346002EFAEA /* DixieLogger.m in Sources */, F5529FCD1AFD4A82002D2004 /* DixieRunTimeHelper.m in Sources */, F54F5AD019E83346002EFAEA /* DixieMethodInfo.m in Sources */, F54F5AAA19E83346002EFAEA /* DixieBlockChaosProvider.m in Sources */, F54F5AAE19E83346002EFAEA /* DixieCompositeChaosProvider.m in Sources */, F5529FC51AFD4A82002D2004 /* DixieCallEnvironment.m in Sources */, F54F5AB019E83346002EFAEA /* DixieCompositeCondition.m in Sources */, F54F5ABE19E83346002EFAEA /* Dixie+Fluent.m in Sources */, F54F5AB819E83346002EFAEA /* DixieNonChaosProvider.m in Sources */, F5529FCB1AFD4A82002D2004 /* NSObject+DixieRunTimeHelper.m in Sources */, F5529FA31AFD3C96002D2004 /* DixieBaseParamProvider.m in Sources */, F56C7E191A5EFBFD004B946F /* DixieRandomChaosProvider.m in Sources */, F54F5AE419E83346002EFAEA /* DixieProfileEntry.m in Sources */, F54F5AB219E83346002EFAEA /* DixieConstantChaosProvider.m in Sources */, F54F5AC419E83346002EFAEA /* DixieSimpleLogger.m in Sources */, F54F5AC019E83346002EFAEA /* Dixie.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; F5965A4B19C0796C00ED0A6A /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( F54F5AAF19E83346002EFAEA /* DixieCompositeChaosProvider.m in Sources */, F5529FCE1AFD4A82002D2004 /* DixieRunTimeHelper.m in Sources */, F5529FDA1B010F0A002D2004 /* NSURLProfile.m in Sources */, F5529FA01AFD3C52002D2004 /* DixieRandomParamProvider.m in Sources */, F5529FCC1AFD4A82002D2004 /* NSObject+DixieRunTimeHelper.m in Sources */, F54F5AAD19E83346002EFAEA /* DixieChaosContext.m in Sources */, F573658A1A2A737200D684CE /* ChaosProviderTestClass.m in Sources */, F5529FD81B010F0A002D2004 /* NSDateProfile.m in Sources */, F54F5ABF19E83346002EFAEA /* Dixie+Fluent.m in Sources */, F54F5B1319E835B7002EFAEA /* DixieAPITests.m in Sources */, F56C7E1A1A5EFBFD004B946F /* DixieRandomChaosProvider.m in Sources */, F54F5AC119E83346002EFAEA /* Dixie.m in Sources */, F54F5AE519E83346002EFAEA /* DixieProfileEntry.m in Sources */, F54F5AB519E83346002EFAEA /* DixieExceptionChaosProvider.m in Sources */, F54F5AC519E83346002EFAEA /* DixieSimpleLogger.m in Sources */, F54F5AB319E83346002EFAEA /* DixieConstantChaosProvider.m in Sources */, F54F5AAB19E83346002EFAEA /* DixieBlockChaosProvider.m in Sources */, F54F5AB119E83346002EFAEA /* DixieCompositeCondition.m in Sources */, F5529FA91AFD3E12002D2004 /* TestClass.m in Sources */, F53EBAC21A1007AF004FAC40 /* RunTimeHelperTests.m in Sources */, F54F5AB919E83346002EFAEA /* DixieNonChaosProvider.m in Sources */, F54F5AC319E83346002EFAEA /* DixieLogger.m in Sources */, F54F5AD119E83346002EFAEA /* DixieMethodInfo.m in Sources */, F54F5ABD19E83346002EFAEA /* DixieSequentialChaosProvider.m in Sources */, F54F5AA919E83346002EFAEA /* DixieBaseChaosProvider.m in Sources */, F54F5B1719E835B7002EFAEA /* ProfileEntryTests.m in Sources */, F54F5AE719E83346002EFAEA /* DixieDefaultPuppetMaker.m in Sources */, F5529FAA1AFD3E12002D2004 /* SubTestClass.m in Sources */, F54F5B1419E835B7002EFAEA /* DixieChaosProviderTests.m in Sources */, F5529FA41AFD3C96002D2004 /* DixieBaseParamProvider.m in Sources */, F5529FC61AFD4A82002D2004 /* DixieCallEnvironment.m in Sources */, F54F5B1119E835B7002EFAEA /* TestPuppetMaker.m in Sources */, F54F5AB719E83346002EFAEA /* DixieNilChaosProvider.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ F5965A5319C0796C00ED0A6A /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; }; name = Debug; }; F5965A5419C0796C00ED0A6A /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = YES; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; }; name = Release; }; F5965A5619C0796C00ED0A6A /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; }; name = Debug; }; F5965A5719C0796C00ED0A6A /* Release */ = { isa = XCBuildConfiguration; buildSettings = { OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; }; name = Release; }; F5965A5919C0796C00ED0A6A /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { FRAMEWORK_SEARCH_PATHS = ( "$(SDKROOT)/Developer/Library/Frameworks", "$(inherited)", ); GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); INFOPLIST_FILE = DixieTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; }; F5965A5A19C0796C00ED0A6A /* Release */ = { isa = XCBuildConfiguration; buildSettings = { FRAMEWORK_SEARCH_PATHS = ( "$(SDKROOT)/Developer/Library/Frameworks", "$(inherited)", ); INFOPLIST_FILE = DixieTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ F5965A3F19C0796C00ED0A6A /* Build configuration list for PBXProject "Dixie" */ = { isa = XCConfigurationList; buildConfigurations = ( F5965A5319C0796C00ED0A6A /* Debug */, F5965A5419C0796C00ED0A6A /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; F5965A5519C0796C00ED0A6A /* Build configuration list for PBXNativeTarget "Dixie" */ = { isa = XCConfigurationList; buildConfigurations = ( F5965A5619C0796C00ED0A6A /* Debug */, F5965A5719C0796C00ED0A6A /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; F5965A5819C0796C00ED0A6A /* Build configuration list for PBXNativeTarget "DixieTests" */ = { isa = XCConfigurationList; buildConfigurations = ( F5965A5919C0796C00ED0A6A /* Debug */, F5965A5A19C0796C00ED0A6A /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = F5965A3C19C0796C00ED0A6A /* Project object */; } ================================================ FILE: Dixie/Dixie.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: Dixie/Dixie.xcodeproj/xcshareddata/xcschemes/Dixie.xcscheme ================================================ ================================================ FILE: Dixie/Dixie.xcodeproj/xcshareddata/xcschemes/DixieTests.xcscheme ================================================ ================================================ FILE: Dixie/DixieTests/Helpers/ChaosProviderTestClass.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import #import typedef int(^TestBlockType)(double, BOOL); @protocol ChaosProviderTestClassDelegate -(BOOL) isItTrue; @end /*! A class to test various method types */ @interface ChaosProviderTestClass : NSObject @property (nonatomic, weak) id testDelegate; -(id) returnValue; -(NSNumber*) numberFromInteger:(int)integer; -(NSString*) variadicMethod:(id)key,... NS_REQUIRES_NIL_TERMINATION; -(int) returnIntValue; +(void) classDoNothing; -(void) throwException; -(void) doNothing; -(void) setNumber:(int)number object:(NSNumber *)numberObj block:(dispatch_block_t)block; -(void) setChar:(char)aChar frame:(CGRect)frame; -(id) arg1:(NSNumber *)arg1 arg2:(NSInteger)arg2 arg3:(double)arg3 arg4:(float)arg4 arg5:(int)arg5 arg6:(int*)arg6 arg7:(BOOL)arg7 arg8:(char)arg8 arg9:(short)arg9 arg10:(long)arg10; -(float) valueFrom:(double)doubleValue; -(TestBlockType) block; @end @interface ChaosProviderTestClass(aCategory) -(unsigned int) randomIntFrom:(int)k; @end ================================================ FILE: Dixie/DixieTests/Helpers/ChaosProviderTestClass.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "ChaosProviderTestClass.h" @implementation ChaosProviderTestClass - (instancetype)init { self = [super init]; if (self) { } return self; } + (void)classDoNothing { } -(id)returnValue { return @2; } -(NSNumber*) numberFromInteger:(int)integer { return @(integer); } -(NSString*) variadicMethod:(id)key,... NS_REQUIRES_NIL_TERMINATION { return @""; } -(int)returnIntValue { return 42; } - (void)throwException { @throw [NSException exceptionWithName:@"Test" reason:@"Arbitrary reason" userInfo:nil]; } - (void)doNothing { } -(void) setNumber:(int)number object:(NSNumber *)numberObj block:(dispatch_block_t)block; { } -(void) setChar:(char)aChar frame:(CGRect)frame { } -(short) _veryPrivateMethod { return 0; } -(id) arg1:(NSNumber *)arg1 arg2:(NSInteger)arg2 arg3:(double)arg3 arg4:(float)arg4 arg5:(int)arg5 arg6:(int*)arg6 arg7:(BOOL)arg7 arg8:(char)arg8 arg9:(short)arg9 arg10:(long)arg10 { return [@(arg1.integerValue + arg2 + arg3 + arg4 + arg5 + *arg6 + arg7 +arg8 + arg9 + arg10) stringValue]; } -(float) valueFrom:(double)doubleValue { return [@(doubleValue) floatValue]; } -(TestBlockType) block { return ^int(double d, BOOL b){ return b ? d : 42;}; } @end @implementation ChaosProviderTestClass (aCategory) -(unsigned int) randomIntFrom:(int)k { return arc4random_uniform(k); } @end ================================================ FILE: Dixie/DixieTests/Helpers/SubTestClass.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "TestClass.h" /** * Inheriting form RunTestClass, this methods defines methods that can be used in ProfileEnty tests */ @interface SubTestClass : TestClass -(void)specialMethod; @end ================================================ FILE: Dixie/DixieTests/Helpers/SubTestClass.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "SubTestClass.h" @implementation SubTestClass -(void)specialMethod { } -(void) doNothing { } @end ================================================ FILE: Dixie/DixieTests/Helpers/TestClass.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import #import @interface TestClass : NSObject + (void)classDoNothing; - (id)returnValue; - (int)returnIntValue; - (void)doNothing; -(void) setNumber:(int)number object:(NSNumber *)numberObj block:(dispatch_block_t)block; -(void) setChar:(char)aChar frame:(CGRect)frame; @end ================================================ FILE: Dixie/DixieTests/Helpers/TestClass.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "TestClass.h" @implementation TestClass + (void)classDoNothing { } - (id)returnValue { return @2; } - (int)returnIntValue { return 42; } - (void)doNothing { } -(void) setNumber:(int)number object:(NSNumber *)numberObj block:(dispatch_block_t)block; { } -(void) setChar:(char)aChar frame:(CGRect)frame { } @end ================================================ FILE: Dixie/DixieTests/Helpers/TestPuppetMaker.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. @import Foundation; #import "DixiePuppetMaking.h" @interface TestPuppetMaker : NSObject @property BOOL isCreateCalled; @property BOOL isDismissCalled; @end ================================================ FILE: Dixie/DixieTests/Helpers/TestPuppetMaker.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "TestPuppetMaker.h" @implementation TestPuppetMaker -(id) init { if (self = [super init]) { self.isCreateCalled = NO; self.isDismissCalled = NO; } return self; } -(void) createPuppet:(DixieProfileEntry*)entry seed:(NSInteger)seed { self.isCreateCalled = YES; } -(void) dismissPuppet:(DixieProfileEntry*)entry { self.isDismissCalled = YES; } @end ================================================ FILE: Dixie/DixieTests/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier com.distinction.$(PRODUCT_NAME:rfc1034identifier) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType BNDL CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1 ================================================ FILE: Dixie/DixieTests/Predefined profiles/NSDateProfile.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "DixieProfileEntry.h" /** * A simple ProfileEntry with default values: * victim: NSDate * selector: date * chaosProvider: ConstantChaosProvider for next week */ @interface NSDateProfile : DixieProfileEntry @end ================================================ FILE: Dixie/DixieTests/Predefined profiles/NSDateProfile.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "NSDateProfile.h" #import "DixieConstantChaosProvider.h" @implementation NSDateProfile -(instancetype) init { return [[self class] entry:[NSDate class] selector:@selector(date) chaosProvider:[DixieConstantChaosProvider constant:[NSDate dateWithTimeIntervalSinceNow:60*60*24]]]; } @end ================================================ FILE: Dixie/DixieTests/Predefined profiles/NSURLConnectionProfile.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "DixieProfileEntry.h" /** * A simple ProfileEntry with default values: * victim: NSURLConnection * selector: canHandleRequest: * chaosProvider: NilChaosProvider */ @interface NSURLConnectionProfile : DixieProfileEntry @end ================================================ FILE: Dixie/DixieTests/Predefined profiles/NSURLConnectionProfile.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "NSURLConnectionProfile.h" #import "DixieNilChaosProvider.h" @implementation NSURLConnectionProfile -(instancetype) init { return [[self class] entry:[NSURLConnection class] selector:@selector(canHandleRequest:) chaosProvider:[DixieNilChaosProvider new]]; } @end ================================================ FILE: Dixie/DixieTests/Predefined profiles/NSURLProfile.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "DixieProfileEntry.h" /** * A simple ProfileEntry with default values: * victim: NSURL * selector: URLWithString: * chaosProvider: NilChaosProvider */ @interface NSURLProfile : DixieProfileEntry @end ================================================ FILE: Dixie/DixieTests/Predefined profiles/NSURLProfile.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "NSURLProfile.h" #import "DixieProfileEntry.h" #import "DixieHeaders.h" @implementation NSURLProfile -(instancetype) init { return [[self class] entry:[NSURL class] selector:@selector(URLWithString:) chaosProvider:[DixieNilChaosProvider new]]; } @end ================================================ FILE: Dixie/DixieTests/Units/DixieAPITests.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "DixieHeaders.h" #import #import "NSURLProfile.h" #import "TestPuppetMaker.h" #import "NSURLProfile.h" @interface DixieAPITests : XCTestCase { Dixie* dixie; } @end @implementation DixieAPITests - (void)setUp { [super setUp]; // Put setup code here. This method is called before the invocation of each test method in the class. dixie = [Dixie new]; } - (void)tearDown { // Put teardown code here. This method is called after the invocation of each test method in the class. [super tearDown]; [dixie revert]; } -(void) testPuppetMakerCreatePuppetCalled { //GIVEN TestPuppetMaker* puppetMaker = [TestPuppetMaker new]; //WHEN dixie .PuppetMaker(puppetMaker) .Profile([NSURLProfile new]) .Apply(); //THEN XCTAssert(puppetMaker.isCreateCalled == YES, @"CreatePuppet protocol function should be called"); } -(void) testPuppetMakerMultiplePuppetCreationReverted { //GIVEN NSURLProfile* profile = [NSURLProfile new]; //WHEN dixie .Profile(profile) .Apply(); dixie.Apply(); dixie.RevertIt(profile); //THEN XCTAssert([[NSURL URLWithString:@"http://www.something.net"].absoluteString isEqualToString:@"http://www.something.net"], @"Multiple puppet creation should be reverted"); } -(void) testPuppetMakerDismissPuppetCalled { //GIVEN TestPuppetMaker* puppetMaker = [TestPuppetMaker new]; dixie .PuppetMaker(puppetMaker) .Profile([NSURLProfile new]) .Apply(); //WHEN dixie .Revert(); //THEN XCTAssert(puppetMaker.isDismissCalled == YES, @"DismissPuppet protocol function should be called"); } -(void) testSingleProfileAdded { //GIVEN DixieProfileEntry* singleProfile = [NSURLProfile new]; //WHEN dixie .Profile(singleProfile) .Apply(); //THEN XCTAssert( [NSURL URLWithString:@"http://www.something.net"] == nil, @"NSURL should be nil"); } -(void) testPuppetCanBeCalledMultipleTimes { //GIVEN DixieProfileEntry* singleProfile = [NSURLProfile new]; //WHEN dixie .Profile(singleProfile) .Apply(); //THEN XCTAssert( [NSURL URLWithString:@"http://www.something.net"] == nil && [NSURL URLWithString:@"http://www.something.net"] == nil, @"NSURL should be nil"); } -(void) testSingleProfileReverted { //GIVEN DixieProfileEntry* entry1 = [DixieProfileEntry entry:[NSURL class] selector:@selector(URLWithString:) chaosProvider:[DixieNilChaosProvider new]]; DixieProfileEntry* entry2 = [DixieProfileEntry entry:[NSURL class] selector:@selector(baseURL) chaosProvider:[DixieNilChaosProvider new]]; dixie .Profiles(@[entry1 , entry2]) .Apply(); //WHEN dixie.RevertIt(entry1); //THEN NSURL* url = [NSURL URLWithString:@"http://something.net"]; XCTAssert(url != nil && url.baseURL == nil, @"First entry should be reverted and second not"); } -(void) testMultipleProfileReverted { //GIVEN DixieProfileEntry* entry1 = [DixieProfileEntry entry:[NSURL class] selector:@selector(URLWithString:) chaosProvider:[DixieNilChaosProvider new]]; DixieProfileEntry* entry2 = [DixieProfileEntry entry:[NSURL class] selector:@selector(baseURL) chaosProvider:[DixieNilChaosProvider new]]; dixie .Profiles(@[entry1 , entry2]) .Apply(); //WHEN dixie.Revert(); //THEN NSURL* url = [NSURL URLWithString:@"http://something.net"]; XCTAssert(url != nil && url.baseURL == nil, @"First entry should be reverted and second not"); } @end ================================================ FILE: Dixie/DixieTests/Units/DixieChaosProviderTests.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import #import "DixieHeaders.h" #import "ChaosProviderTestClass.h" #import "NSObject+DixieRunTimeHelper.h" @interface DixieChaosProviderTests : XCTestCase { Dixie* dixie; } @end @implementation DixieChaosProviderTests - (void)setUp { [super setUp]; // Put setup code here. This method is called before the invocation of each test method in the class. dixie = [Dixie new]; } - (void)tearDown { // Put teardown code here. This method is called after the invocation of each test method in the class. [dixie revert]; [super tearDown]; } #pragma mark - Nil -(void) testFluentNilChaosProvider { DixieProfileEntry* profile = [DixieProfileEntry entry:[ChaosProviderTestClass class] selector:@selector(returnValue) chaosProvider:[DixieNilChaosProvider new]]; dixie .Profile(profile) .Apply(); id value = [[ChaosProviderTestClass new] returnValue]; XCTAssert( value == nil , "Value should be nil"); } #pragma mark - Non -(void) testNonChaosProvider { DixieProfileEntry* profile = [DixieProfileEntry entry:[ChaosProviderTestClass class] selector:@selector(returnValue) chaosProvider:[DixieNonChaosProvider new]]; dixie .Profile(profile) .Apply(); id value = [[ChaosProviderTestClass new] returnValue]; XCTAssert([value isEqualToNumber:@2], "ChaosProviderTestClass should be kept unchanged"); } -(void) testForwardChaosToNonChaosProvider { DixieProfileEntry* profile = [DixieProfileEntry entry:[ChaosProviderTestClass class] selector:@selector(returnValue) chaosProvider:[DixieBlockChaosProvider block:^(DixieBaseChaosProvider *chaosProvider, id victim, DixieCallEnvironment *environment) { [chaosProvider forwardChaosOf:victim environment:environment to:[DixieNonChaosProvider new]]; }]]; dixie .Profile(profile) .Apply(); NSDate* date = [NSDate date]; XCTAssert(date, "NSDate should be kept unchanged"); } #pragma mark - Constant -(void) testConstantChaosProvider { DixieProfileEntry* profile = [DixieProfileEntry entry:[ChaosProviderTestClass class] selector:@selector(returnValue) chaosProvider:[DixieConstantChaosProvider constant:@7]]; dixie .Profile(profile) .Apply(); id value = [[ChaosProviderTestClass new] returnValue]; XCTAssert( [value isEqualToNumber:@7] , "Number should be 7"); } #pragma mark - Composite -(void) testCompositeChaosProvider { DixieCompositeCondition* condition = [DixieCompositeCondition condition:0 value:@2 chaosProvider:[DixieNilChaosProvider new]]; DixieCompositeChaosProvider* provider = [DixieCompositeChaosProvider conditions:@[condition]]; DixieProfileEntry* profile = [DixieProfileEntry entry:[ChaosProviderTestClass class] selector:@selector(numberFromInteger:) chaosProvider:provider]; dixie .Profile(profile) .Apply(); id value = [[ChaosProviderTestClass new] numberFromInteger:2]; XCTAssert(value == nil, "Value should be nil"); value = [[ChaosProviderTestClass new] numberFromInteger:8]; XCTAssert([value isEqualToNumber:@8], "Value should be created"); } #pragma mark - Block -(void) testBlockChaosProvider { DixieBlockChaosProvider* provider = [DixieBlockChaosProvider block:^(DixieBaseChaosProvider* provider, id victim, DixieCallEnvironment *environment) { NSNumber* param = [environment.arguments firstObject]; environment.returnValue = (__bridge void *)(@(param.integerValue + 1)); }]; DixieProfileEntry* profile = [DixieProfileEntry entry:[ChaosProviderTestClass class] selector:@selector(numberFromInteger:) chaosProvider:provider]; dixie .Profile(profile) .Apply(); id value = [[ChaosProviderTestClass new] numberFromInteger:2]; XCTAssert([value isEqualToNumber:@3] , "Value should be incremented"); } #pragma mark - Random -(void) testRandomIntChaosProvider { DixieProfileEntry* profile = [DixieProfileEntry entry:[ChaosProviderTestClass class] selector:@selector(returnValue) chaosProvider:[DixieRandomChaosProvider randomProvider:[DixieRandomParamProvider providerWithUpperBound:100]]]; dixie .Profile(profile) .Apply(); id returnValue = [[ChaosProviderTestClass new] returnValue]; id returnValue2 = [[ChaosProviderTestClass new] returnValue]; XCTAssert(![returnValue isEqualToNumber:returnValue2], "Values should be random"); } #pragma mark - Exception -(void) testExceptionChaosProvider { DixieProfileEntry* profile = [DixieProfileEntry entry:[ChaosProviderTestClass class] selector:@selector(returnValue) chaosProvider:[DixieExceptionChaosProvider exception:[NSException exceptionWithName:@"ChaosProviderException" reason:@"ExceptionChaosProvider was applied" userInfo:nil]]]; dixie .Profile(profile) .Apply(); XCTAssertThrowsSpecificNamed([[ChaosProviderTestClass new] returnValue], NSException, @"ChaosProviderException", @"Should throw a NSException"); } #pragma mark - Sequential -(void) testSequentalChaosProvider { //GIVEN DixieProfileEntry* profile = [DixieProfileEntry entry:[ChaosProviderTestClass class] selector:@selector(returnValue) chaosProvider:[DixieSequentialChaosProvider sequence:@[ [DixieNilChaosProvider new] , [DixieConstantChaosProvider constant:@2]]]]; dixie .Profile(profile) .Apply(); //WHEN id returnValue = [[ChaosProviderTestClass new] returnValue]; id returnValue2 = [[ChaosProviderTestClass new] returnValue]; //THEN XCTAssert(returnValue == nil && [returnValue2 isEqual:@2], @"Sequential should return nil for the first call and @2 for the second call"); } -(void) testSequentialReturnsLastAtOutOfBounds { //GIVEN DixieProfileEntry* profile = [DixieProfileEntry entry:[ChaosProviderTestClass class] selector:@selector(returnValue) chaosProvider:[DixieSequentialChaosProvider sequence:@[ [DixieNilChaosProvider new] , [DixieConstantChaosProvider constant:@2]]]]; dixie .Profile(profile) .Apply(); //WHEN [[ChaosProviderTestClass new] returnValue]; [[ChaosProviderTestClass new] returnValue]; id returnValue = [[ChaosProviderTestClass new] returnValue]; //THEN XCTAssert([returnValue isEqual:@2], @"Sequential should return the result of the last chaos provider, when called more then the count of the defined providers"); } #pragma mark - Variadic -(void) testChaosForwardedToVariadic { //GIVEN DixieBlockChaosProvider* blockProvider = [DixieBlockChaosProvider block:^(DixieBaseChaosProvider *chaosProvider, id victim, DixieCallEnvironment *environment) { [chaosProvider forwardChaosOf:victim environment:environment to:[DixieNonChaosProvider new]]; }]; DixieProfileEntry* entry = [DixieProfileEntry entry:[ChaosProviderTestClass class] selector:@selector(variadicMethod:) chaosProvider:blockProvider]; dixie .Profile(entry) .Apply(); ChaosProviderTestClass* testObject = [ChaosProviderTestClass new]; //WHEN NSString* string = [testObject variadicMethod:@"key", @"haho", @2, nil]; //THEN XCTAssert([string isEqualToString:@""], @"Original variadic function should be called"); } -(void) testVariadicStubbed { //GIVEN DixieConstantChaosProvider *provider = [DixieConstantChaosProvider constant:@"Hello"]; DixieProfileEntry *entry = [DixieProfileEntry entry:[ChaosProviderTestClass class] selector:@selector(variadicMethod:) chaosProvider:provider]; dixie.Profile(entry).Apply(); //WHEN NSString *string = [[ChaosProviderTestClass new] variadicMethod:@"key",@2,nil]; //THEN XCTAssert([string isEqualToString:@"Hello"], @"Wrong return value for variadic stubbing"); } #pragma mark - Primitives -(void) testChaosForPrimitiveReturnType { //GIVEN int intValue = 11; DixieBlockChaosProvider* blockProvider = [DixieBlockChaosProvider block:^(DixieBaseChaosProvider *chaosProvider, id victim, DixieCallEnvironment *environment) { environment.returnValue = (void *)&intValue; }]; DixieProfileEntry* entry = [DixieProfileEntry entry:[ChaosProviderTestClass class] selector:@selector(returnIntValue) chaosProvider:blockProvider]; dixie .Profile(entry) .Apply(); ChaosProviderTestClass* testObject = [ChaosProviderTestClass new]; //WHEN int returnedIntValue = [testObject returnIntValue]; //THEN XCTAssert(returnedIntValue == 11, @"New int value should be returned"); } -(void) testChaosPrimitiveParameterIsForwarded { //GIVEN DixieBlockChaosProvider* blockProvider = [DixieBlockChaosProvider block:^(DixieBaseChaosProvider *chaosProvider, id victim, DixieCallEnvironment *environment) { NSNumber *newNumber = @11; storeOriginal(@11, int, 11); NSMutableArray *myArguments = [environment.arguments mutableCopy]; myArguments[0] = newNumber; environment.arguments = myArguments; [chaosProvider forwardChaosOf:victim environment:environment to:[DixieNonChaosProvider new]]; }]; DixieProfileEntry* entry = [DixieProfileEntry entry:[ChaosProviderTestClass class] selector:@selector(numberFromInteger:) chaosProvider:blockProvider]; dixie .Profile(entry) .Apply(); ChaosProviderTestClass* testObject = [ChaosProviderTestClass new]; //WHEN NSNumber *number = [testObject numberFromInteger:42]; //THEN XCTAssert([number isEqualToNumber:@11], @"New int value should be returned"); } #pragma mark - Method type fuzzing -(void) testPropertyGetterSetterChanged { //GIVEN DixieBlockChaosProvider *setterBlockProvider = [DixieBlockChaosProvider block:^(DixieBaseChaosProvider *chaosProvider, id victim, DixieCallEnvironment *environment) { //THEN XCTAssert(environment.arguments.firstObject == self, @"First argument is invalid"); }]; DixieBlockChaosProvider *getterBlockProvider = [DixieBlockChaosProvider block:^(DixieBaseChaosProvider *chaosProvider, id victim, DixieCallEnvironment *environment) { environment.returnValue = (__bridge void *)(self); }]; DixieProfileEntry *setterEntry = [DixieProfileEntry entry:[ChaosProviderTestClass class] selector:@selector(setTestDelegate:) chaosProvider:setterBlockProvider]; DixieProfileEntry *getterEntry = [DixieProfileEntry entry:[ChaosProviderTestClass class] selector:@selector(testDelegate) chaosProvider:getterBlockProvider]; ChaosProviderTestClass *testObject = [ChaosProviderTestClass new]; //WHEN dixie.Profile(setterEntry).Apply(); [testObject setTestDelegate:self]; dixie.RevertIt(setterEntry); [testObject setTestDelegate:nil]; dixie.Profile(getterEntry).Apply(); //THEN XCTAssert(testObject.testDelegate == self, @"Getter property invalid"); } -(void) testPrivateMethodChanged { //GIVEN short original = 2; NSNumber *number = @2; storeOriginal(number, short, original); DixieConstantChaosProvider *provider = [DixieConstantChaosProvider constant:number]; dixie .Profile([DixieProfileEntry entry:[ChaosProviderTestClass class] selector:NSSelectorFromString(@"_veryPrivateMethod") chaosProvider:provider]) .Apply(); //WHEN NSNumber *value = [[ChaosProviderTestClass new] valueForKeyPath:@"_veryPrivateMethod"]; //THEN XCTAssert([value isEqualToNumber:@2], @"Private method is not changed"); } -(void) testUltimateMethodChanged { //GIVEN DixieNilChaosProvider *provider = [DixieNilChaosProvider new]; DixieProfileEntry *entry = [DixieProfileEntry entry:[ChaosProviderTestClass class] selector:@selector(arg1:arg2:arg3:arg4:arg5:arg6:arg7:arg8:arg9:arg10:) chaosProvider:provider]; dixie.Profile(entry).Apply(); //WHEN int arg6 = 2; id value = [[ChaosProviderTestClass new] arg1:@2 arg2:2 arg3:2.0 arg4:2.f arg5:2 arg6:&arg6 arg7:NO arg8:'a' arg9:5 arg10:67l]; //THEN XCTAssert(value == nil,@"Ultimate method not changed"); } -(void) testUseBlockParameterOfMethod { //GIVEN __block BOOL called = NO; dispatch_block_t aBlock = ^{called = YES;}; DixieBlockChaosProvider *blockProvider = [DixieBlockChaosProvider block:^(DixieBaseChaosProvider *chaosProvider, id victim, DixieCallEnvironment *environment) { dispatch_block_t block = environment.arguments[2]; block(); }]; DixieProfileEntry *entry = [DixieProfileEntry entry:[ChaosProviderTestClass class] selector:@selector(setNumber:object:block:) chaosProvider:blockProvider]; dixie.Profile(entry).Apply(); //WHEN [[ChaosProviderTestClass new] setNumber:2 object:@2 block:aBlock]; //THEN XCTAssert(called == YES, @"Block parameter of method is not called"); } -(void) testUseBlockReturnType { //GIVEN DixieConstantChaosProvider *provider = [DixieConstantChaosProvider constant:[^int(double d, BOOL b){return (int)b;} copy]]; DixieProfileEntry *entry = [DixieProfileEntry entry:[ChaosProviderTestClass class] selector:@selector(block) chaosProvider:provider]; dixie.Profile(entry).Apply(); //WHEN TestBlockType block = [[ChaosProviderTestClass new] block]; //THEN XCTAssert(block(0.4,YES) == 1, @"Wrong block returned"); } -(void) testCategoryMethodChanged { //GIVEN unsigned int k = 103; NSNumber *number = @(k); storeOriginal(number, unsigned int, k); DixieProfileEntry *entry = [DixieProfileEntry entry:[ChaosProviderTestClass class] selector:@selector(randomIntFrom:) chaosProvider:[DixieConstantChaosProvider constant:number]]; dixie.Profile(entry).Apply(); //WHEN unsigned int n = [[ChaosProviderTestClass new] randomIntFrom:4]; //THEN XCTAssert(n == k, @"Category method is not changed"); } - (void)testProtocolParamUsed { //GIVEN __block BOOL answer = NO; DixieBlockChaosProvider *setterBlockProvider = [DixieBlockChaosProvider block:^(DixieBaseChaosProvider *chaosProvider, id victim, DixieCallEnvironment *environment) { answer = [(id)environment.arguments.firstObject isItTrue]; }]; DixieProfileEntry *setterEntry = [DixieProfileEntry entry:[ChaosProviderTestClass class] selector:@selector(setTestDelegate:) chaosProvider:setterBlockProvider]; dixie.Profile(setterEntry).Apply(); //WHEN [[ChaosProviderTestClass new] setTestDelegate:self]; //THEN XCTAssert(answer == YES, @"Protocol parameter could not be used"); } #pragma mark - ChaosProviderTestClassDelegate -(BOOL) isItTrue { return YES; } @end ================================================ FILE: Dixie/DixieTests/Units/ProfileEntryTests.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import #import "DixieHeaders.h" #import "TestClass.h" #import "SubTestClass.h" #import "NSDateProfile.h" @interface ProfileEntryTests : XCTestCase @end @implementation ProfileEntryTests - (void)setUp { [super setUp]; // Put setup code here. This method is called before the invocation of each test method in the class. } - (void)tearDown { // Put teardown code here. This method is called after the invocation of each test method in the class. [super tearDown]; } - (void)testEntriesCreated { NSArray* excludes = @[NSStringFromSelector(@selector(signature))]; NSArray* entries = [DixieProfileEntry entries:[DixieChaosContext class] excludes:excludes chaosProvider:[DixieNilChaosProvider new]]; BOOL hasExcluded = YES; NSString* selectorName; for (DixieProfileEntry* entry in entries) { selectorName = NSStringFromSelector(entry.methodInfo.selector); if ([excludes containsObject:selectorName]) { hasExcluded = NO; break; } } XCTAssert(hasExcluded, "There should not be a profile entry with excluded selector:%@", selectorName); } -(void) testExcludedClassSelectorsNotIncludedInProfileEntries { //Given Class classToExclude = [TestClass class]; NSArray* excludedSelectors = [DixieRunTimeHelper selectorsForClass:classToExclude]; //When NSArray* entries = [DixieProfileEntry entries:[SubTestClass class] excludeSelectorsOfClass:classToExclude chaosProvider:[DixieNilChaosProvider new]]; //Then BOOL areEntriesCorrect = YES; for (DixieProfileEntry* entry in entries) { NSString* selectorName = NSStringFromSelector(entry.methodInfo.selector); if ([excludedSelectors containsObject:selectorName]) { areEntriesCorrect = NO; break; } } XCTAssertTrue(areEntriesCorrect, @"ProfileEntry method did not excluded the selectors of the class"); } #pragma mark - Pre-defined entries #pragma NSDateProfile -(void) testDateProfileIsCorrect { //GIVEN NSDateProfile* profile = [NSDateProfile new]; //WHEN BOOL isTargetClassCorrect = [profile.methodInfo.targetClass isSubclassOfClass:[NSDate class]]; BOOL isSelectorCorrect = [NSStringFromSelector( profile.methodInfo.selector ) isEqualToString:NSStringFromSelector(@selector(date))]; BOOL isChaosProviderCorrect = [profile.chaosProvider isKindOfClass:[DixieConstantChaosProvider class]]; XCTAssert(isTargetClassCorrect && isSelectorCorrect && isChaosProviderCorrect, @"NSDateProfile should target +[NSDate date] with a ConstantChaosProvider"); } @end ================================================ FILE: Dixie/DixieTests/Units/RandomParamProviderTests.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import #import #import "RandomChaosProvider.h" @interface RandomParamProviderTests : XCTestCase { RandomParamProvider* _paramProvider; } @end @implementation RandomParamProviderTests - (void)setUp { [super setUp]; // Put setup code here. This method is called before the invocation of each test method in the class. _paramProvider = [RandomParamProvider providerWithUpperBound:1000]; } - (void)tearDown { // Put teardown code here. This method is called after the invocation of each test method in the class. [super tearDown]; } - (void)testProviderDoesNotReturnAlwaysSameValue { //GIVEN [_paramProvider setSeed:0]; //WHEN NSNumber* value1 = [_paramProvider parameter]; NSNumber* value2 = [_paramProvider parameter]; NSNumber* value3 = [_paramProvider parameter]; NSArray* numbers = @[value1, value2, value3]; //THEN NSSet* uniqueValues = [NSSet setWithArray:numbers]; XCTAssert(uniqueValues.allObjects.count == numbers.count, @"Some of the values are the same"); } - (void)testProviderReturnsSameSequenceForSameSeed { //GIVEN [_paramProvider setSeed:0]; RandomParamProvider* anotherProvider = [RandomParamProvider providerWithUpperBound:1000]; [anotherProvider setSeed:0]; //WHEN NSMutableArray* sequence = [NSMutableArray array]; NSMutableArray* anotherSequence = [NSMutableArray array]; for (int i = 0; i < 3; i++) { [sequence addObject:[_paramProvider parameter]]; [anotherSequence addObject:[anotherProvider parameter]]; } //THEN XCTAssert([sequence isEqualToArray:anotherSequence], @"Random generator should return same sequence with same starting seed"); } @end ================================================ FILE: Dixie/DixieTests/Units/RunTimeHelperTests.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import #import "DixieRunTimeHelper.h" #import "TestClass.h" @interface DixieRunTimeHelper(UnitTest) +(NSArray*) argumentsFor:(NSMethodSignature*)signature originalArguments:(va_list)arguments; +(id) objectFromNext:(va_list)arguments type:(const char*)argType outputArgumentList:(out void *)oVa_List; +(id) blockForSignature:(NSMethodSignature*)signature block:(DixieImplementationBlock)block; @end @interface RunTimeHelperTests : XCTestCase @end @implementation RunTimeHelperTests - (void)setUp { [super setUp]; // Put setup code here. This method is called before the invocation of each test method in the class. } - (void)tearDown { // Put teardown code here. This method is called after the invocation of each test method in the class. [super tearDown]; } - (void)testCorrectImplementationCalled { //Given DixieMethodInfo* info = [DixieMethodInfo infoWithClass:[TestClass class] selector:@selector(returnValue)]; DixieChaosContext* context = [[DixieChaosContext alloc] init:0 methodInfo:info]; //When __block BOOL isIMPCalled = NO; id(*implementation)(id,SEL) = (id(*)(id,SEL))[DixieRunTimeHelper implementationWithChaosContext:context environment:^(id victim, DixieCallEnvironment *environment) { isIMPCalled = YES; }]; implementation([TestClass new], @selector(returnValue)); XCTAssert(isIMPCalled, @"Correct IMP should be returned"); } -(void)testImplementationIsCalled { //Given DixieMethodInfo* info = [DixieMethodInfo infoWithClass:[TestClass class] selector:@selector(returnValue)]; DixieChaosContext* context = [[DixieChaosContext alloc] init:0 methodInfo:info]; DixieCallEnvironment* environment = [DixieCallEnvironment new]; IMP implementation = [[TestClass new] methodForSelector:@selector(returnValue)]; //When [DixieRunTimeHelper callImplementation:implementation on:[TestClass new] chaosContext:context environment:environment]; //Then XCTAssert([(NSNumber *)environment.returnValue isEqualToNumber:@2], @"IMP should be called correctly"); } -(void)testClassVoidImplementationIsCalled { //Given DixieMethodInfo* info = [DixieMethodInfo infoWithClass:[TestClass class] selector:@selector(classDoNothing)]; DixieChaosContext* context = [[DixieChaosContext alloc] init:0 methodInfo:info]; DixieCallEnvironment* environment = [DixieCallEnvironment new]; IMP implementation = [[TestClass class] methodForSelector:@selector(classDoNothing)]; //When @try { [DixieRunTimeHelper callImplementation:implementation on:[TestClass class] chaosContext:context environment:environment]; } @catch (NSException *exception) { //Then XCTFail(@"Class void implementation should be called"); } } - (void)testValuesCorrectlyConverted { //Given - Hack to create va_list id(^testBlock)(const char*, ...) = ^id(const char* encoding, ...){ va_list arguments; va_start(arguments, encoding); id object = [DixieRunTimeHelper objectFromNext:arguments type:encoding outputArgumentList:arguments]; va_end(arguments); return object; }; XCTAssert([testBlock(@encode(char),'c') isEqualToNumber:@('c')], @"%c converted wrongly", 'c'); XCTAssert([testBlock(@encode(int),2) isEqualToNumber:@2], @"%d converted wrongly", 2); XCTAssert([testBlock(@encode(BOOL),YES) isEqualToNumber:@YES], @"%d converted wrongly", YES); XCTAssert([testBlock(@encode(long),12345678L) isEqualToNumber:@12345678L], @"%ld converted wrongly", 12345678L); XCTAssert([testBlock(@encode(float), 4.5f) isEqualToNumber:@4.5f], @"%f converted wrongly", 4.5f); XCTAssert([testBlock(@encode(double),5.0) isEqualToNumber:@5.0], @"%lf converted wrongly", 5.0); XCTAssert([testBlock(@encode(char*),"temp") isEqualToString:@"temp"], @"%s converted wrongly", "temp"); XCTAssert([testBlock(@encode(Class),[NSNumber class]) isEqualToString:@"NSNumber"], @"%@ converted wrongly", [NSNumber class]); XCTAssert([testBlock(@encode(SEL),@selector(testValuesCorrectlyConverted)) isEqualToString:@"testValuesCorrectlyConverted"], @"%@ converted wrongly", NSStringFromSelector(@selector(testValuesCorrectlyConverted))); } //Structs are currently not supported, so DixieRunTimeHelper will fail and adds an NSNull into the arguments array -(void) testArgumentObjectsCreatedCorrectly { //Given - Hack to create va_list ^(NSString* first, ...){ NSArray* expectedValues = @[ @('c'), [NSNull null] ]; va_list arguments; va_start(arguments, first); NSMethodSignature* signature = [[TestClass new] methodSignatureForSelector:@selector(setChar:frame:)]; //When NSArray* values = [DixieRunTimeHelper argumentsFor:signature originalArguments:arguments]; va_end(arguments); //Then XCTAssert([expectedValues isEqualToArray:values], @"Values should be corrected into objects"); }(@"Input value:",'c', CGRectMake(0, 0, 0, 0)); } -(void) testArgumentObjectsCretedCorrectlyForBlock { //Given NSMethodSignature* signature = [[TestClass new] methodSignatureForSelector:@selector(setNumber:object:block:)]; //When void(^block)(id,...) = [DixieRunTimeHelper blockForSignature:signature block:^(id victim, DixieCallEnvironment *environment) { //Then XCTAssert([environment.arguments[0] intValue] == 2, @"First parameter should be an int"); XCTAssert([environment.arguments[1] isEqualToNumber:@2], @"Second parameter should be an int"); BOOL(^thirdParameter)(void) = environment.arguments[2]; XCTAssert(thirdParameter(), @"Third parameter should be a block"); }]; //For blocks, do NOT send the selector block([TestClass new],2,@2,[^{return YES;} copy]); } -(void) testVoidBlockReturned { //Given NSMethodSignature* signature = [[TestClass new] methodSignatureForSelector:@selector(doNothing)]; //When void(^block)(id,...) = [DixieRunTimeHelper blockForSignature:signature block:^(id victim, DixieCallEnvironment *environment) {}]; //Then @try { block([TestClass new], @selector(doNothing)); } @catch (NSException *exception) { XCTFail(@"Correct void block should be returned"); } } -(void) testIdReturnBlockReturned { //Given NSMethodSignature* signature = [[TestClass new] methodSignatureForSelector:@selector(returnValue)]; //When id(^block)(id, ...) = [DixieRunTimeHelper blockForSignature:signature block:^(id victim, DixieCallEnvironment *environment) { environment.returnValue = (__bridge void *)(@2); }]; //Then @try { id returnValue = block([TestClass new], @selector(returnValue)); XCTAssert([returnValue isEqualToNumber:@2], @"Correct id value should be returned"); } @catch (NSException *exception) { XCTFail(@"Correct void block should be returned"); } } -(void) testIntReturnBlockReturned { //Given NSMethodSignature* signature = [[TestClass new] methodSignatureForSelector:@selector(returnIntValue)]; //When int intValue = 11; int(^block)(id, ...) = [DixieRunTimeHelper blockForSignature:signature block:^(id victim, DixieCallEnvironment *environment) { environment.returnValue = (void *)&intValue; }]; //Then @try { int returnValue = block([TestClass new], @selector(returnValue)); XCTAssert(returnValue == 11, @"Correct int value should be returned"); } @catch (NSException *exception) { XCTFail(@"Correct void block should be returned"); } } -(void) testCorrectSelectorsReturnedForClass { //Given Class testClass = [TestClass class]; NSArray* expectedSelector = @[ NSStringFromSelector(@selector(doNothing)), NSStringFromSelector(@selector(returnValue)), NSStringFromSelector(@selector(setChar:frame:)) ]; //When NSArray* selectors = [DixieRunTimeHelper selectorsForClass:testClass]; //Then for (id selectorString in expectedSelector) { XCTAssert([selectors containsObject:selectorString], @"Selectors should contain: %@", selectorString); } } -(void) testMethodStructIsReturned { //Given DixieMethodInfo* info = [DixieMethodInfo infoWithClass:[TestClass class] selector:@selector(returnValue)]; //When Method m = [DixieRunTimeHelper methodForMethodInfo:info]; //Then XCTAssert(m != NULL, @"Method returned"); } -(void) testCorrectMethodTypeEncodingReturned { //Given DixieMethodInfo* info = [DixieMethodInfo infoWithClass:[TestClass class] selector:@selector(returnValue)]; //When const char* encoding = [DixieRunTimeHelper methodTypeEncodingForMethodInfo:info]; //Then XCTAssert(strcmp(encoding, "@@:") , @"Correct method type encoding should be returned"); } -(void) testClassMethodIsDifferent { //Given DixieMethodInfo* classInfo = [DixieMethodInfo infoWithClass:[NSURL class] selector:@selector(URLWithString:)]; DixieMethodInfo* instanceInfo = [DixieMethodInfo infoWithClass:[NSURL class] selector:@selector(initWithURL:)]; //When Class returnedClass = [DixieRunTimeHelper classForMethodInfo:classInfo]; Class returnedInstanceClass = [DixieRunTimeHelper classForMethodInfo:instanceInfo]; //Then XCTAssert(returnedClass != returnedInstanceClass, @"Class method should have different target class"); } @end ================================================ FILE: Dixie.podspec ================================================ Pod::Spec.new do |s| s.name = "Dixie" s.version = "1.0" s.summary = "An alternative mocking framework." s.license = "Apache License 2.0" s.homepage = "https://medium.com/@Skyscanner/dixie-turning-chaos-to-your-advantage-4f3749e6d485" s.author = { "Peter Adam Wiesner" => "peter.wiesner@skyscanner.net", "Zsolt Varnai" => "zsolt.varnai@skyscanner.net", "Csaba Szabo" => "csaba.szabo@skyscanner.net", "Zsombor Fuszenecker" => "zsombor.fuszenecker@skyscanner.net"} s.platform = :ios s.source = { :git => "https://github.com/Skyscanner/Dixie.git", tag:s.version.to_s} s.source_files = "Dixie/Dixie/**/*.{h,m}" s.public_header_files = "Dixie/Dixie/**/*.h" s.requires_arc = true end ================================================ FILE: DixieBasicChaos.codesnippet ================================================ IDECodeSnippetCompletionPrefix DixieBasicChaos IDECodeSnippetCompletionScopes CodeBlock IDECodeSnippetContents [Dixie new] .Profile([DixieProfileEntry entry:<#class#> selector:@selector(<#selector#>) chaosProvider:<#chaosProvider#>]) .Apply(); IDECodeSnippetIdentifier 4DEE241B-652D-4A02-BA43-F5A44C22A34F IDECodeSnippetLanguage Xcode.SourceCodeLanguage.Objective-C IDECodeSnippetSummary Applies a chaos to a class' selector IDECodeSnippetTitle Dixie Basic Chaos IDECodeSnippetUserSnippet IDECodeSnippetVersion 2 ================================================ FILE: DixieExampleApp/DixieExampleApp/AppDelegate.h ================================================ // // AppDelegate.h // WhenIsWWDC // // Created by Skyscanner on 15/05/15. // Copyright (c) 2015 Skyscanner. All rights reserved. // #import @interface AppDelegate : UIResponder @property (strong, nonatomic) UIWindow *window; @end ================================================ FILE: DixieExampleApp/DixieExampleApp/AppDelegate.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "AppDelegate.h" @interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { return YES; } @end ================================================ FILE: DixieExampleApp/DixieExampleApp/Base.lproj/LaunchScreen.xib ================================================ ================================================ FILE: DixieExampleApp/DixieExampleApp/Base.lproj/Main.storyboard ================================================ ================================================ FILE: DixieExampleApp/DixieExampleApp/CountDownViewController.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import #import "DixieHeaders.h" @interface CountDownViewController : UIViewController { NSDate* nextHalleyVisit; NSTimer* timer; } @property (weak, nonatomic) IBOutlet UILabel *countdownLabel; @property (weak, nonatomic) IBOutlet UILabel *actualDate; - (void) updateTime; - (IBAction)tapUpdateTimeButton:(id)sender; - (IBAction)revertDixie:(id)sender; @end ================================================ FILE: DixieExampleApp/DixieExampleApp/CountDownViewController.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "CountDownViewController.h" @interface CountDownViewController () { Dixie *myDixie; DixieProfileEntry *previousEntry; } @end @implementation CountDownViewController - (void) viewDidLoad { // Set Halley's Comet next perihelion predicted (28 July 2061) nextHalleyVisit = [NSDate dateWithTimeIntervalSince1970:2889777600]; // Start timer timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateTime) userInfo:nil repeats:YES]; // Initialise Dixie myDixie = [Dixie new]; } - (void) viewDidDisappear:(BOOL)animated { // Revert Dixie when change a Tab - next time it will start with the original state myDixie.Revert(); } - (void) updateTime { // Check if it's future date or not NSComparisonResult result = [[NSDate date] compare:nextHalleyVisit]; // Prepare date variables NSCalendar* calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; int units = NSCalendarUnitYear | NSCalendarUnitDay; NSDateComponents* components = [calendar components:units fromDate:[NSDate date] toDate:nextHalleyVisit options:0]; switch (result) { case NSOrderedAscending: // Update countdown timer [self.countdownLabel setText:[NSString stringWithFormat:@"%ld%c - %ld%c", (long)[components year], 'y', (long)[components day], 'd']]; break; case NSOrderedDescending: self.countdownLabel.text=@"Already started/ended."; break; case NSOrderedSame: self.countdownLabel.text=@"It's just starting now!"; break; default: NSLog(@"Error Comparing Dates"); break; } // Update actual date timer NSDate *now = [NSDate date]; NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateFormat:@"yyyy-MM-dd-HH-mm-ss"]; self.actualDate.text = [dateFormatter stringFromDate:now]; } - (IBAction)tapUpdateTimeButton:(id)sender { // Generate a date between -10000 and +10000 days int randDays = arc4random() % 10000; if ((arc4random() % 2) == 1) { randDays = randDays * -1; } NSDate* testDate = [NSDate dateWithTimeIntervalSinceNow:86000*randDays]; // Creating a Constant provider DixieBaseChaosProvider* provider = [DixieConstantChaosProvider constant:testDate]; // Creating an Entry to change [NSDate date] DixieProfileEntry* entry = [DixieProfileEntry entry:[NSDate class] selector:@selector(date) chaosProvider:provider]; // Revert the previously set entry if (previousEntry != nil) { myDixie.RevertIt(previousEntry); } // Set and apply the Entry myDixie.Profile(entry).Apply(); // Save the previous entry - to be able to revert it previousEntry = entry; } - (IBAction)revertDixie:(id)sender { // Revert the previosuly set Entry myDixie.RevertIt(previousEntry); } @end ================================================ FILE: DixieExampleApp/DixieExampleApp/Images.xcassets/AppIcon.appiconset/Contents.json ================================================ { "images" : [ { "size" : "29x29", "idiom" : "iphone", "filename" : "Icon-Small@2x.png", "scale" : "2x" }, { "size" : "29x29", "idiom" : "iphone", "filename" : "Icon-Small@3x.png", "scale" : "3x" }, { "size" : "40x40", "idiom" : "iphone", "filename" : "Icon-40@2x.png", "scale" : "2x" }, { "size" : "40x40", "idiom" : "iphone", "filename" : "Icon-40@3x.png", "scale" : "3x" }, { "size" : "60x60", "idiom" : "iphone", "filename" : "Icon-60@2x.png", "scale" : "2x" }, { "size" : "60x60", "idiom" : "iphone", "filename" : "Icon-60@3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: DixieExampleApp/DixieExampleApp/Info.plist ================================================ NSLocationWhenInUseUsageDescription Dixie Example App shows your location on a map CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier net.skyscanner.$(PRODUCT_NAME:rfc1034identifier) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType APPL CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1 LSRequiresIPhoneOS UILaunchStoryboardName LaunchScreen UIMainStoryboardFile Main UIRequiredDeviceCapabilities armv7 NSAppTransportSecurity NSAllowsArbitraryLoads UISupportedInterfaceOrientations UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight ================================================ FILE: DixieExampleApp/DixieExampleApp/MapViewController.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import #import #import #import "DixieHeaders.h" @interface MapViewController : UIViewController { } @property (weak, nonatomic) IBOutlet MKMapView *mapView; @property (weak, nonatomic) IBOutlet UILabel *longitudeLabel; @property (weak, nonatomic) IBOutlet UILabel *latitudeLabel; - (IBAction)dixieChangeLocation:(id)sender; - (IBAction)dixieRevertChanges:(id)sender; @end ================================================ FILE: DixieExampleApp/DixieExampleApp/MapViewController.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "MapViewController.h" @implementation MapViewController { CLLocationManager *locationManager; Dixie *myDixie; DixieProfileEntry *previousEntry; NSArray *mockLocations; CLLocation *actualMockLocation; MKPointAnnotation *actualAnnocation; } - (void) viewDidLoad { [super viewDidLoad]; // Setup location manager locationManager = [[CLLocationManager alloc] init]; locationManager.delegate = self; locationManager.desiredAccuracy = kCLLocationAccuracyKilometer; [locationManager requestWhenInUseAuthorization]; [locationManager setDistanceFilter:100]; [locationManager startUpdatingLocation]; self.mapView.showsUserLocation = NO; // Set annotation actualAnnocation = [[MKPointAnnotation alloc] init]; actualAnnocation.coordinate = locationManager.location.coordinate; [self.mapView addAnnotation:actualAnnocation]; [self.mapView setCenterCoordinate:locationManager.location.coordinate animated:YES]; // Initialise Dixie myDixie = [Dixie new]; // Create mock locations CLLocation *Shanghai = [[CLLocation alloc] initWithLatitude:31.2 longitude:121.5]; CLLocation *Moscow = [[CLLocation alloc] initWithLatitude:55.75 longitude:37.616667]; CLLocation *Tokyo = [[CLLocation alloc] initWithLatitude:35.683333 longitude:139.683333]; CLLocation *MexicoCity = [[CLLocation alloc] initWithLatitude:19.433333 longitude:-99.133333]; CLLocation *NewYorkCity = [[CLLocation alloc] initWithLatitude:40.7127 longitude:-74.0059]; CLLocation *London = [[CLLocation alloc] initWithLatitude:51.507222 longitude:-0.1275]; CLLocation *RioDeJeneiro = [[CLLocation alloc] initWithLatitude:-22.908333 longitude:-43.196389]; CLLocation *LosAngeles = [[CLLocation alloc] initWithLatitude:34.05 longitude:-118.25]; mockLocations = [NSArray arrayWithObjects:Shanghai, Moscow, Tokyo, MexicoCity, NewYorkCity, London, RioDeJeneiro, LosAngeles, nil]; } - (void) viewDidDisappear:(BOOL)animated { // Revert Dixie when change a Tab - next time it will start with the original state myDixie.RevertIt(previousEntry); // Update map [self.mapView setCenterCoordinate:locationManager.location.coordinate animated:YES]; actualAnnocation.coordinate = locationManager.location.coordinate; [locationManager stopUpdatingLocation]; } - (IBAction)dixieChangeLocation:(id)sender { // Set mock location and annocation actualMockLocation = [mockLocations objectAtIndex:(arc4random() % 8)]; [self.mapView setCenterCoordinate:actualMockLocation.coordinate animated:YES]; actualAnnocation.coordinate = actualMockLocation.coordinate; // Create a block provider DixieBaseChaosProvider *provider = [DixieBlockChaosProvider block:^(DixieBaseChaosProvider *chaosProvider, id victim, DixieCallEnvironment *environment) { // chaos: return with the actualMockLocation NSMutableArray* myArguments = [environment.arguments mutableCopy]; NSArray *argument = [NSArray arrayWithObjects:actualMockLocation, nil]; myArguments[1] = argument; environment.arguments = myArguments; // forward the chaos [chaosProvider forwardChaosOf:victim environment:environment to:[DixieNonChaosProvider new]]; }]; // Change locationManager's didUpdateToLocation:fromLocation: method DixieProfileEntry *entry = [DixieProfileEntry entry:[self class] selector:@selector(locationManager:didUpdateLocations:) chaosProvider:provider]; // Revert the previously set entry if (previousEntry != nil) { myDixie.RevertIt(previousEntry); } // Set and apply the Entry myDixie.Profile(entry).Apply(); // Save the previous entry - to be able to revert it previousEntry = entry; // Apply the chaos myDixie.Profile(entry).Apply(); // Call locationManager to make sure that the didUpdateLocations is called [locationManager startUpdatingLocation]; } - (IBAction)dixieRevertChanges:(id)sender { // Revert the previousy entry myDixie.RevertIt(previousEntry); // Reset Map [self.mapView setCenterCoordinate:locationManager.location.coordinate animated:YES]; actualAnnocation.coordinate = locationManager.location.coordinate; } #pragma mark - CLLocationManagerDelegate - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { NSLog(@"didFailWithError: %@", error); UIAlertView *errorAlert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Failed to Get Your Location" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [errorAlert show]; } - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { NSLog(@"didUpdateLocations: %@", locations); CLLocation *currentLocation = [locations objectAtIndex:0]; if (currentLocation != nil) { // update the lon/lat labels self.longitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude]; self.latitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude]; // update the annotation actualAnnocation.coordinate = currentLocation.coordinate; [self.mapView setCenterCoordinate:currentLocation.coordinate animated:YES]; } } @end ================================================ FILE: DixieExampleApp/DixieExampleApp/WeatherModel.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import #import #import @interface WeatherModel : NSObject @property (nonatomic, copy, readonly) NSString *city; @property (nonatomic, readonly) CGFloat tempCurrent; - (void)getCurrentWeatherWithLongitude:(CGFloat)lon andLatitude:(CGFloat)lat andCallback:(void (^)(WeatherModel *))callback; @end ================================================ FILE: DixieExampleApp/DixieExampleApp/WeatherModel.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "WeatherModel.h" @implementation WeatherModel { NSDictionary *weatherServiceResponse; } - (id)init { self = [super init]; weatherServiceResponse = @{}; return self; } - (void)getCurrentWeatherWithLongitude:(CGFloat)lon andLatitude:(CGFloat)lat andCallback:(void (^)(WeatherModel *))callback { // Create the request URL NSString *const BASE_URL_STRING = @"http://api.openweathermap.org/data/2.5/weather"; NSString *weatherURLText = [NSString stringWithFormat:@"%@?lat=%lf&lon=%lf", BASE_URL_STRING, lat, lon]; // Do the request AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; [manager GET:weatherURLText parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) { // Get and parse the response weatherServiceResponse = (NSDictionary *)responseObject; [self parseWeatherServiceResponse]; callback(self); } failure:^(AFHTTPRequestOperation *operation, NSError *error) { // AFNetwork error NSLog(@"Error: %@", error); weatherServiceResponse = @{}; }]; } - (void)parseWeatherServiceResponse { // Convert from Kelvin to Celsius _tempCurrent = [weatherServiceResponse[@"main"][@"temp"] doubleValue] - 273.15; _city = weatherServiceResponse[@"name"]; } @end ================================================ FILE: DixieExampleApp/DixieExampleApp/WeatherViewController.h ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import #import #import "WeatherModel.h" #import "DixieHeaders.h" @interface WeatherViewController : UIViewController @property (weak, nonatomic) IBOutlet UILabel *latitudeLabel; @property (weak, nonatomic) IBOutlet UILabel *longitudeLabel; @property (weak, nonatomic) IBOutlet UILabel *currentTempLabel; - (IBAction)updateWeather:(id)sender; - (IBAction)dixieChangeResponse:(id)sender; - (IBAction)dixieRevertMock:(id)sender; @end ================================================ FILE: DixieExampleApp/DixieExampleApp/WeatherViewController.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import "WeatherViewController.h" @implementation WeatherViewController { CLLocationManager *locationManager; WeatherModel *weather; CGFloat lon; CGFloat lat; Dixie *myDixie; DixieProfileEntry *previousEntry; } - (void)viewDidLoad { [super viewDidLoad]; weather = [[WeatherModel alloc] init]; // Get the location locationManager = [[CLLocationManager alloc] init]; locationManager.desiredAccuracy = kCLLocationAccuracyBest; [locationManager requestAlwaysAuthorization]; lon = locationManager.location.coordinate.longitude; lat = locationManager.location.coordinate.latitude; // Display the location on the view self.longitudeLabel.text = [NSString stringWithFormat:@"%f", lon]; self.latitudeLabel.text = [NSString stringWithFormat:@"%f", lat]; // Init Dixie myDixie = [Dixie new]; } - (void) viewDidDisappear:(BOOL)animated { // Revert Dixie when change a Tab - next time it will start with the original state myDixie.RevertIt(previousEntry); } - (IBAction)updateWeather:(id)sender { // Get weather from the model [weather getCurrentWeatherWithLongitude:lon andLatitude:lat andCallback:^(WeatherModel *response) { // Display city and temperature to the view self.currentTempLabel.text = [NSString stringWithFormat:@"%@ %.1lf °C", response.city, response.tempCurrent]; }]; } - (IBAction)dixieChangeResponse:(id)sender { // Create a Dixie Block provider which will contain the new implementation DixieBlockChaosProvider *getProvider = [DixieBlockChaosProvider block:^(DixieBaseChaosProvider *chaosProvider, id victim, DixieCallEnvironment *environment) { // Get all the method arguments NSMutableArray* myArguments = [environment.arguments mutableCopy]; // Create the mocked data AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] init]; NSString *mockCity = @"Sin City"; NSString *mockTemperatureK = @"324.792"; NSDictionary *responseObject = @{ @"base": @"cmc stations", @"clouds": @{ @"all": @92 }, @"cod": @200, @"coord": @{ @"lat": @"37.33", @"lon": @"-122.03", }, @"dt": @1432213431, @"id": @5341145, @"main": @{ @"grnd_level": @"1015.29", @"humidity": @100, @"pressure": @"1015.29", @"sea_level": @"1027.32", @"temp": mockTemperatureK, @"temp_max": @"284.792", @"temp_min": @"284.792" }, @"name": mockCity, @"rain": @{ @"3h": @"0.41125", }, @"sys": @{ @"country": @"US", @"message": @"0.0102", @"sunrise": @1432212857, @"sunset": @1432264512, }, @"weather": @[ @{ @"description": @"light rain", @"icon": @"10d", @"id": @500, @"main": @"Rain" } ], @"wind": @{ @"deg": @"284.001", @"speed": @"1.46" } }; // Get the 3rd parameter of the "GET:parameters:success:failure:" method, the success block void(^block)(id,...) = [myArguments objectAtIndex:2]; // Call the success block block(operation, responseObject); // Don't forward the chaos to the original Implementation, because I don't want to send out the request to network }]; // Create the Dixie entry DixieProfileEntry *getEntry = [DixieProfileEntry entry:[AFHTTPRequestOperationManager class] selector:@selector(GET:parameters:success:failure:) chaosProvider:getProvider]; // Revert the previously set entry if (previousEntry != nil) { myDixie.RevertIt(previousEntry); } // Save the previous entry - to be able to revert it previousEntry = getEntry; // Set Profile and Apply it myDixie.Profile(getEntry).Apply(); } - (IBAction)dixieRevertMock:(id)sender { myDixie.RevertIt(previousEntry); } @end ================================================ FILE: DixieExampleApp/DixieExampleApp/main.m ================================================ // // Dixie // Copyright 2015 Skyscanner Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and limitations under the License. #import #import "AppDelegate.h" int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } } ================================================ FILE: DixieExampleApp/DixieExampleApp.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 1712B4371B1DE2E300E94E51 /* Clock-32.png in Resources */ = {isa = PBXBuildFile; fileRef = 1712B4361B1DE2E300E94E51 /* Clock-32.png */; }; 1712B43A1B1DE35400E94E51 /* Map-32.png in Resources */ = {isa = PBXBuildFile; fileRef = 1712B4381B1DE35400E94E51 /* Map-32.png */; }; 1712B43B1B1DE35400E94E51 /* Cloud-32.png in Resources */ = {isa = PBXBuildFile; fileRef = 1712B4391B1DE35400E94E51 /* Cloud-32.png */; }; 1712B4401B1DED9300E94E51 /* Lspn_comet_halley.png in Resources */ = {isa = PBXBuildFile; fileRef = 1712B43F1B1DED9300E94E51 /* Lspn_comet_halley.png */; }; 172956671B0A298A000DC70E /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 172956661B0A298A000DC70E /* MapKit.framework */; }; 1738B0C01B0BE1E2009C4039 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1738B0BF1B0BE1E2009C4039 /* AppDelegate.m */; }; 1738B0C31B0BE1EB009C4039 /* MapViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1738B0C21B0BE1EB009C4039 /* MapViewController.m */; }; 1738B0C61B0BE1F4009C4039 /* CountDownViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1738B0C51B0BE1F4009C4039 /* CountDownViewController.m */; }; 1738B0C81B0BE204009C4039 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 1738B0C71B0BE204009C4039 /* main.m */; }; 1738B0C91B0BE21F009C4039 /* libDixie.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 17722FE51B0BE0B300E5E21F /* libDixie.a */; }; 1738B0D31B0BE23A009C4039 /* dixie_logo.png in Resources */ = {isa = PBXBuildFile; fileRef = 1738B0CB1B0BE23A009C4039 /* dixie_logo.png */; }; 1738B0DD1B0BE255009C4039 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1738B0DC1B0BE255009C4039 /* Images.xcassets */; }; 1738B0E21B0BE264009C4039 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1738B0DE1B0BE264009C4039 /* LaunchScreen.xib */; }; 1738B0E31B0BE264009C4039 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1738B0E01B0BE264009C4039 /* Main.storyboard */; }; 1738B0F11B0BE48F009C4039 /* WeatherViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1738B0F01B0BE48F009C4039 /* WeatherViewController.m */; }; 17BD56541B0C5D1200485E99 /* WeatherModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 17BD56531B0C5D1200485E99 /* WeatherModel.m */; }; 17C45D2B1B0A435100F4C10C /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 17C45D2A1B0A435100F4C10C /* CoreLocation.framework */; }; 45CD4B91B2C24760625E845D /* libPods-DixieExampleApp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 820543A0E7A5A8D9FBB1E397 /* libPods-DixieExampleApp.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ 17722FE41B0BE0B300E5E21F /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 17722FDF1B0BE0B200E5E21F /* Dixie.xcodeproj */; proxyType = 2; remoteGlobalIDString = F5965A4419C0796C00ED0A6A; remoteInfo = Dixie; }; 17722FE61B0BE0B300E5E21F /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 17722FDF1B0BE0B200E5E21F /* Dixie.xcodeproj */; proxyType = 2; remoteGlobalIDString = F5965A4F19C0796C00ED0A6A; remoteInfo = DixieTests; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ 1712B4361B1DE2E300E94E51 /* Clock-32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Clock-32.png"; sourceTree = ""; }; 1712B4381B1DE35400E94E51 /* Map-32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Map-32.png"; sourceTree = ""; }; 1712B4391B1DE35400E94E51 /* Cloud-32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Cloud-32.png"; sourceTree = ""; }; 1712B43F1B1DED9300E94E51 /* Lspn_comet_halley.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Lspn_comet_halley.png; sourceTree = ""; }; 172956661B0A298A000DC70E /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = System/Library/Frameworks/MapKit.framework; sourceTree = SDKROOT; }; 1738B0BF1B0BE1E2009C4039 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = DixieExampleApp/AppDelegate.m; sourceTree = SOURCE_ROOT; }; 1738B0C11B0BE1EB009C4039 /* MapViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MapViewController.h; path = DixieExampleApp/MapViewController.h; sourceTree = SOURCE_ROOT; }; 1738B0C21B0BE1EB009C4039 /* MapViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MapViewController.m; path = DixieExampleApp/MapViewController.m; sourceTree = SOURCE_ROOT; }; 1738B0C41B0BE1F4009C4039 /* CountDownViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CountDownViewController.h; path = DixieExampleApp/CountDownViewController.h; sourceTree = SOURCE_ROOT; }; 1738B0C51B0BE1F4009C4039 /* CountDownViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CountDownViewController.m; path = DixieExampleApp/CountDownViewController.m; sourceTree = SOURCE_ROOT; }; 1738B0C71B0BE204009C4039 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = DixieExampleApp/main.m; sourceTree = SOURCE_ROOT; }; 1738B0CB1B0BE23A009C4039 /* dixie_logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = dixie_logo.png; path = DixieExampleApp/dixie_logo.png; sourceTree = SOURCE_ROOT; }; 1738B0DC1B0BE255009C4039 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = DixieExampleApp/Images.xcassets; sourceTree = SOURCE_ROOT; }; 1738B0DF1B0BE264009C4039 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = DixieExampleApp/Base.lproj/LaunchScreen.xib; sourceTree = SOURCE_ROOT; }; 1738B0E11B0BE264009C4039 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = DixieExampleApp/Base.lproj/Main.storyboard; sourceTree = SOURCE_ROOT; }; 1738B0EF1B0BE48F009C4039 /* WeatherViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeatherViewController.h; sourceTree = ""; }; 1738B0F01B0BE48F009C4039 /* WeatherViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WeatherViewController.m; sourceTree = ""; }; 17722FDF1B0BE0B200E5E21F /* Dixie.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Dixie.xcodeproj; path = ../Dixie/Dixie.xcodeproj; sourceTree = ""; }; 17BD56521B0C5D1200485E99 /* WeatherModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeatherModel.h; sourceTree = ""; }; 17BD56531B0C5D1200485E99 /* WeatherModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WeatherModel.m; sourceTree = ""; }; 17BE29BF1B06856D00144FEF /* DixieExampleApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DixieExampleApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; 17BE29C31B06856D00144FEF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 17C45D2A1B0A435100F4C10C /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; }; 820543A0E7A5A8D9FBB1E397 /* libPods-DixieExampleApp.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-DixieExampleApp.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 91D1541A6DBFF2E95E468D61 /* libPods-WhenIsWWDC.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-WhenIsWWDC.a"; sourceTree = BUILT_PRODUCTS_DIR; }; A5A6E20515E680E57C22A7FD /* Pods-DixieExampleApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DixieExampleApp.debug.xcconfig"; path = "Pods/Target Support Files/Pods-DixieExampleApp/Pods-DixieExampleApp.debug.xcconfig"; sourceTree = ""; }; E15280D1C0793F813C6D0626 /* Pods-DixieExampleApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DixieExampleApp.release.xcconfig"; path = "Pods/Target Support Files/Pods-DixieExampleApp/Pods-DixieExampleApp.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 17BE29BC1B06856D00144FEF /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 1738B0C91B0BE21F009C4039 /* libDixie.a in Frameworks */, 17C45D2B1B0A435100F4C10C /* CoreLocation.framework in Frameworks */, 172956671B0A298A000DC70E /* MapKit.framework in Frameworks */, 45CD4B91B2C24760625E845D /* libPods-DixieExampleApp.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 17722FE01B0BE0B200E5E21F /* Products */ = { isa = PBXGroup; children = ( 17722FE51B0BE0B300E5E21F /* libDixie.a */, 17722FE71B0BE0B300E5E21F /* DixieTests.xctest */, ); name = Products; sourceTree = ""; }; 17BE29B61B06856D00144FEF = { isa = PBXGroup; children = ( 17722FDF1B0BE0B200E5E21F /* Dixie.xcodeproj */, 17BE29C11B06856D00144FEF /* DixieExampleApp */, 17BE29C01B06856D00144FEF /* Products */, 5010AFE29675F46E7B8D0389 /* Frameworks */, B5A70F9F333BA3C099A528AF /* Pods */, ); sourceTree = ""; }; 17BE29C01B06856D00144FEF /* Products */ = { isa = PBXGroup; children = ( 17BE29BF1B06856D00144FEF /* DixieExampleApp.app */, ); name = Products; sourceTree = ""; }; 17BE29C11B06856D00144FEF /* DixieExampleApp */ = { isa = PBXGroup; children = ( 17BE29E81B0685F100144FEF /* Images */, 1738B0BF1B0BE1E2009C4039 /* AppDelegate.m */, 1738B0C11B0BE1EB009C4039 /* MapViewController.h */, 1738B0C21B0BE1EB009C4039 /* MapViewController.m */, 1738B0C41B0BE1F4009C4039 /* CountDownViewController.h */, 1738B0C51B0BE1F4009C4039 /* CountDownViewController.m */, 1738B0EF1B0BE48F009C4039 /* WeatherViewController.h */, 1738B0F01B0BE48F009C4039 /* WeatherViewController.m */, 17BD56521B0C5D1200485E99 /* WeatherModel.h */, 17BD56531B0C5D1200485E99 /* WeatherModel.m */, 1738B0DC1B0BE255009C4039 /* Images.xcassets */, 1738B0DE1B0BE264009C4039 /* LaunchScreen.xib */, 1738B0E01B0BE264009C4039 /* Main.storyboard */, 17BE29C21B06856D00144FEF /* Supporting Files */, ); path = DixieExampleApp; sourceTree = ""; }; 17BE29C21B06856D00144FEF /* Supporting Files */ = { isa = PBXGroup; children = ( 17BE29C31B06856D00144FEF /* Info.plist */, 1738B0C71B0BE204009C4039 /* main.m */, ); name = "Supporting Files"; sourceTree = ""; }; 17BE29E81B0685F100144FEF /* Images */ = { isa = PBXGroup; children = ( 1712B4381B1DE35400E94E51 /* Map-32.png */, 1712B4391B1DE35400E94E51 /* Cloud-32.png */, 1712B4361B1DE2E300E94E51 /* Clock-32.png */, 1738B0CB1B0BE23A009C4039 /* dixie_logo.png */, 1712B43F1B1DED9300E94E51 /* Lspn_comet_halley.png */, ); name = Images; sourceTree = ""; }; 5010AFE29675F46E7B8D0389 /* Frameworks */ = { isa = PBXGroup; children = ( 17C45D2A1B0A435100F4C10C /* CoreLocation.framework */, 172956661B0A298A000DC70E /* MapKit.framework */, 91D1541A6DBFF2E95E468D61 /* libPods-WhenIsWWDC.a */, 820543A0E7A5A8D9FBB1E397 /* libPods-DixieExampleApp.a */, ); name = Frameworks; sourceTree = ""; }; B5A70F9F333BA3C099A528AF /* Pods */ = { isa = PBXGroup; children = ( A5A6E20515E680E57C22A7FD /* Pods-DixieExampleApp.debug.xcconfig */, E15280D1C0793F813C6D0626 /* Pods-DixieExampleApp.release.xcconfig */, ); name = Pods; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ 17BE29BE1B06856D00144FEF /* DixieExampleApp */ = { isa = PBXNativeTarget; buildConfigurationList = 17BE29E21B06856D00144FEF /* Build configuration list for PBXNativeTarget "DixieExampleApp" */; buildPhases = ( 64DA7913B5D2132ABBBAA9F1 /* Check Pods Manifest.lock */, 17BE29BB1B06856D00144FEF /* Sources */, 17BE29BC1B06856D00144FEF /* Frameworks */, 17BE29BD1B06856D00144FEF /* Resources */, DA0BE881D48D1E01B5A556B8 /* Copy Pods Resources */, ); buildRules = ( ); dependencies = ( ); name = DixieExampleApp; productName = DixieExampleApp; productReference = 17BE29BF1B06856D00144FEF /* DixieExampleApp.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 17BE29B71B06856D00144FEF /* Project object */ = { isa = PBXProject; attributes = { LastUpgradeCheck = 0630; ORGANIZATIONNAME = Skyscanner; TargetAttributes = { 17BE29BE1B06856D00144FEF = { CreatedOnToolsVersion = 6.3.1; }; }; }; buildConfigurationList = 17BE29BA1B06856D00144FEF /* Build configuration list for PBXProject "DixieExampleApp" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( en, Base, ); mainGroup = 17BE29B61B06856D00144FEF; productRefGroup = 17BE29C01B06856D00144FEF /* Products */; projectDirPath = ""; projectReferences = ( { ProductGroup = 17722FE01B0BE0B200E5E21F /* Products */; ProjectRef = 17722FDF1B0BE0B200E5E21F /* Dixie.xcodeproj */; }, ); projectRoot = ""; targets = ( 17BE29BE1B06856D00144FEF /* DixieExampleApp */, ); }; /* End PBXProject section */ /* Begin PBXReferenceProxy section */ 17722FE51B0BE0B300E5E21F /* libDixie.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; path = libDixie.a; remoteRef = 17722FE41B0BE0B300E5E21F /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; 17722FE71B0BE0B300E5E21F /* DixieTests.xctest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; path = DixieTests.xctest; remoteRef = 17722FE61B0BE0B300E5E21F /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXReferenceProxy section */ /* Begin PBXResourcesBuildPhase section */ 17BE29BD1B06856D00144FEF /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 1738B0D31B0BE23A009C4039 /* dixie_logo.png in Resources */, 1738B0E31B0BE264009C4039 /* Main.storyboard in Resources */, 1738B0DD1B0BE255009C4039 /* Images.xcassets in Resources */, 1712B4401B1DED9300E94E51 /* Lspn_comet_halley.png in Resources */, 1738B0E21B0BE264009C4039 /* LaunchScreen.xib in Resources */, 1712B4371B1DE2E300E94E51 /* Clock-32.png in Resources */, 1712B43B1B1DE35400E94E51 /* Cloud-32.png in Resources */, 1712B43A1B1DE35400E94E51 /* Map-32.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ 64DA7913B5D2132ABBBAA9F1 /* Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); name = "Check Pods Manifest.lock"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; showEnvVarsInLog = 0; }; DA0BE881D48D1E01B5A556B8 /* Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); name = "Copy Pods Resources"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-DixieExampleApp/Pods-DixieExampleApp-resources.sh\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 17BE29BB1B06856D00144FEF /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 17BD56541B0C5D1200485E99 /* WeatherModel.m in Sources */, 1738B0C61B0BE1F4009C4039 /* CountDownViewController.m in Sources */, 1738B0C01B0BE1E2009C4039 /* AppDelegate.m in Sources */, 1738B0C81B0BE204009C4039 /* main.m in Sources */, 1738B0F11B0BE48F009C4039 /* WeatherViewController.m in Sources */, 1738B0C31B0BE1EB009C4039 /* MapViewController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ 1738B0DE1B0BE264009C4039 /* LaunchScreen.xib */ = { isa = PBXVariantGroup; children = ( 1738B0DF1B0BE264009C4039 /* Base */, ); name = LaunchScreen.xib; sourceTree = ""; }; 1738B0E01B0BE264009C4039 /* Main.storyboard */ = { isa = PBXVariantGroup; children = ( 1738B0E11B0BE264009C4039 /* Base */, ); name = Main.storyboard; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ 17BE29E01B06856D00144FEF /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.3; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; }; name = Debug; }; 17BE29E11B06856D00144FEF /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.3; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; }; name = Release; }; 17BE29E31B06856D00144FEF /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = A5A6E20515E680E57C22A7FD /* Pods-DixieExampleApp.debug.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = DixieExampleApp/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; OTHER_LDFLAGS = "$(inherited)"; OTHER_LIBTOOLFLAGS = "$(inherited)"; PRODUCT_NAME = "$(TARGET_NAME)"; USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/../Dixie/Dixie/**"; }; name = Debug; }; 17BE29E41B06856D00144FEF /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = E15280D1C0793F813C6D0626 /* Pods-DixieExampleApp.release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = DixieExampleApp/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; OTHER_LDFLAGS = "$(inherited)"; OTHER_LIBTOOLFLAGS = "$(inherited)"; PRODUCT_NAME = "$(TARGET_NAME)"; USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/../Dixie/Dixie/**"; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 17BE29BA1B06856D00144FEF /* Build configuration list for PBXProject "DixieExampleApp" */ = { isa = XCConfigurationList; buildConfigurations = ( 17BE29E01B06856D00144FEF /* Debug */, 17BE29E11B06856D00144FEF /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 17BE29E21B06856D00144FEF /* Build configuration list for PBXNativeTarget "DixieExampleApp" */ = { isa = XCConfigurationList; buildConfigurations = ( 17BE29E31B06856D00144FEF /* Debug */, 17BE29E41B06856D00144FEF /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 17BE29B71B06856D00144FEF /* Project object */; } ================================================ FILE: DixieExampleApp/DixieExampleApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: DixieExampleApp/DixieExampleApp.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: DixieExampleApp/Podfile ================================================ # Uncomment this line to define a global platform for your project # platform :ios, '6.0' target 'DixieExampleApp' do pod 'AFNetworking' end ================================================ FILE: Documentation/docset/Contents/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleIdentifier com.skyscanner.dixie.Dixie CFBundleName Dixie Documentation CFBundleShortVersionString 1.0 CFBundleVersion 1.0 DocSetFeedName Dixie Documentation DocSetMinimumXcodeVersion 3.0 DashDocSetFamily appledoc DocSetPublisherIdentifier com.skyscanner.dixie.documentation DocSetPublisherName Skyscanner NSHumanReadableCopyright Copyright © 2015 Skyscanner. All rights reserved. ================================================ FILE: Documentation/docset/Contents/Resources/Documents/Blocks/DixieCustomChaosBlock.html ================================================ DixieCustomChaosBlock Block Reference
Declared in DixieBlockChaosProvider.h

Block Definition

DixieCustomChaosBlock

Block type, that can describe a method implementation

typedef void (^DixieCustomChaosBlock) (DixieBaseChaosProvider *chaosProvider, id victim, DixieCallEnvironment *environment)

Discussion

Block type, that can describe a method implementation

Declared In

DixieBlockChaosProvider.h
================================================ FILE: Documentation/docset/Contents/Resources/Documents/Blocks/DixieImplementationBlock.html ================================================ DixieImplementationBlock Block Reference
Declared in DixieRunTimeHelper.h

Block Definition

DixieImplementationBlock

Block type to describe a method’s concrete implementation

typedef void (^DixieImplementationBlock) (id victim, DixieCallEnvironment *environment)

Discussion

Block type to describe a method’s concrete implementation

Declared In

DixieRunTimeHelper.h
================================================ FILE: Documentation/docset/Contents/Resources/Documents/Categories/NSObject+DixieRunTimeHelper.html ================================================ NSObject(DixieRunTimeHelper) Category Reference
Declared in NSObject+DixieRunTimeHelper.h

Overview

Helper category on NSObject to store the original type encoding and value if the object was converted from non-object type

================================================ FILE: Documentation/docset/Contents/Resources/Documents/Classes/Dixie.html ================================================ Dixie Class Reference
Inherits from NSObject
Declared in Dixie.h
Dixie.m

Overview

Represents a Dixie configuration.

Fluent API of Dixie for easier configuration @code [Dixie new].Profile(aProfile).Apply();

Instance Methods

apply

Applies the Dixie configuration.

- (void)apply

Discussion

Applies the Dixie configuration.

Declared In

Dixie.h

apply:

Applies the Dixie configuration with the specified seed (used for random generation).

- (void)apply:(id)seed

Parameters

seed

The seed for random generation

Discussion

Applies the Dixie configuration with the specified seed (used for random generation).

Declared In

Dixie.h

profile:

Registers a single profiles.

- (instancetype)profile:(id)profile

Parameters

profile

A DixieProfileEntry objects.

Return Value

Same Dixie object.

Discussion

Registers a single profiles.

Declared In

Dixie.h

profiles:

Registers profiles.

- (instancetype)profiles:(id)arrayOfEntries

Parameters

arrayOfEntries

Collection of DixieProfileEntry objects.

Return Value

Same Dixie object.

Discussion

Registers profiles.

Declared In

Dixie.h

puppetMaker:

Sets the default puppetmaker

- (instancetype)puppetMaker:(id)puppetMaker

Parameters

puppetMaker

An object that conforms to the PuppetMaking protocol.

Return Value

The active Dixie object

Discussion

Sets the default puppetmaker

Declared In

Dixie.h

revert

Reverts the Dixie configuration.

- (void)revert

Discussion

Reverts the Dixie configuration.

Declared In

Dixie.h

revert:

Reverts one DixieProfileEntry from the Dixie configuration.

- (void)revert:(id)entry

Parameters

entry

The profile to revert

Discussion

Reverts one DixieProfileEntry from the Dixie configuration.

Declared In

Dixie.h
================================================ FILE: Documentation/docset/Contents/Resources/Documents/Classes/DixieBaseChaosProvider.html ================================================ DixieBaseChaosProvider Class Reference
Inherits from NSObject
Declared in DixieBaseChaosProvider.h
DixieBaseChaosProvider.m

Instance Methods

chaos

Returns a new behaviour implementation

- (IMP)chaos

Return Value

An implementation pointer

Discussion

Returns a new behaviour implementation

Declared In

DixieBaseChaosProvider.h

chaosImplementationFor:environment:

The behaviour implementation

- (void)chaosImplementationFor:(id)victim environment:(id)environment

Parameters

victim

The class or instance of the class, that’s method should be changed

environment

A DixieCallEnvironment, that describes the arguments and return value

Discussion

The behaviour implementation

Declared In

DixieBaseChaosProvider.h

forwardChaosOf:environment:to:

Will forward the result of one DixieChaosProvider to the next.

- (void)forwardChaosOf:(id)victim environment:(id)environment to:(id)chaosProvider

Parameters

victim

The class or instance of the class, that’s method should be changed

environment

A DixieCallEnvironment, that describes the arguments and return value

chaosProvider

The target DixieBaseChaosProvider, who should provider the behaviour

Discussion

Will forward the result of one DixieChaosProvider to the next.

Declared In

DixieBaseChaosProvider.h
================================================ FILE: Documentation/docset/Contents/Resources/Documents/Classes/DixieBaseParamProvider.html ================================================ DixieBaseParamProvider Class Reference
Inherits from NSObject
Declared in DixieBaseParamProvider.h
DixieBaseParamProvider.m

Overview

Base class for objects, that can return an object

Instance Methods

parameter

Returns an object

- (id)parameter

Return Value

an object

Discussion

Returns an object

Declared In

DixieBaseParamProvider.h
================================================ FILE: Documentation/docset/Contents/Resources/Documents/Classes/DixieBlockChaosProvider.html ================================================ DixieBlockChaosProvider Class Reference
Inherits from DixieBaseChaosProvider : NSObject
Declared in DixieBlockChaosProvider.h
DixieBlockChaosProvider.m

Overview

Provides a behaviour, where the original method’s implementation can be replaced by a custom block

Tasks

Other Methods

Other Methods

Class Methods

block:

Creates an instance of DixieBlockChaosProvider

+ (instancetype)block:(id)block

Parameters

block

The block, that should be called as the method’s implementation

Return Value

a new instance of DixieBlockChaosProvider

Discussion

Creates an instance of DixieBlockChaosProvider

Declared In

DixieBlockChaosProvider.h

Instance Methods

chaosImplementationFor:environment:

The behaviour implementation

- (void)chaosImplementationFor:(id)victim environment:(id)environment

Parameters

victim

The class or instance of the class, that’s method should be changed

environment

A DixieCallEnvironment, that describes the arguments and return value

Discussion

The behaviour implementation

Declared In

DixieBaseChaosProvider.h
================================================ FILE: Documentation/docset/Contents/Resources/Documents/Classes/DixieCallEnvironment.html ================================================ DixieCallEnvironment Class Reference
Inherits from NSObject
Declared in DixieCallEnvironment.h
DixieCallEnvironment.m

Overview

Describes the environment of a method’s implementation

Properties

arguments

Arguments of the method call converted into objects

@property (strong) NSArray *arguments

Discussion

Arguments of the method call converted into objects

Declared In

DixieCallEnvironment.h

returnValue

The return value of a method’s implementation

@property (nonatomic) id returnValue

Discussion

The return value of a method’s implementation

Declared In

DixieCallEnvironment.h

Instance Methods

initWithArguments:

Creates a DixieCallEnvironment with the arguments

- (instancetype)initWithArguments:(id)arguments

Parameters

arguments

Arguments of the method call converted into objects

Return Value

a DixieCallEnvironment

Discussion

Creates a DixieCallEnvironment with the arguments

Declared In

DixieCallEnvironment.h
================================================ FILE: Documentation/docset/Contents/Resources/Documents/Classes/DixieChaosContext.html ================================================ DixieChaosContext Class Reference
Inherits from NSObject
Declared in DixieChaosContext.h
DixieChaosContext.m

Overview

Defining the context for the DixieChaosProviders

Properties

methodInfo

A DixieMethodInfo, that describes the class and one of its method

@property (readonly) DixieMethodInfo *methodInfo

Discussion

A DixieMethodInfo, that describes the class and one of its method

Declared In

DixieChaosContext.h

originalIMP

The original implementation of the class method, described in the methodInfo property.

@property IMP originalIMP

Discussion

The original implementation of the class method, described in the methodInfo property.

Declared In

DixieChaosContext.h

seed

A seed for deterministic behaviour.

@property (readonly) NSInteger seed

Discussion

A seed for deterministic behaviour.

Declared In

DixieChaosContext.h

Instance Methods

init:methodInfo:

Creates a DixieChaosContext with a given seed and methodInfo

- (instancetype)init:(id)seed methodInfo:(id)methodInfo

Parameters

seed

A seed for deterministic behaviour.

methodInfo

A DixieMethodInfo, that describes the class and one of its method

Return Value

A DixieChaosContext

Discussion

Creates a DixieChaosContext with a given seed and methodInfo

Declared In

DixieChaosContext.h
================================================ FILE: Documentation/docset/Contents/Resources/Documents/Classes/DixieCompositeChaosProvider.html ================================================ DixieCompositeChaosProvider Class Reference
Inherits from DixieBaseChaosProvider : NSObject
Declared in DixieCompositeChaosProvider.h
DixieCompositeChaosProvider.m

Overview

Provides a behaviour, where the method’s implementation can be changed according the passed arguments

Tasks

Other Methods

Other Methods

Class Methods

conditions:

Creates a new instance of DixieCompositeChaosProvider

+ (instancetype)conditions:(id)arrayOfConditions

Parameters

arrayOfConditions

an array of DixieCompositeConditions

Return Value

a new instance of DixieCompositeChaosProvider

Discussion

Creates a new instance of DixieCompositeChaosProvider

Declared In

DixieCompositeChaosProvider.h

Instance Methods

chaosImplementationFor:environment:

The behaviour implementation

- (void)chaosImplementationFor:(id)victim environment:(id)environment

Parameters

victim

The class or instance of the class, that’s method should be changed

environment

A DixieCallEnvironment, that describes the arguments and return value

Discussion

The behaviour implementation

Declared In

DixieBaseChaosProvider.h
================================================ FILE: Documentation/docset/Contents/Resources/Documents/Classes/DixieCompositeCondition.html ================================================ DixieCompositeCondition Class Reference
Inherits from NSObject
Declared in DixieCompositeCondition.h
DixieCompositeCondition.m

Overview

Describes which chaosProvider should define the method’s behaviour if the argument at index, matches the given value. DixieCompositeChaosProvider uses this object to delegate the implementation to different providers.

Properties

chaosProvider

The ChaosProvider to apply

@property (readonly) DixieBaseChaosProvider *chaosProvider

Discussion

The ChaosProvider to apply

Declared In

DixieCompositeCondition.h

index

The index of the argument to check

@property (readonly) NSInteger index

Discussion

The index of the argument to check

Declared In

DixieCompositeCondition.h

value

The value of the argument we wish to compare

@property (readonly) id value

Discussion

The value of the argument we wish to compare

Declared In

DixieCompositeCondition.h

Class Methods

condition:value:chaosProvider:

Creates a DixieCompositeCondition

+ (instancetype)condition:(id)index value:(id)value chaosProvider:(id)chaosProvider

Parameters

index

The index of the argument to check

value

The value to compare the argument against

chaosProvider

The DixieChaosProvider to apply, if the argument matches the value

Return Value

a DixieCompositeCondition

Discussion

Creates a DixieCompositeCondition

Declared In

DixieCompositeCondition.h
================================================ FILE: Documentation/docset/Contents/Resources/Documents/Classes/DixieConstantChaosProvider.html ================================================ DixieConstantChaosProvider Class Reference
Inherits from DixieBaseChaosProvider : NSObject
Declared in DixieConstantChaosProvider.h
DixieConstantChaosProvider.m

Overview

Provides a behaviour, where a given constant will be returned from the method’s implementation

Tasks

Other Methods

Other Methods

Properties

constant

The constant value to return

@property (readonly) id constant

Discussion

The constant value to return

Declared In

DixieConstantChaosProvider.h

Class Methods

constant:

Creates a DixieConstantChaosProvider

+ (instancetype)constant:(id)constant

Parameters

constant

The value the DixieConstantChaosProvider will return

Return Value

a DixieConstantChaosProvider

Discussion

Creates a DixieConstantChaosProvider

Declared In

DixieConstantChaosProvider.h

Instance Methods

chaosImplementationFor:environment:

The behaviour implementation

- (void)chaosImplementationFor:(id)victim environment:(id)environment

Parameters

victim

The class or instance of the class, that’s method should be changed

environment

A DixieCallEnvironment, that describes the arguments and return value

Discussion

The behaviour implementation

Declared In

DixieBaseChaosProvider.h
================================================ FILE: Documentation/docset/Contents/Resources/Documents/Classes/DixieDefaultPuppetMaker.html ================================================ DixieDefaultPuppetMaker Class Reference
Inherits from NSObject
Conforms to DixiePuppetMaking
Declared in DixieDefaultPuppetMaker.h
DixieDefaultPuppetMaker.m

Overview

Default implementation of the DixiePuppetMaking interface

Instance Methods

createPuppet:seed:

Creates puppet according to a given entry for the specified seed, by replacing the original behaviour with a new

- (void)createPuppet:(id)entry seed:(id)seed

Parameters

entry

The entry specifying the victim class, selector and behaviour

seed

An integer value to make the invocations on the puppets deterministic

Discussion

Creates puppet according to a given entry for the specified seed, by replacing the original behaviour with a new

Declared In

DixiePuppetMaking.h

dismissPuppet:

Dismisses the puppets for a given entry

- (void)dismissPuppet:(id)entry

Parameters

entry

The entry specifying the victim class, selector and behaviour

Discussion

Dismisses the puppets for a given entry

Declared In

DixiePuppetMaking.h
================================================ FILE: Documentation/docset/Contents/Resources/Documents/Classes/DixieExceptionChaosProvider.html ================================================ DixieExceptionChaosProvider Class Reference
Inherits from DixieBaseChaosProvider : NSObject
Declared in DixieExceptionChaosProvider.h
DixieExceptionChaosProvider.m

Overview

Provides a behaviour, where the method’s implementation will always crash on calling

Tasks

Other Methods

Other Methods

Properties

exception

The exception to raise

@property (readonly) NSException *exception

Discussion

The exception to raise

Declared In

DixieExceptionChaosProvider.h

Class Methods

exception:

Creates an DixieExceptionChaosProvider

+ (instancetype)exception:(id)exception

Parameters

exception

The exception to raise

Return Value

an DixieExceptionChaosProvider

Discussion

Creates an DixieExceptionChaosProvider

Declared In

DixieExceptionChaosProvider.h

Instance Methods

chaosImplementationFor:environment:

The behaviour implementation

- (void)chaosImplementationFor:(id)victim environment:(id)environment

Parameters

victim

The class or instance of the class, that’s method should be changed

environment

A DixieCallEnvironment, that describes the arguments and return value

Discussion

The behaviour implementation

Declared In

DixieBaseChaosProvider.h
================================================ FILE: Documentation/docset/Contents/Resources/Documents/Classes/DixieLogger.html ================================================ DixieLogger Class Reference
Inherits from NSObject
Declared in DixieLogger.h
DixieLogger.m

Overview

Base class for logging

Class Methods

defaultLogger

Returns default logger.

+ (instancetype)defaultLogger

Return Value

The logger.

Discussion

Returns default logger.

Declared In

DixieLogger.h

setDefaultLogger:

Changes the default logger.

+ (void)setDefaultLogger:(id)logger

Parameters

logger

The logger.

Discussion

Changes the default logger.

Declared In

DixieLogger.h

Instance Methods

log:

Logs a message.

- (void)log:(id)format, ...

Parameters

format

The format of the message. It can be followed by variadic arguments.

Discussion

Logs a message.

Declared In

DixieLogger.h
================================================ FILE: Documentation/docset/Contents/Resources/Documents/Classes/DixieMethodInfo.html ================================================ DixieMethodInfo Class Reference
Inherits from NSObject
Declared in DixieMethodInfo.h
DixieMethodInfo.m

Overview

Describes a class and one of its method

Properties

isClassMethod

Indicates whether the method is a class method.

@property (readonly) BOOL isClassMethod

Discussion

Indicates whether the method is a class method.

Declared In

DixieMethodInfo.h

methodTypeEncoding

The string representation of the method encoding

@property (readonly) const char *methodTypeEncoding

Discussion

The string representation of the method encoding

Declared In

DixieMethodInfo.h

selector

Selector of the method.

@property (readonly) SEL selector

Discussion

Selector of the method.

Declared In

DixieMethodInfo.h

signature

Signature of the method.

@property (readonly) NSMethodSignature *signature

Discussion

Signature of the method.

Declared In

DixieMethodInfo.h

targetClass

Owner of the method.

@property (readonly) Class targetClass

Discussion

Owner of the method.

Declared In

DixieMethodInfo.h

Class Methods

infoWithClass:selector:

Creates a new MethodInfo instance.

+ (instancetype)infoWithClass:(id)targetClass selector:(id)selector

Parameters

targetClass

The owner of the method.

selector

The selector of the method.

Return Value

A MethodInfo instance.

Discussion

Creates a new MethodInfo instance.

Declared In

DixieMethodInfo.h
================================================ FILE: Documentation/docset/Contents/Resources/Documents/Classes/DixieNilChaosProvider.html ================================================ DixieNilChaosProvider Class Reference
Inherits from DixieBaseChaosProvider : NSObject
Declared in DixieNilChaosProvider.h
DixieNilChaosProvider.m

Overview

Provides a behaviour, where the method’s implementation always returns nil;

Instance Methods

chaosImplementationFor:environment:

The behaviour implementation

- (void)chaosImplementationFor:(id)victim environment:(id)environment

Parameters

victim

The class or instance of the class, that’s method should be changed

environment

A DixieCallEnvironment, that describes the arguments and return value

Discussion

The behaviour implementation

Declared In

DixieBaseChaosProvider.h
================================================ FILE: Documentation/docset/Contents/Resources/Documents/Classes/DixieNonChaosProvider.html ================================================ DixieNonChaosProvider Class Reference
Inherits from DixieBaseChaosProvider : NSObject
Declared in DixieNonChaosProvider.h
DixieNonChaosProvider.m

Overview

Provides the original behaviour

Tasks

Instance Methods

chaos

Returns a new behaviour implementation

- (IMP)chaos

Return Value

An implementation pointer

Discussion

Returns a new behaviour implementation

Declared In

DixieBaseChaosProvider.h
================================================ FILE: Documentation/docset/Contents/Resources/Documents/Classes/DixieProfileEntry.html ================================================ DixieProfileEntry Class Reference
Inherits from NSObject
Declared in DixieProfileEntry.h
DixieProfileEntry.m

Overview

Describe the target class, selector and the desired behaviour

Properties

chaosProvider

The ChaosProvider which will provide the new implementation

@property (nonatomic, strong) DixieBaseChaosProvider *chaosProvider

Discussion

The ChaosProvider which will provide the new implementation

Declared In

DixieProfileEntry.h

entryID

Uniquely identifies the entry

@property (readonly) NSString *entryID

Discussion

Uniquely identifies the entry

Declared In

DixieProfileEntry.h

methodInfo

The DixieMethodInfo object, that describes the class and its method

@property (nonatomic, readonly) DixieMethodInfo *methodInfo

Discussion

The DixieMethodInfo object, that describes the class and its method

Declared In

DixieProfileEntry.h

Class Methods

entries:excludeSelectorsOfClass:chaosProvider:

Creates an array of DixieProfileEntry. The DixieProfileEntry array consists of all selectors on the victim EXCEPT those defined in the klass

+ (NSArray *)entries:(id)victim excludeSelectorsOfClass:(id)excludeClass chaosProvider:(id)chaosProvider

Parameters

victim

The victim whose method we wish to override

chaosProvider

The ChaosProvider which will provide the new implementation

klass

Tha class, whose selectors should not be added to the list of entries

Return Value

an array of DixieProfileEntries representing all available selectors on the victim EXCEPT those defined in the excludeClass

Discussion

Creates an array of DixieProfileEntry. The DixieProfileEntry array consists of all selectors on the victim EXCEPT those defined in the klass

Declared In

DixieProfileEntry.h

entries:excludes:chaosProvider:

Creates an array of DixieProfileEntries The DixieProfileEntries array consists of all selectors on the victim EXCEPT those specified in excludedSelectorNames

+ (NSArray *)entries:(id)victim excludes:(id)excludedSelectorNames chaosProvider:(id)chaosProvider

Parameters

victim

The victim whose method we wish to override

excludedSelectorNames

The selectors we do NOT wish to include in the return calue

chaosProvider

The ChaosProvider which will provide the new implementation

Return Value

an array of DixieProfileEntries representing all available selectors on the victim EXCEPT those specified

Discussion

Creates an array of DixieProfileEntries The DixieProfileEntries array consists of all selectors on the victim EXCEPT those specified in excludedSelectorNames

Declared In

DixieProfileEntry.h

entry:selector:chaosProvider:

Creates a DixieProfileEntry with the main properties set

+ (instancetype)entry:(id)victim selector:(id)selector chaosProvider:(id)chaosProvider

Parameters

victim

The victim whose method we wish to override

selector

The selector for the method we wish to override

chaosProvider

The ChaosProvider which will provide the new implementation

Return Value

a new DixieProfileEntry with the properties set

Discussion

Creates a DixieProfileEntry with the main properties set

Declared In

DixieProfileEntry.h
================================================ FILE: Documentation/docset/Contents/Resources/Documents/Classes/DixieRandomChaosProvider.html ================================================ DixieRandomChaosProvider Class Reference
Inherits from DixieBaseChaosProvider : NSObject
Declared in DixieRandomChaosProvider.h
DixieRandomChaosProvider.m

Overview

Provides a behaviour, where the method’s implementation returns a random object, generated with a DixieRandomParamProvider

Class Methods

randomProvider:

Creates a DixieRandomChaosProvider

+ (instancetype)randomProvider:(id)paramProvider

Parameters

paramProvider

The DixieRandomParamProvider to use as the random object generator

Return Value

a DixieRandomChaosProvider

Discussion

Creates a DixieRandomChaosProvider

Declared In

DixieRandomChaosProvider.h

Instance Methods

chaosImplementationFor:environment:

The behaviour implementation

- (void)chaosImplementationFor:(id)victim environment:(id)environment

Parameters

victim

The class or instance of the class, that’s method should be changed

environment

A DixieCallEnvironment, that describes the arguments and return value

Discussion

The behaviour implementation

Declared In

DixieBaseChaosProvider.h
================================================ FILE: Documentation/docset/Contents/Resources/Documents/Classes/DixieRandomParamProvider.html ================================================ DixieRandomParamProvider Class Reference
Inherits from DixieBaseParamProvider : NSObject
Declared in DixieRandomParamProvider.h
DixieRandomParamProvider.m

Overview

Provides a random number object

Tasks

Other Methods

Other Methods

Class Methods

providerWithUpperBound:

Creates a DixieRandomParamProvider with a given uppper bound

+ (instancetype)providerWithUpperBound:(id)upperBound

Parameters

upperBound

The upper limit to the random numbers, the numbers can be only lower than this

Return Value

a DixieRandomParamProvider

Discussion

Creates a DixieRandomParamProvider with a given uppper bound

Declared In

DixieRandomParamProvider.h

Instance Methods

parameter

Returns an object

- (id)parameter

Return Value

an object

Discussion

Returns an object

Declared In

DixieBaseParamProvider.h

setSeed:

Set the seed for the random generator

- (void)setSeed:(id)seed

Parameters

seed

A seed for deterministic behaviour

Discussion

Set the seed for the random generator

Declared In

DixieRandomParamProvider.h
================================================ FILE: Documentation/docset/Contents/Resources/Documents/Classes/DixieRunTimeHelper.html ================================================ DixieRunTimeHelper Class Reference
Inherits from NSObject
Declared in DixieRunTimeHelper.h
DixieRunTimeHelper.m

Overview

Helper to generate behaviour implementation, transparently call implementations and provide Runtime informations

Class Methods

argumentsFor:originalArguments:

  • Parses a variadic list into array of objects
+ (NSArray *)argumentsFor:(id)signature originalArguments:(id)arguments

Discussion

  • Parses a variadic list into array of objects

Note: The current solution handles only object,selector,BOOL and char types. * * @param signature The signature to determine the type of parameters in the variadic list * @param arguments The variadic list * * @return Array of parsed objects

Declared In

DixieRunTimeHelper.m

blockForSignature:block:

Returns a block implementation for a given signature

+ (id)blockForSignature:(id)signature block:(id)block

Parameters

signature

The method signature

block

The body of the block implementation

Return Value

A block, that matches the signature and calls the block

Discussion

Returns a block implementation for a given signature

Declared In

DixieRunTimeHelper.m

callImplementation:on:chaosContext:environment:

Calls the implementation pointer

+ (void)callImplementation:(id)implementation on:(id)puppet chaosContext:(id)chaosContext environment:(id)environment

Parameters

implementation

The IMP pointer to call

puppet

The receiver of the ObjC message

chaosContext

The context of the behaviour

environment

The environment of the method’s implementation call

Discussion

Calls the implementation pointer

Declared In

DixieRunTimeHelper.h

classForMethodInfo:

Returns the class for the method described in the MethodInfo.

+ (Class)classForMethodInfo:(id)methodInfo

Parameters

methodInfo

Describes the target class and it’s method

Return Value

A Class object for instance methods and meta class object for class methods

Discussion

Returns the class for the method described in the MethodInfo.

Declared In

DixieRunTimeHelper.h

implementationWithChaosContext:environment:

Generates an implementation pointer that confirms to the chaosContext and block

+ (IMP)implementationWithChaosContext:(id)chaosContext environment:(id)block

Parameters

chaosContext

The context of the implementation

block

Block for the body of the implementation pointer

Return Value

the implementation pointer

Discussion

Generates an implementation pointer that confirms to the chaosContext and block

Declared In

DixieRunTimeHelper.h

methodForMethodInfo:

Returns the Method pointer for a given MethodInfo object

+ (Method)methodForMethodInfo:(id)methodInfo

Parameters

methodInfo

Describes the target class and it’s method

Return Value

The Method pointer

Discussion

Returns the Method pointer for a given MethodInfo object

Declared In

DixieRunTimeHelper.h

methodTypeEncodingForMethodInfo:

Returns the string representation of the method encoding describes by the MethodInfo object

+ (const char *)methodTypeEncodingForMethodInfo:(id)methodInfo

Parameters

methodInfo

Describes the target class and it’s method

Return Value

the string representation of the method encoding

Discussion

Returns the string representation of the method encoding describes by the MethodInfo object

Declared In

DixieRunTimeHelper.h

objectFromNext:type:

Converts the next item in the variadic arguments list into subclass of NSObjects

+ (id)objectFromNext:(id)arguments type:(id)argType

Parameters

arguments

The variadic list

argType

the expected type of the next item

Return Value

An NSObject subclass that represents the argument

Discussion

Converts the next item in the variadic arguments list into subclass of NSObjects

Note: We are using core foundation factories here, NSNumber, NSString might be swizzled

Declared In

DixieRunTimeHelper.m

selectorsForClass:

Collects the runtime public methodnames for a given class

+ (NSArray *)selectorsForClass:(id)targetClass

Parameters

targetClass

The class

Return Value

Array of public selector strings

Discussion

Collects the runtime public methodnames for a given class

Declared In

DixieRunTimeHelper.h
================================================ FILE: Documentation/docset/Contents/Resources/Documents/Classes/DixieSequentialChaosProvider.html ================================================ DixieSequentialChaosProvider Class Reference
Inherits from DixieBaseChaosProvider : NSObject
Declared in DixieSequentialChaosProvider.h
DixieSequentialChaosProvider.m

Overview

Provides a behaviour, where the method’s implementation behaves differently for a new call. The different behaviours depend on the defined different DixieChaosProviders of the class

Tasks

Other Methods

Other Methods

Class Methods

sequence:

Creates a DixieSequentialChaosProvider

+ (instancetype)sequence:(id)sequenceOfChaosProviders

Parameters

sequenceOfChaosProviders

Array of DixieBaseChaosProvider, the order of the array defines, how the method’s implementation will behave for a new call.

Return Value

a DixieSequentialChaosProvider

Discussion

Creates a DixieSequentialChaosProvider

Declared In

DixieSequentialChaosProvider.h

Instance Methods

chaosImplementationFor:environment:

The behaviour implementation

- (void)chaosImplementationFor:(id)victim environment:(id)environment

Parameters

victim

The class or instance of the class, that’s method should be changed

environment

A DixieCallEnvironment, that describes the arguments and return value

Discussion

The behaviour implementation

Declared In

DixieBaseChaosProvider.h
================================================ FILE: Documentation/docset/Contents/Resources/Documents/Classes/DixieSimpleLogger.html ================================================ DixieSimpleLogger Class Reference
Inherits from DixieLogger : NSObject
Declared in DixieSimpleLogger.h
DixieSimpleLogger.m

Overview

Default subclass of DixieLogger,that uses NSLog

Tasks

Instance Methods

log:

Logs a message.

- (void)log:(id)format, ...

Parameters

format

The format of the message. It can be followed by variadic arguments.

Discussion

Logs a message.

Declared In

DixieLogger.h
================================================ FILE: Documentation/docset/Contents/Resources/Documents/Protocols/DixiePuppetMaking.html ================================================ DixiePuppetMaking Protocol Reference
Conforms to NSObject
Declared in DixiePuppetMaking.h

Overview

Interface to objects, that can change the behaviour of a class' method.

Tasks

Instance Methods

createPuppet:seed:

Creates puppet according to a given entry for the specified seed, by replacing the original behaviour with a new

- (void)createPuppet:(id)entry seed:(id)seed

Parameters

entry

The entry specifying the victim class, selector and behaviour

seed

An integer value to make the invocations on the puppets deterministic

Discussion

Creates puppet according to a given entry for the specified seed, by replacing the original behaviour with a new

Declared In

DixiePuppetMaking.h

dismissPuppet:

Dismisses the puppets for a given entry

- (void)dismissPuppet:(id)entry

Parameters

entry

The entry specifying the victim class, selector and behaviour

Discussion

Dismisses the puppets for a given entry

Declared In

DixiePuppetMaking.h
================================================ FILE: Documentation/docset/Contents/Resources/Documents/css/styles.css ================================================ body { font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; font-size: 13px; } code { font-family: Courier, Consolas, monospace; font-size: 13px; color: #666; } pre { font-family: Courier, Consolas, monospace; font-size: 13px; line-height: 18px; tab-interval: 0.5em; border: 1px solid #C7CFD5; background-color: #F1F5F9; color: #666; padding: 0.3em 1em; } ul { list-style-type: square; } li { margin-bottom: 10px; } a, a code { text-decoration: none; color: #36C; } a:hover, a:hover code { text-decoration: underline; color: #36C; } h2 { border-bottom: 1px solid #8391A8; color: #3C4C6C; font-size: 187%; font-weight: normal; margin-top: 1.75em; padding-bottom: 2px; } table { margin-bottom: 4em; border-collapse:collapse; vertical-align: middle; } td { border: 1px solid #9BB3CD; padding: .667em; font-size: 100%; } th { border: 1px solid #9BB3CD; padding: .3em .667em .3em .667em; background: #93A5BB; font-size: 103%; font-weight: bold; color: white; text-align: left; } /* @group Common page elements */ #top_header { height: 91px; left: 0; min-width: 598px; position: absolute; right: 0; top: 0; z-index: 900; } #footer { clear: both; padding-top: 20px; text-align: center; } #contents, #overview_contents { -webkit-overflow-scrolling: touch; border-top: 1px solid #A9A9A9; position: absolute; top: 90px; left: 0; right: 0; bottom: 0; overflow-x: hidden; overflow-y: auto; padding-left: 2em; padding-right: 2em; padding-top: 1em; min-width: 550px; } #contents.isShowingTOC { left: 230px; min-width: 320px; } .copyright { font-size: 12px; } .generator { font-size: 11px; } .main-navigation ul li { display: inline; margin-left: 15px; list-style: none; } .navigation-top { clear: both; float: right; } .navigation-bottom { clear: both; float: right; margin-top: 20px; margin-bottom: -10px; } .open > .disclosure { background-image: url("../img/disclosure_open.png"); } .disclosure { background: url("../img/disclosure.png") no-repeat scroll 0 0; } .disclosure, .nodisclosure { display: inline-block; height: 8px; margin-right: 5px; position: relative; width: 9px; } /* @end */ /* @group Header */ #top_header #library { background: url("../img/library_background.png") repeat-x 0 0 #485E78; background-color: #ccc; height: 35px; font-size: 115%; } #top_header #library #libraryTitle { color: #FFFFFF; margin-left: 15px; text-shadow: 0 -1px 0 #485E78; top: 8px; position: absolute; } #libraryTitle { left: 0; } #top_header #library #developerHome { color: #92979E; right: 15px; top: 8px; position: absolute; } #top_header #library a:hover { text-decoration: none; } #top_header #title { background: url("../img/title_background.png") repeat-x 0 0 #8A98A9; border-bottom: 1px solid #757575; height: 25px; overflow: hidden; } #top_header h1 { font-size: 105%; font-weight: normal; margin: 0; padding: 3px 0 2px; text-align: center; /*text-shadow: 0 1px 0 #D5D5D5;*/ white-space: nowrap; } #headerButtons { background-color: #D8D8D8; background-image: url("../img/button_bar_background.png"); border-bottom: 0px solid #EDEDED; border-top: 0px solid #a8a8a8; font-size: 8pt; height: 28px; left: 0; list-style: none outside none; margin: 0; overflow: hidden; padding: 0; position: absolute; right: 0; top: 61px; } #headerButtons li { background-repeat: no-repeat; display: inline; margin-top: 0; margin-bottom: 0; padding: 0; } #toc_button button { background-color: #EBEEF1; border-color: #ACACAC; border-style: none solid none none; border-width: 0 1px 0 0; height: 28px; margin: 0; padding-left: 30px; text-align: left; width: 230px; } li#jumpto_button { left: 230px; margin-left: 0; position: absolute; } li#jumpto_button select { height: 22px; margin: 5px 2px 0 10px; max-width: 300px; } /* @end */ /* @group Table of contents */ #tocContainer.isShowingTOC { border-right: 1px solid #ACACAC; display: block; overflow-x: hidden; overflow-y: auto; padding: 0; } #tocContainer { background-color: #EBEEF1; border-top: 1px solid #ACACAC; bottom: 0; display: none; left: 0; overflow: hidden; position: absolute; top: 90px; width: 229px; } #tocContainer > ul#toc { font-size: 11px; margin: 0; padding: 12px 0 18px; width: 209px; -moz-user-select: none; -webkit-user-select: none; user-select: none; } #tocContainer > ul#toc > li { margin: 0; padding: 0 0 7px 30px; text-indent: -15px; } #tocContainer > ul#toc > li > .sectionName a { color: #000000; font-weight: bold; } #tocContainer > ul#toc > li > .sectionName a:hover { text-decoration: none; } #tocContainer > ul#toc li.children > ul { display: none; height: 0; } #tocContainer > ul#toc > li > ul { margin: 0; padding: 0; } #tocContainer > ul#toc > li > ul, ul#toc > li > ul > li { margin-left: 0; margin-bottom: 0; padding-left: 15px; } #tocContainer > ul#toc > li ul { list-style: none; margin-right: 0; padding-right: 0; } #tocContainer > ul#toc li.children.open > ul { display: block; height: auto; margin-left: -15px; padding-left: 0; } #tocContainer > ul#toc > li > ul, ul#toc > li > ul > li { margin-left: 0; padding-left: 15px; } #tocContainer li ul li { margin-top: 0.583em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } #tocContainer li ul li span.sectionName { white-space: normal; } #tocContainer > ul#toc > li > ul > li > .sectionName a { font-weight: bold; } #tocContainer > ul#toc > li > ul a { color: #4F4F4F; } /* @end */ /* @group Index formatting */ .index-title { font-size: 13px; font-weight: normal; } .index-column { float: left; width: 30%; min-width: 200px; font-size: 11px; } .index-column ul { margin: 8px 0 0 0; padding: 0; list-style: none; } .index-column ul li { margin: 0 0 3px 0; padding: 0; } .hierarchy-column { min-width: 400px; } .hierarchy-column ul { margin: 3px 0 0 15px; } .hierarchy-column ul li { list-style-type: square; } /* @end */ /* @group Common formatting elements */ .title { font-weight: normal; font-size: 215%; margin-top:0; } .subtitle { font-weight: normal; font-size: 180%; color: #3C4C6C; border-bottom: 1px solid #5088C5; } .subsubtitle { font-weight: normal; font-size: 145%; height: 0.7em; } .note { border: 1px solid #5088C5; background-color: white; margin: 1.667em 0 1.75em 0; padding: 0 .667em .083em .750em; } .warning { border: 1px solid #5088C5; background-color: #F0F3F7; margin-bottom: 0.5em; padding: 0.3em 0.8em; } .bug { border: 1px solid #000; background-color: #ffffcc; margin-bottom: 0.5em; padding: 0.3em 0.8em; } .deprecated { color: #F60425; } /* @end */ /* @group Common layout */ .section { margin-top: 3em; } /* @end */ /* @group Object specification section */ .section-specification { margin-left: 2.5em; margin-right: 2.5em; font-size: 12px; } .section-specification table { margin-bottom: 0em; border-top: 1px solid #d6e0e5; } .section-specification td { vertical-align: top; border-bottom: 1px solid #d6e0e5; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; padding: .6em; } .section-specification .specification-title { font-weight: bold; } /* @end */ /* @group Tasks section */ .task-list { list-style-type: none; padding-left: 0px; } .task-list li { margin-bottom: 3px; } .task-item-suffix { color: #996; font-size: 12px; font-style: italic; margin-left: 0.5em; } span.tooltip span.tooltip { font-size: 1.0em; display: none; padding: 0.3em; border: 1px solid #aaa; background-color: #fdfec8; color: #000; text-align: left; } span.tooltip:hover span.tooltip { display: block; position: absolute; margin-left: 2em; } /* @end */ /* @group Method section */ .section-method { margin-top: 2.3em; } .method-title { margin-bottom: 1.5em; } .method-subtitle { margin-top: 0.7em; margin-bottom: 0.2em; } .method-subsection p { margin-top: 0.4em; margin-bottom: 0.8em; } .method-declaration { margin-top:1.182em; margin-bottom:.909em; } .method-declaration code { font:14px Courier, Consolas, monospace; color:#000; } .declaration { color: #000; } .termdef { margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 0px; } .termdef dt { margin: 0; padding: 0; } .termdef dd { margin-bottom: 6px; margin-left: 16px; margin-right: 0px; margin-top: 1px; } .termdef dd p { margin-bottom: 6px; margin-left: 0px; margin-right: 0px; margin-top: -1px; } .argument-def { margin-top: 0.3em; margin-bottom: 0.3em; } .argument-def dd { margin-left: 1.25em; } .see-also-section ul { list-style-type: none; padding-left: 0px; margin-top: 0; } .see-also-section li { margin-bottom: 3px; } .declared-in-ref { color: #666; } #tocContainer.hideInXcode { display: none; border: 0px solid black; } #top_header.hideInXcode { display: none; } #contents.hideInXcode { border: 0px solid black; top: 0px; left: 0px; } /* @end */ ================================================ FILE: Documentation/docset/Contents/Resources/Documents/css/stylesPrint.css ================================================ header { display: none; } div.main-navigation, div.navigation-top { display: none; } div#overview_contents, div#contents.isShowingTOC, div#contents { overflow: visible; position: relative; top: 0px; border: none; left: 0; } #tocContainer.isShowingTOC { display: none; } nav { display: none; } ================================================ FILE: Documentation/docset/Contents/Resources/Documents/hierarchy.html ================================================ Dixie Hierarchy
================================================ FILE: Documentation/docset/Contents/Resources/Documents/index.html ================================================ Dixie Reference
================================================ FILE: Documentation/docset/Contents/Resources/Nodes.xml ================================================ Dixie index.html Classes index.html Categories index.html Protocols index.html Blocks index.html Dixie Classes/Dixie.html Classes/Dixie.html Overview overview Classes/Dixie.html Tasks tasks Classes/Dixie.html Instance Methods instance_methods DixieBaseChaosProvider Classes/DixieBaseChaosProvider.html Classes/DixieBaseChaosProvider.html Overview overview Classes/DixieBaseChaosProvider.html Tasks tasks Classes/DixieBaseChaosProvider.html Instance Methods instance_methods DixieBaseParamProvider Classes/DixieBaseParamProvider.html Classes/DixieBaseParamProvider.html Overview overview Classes/DixieBaseParamProvider.html Tasks tasks Classes/DixieBaseParamProvider.html Instance Methods instance_methods DixieBlockChaosProvider Classes/DixieBlockChaosProvider.html Classes/DixieBlockChaosProvider.html Overview overview Classes/DixieBlockChaosProvider.html Tasks tasks Classes/DixieBlockChaosProvider.html Class Methods class_methods Classes/DixieBlockChaosProvider.html Instance Methods instance_methods DixieCallEnvironment Classes/DixieCallEnvironment.html Classes/DixieCallEnvironment.html Overview overview Classes/DixieCallEnvironment.html Tasks tasks Classes/DixieCallEnvironment.html Properties properties Classes/DixieCallEnvironment.html Instance Methods instance_methods DixieChaosContext Classes/DixieChaosContext.html Classes/DixieChaosContext.html Overview overview Classes/DixieChaosContext.html Tasks tasks Classes/DixieChaosContext.html Properties properties Classes/DixieChaosContext.html Instance Methods instance_methods DixieCompositeChaosProvider Classes/DixieCompositeChaosProvider.html Classes/DixieCompositeChaosProvider.html Overview overview Classes/DixieCompositeChaosProvider.html Tasks tasks Classes/DixieCompositeChaosProvider.html Class Methods class_methods Classes/DixieCompositeChaosProvider.html Instance Methods instance_methods DixieCompositeCondition Classes/DixieCompositeCondition.html Classes/DixieCompositeCondition.html Overview overview Classes/DixieCompositeCondition.html Tasks tasks Classes/DixieCompositeCondition.html Properties properties Classes/DixieCompositeCondition.html Class Methods class_methods DixieConstantChaosProvider Classes/DixieConstantChaosProvider.html Classes/DixieConstantChaosProvider.html Overview overview Classes/DixieConstantChaosProvider.html Tasks tasks Classes/DixieConstantChaosProvider.html Properties properties Classes/DixieConstantChaosProvider.html Class Methods class_methods Classes/DixieConstantChaosProvider.html Instance Methods instance_methods DixieDefaultPuppetMaker Classes/DixieDefaultPuppetMaker.html Classes/DixieDefaultPuppetMaker.html Overview overview Classes/DixieDefaultPuppetMaker.html Tasks tasks Classes/DixieDefaultPuppetMaker.html Instance Methods instance_methods DixieExceptionChaosProvider Classes/DixieExceptionChaosProvider.html Classes/DixieExceptionChaosProvider.html Overview overview Classes/DixieExceptionChaosProvider.html Tasks tasks Classes/DixieExceptionChaosProvider.html Properties properties Classes/DixieExceptionChaosProvider.html Class Methods class_methods Classes/DixieExceptionChaosProvider.html Instance Methods instance_methods DixieLogger Classes/DixieLogger.html Classes/DixieLogger.html Overview overview Classes/DixieLogger.html Tasks tasks Classes/DixieLogger.html Class Methods class_methods Classes/DixieLogger.html Instance Methods instance_methods DixieMethodInfo Classes/DixieMethodInfo.html Classes/DixieMethodInfo.html Overview overview Classes/DixieMethodInfo.html Tasks tasks Classes/DixieMethodInfo.html Properties properties Classes/DixieMethodInfo.html Class Methods class_methods DixieNilChaosProvider Classes/DixieNilChaosProvider.html Classes/DixieNilChaosProvider.html Overview overview Classes/DixieNilChaosProvider.html Tasks tasks Classes/DixieNilChaosProvider.html Instance Methods instance_methods DixieNonChaosProvider Classes/DixieNonChaosProvider.html Classes/DixieNonChaosProvider.html Overview overview Classes/DixieNonChaosProvider.html Tasks tasks Classes/DixieNonChaosProvider.html Instance Methods instance_methods DixieProfileEntry Classes/DixieProfileEntry.html Classes/DixieProfileEntry.html Overview overview Classes/DixieProfileEntry.html Tasks tasks Classes/DixieProfileEntry.html Properties properties Classes/DixieProfileEntry.html Class Methods class_methods DixieRandomChaosProvider Classes/DixieRandomChaosProvider.html Classes/DixieRandomChaosProvider.html Overview overview Classes/DixieRandomChaosProvider.html Tasks tasks Classes/DixieRandomChaosProvider.html Class Methods class_methods Classes/DixieRandomChaosProvider.html Instance Methods instance_methods DixieRandomParamProvider Classes/DixieRandomParamProvider.html Classes/DixieRandomParamProvider.html Overview overview Classes/DixieRandomParamProvider.html Tasks tasks Classes/DixieRandomParamProvider.html Class Methods class_methods Classes/DixieRandomParamProvider.html Instance Methods instance_methods DixieRunTimeHelper Classes/DixieRunTimeHelper.html Classes/DixieRunTimeHelper.html Overview overview Classes/DixieRunTimeHelper.html Tasks tasks Classes/DixieRunTimeHelper.html Class Methods class_methods DixieSequentialChaosProvider Classes/DixieSequentialChaosProvider.html Classes/DixieSequentialChaosProvider.html Overview overview Classes/DixieSequentialChaosProvider.html Tasks tasks Classes/DixieSequentialChaosProvider.html Class Methods class_methods Classes/DixieSequentialChaosProvider.html Instance Methods instance_methods DixieSimpleLogger Classes/DixieSimpleLogger.html Classes/DixieSimpleLogger.html Overview overview Classes/DixieSimpleLogger.html Tasks tasks Classes/DixieSimpleLogger.html Instance Methods instance_methods NSObject(DixieRunTimeHelper) Categories/NSObject+DixieRunTimeHelper.html DixiePuppetMaking Protocols/DixiePuppetMaking.html Protocols/DixiePuppetMaking.html Overview overview Protocols/DixiePuppetMaking.html Tasks tasks Protocols/DixiePuppetMaking.html Instance Methods instance_methods DixieCustomChaosBlock Blocks/DixieCustomChaosBlock.html DixieImplementationBlock Blocks/DixieImplementationBlock.html ================================================ FILE: Documentation/docset/Contents/Resources/Tokens1.xml ================================================ //apple_ref/occ/cl/Dixie Represents a Dixie configuration. Dixie.h //apple_ref/occ/instm/Dixie/puppetMaker: Sets the default puppetmaker Dixie.h - (instancetype)puppetMaker:(id)puppetMaker puppetMaker An object that conforms to the PuppetMaking protocol. The active Dixie object //api/name/puppetMaker: //apple_ref/occ/instm/Dixie/profile: Registers a single profiles. Dixie.h - (instancetype)profile:(id)profile profile A DixieProfileEntry objects. Same Dixie object. //api/name/profile: //apple_ref/occ/instm/Dixie/profiles: Registers profiles. Dixie.h - (instancetype)profiles:(id)arrayOfEntries arrayOfEntries Collection of DixieProfileEntry objects. Same Dixie object. //api/name/profiles: //apple_ref/occ/instm/Dixie/apply Applies the Dixie configuration. Dixie.h - (void)apply //api/name/apply //apple_ref/occ/instm/Dixie/apply: Applies the Dixie configuration with the specified seed (used for random generation). Dixie.h - (void)apply:(id)seed seed The seed for random generation //api/name/apply: //apple_ref/occ/instm/Dixie/revert Reverts the Dixie configuration. Dixie.h - (void)revert //api/name/revert //apple_ref/occ/instm/Dixie/revert: Reverts one DixieProfileEntry from the Dixie configuration. Dixie.h - (void)revert:(id)entry entry The profile to revert //api/name/revert: ================================================ FILE: Documentation/docset/Contents/Resources/Tokens10.xml ================================================ //apple_ref/occ/cl/DixieDefaultPuppetMaker Default implementation of the DixiePuppetMaking interface DixieDefaultPuppetMaker.h //apple_ref/occ/instm/DixieDefaultPuppetMaker/createPuppet:seed: Creates puppet according to a given entry for the specified seed, by replacing the original behaviour with a new DixieDefaultPuppetMaker.m - (void)createPuppet:(id)entry seed:(id)seed entry The entry specifying the victim class, selector and behaviour seed An integer value to make the invocations on the puppets deterministic //api/name/createPuppet:seed: //apple_ref/occ/instm/DixieDefaultPuppetMaker/dismissPuppet: Dismisses the puppets for a given entry DixieDefaultPuppetMaker.m - (void)dismissPuppet:(id)entry entry The entry specifying the victim class, selector and behaviour //api/name/dismissPuppet: ================================================ FILE: Documentation/docset/Contents/Resources/Tokens11.xml ================================================ //apple_ref/occ/cl/DixieExceptionChaosProvider Provides a behaviour, where the method's implementation will always crash on calling DixieExceptionChaosProvider.h //apple_ref/occ/instm/DixieExceptionChaosProvider/setException: The exception to raise DixieExceptionChaosProvider.h @property (readonly) NSException *exception //api/name/exception //apple_ref/occ/instm/DixieExceptionChaosProvider/exception The exception to raise DixieExceptionChaosProvider.h @property (readonly) NSException *exception //api/name/exception //apple_ref/occ/instp/DixieExceptionChaosProvider/exception The exception to raise DixieExceptionChaosProvider.h @property (readonly) NSException *exception //api/name/exception //apple_ref/occ/clm/DixieExceptionChaosProvider/exception: Creates an DixieExceptionChaosProvider DixieExceptionChaosProvider.h + (instancetype)exception:(id)exception exception The exception to raise an DixieExceptionChaosProvider //api/name/exception: //apple_ref/occ/instm/DixieExceptionChaosProvider/chaosImplementationFor:environment: The behaviour implementation DixieExceptionChaosProvider.m - (void)chaosImplementationFor:(id)victim environment:(id)environment victim The class or instance of the class, that's method should be changed environment A DixieCallEnvironment, that describes the arguments and return value //api/name/chaosImplementationFor:environment: ================================================ FILE: Documentation/docset/Contents/Resources/Tokens12.xml ================================================ //apple_ref/occ/cl/DixieLogger Base class for logging DixieLogger.h //apple_ref/occ/clm/DixieLogger/defaultLogger Returns default logger. DixieLogger.h + (instancetype)defaultLogger The logger. //api/name/defaultLogger //apple_ref/occ/clm/DixieLogger/setDefaultLogger: Changes the default logger. DixieLogger.h + (void)setDefaultLogger:(id)logger logger The logger. //api/name/setDefaultLogger: //apple_ref/occ/instm/DixieLogger/log: Logs a message. DixieLogger.h - (void)log:(id)format, ... format The format of the message. It can be followed by variadic arguments. //api/name/log: ================================================ FILE: Documentation/docset/Contents/Resources/Tokens13.xml ================================================ //apple_ref/occ/cl/DixieMethodInfo Describes a class and one of its method DixieMethodInfo.h //apple_ref/occ/instm/DixieMethodInfo/setTargetClass: Owner of the method. DixieMethodInfo.h @property (readonly) Class targetClass //api/name/targetClass //apple_ref/occ/instm/DixieMethodInfo/targetClass Owner of the method. DixieMethodInfo.h @property (readonly) Class targetClass //api/name/targetClass //apple_ref/occ/instp/DixieMethodInfo/targetClass Owner of the method. DixieMethodInfo.h @property (readonly) Class targetClass //api/name/targetClass //apple_ref/occ/instm/DixieMethodInfo/setSelector: Selector of the method. DixieMethodInfo.h @property (readonly) SEL selector //api/name/selector //apple_ref/occ/instm/DixieMethodInfo/selector Selector of the method. DixieMethodInfo.h @property (readonly) SEL selector //api/name/selector //apple_ref/occ/instp/DixieMethodInfo/selector Selector of the method. DixieMethodInfo.h @property (readonly) SEL selector //api/name/selector //apple_ref/occ/instm/DixieMethodInfo/setMethodTypeEncoding: The string representation of the method encoding DixieMethodInfo.h @property (readonly) const char *methodTypeEncoding //api/name/methodTypeEncoding //apple_ref/occ/instm/DixieMethodInfo/methodTypeEncoding The string representation of the method encoding DixieMethodInfo.h @property (readonly) const char *methodTypeEncoding //api/name/methodTypeEncoding //apple_ref/occ/instp/DixieMethodInfo/methodTypeEncoding The string representation of the method encoding DixieMethodInfo.h @property (readonly) const char *methodTypeEncoding //api/name/methodTypeEncoding //apple_ref/occ/instm/DixieMethodInfo/setIsClassMethod: Indicates whether the method is a class method. DixieMethodInfo.h @property (readonly) BOOL isClassMethod //api/name/isClassMethod //apple_ref/occ/instm/DixieMethodInfo/isClassMethod Indicates whether the method is a class method. DixieMethodInfo.h @property (readonly) BOOL isClassMethod //api/name/isClassMethod //apple_ref/occ/instp/DixieMethodInfo/isClassMethod Indicates whether the method is a class method. DixieMethodInfo.h @property (readonly) BOOL isClassMethod //api/name/isClassMethod //apple_ref/occ/instm/DixieMethodInfo/setSignature: Signature of the method. DixieMethodInfo.h @property (readonly) NSMethodSignature *signature //api/name/signature //apple_ref/occ/instm/DixieMethodInfo/signature Signature of the method. DixieMethodInfo.h @property (readonly) NSMethodSignature *signature //api/name/signature //apple_ref/occ/instp/DixieMethodInfo/signature Signature of the method. DixieMethodInfo.h @property (readonly) NSMethodSignature *signature //api/name/signature //apple_ref/occ/clm/DixieMethodInfo/infoWithClass:selector: Creates a new MethodInfo instance. DixieMethodInfo.h + (instancetype)infoWithClass:(id)targetClass selector:(id)selector targetClass The owner of the method. selector The selector of the method. A MethodInfo instance. //api/name/infoWithClass:selector: ================================================ FILE: Documentation/docset/Contents/Resources/Tokens14.xml ================================================ //apple_ref/occ/cl/DixieNilChaosProvider Provides a behaviour, where the method's implementation always returns nil; DixieNilChaosProvider.h //apple_ref/occ/instm/DixieNilChaosProvider/chaosImplementationFor:environment: The behaviour implementation DixieNilChaosProvider.m - (void)chaosImplementationFor:(id)victim environment:(id)environment victim The class or instance of the class, that's method should be changed environment A DixieCallEnvironment, that describes the arguments and return value //api/name/chaosImplementationFor:environment: ================================================ FILE: Documentation/docset/Contents/Resources/Tokens15.xml ================================================ //apple_ref/occ/cl/DixieNonChaosProvider Provides the original behaviour DixieNonChaosProvider.h //apple_ref/occ/instm/DixieNonChaosProvider/chaos Returns a new behaviour implementation DixieNonChaosProvider.m - (IMP)chaos An implementation pointer //api/name/chaos ================================================ FILE: Documentation/docset/Contents/Resources/Tokens16.xml ================================================ //apple_ref/occ/cl/DixieProfileEntry Describe the target class, selector and the desired behaviour DixieProfileEntry.h //apple_ref/occ/instm/DixieProfileEntry/setEntryID: Uniquely identifies the entry DixieProfileEntry.h @property (readonly) NSString *entryID //api/name/entryID //apple_ref/occ/instm/DixieProfileEntry/entryID Uniquely identifies the entry DixieProfileEntry.h @property (readonly) NSString *entryID //api/name/entryID //apple_ref/occ/instp/DixieProfileEntry/entryID Uniquely identifies the entry DixieProfileEntry.h @property (readonly) NSString *entryID //api/name/entryID //apple_ref/occ/instm/DixieProfileEntry/setMethodInfo: The DixieMethodInfo object, that describes the class and its method DixieProfileEntry.h @property (nonatomic, readonly) DixieMethodInfo *methodInfo //api/name/methodInfo //apple_ref/occ/instm/DixieProfileEntry/methodInfo The DixieMethodInfo object, that describes the class and its method DixieProfileEntry.h @property (nonatomic, readonly) DixieMethodInfo *methodInfo //api/name/methodInfo //apple_ref/occ/instp/DixieProfileEntry/methodInfo The DixieMethodInfo object, that describes the class and its method DixieProfileEntry.h @property (nonatomic, readonly) DixieMethodInfo *methodInfo //api/name/methodInfo //apple_ref/occ/instm/DixieProfileEntry/setChaosProvider: The ChaosProvider which will provide the new implementation DixieProfileEntry.h @property (nonatomic, strong) DixieBaseChaosProvider *chaosProvider //api/name/chaosProvider //apple_ref/occ/instm/DixieProfileEntry/chaosProvider The ChaosProvider which will provide the new implementation DixieProfileEntry.h @property (nonatomic, strong) DixieBaseChaosProvider *chaosProvider //api/name/chaosProvider //apple_ref/occ/instp/DixieProfileEntry/chaosProvider The ChaosProvider which will provide the new implementation DixieProfileEntry.h @property (nonatomic, strong) DixieBaseChaosProvider *chaosProvider //api/name/chaosProvider //apple_ref/occ/clm/DixieProfileEntry/entry:selector:chaosProvider: Creates a DixieProfileEntry with the main properties set DixieProfileEntry.h + (instancetype)entry:(id)victim selector:(id)selector chaosProvider:(id)chaosProvider victim The victim whose method we wish to override selector The selector for the method we wish to override chaosProvider The ChaosProvider which will provide the new implementation a new DixieProfileEntry with the properties set //api/name/entry:selector:chaosProvider: //apple_ref/occ/clm/DixieProfileEntry/entries:excludeSelectorsOfClass:chaosProvider: Creates an array of DixieProfileEntry. The DixieProfileEntry array consists of all selectors on the victim EXCEPT those defined in the klass DixieProfileEntry.h + (NSArray *)entries:(id)victim excludeSelectorsOfClass:(id)excludeClass chaosProvider:(id)chaosProvider victim The victim whose method we wish to override chaosProvider The ChaosProvider which will provide the new implementation klass Tha class, whose selectors should not be added to the list of entries an array of DixieProfileEntries representing all available selectors on the victim EXCEPT those defined in the excludeClass //api/name/entries:excludeSelectorsOfClass:chaosProvider: //apple_ref/occ/clm/DixieProfileEntry/entries:excludes:chaosProvider: Creates an array of DixieProfileEntries The DixieProfileEntries array consists of all selectors on the victim EXCEPT those specified in excludedSelectorNames DixieProfileEntry.h + (NSArray *)entries:(id)victim excludes:(id)excludedSelectorNames chaosProvider:(id)chaosProvider victim The victim whose method we wish to override excludedSelectorNames The selectors we do NOT wish to include in the return calue chaosProvider The ChaosProvider which will provide the new implementation an array of DixieProfileEntries representing all available selectors on the victim EXCEPT those specified //api/name/entries:excludes:chaosProvider: ================================================ FILE: Documentation/docset/Contents/Resources/Tokens17.xml ================================================ //apple_ref/occ/cl/DixieRandomChaosProvider Provides a behaviour, where the method's implementation returns a random object, generated with a DixieRandomParamProvider DixieRandomChaosProvider.h //apple_ref/occ/clm/DixieRandomChaosProvider/randomProvider: Creates a DixieRandomChaosProvider DixieRandomChaosProvider.h + (instancetype)randomProvider:(id)paramProvider paramProvider The DixieRandomParamProvider to use as the random object generator a DixieRandomChaosProvider //api/name/randomProvider: //apple_ref/occ/instm/DixieRandomChaosProvider/chaosImplementationFor:environment: The behaviour implementation DixieRandomChaosProvider.m - (void)chaosImplementationFor:(id)victim environment:(id)environment victim The class or instance of the class, that's method should be changed environment A DixieCallEnvironment, that describes the arguments and return value //api/name/chaosImplementationFor:environment: ================================================ FILE: Documentation/docset/Contents/Resources/Tokens18.xml ================================================ //apple_ref/occ/cl/DixieRandomParamProvider Provides a random number object DixieRandomParamProvider.h //apple_ref/occ/clm/DixieRandomParamProvider/providerWithUpperBound: Creates a DixieRandomParamProvider with a given uppper bound DixieRandomParamProvider.h + (instancetype)providerWithUpperBound:(id)upperBound upperBound The upper limit to the random numbers, the numbers can be only lower than this a DixieRandomParamProvider //api/name/providerWithUpperBound: //apple_ref/occ/instm/DixieRandomParamProvider/setSeed: Set the seed for the random generator DixieRandomParamProvider.h - (void)setSeed:(id)seed seed A seed for deterministic behaviour //api/name/setSeed: //apple_ref/occ/instm/DixieRandomParamProvider/parameter Returns an object DixieRandomParamProvider.m - (id)parameter an object //api/name/parameter ================================================ FILE: Documentation/docset/Contents/Resources/Tokens19.xml ================================================ //apple_ref/occ/cl/DixieRunTimeHelper Helper to generate behaviour implementation, transparently call implementations and provide Runtime informations DixieRunTimeHelper.h //apple_ref/occ/clm/DixieRunTimeHelper/implementationWithChaosContext:environment: Generates an implementation pointer that confirms to the chaosContext and block DixieRunTimeHelper.h + (IMP)implementationWithChaosContext:(id)chaosContext environment:(id)block chaosContext The context of the implementation block Block for the body of the implementation pointer the implementation pointer //api/name/implementationWithChaosContext:environment: //apple_ref/occ/clm/DixieRunTimeHelper/callImplementation:on:chaosContext:environment: Calls the implementation pointer DixieRunTimeHelper.h + (void)callImplementation:(id)implementation on:(id)puppet chaosContext:(id)chaosContext environment:(id)environment implementation The IMP pointer to call puppet The receiver of the ObjC message chaosContext The context of the behaviour environment The environment of the method's implementation call //api/name/callImplementation:on:chaosContext:environment: //apple_ref/occ/clm/DixieRunTimeHelper/selectorsForClass: Collects the runtime public methodnames for a given class DixieRunTimeHelper.h + (NSArray *)selectorsForClass:(id)targetClass targetClass The class Array of public selector strings //api/name/selectorsForClass: //apple_ref/occ/clm/DixieRunTimeHelper/methodForMethodInfo: Returns the Method pointer for a given MethodInfo object DixieRunTimeHelper.h + (Method)methodForMethodInfo:(id)methodInfo methodInfo Describes the target class and it's method The Method pointer //api/name/methodForMethodInfo: //apple_ref/occ/clm/DixieRunTimeHelper/methodTypeEncodingForMethodInfo: Returns the string representation of the method encoding describes by the MethodInfo object DixieRunTimeHelper.h + (const char *)methodTypeEncodingForMethodInfo:(id)methodInfo methodInfo Describes the target class and it's method the string representation of the method encoding //api/name/methodTypeEncodingForMethodInfo: //apple_ref/occ/clm/DixieRunTimeHelper/classForMethodInfo: Returns the class for the method described in the MethodInfo. DixieRunTimeHelper.h + (Class)classForMethodInfo:(id)methodInfo methodInfo Describes the target class and it's method A Class object for instance methods and meta class object for class methods //api/name/classForMethodInfo: //apple_ref/occ/clm/DixieRunTimeHelper/blockForSignature:block: Returns a block implementation for a given signature DixieRunTimeHelper.m + (id)blockForSignature:(id)signature block:(id)block signature The method signature block The body of the block implementation A block, that matches the signature and calls the block //api/name/blockForSignature:block: //apple_ref/occ/clm/DixieRunTimeHelper/argumentsFor:originalArguments: * Parses a variadic list into array of objects DixieRunTimeHelper.m + (NSArray *)argumentsFor:(id)signature originalArguments:(id)arguments //api/name/argumentsFor:originalArguments: //apple_ref/occ/clm/DixieRunTimeHelper/objectFromNext:type: Converts the next item in the variadic arguments list into subclass of NSObjects DixieRunTimeHelper.m + (id)objectFromNext:(id)arguments type:(id)argType arguments The variadic list argType the expected type of the next item An NSObject subclass that represents the argument //api/name/objectFromNext:type: ================================================ FILE: Documentation/docset/Contents/Resources/Tokens2.xml ================================================ //apple_ref/occ/cl/DixieBaseChaosProvider DixieBaseChaosProvider.h //apple_ref/occ/instm/DixieBaseChaosProvider/chaos Returns a new behaviour implementation DixieBaseChaosProvider.h - (IMP)chaos An implementation pointer //api/name/chaos //apple_ref/occ/instm/DixieBaseChaosProvider/forwardChaosOf:environment:to: Will forward the result of one DixieChaosProvider to the next. DixieBaseChaosProvider.h - (void)forwardChaosOf:(id)victim environment:(id)environment to:(id)chaosProvider victim The class or instance of the class, that's method should be changed environment A DixieCallEnvironment, that describes the arguments and return value chaosProvider The target DixieBaseChaosProvider, who should provider the behaviour //api/name/forwardChaosOf:environment:to: //apple_ref/occ/instm/DixieBaseChaosProvider/chaosImplementationFor:environment: The behaviour implementation DixieBaseChaosProvider.h - (void)chaosImplementationFor:(id)victim environment:(id)environment victim The class or instance of the class, that's method should be changed environment A DixieCallEnvironment, that describes the arguments and return value //api/name/chaosImplementationFor:environment: ================================================ FILE: Documentation/docset/Contents/Resources/Tokens20.xml ================================================ //apple_ref/occ/cl/DixieSequentialChaosProvider Provides a behaviour, where the method's implementation behaves differently for a new call. The different behaviours depend on the defined different DixieChaosProviders of the class DixieSequentialChaosProvider.h //apple_ref/occ/clm/DixieSequentialChaosProvider/sequence: Creates a DixieSequentialChaosProvider DixieSequentialChaosProvider.h + (instancetype)sequence:(id)sequenceOfChaosProviders sequenceOfChaosProviders Array of DixieBaseChaosProvider, the order of the array defines, how the method's implementation will behave for a new call. a DixieSequentialChaosProvider //api/name/sequence: //apple_ref/occ/instm/DixieSequentialChaosProvider/chaosImplementationFor:environment: The behaviour implementation DixieSequentialChaosProvider.m - (void)chaosImplementationFor:(id)victim environment:(id)environment victim The class or instance of the class, that's method should be changed environment A DixieCallEnvironment, that describes the arguments and return value //api/name/chaosImplementationFor:environment: ================================================ FILE: Documentation/docset/Contents/Resources/Tokens21.xml ================================================ //apple_ref/occ/cl/DixieSimpleLogger Default subclass of DixieLogger,that uses NSLog DixieSimpleLogger.h //apple_ref/occ/instm/DixieSimpleLogger/log: Logs a message. DixieSimpleLogger.m - (void)log:(id)format, ... format The format of the message. It can be followed by variadic arguments. //api/name/log: ================================================ FILE: Documentation/docset/Contents/Resources/Tokens22.xml ================================================ //apple_ref/occ/cat/NSObject(DixieRunTimeHelper) Helper category on NSObject to store the original type encoding and value if the object was converted from non-object type NSObject+DixieRunTimeHelper.h ================================================ FILE: Documentation/docset/Contents/Resources/Tokens23.xml ================================================ //apple_ref/occ/intf/DixiePuppetMaking Interface to objects, that can change the behaviour of a class' method. DixiePuppetMaking.h //apple_ref/occ/intfm/DixiePuppetMaking/createPuppet:seed: Creates puppet according to a given entry for the specified seed, by replacing the original behaviour with a new DixiePuppetMaking.h - (void)createPuppet:(id)entry seed:(id)seed entry The entry specifying the victim class, selector and behaviour seed An integer value to make the invocations on the puppets deterministic //api/name/createPuppet:seed: //apple_ref/occ/intfm/DixiePuppetMaking/dismissPuppet: Dismisses the puppets for a given entry DixiePuppetMaking.h - (void)dismissPuppet:(id)entry entry The entry specifying the victim class, selector and behaviour //api/name/dismissPuppet: ================================================ FILE: Documentation/docset/Contents/Resources/Tokens24.xml ================================================ ================================================ FILE: Documentation/docset/Contents/Resources/Tokens25.xml ================================================ ================================================ FILE: Documentation/docset/Contents/Resources/Tokens3.xml ================================================ //apple_ref/occ/cl/DixieBaseParamProvider Base class for objects, that can return an object DixieBaseParamProvider.h //apple_ref/occ/instm/DixieBaseParamProvider/parameter Returns an object DixieBaseParamProvider.h - (id)parameter an object //api/name/parameter ================================================ FILE: Documentation/docset/Contents/Resources/Tokens4.xml ================================================ //apple_ref/occ/cl/DixieBlockChaosProvider Provides a behaviour, where the original method's implementation can be replaced by a custom block DixieBlockChaosProvider.h //apple_ref/occ/clm/DixieBlockChaosProvider/block: Creates an instance of DixieBlockChaosProvider DixieBlockChaosProvider.h + (instancetype)block:(id)block block The block, that should be called as the method's implementation a new instance of DixieBlockChaosProvider //api/name/block: //apple_ref/occ/instm/DixieBlockChaosProvider/chaosImplementationFor:environment: The behaviour implementation DixieBlockChaosProvider.m - (void)chaosImplementationFor:(id)victim environment:(id)environment victim The class or instance of the class, that's method should be changed environment A DixieCallEnvironment, that describes the arguments and return value //api/name/chaosImplementationFor:environment: ================================================ FILE: Documentation/docset/Contents/Resources/Tokens5.xml ================================================ //apple_ref/occ/cl/DixieCallEnvironment Describes the environment of a method's implementation DixieCallEnvironment.h //apple_ref/occ/instm/DixieCallEnvironment/setArguments: Arguments of the method call converted into objects DixieCallEnvironment.h @property (strong) NSArray *arguments //api/name/arguments //apple_ref/occ/instm/DixieCallEnvironment/arguments Arguments of the method call converted into objects DixieCallEnvironment.h @property (strong) NSArray *arguments //api/name/arguments //apple_ref/occ/instp/DixieCallEnvironment/arguments Arguments of the method call converted into objects DixieCallEnvironment.h @property (strong) NSArray *arguments //api/name/arguments //apple_ref/occ/instm/DixieCallEnvironment/setReturnValue: The return value of a method's implementation DixieCallEnvironment.h @property (nonatomic) id returnValue //api/name/returnValue //apple_ref/occ/instm/DixieCallEnvironment/returnValue The return value of a method's implementation DixieCallEnvironment.h @property (nonatomic) id returnValue //api/name/returnValue //apple_ref/occ/instp/DixieCallEnvironment/returnValue The return value of a method's implementation DixieCallEnvironment.h @property (nonatomic) id returnValue //api/name/returnValue //apple_ref/occ/instm/DixieCallEnvironment/initWithArguments: Creates a DixieCallEnvironment with the arguments DixieCallEnvironment.h - (instancetype)initWithArguments:(id)arguments arguments Arguments of the method call converted into objects a DixieCallEnvironment //api/name/initWithArguments: ================================================ FILE: Documentation/docset/Contents/Resources/Tokens6.xml ================================================ //apple_ref/occ/cl/DixieChaosContext Defining the context for the DixieChaosProviders DixieChaosContext.h //apple_ref/occ/instm/DixieChaosContext/setSeed: A seed for deterministic behaviour. DixieChaosContext.h @property (readonly) NSInteger seed //api/name/seed //apple_ref/occ/instm/DixieChaosContext/seed A seed for deterministic behaviour. DixieChaosContext.h @property (readonly) NSInteger seed //api/name/seed //apple_ref/occ/instp/DixieChaosContext/seed A seed for deterministic behaviour. DixieChaosContext.h @property (readonly) NSInteger seed //api/name/seed //apple_ref/occ/instm/DixieChaosContext/setMethodInfo: A DixieMethodInfo, that describes the class and one of its method DixieChaosContext.h @property (readonly) DixieMethodInfo *methodInfo //api/name/methodInfo //apple_ref/occ/instm/DixieChaosContext/methodInfo A DixieMethodInfo, that describes the class and one of its method DixieChaosContext.h @property (readonly) DixieMethodInfo *methodInfo //api/name/methodInfo //apple_ref/occ/instp/DixieChaosContext/methodInfo A DixieMethodInfo, that describes the class and one of its method DixieChaosContext.h @property (readonly) DixieMethodInfo *methodInfo //api/name/methodInfo //apple_ref/occ/instm/DixieChaosContext/setOriginalIMP: The original implementation of the class method, described in the methodInfo property. DixieChaosContext.h @property IMP originalIMP //api/name/originalIMP //apple_ref/occ/instm/DixieChaosContext/originalIMP The original implementation of the class method, described in the methodInfo property. DixieChaosContext.h @property IMP originalIMP //api/name/originalIMP //apple_ref/occ/instp/DixieChaosContext/originalIMP The original implementation of the class method, described in the methodInfo property. DixieChaosContext.h @property IMP originalIMP //api/name/originalIMP //apple_ref/occ/instm/DixieChaosContext/init:methodInfo: Creates a DixieChaosContext with a given seed and methodInfo DixieChaosContext.h - (instancetype)init:(id)seed methodInfo:(id)methodInfo seed A seed for deterministic behaviour. methodInfo A DixieMethodInfo, that describes the class and one of its method A DixieChaosContext //api/name/init:methodInfo: ================================================ FILE: Documentation/docset/Contents/Resources/Tokens7.xml ================================================ //apple_ref/occ/cl/DixieCompositeChaosProvider Provides a behaviour, where the method's implementation can be changed according the passed arguments DixieCompositeChaosProvider.h //apple_ref/occ/clm/DixieCompositeChaosProvider/conditions: Creates a new instance of DixieCompositeChaosProvider DixieCompositeChaosProvider.h + (instancetype)conditions:(id)arrayOfConditions arrayOfConditions an array of DixieCompositeConditions a new instance of DixieCompositeChaosProvider //api/name/conditions: //apple_ref/occ/instm/DixieCompositeChaosProvider/chaosImplementationFor:environment: The behaviour implementation DixieCompositeChaosProvider.m - (void)chaosImplementationFor:(id)victim environment:(id)environment victim The class or instance of the class, that's method should be changed environment A DixieCallEnvironment, that describes the arguments and return value //api/name/chaosImplementationFor:environment: ================================================ FILE: Documentation/docset/Contents/Resources/Tokens8.xml ================================================ //apple_ref/occ/cl/DixieCompositeCondition Describes which chaosProvider should define the method's behaviour if the argument at index, matches the given value. DixieCompositeChaosProvider uses this object to delegate the implementation to different providers. DixieCompositeCondition.h //apple_ref/occ/instm/DixieCompositeCondition/setIndex: The index of the argument to check DixieCompositeCondition.h @property (readonly) NSInteger index //api/name/index //apple_ref/occ/instm/DixieCompositeCondition/index The index of the argument to check DixieCompositeCondition.h @property (readonly) NSInteger index //api/name/index //apple_ref/occ/instp/DixieCompositeCondition/index The index of the argument to check DixieCompositeCondition.h @property (readonly) NSInteger index //api/name/index //apple_ref/occ/instm/DixieCompositeCondition/setValue: The value of the argument we wish to compare DixieCompositeCondition.h @property (readonly) id value //api/name/value //apple_ref/occ/instm/DixieCompositeCondition/value The value of the argument we wish to compare DixieCompositeCondition.h @property (readonly) id value //api/name/value //apple_ref/occ/instp/DixieCompositeCondition/value The value of the argument we wish to compare DixieCompositeCondition.h @property (readonly) id value //api/name/value //apple_ref/occ/instm/DixieCompositeCondition/setChaosProvider: The ChaosProvider to apply DixieCompositeCondition.h @property (readonly) DixieBaseChaosProvider *chaosProvider //api/name/chaosProvider //apple_ref/occ/instm/DixieCompositeCondition/chaosProvider The ChaosProvider to apply DixieCompositeCondition.h @property (readonly) DixieBaseChaosProvider *chaosProvider //api/name/chaosProvider //apple_ref/occ/instp/DixieCompositeCondition/chaosProvider The ChaosProvider to apply DixieCompositeCondition.h @property (readonly) DixieBaseChaosProvider *chaosProvider //api/name/chaosProvider //apple_ref/occ/clm/DixieCompositeCondition/condition:value:chaosProvider: Creates a DixieCompositeCondition DixieCompositeCondition.h + (instancetype)condition:(id)index value:(id)value chaosProvider:(id)chaosProvider index The index of the argument to check value The value to compare the argument against chaosProvider The DixieChaosProvider to apply, if the argument matches the value a DixieCompositeCondition //api/name/condition:value:chaosProvider: ================================================ FILE: Documentation/docset/Contents/Resources/Tokens9.xml ================================================ //apple_ref/occ/cl/DixieConstantChaosProvider Provides a behaviour, where a given constant will be returned from the method's implementation DixieConstantChaosProvider.h //apple_ref/occ/instm/DixieConstantChaosProvider/setConstant: The constant value to return DixieConstantChaosProvider.h @property (readonly) id constant //api/name/constant //apple_ref/occ/instm/DixieConstantChaosProvider/constant The constant value to return DixieConstantChaosProvider.h @property (readonly) id constant //api/name/constant //apple_ref/occ/instp/DixieConstantChaosProvider/constant The constant value to return DixieConstantChaosProvider.h @property (readonly) id constant //api/name/constant //apple_ref/occ/clm/DixieConstantChaosProvider/constant: Creates a DixieConstantChaosProvider DixieConstantChaosProvider.h + (instancetype)constant:(id)constant constant The value the DixieConstantChaosProvider will return a DixieConstantChaosProvider //api/name/constant: //apple_ref/occ/instm/DixieConstantChaosProvider/chaosImplementationFor:environment: The behaviour implementation DixieConstantChaosProvider.m - (void)chaosImplementationFor:(id)victim environment:(id)environment victim The class or instance of the class, that's method should be changed environment A DixieCallEnvironment, that describes the arguments and return value //api/name/chaosImplementationFor:environment: ================================================ FILE: Documentation/docset-installed.txt ================================================ Documentation set was installed to Xcode! Path: /Users/peterwiesner/Library/Developer/Shared/Documentation/DocSets/com.skyscanner.dixie.Dixie.docset Time: 2015-06-01 17:00:00 +0000 ================================================ FILE: Documentation/html/Blocks/DixieCustomChaosBlock.html ================================================ DixieCustomChaosBlock Block Reference
Declared in DixieBlockChaosProvider.h

Block Definition

DixieCustomChaosBlock

Block type, that can describe a method implementation

typedef void (^DixieCustomChaosBlock) (DixieBaseChaosProvider *chaosProvider, id victim, DixieCallEnvironment *environment)

Discussion

Block type, that can describe a method implementation

Declared In

DixieBlockChaosProvider.h
================================================ FILE: Documentation/html/Blocks/DixieImplementationBlock.html ================================================ DixieImplementationBlock Block Reference
Declared in DixieRunTimeHelper.h

Block Definition

DixieImplementationBlock

Block type to describe a method’s concrete implementation

typedef void (^DixieImplementationBlock) (id victim, DixieCallEnvironment *environment)

Discussion

Block type to describe a method’s concrete implementation

Declared In

DixieRunTimeHelper.h
================================================ FILE: Documentation/html/Categories/NSObject+DixieRunTimeHelper.html ================================================ NSObject(DixieRunTimeHelper) Category Reference
Declared in NSObject+DixieRunTimeHelper.h

Overview

Helper category on NSObject to store the original type encoding and value if the object was converted from non-object type

================================================ FILE: Documentation/html/Classes/Dixie.html ================================================ Dixie Class Reference
Inherits from NSObject
Declared in Dixie.h
Dixie.m

Overview

Represents a Dixie configuration.

Fluent API of Dixie for easier configuration @code [Dixie new].Profile(aProfile).Apply();

Instance Methods

apply

Applies the Dixie configuration.

- (void)apply

Discussion

Applies the Dixie configuration.

Declared In

Dixie.h

apply:

Applies the Dixie configuration with the specified seed (used for random generation).

- (void)apply:(id)seed

Parameters

seed

The seed for random generation

Discussion

Applies the Dixie configuration with the specified seed (used for random generation).

Declared In

Dixie.h

profile:

Registers a single profiles.

- (instancetype)profile:(id)profile

Parameters

profile

A DixieProfileEntry objects.

Return Value

Same Dixie object.

Discussion

Registers a single profiles.

Declared In

Dixie.h

profiles:

Registers profiles.

- (instancetype)profiles:(id)arrayOfEntries

Parameters

arrayOfEntries

Collection of DixieProfileEntry objects.

Return Value

Same Dixie object.

Discussion

Registers profiles.

Declared In

Dixie.h

puppetMaker:

Sets the default puppetmaker

- (instancetype)puppetMaker:(id)puppetMaker

Parameters

puppetMaker

An object that conforms to the PuppetMaking protocol.

Return Value

The active Dixie object

Discussion

Sets the default puppetmaker

Declared In

Dixie.h

revert

Reverts the Dixie configuration.

- (void)revert

Discussion

Reverts the Dixie configuration.

Declared In

Dixie.h

revert:

Reverts one DixieProfileEntry from the Dixie configuration.

- (void)revert:(id)entry

Parameters

entry

The profile to revert

Discussion

Reverts one DixieProfileEntry from the Dixie configuration.

Declared In

Dixie.h
================================================ FILE: Documentation/html/Classes/DixieBaseChaosProvider.html ================================================ DixieBaseChaosProvider Class Reference
Inherits from NSObject
Declared in DixieBaseChaosProvider.h
DixieBaseChaosProvider.m

Instance Methods

chaos

Returns a new behaviour implementation

- (IMP)chaos

Return Value

An implementation pointer

Discussion

Returns a new behaviour implementation

Declared In

DixieBaseChaosProvider.h

chaosImplementationFor:environment:

The behaviour implementation

- (void)chaosImplementationFor:(id)victim environment:(id)environment

Parameters

victim

The class or instance of the class, that’s method should be changed

environment

A DixieCallEnvironment, that describes the arguments and return value

Discussion

The behaviour implementation

Declared In

DixieBaseChaosProvider.h

forwardChaosOf:environment:to:

Will forward the result of one DixieChaosProvider to the next.

- (void)forwardChaosOf:(id)victim environment:(id)environment to:(id)chaosProvider

Parameters

victim

The class or instance of the class, that’s method should be changed

environment

A DixieCallEnvironment, that describes the arguments and return value

chaosProvider

The target DixieBaseChaosProvider, who should provider the behaviour

Discussion

Will forward the result of one DixieChaosProvider to the next.

Declared In

DixieBaseChaosProvider.h
================================================ FILE: Documentation/html/Classes/DixieBaseParamProvider.html ================================================ DixieBaseParamProvider Class Reference
Inherits from NSObject
Declared in DixieBaseParamProvider.h
DixieBaseParamProvider.m

Overview

Base class for objects, that can return an object

Instance Methods

parameter

Returns an object

- (id)parameter

Return Value

an object

Discussion

Returns an object

Declared In

DixieBaseParamProvider.h
================================================ FILE: Documentation/html/Classes/DixieBlockChaosProvider.html ================================================ DixieBlockChaosProvider Class Reference
Inherits from DixieBaseChaosProvider : NSObject
Declared in DixieBlockChaosProvider.h
DixieBlockChaosProvider.m

Overview

Provides a behaviour, where the original method’s implementation can be replaced by a custom block

Tasks

Other Methods

Other Methods

Class Methods

block:

Creates an instance of DixieBlockChaosProvider

+ (instancetype)block:(id)block

Parameters

block

The block, that should be called as the method’s implementation

Return Value

a new instance of DixieBlockChaosProvider

Discussion

Creates an instance of DixieBlockChaosProvider

Declared In

DixieBlockChaosProvider.h

Instance Methods

chaosImplementationFor:environment:

The behaviour implementation

- (void)chaosImplementationFor:(id)victim environment:(id)environment

Parameters

victim

The class or instance of the class, that’s method should be changed

environment

A DixieCallEnvironment, that describes the arguments and return value

Discussion

The behaviour implementation

Declared In

DixieBaseChaosProvider.h
================================================ FILE: Documentation/html/Classes/DixieCallEnvironment.html ================================================ DixieCallEnvironment Class Reference
Inherits from NSObject
Declared in DixieCallEnvironment.h
DixieCallEnvironment.m

Overview

Describes the environment of a method’s implementation

Properties

arguments

Arguments of the method call converted into objects

@property (strong) NSArray *arguments

Discussion

Arguments of the method call converted into objects

Declared In

DixieCallEnvironment.h

returnValue

The return value of a method’s implementation

@property (nonatomic) id returnValue

Discussion

The return value of a method’s implementation

Declared In

DixieCallEnvironment.h

Instance Methods

initWithArguments:

Creates a DixieCallEnvironment with the arguments

- (instancetype)initWithArguments:(id)arguments

Parameters

arguments

Arguments of the method call converted into objects

Return Value

a DixieCallEnvironment

Discussion

Creates a DixieCallEnvironment with the arguments

Declared In

DixieCallEnvironment.h
================================================ FILE: Documentation/html/Classes/DixieChaosContext.html ================================================ DixieChaosContext Class Reference
Inherits from NSObject
Declared in DixieChaosContext.h
DixieChaosContext.m

Overview

Defining the context for the DixieChaosProviders

Properties

methodInfo

A DixieMethodInfo, that describes the class and one of its method

@property (readonly) DixieMethodInfo *methodInfo

Discussion

A DixieMethodInfo, that describes the class and one of its method

Declared In

DixieChaosContext.h

originalIMP

The original implementation of the class method, described in the methodInfo property.

@property IMP originalIMP

Discussion

The original implementation of the class method, described in the methodInfo property.

Declared In

DixieChaosContext.h

seed

A seed for deterministic behaviour.

@property (readonly) NSInteger seed

Discussion

A seed for deterministic behaviour.

Declared In

DixieChaosContext.h

Instance Methods

init:methodInfo:

Creates a DixieChaosContext with a given seed and methodInfo

- (instancetype)init:(id)seed methodInfo:(id)methodInfo

Parameters

seed

A seed for deterministic behaviour.

methodInfo

A DixieMethodInfo, that describes the class and one of its method

Return Value

A DixieChaosContext

Discussion

Creates a DixieChaosContext with a given seed and methodInfo

Declared In

DixieChaosContext.h
================================================ FILE: Documentation/html/Classes/DixieCompositeChaosProvider.html ================================================ DixieCompositeChaosProvider Class Reference
Inherits from DixieBaseChaosProvider : NSObject
Declared in DixieCompositeChaosProvider.h
DixieCompositeChaosProvider.m

Overview

Provides a behaviour, where the method’s implementation can be changed according the passed arguments

Tasks

Other Methods

Other Methods

Class Methods

conditions:

Creates a new instance of DixieCompositeChaosProvider

+ (instancetype)conditions:(id)arrayOfConditions

Parameters

arrayOfConditions

an array of DixieCompositeConditions

Return Value

a new instance of DixieCompositeChaosProvider

Discussion

Creates a new instance of DixieCompositeChaosProvider

Declared In

DixieCompositeChaosProvider.h

Instance Methods

chaosImplementationFor:environment:

The behaviour implementation

- (void)chaosImplementationFor:(id)victim environment:(id)environment

Parameters

victim

The class or instance of the class, that’s method should be changed

environment

A DixieCallEnvironment, that describes the arguments and return value

Discussion

The behaviour implementation

Declared In

DixieBaseChaosProvider.h
================================================ FILE: Documentation/html/Classes/DixieCompositeCondition.html ================================================ DixieCompositeCondition Class Reference
Inherits from NSObject
Declared in DixieCompositeCondition.h
DixieCompositeCondition.m

Overview

Describes which chaosProvider should define the method’s behaviour if the argument at index, matches the given value. DixieCompositeChaosProvider uses this object to delegate the implementation to different providers.

Properties

chaosProvider

The ChaosProvider to apply

@property (readonly) DixieBaseChaosProvider *chaosProvider

Discussion

The ChaosProvider to apply

Declared In

DixieCompositeCondition.h

index

The index of the argument to check

@property (readonly) NSInteger index

Discussion

The index of the argument to check

Declared In

DixieCompositeCondition.h

value

The value of the argument we wish to compare

@property (readonly) id value

Discussion

The value of the argument we wish to compare

Declared In

DixieCompositeCondition.h

Class Methods

condition:value:chaosProvider:

Creates a DixieCompositeCondition

+ (instancetype)condition:(id)index value:(id)value chaosProvider:(id)chaosProvider

Parameters

index

The index of the argument to check

value

The value to compare the argument against

chaosProvider

The DixieChaosProvider to apply, if the argument matches the value

Return Value

a DixieCompositeCondition

Discussion

Creates a DixieCompositeCondition

Declared In

DixieCompositeCondition.h
================================================ FILE: Documentation/html/Classes/DixieConstantChaosProvider.html ================================================ DixieConstantChaosProvider Class Reference
Inherits from DixieBaseChaosProvider : NSObject
Declared in DixieConstantChaosProvider.h
DixieConstantChaosProvider.m

Overview

Provides a behaviour, where a given constant will be returned from the method’s implementation

Tasks

Other Methods

Other Methods

Properties

constant

The constant value to return

@property (readonly) id constant

Discussion

The constant value to return

Declared In

DixieConstantChaosProvider.h

Class Methods

constant:

Creates a DixieConstantChaosProvider

+ (instancetype)constant:(id)constant

Parameters

constant

The value the DixieConstantChaosProvider will return

Return Value

a DixieConstantChaosProvider

Discussion

Creates a DixieConstantChaosProvider

Declared In

DixieConstantChaosProvider.h

Instance Methods

chaosImplementationFor:environment:

The behaviour implementation

- (void)chaosImplementationFor:(id)victim environment:(id)environment

Parameters

victim

The class or instance of the class, that’s method should be changed

environment

A DixieCallEnvironment, that describes the arguments and return value

Discussion

The behaviour implementation

Declared In

DixieBaseChaosProvider.h
================================================ FILE: Documentation/html/Classes/DixieDefaultPuppetMaker.html ================================================ DixieDefaultPuppetMaker Class Reference
Inherits from NSObject
Conforms to DixiePuppetMaking
Declared in DixieDefaultPuppetMaker.h
DixieDefaultPuppetMaker.m

Overview

Default implementation of the DixiePuppetMaking interface

Instance Methods

createPuppet:seed:

Creates puppet according to a given entry for the specified seed, by replacing the original behaviour with a new

- (void)createPuppet:(id)entry seed:(id)seed

Parameters

entry

The entry specifying the victim class, selector and behaviour

seed

An integer value to make the invocations on the puppets deterministic

Discussion

Creates puppet according to a given entry for the specified seed, by replacing the original behaviour with a new

Declared In

DixiePuppetMaking.h

dismissPuppet:

Dismisses the puppets for a given entry

- (void)dismissPuppet:(id)entry

Parameters

entry

The entry specifying the victim class, selector and behaviour

Discussion

Dismisses the puppets for a given entry

Declared In

DixiePuppetMaking.h
================================================ FILE: Documentation/html/Classes/DixieExceptionChaosProvider.html ================================================ DixieExceptionChaosProvider Class Reference
Inherits from DixieBaseChaosProvider : NSObject
Declared in DixieExceptionChaosProvider.h
DixieExceptionChaosProvider.m

Overview

Provides a behaviour, where the method’s implementation will always crash on calling

Tasks

Other Methods

Other Methods

Properties

exception

The exception to raise

@property (readonly) NSException *exception

Discussion

The exception to raise

Declared In

DixieExceptionChaosProvider.h

Class Methods

exception:

Creates an DixieExceptionChaosProvider

+ (instancetype)exception:(id)exception

Parameters

exception

The exception to raise

Return Value

an DixieExceptionChaosProvider

Discussion

Creates an DixieExceptionChaosProvider

Declared In

DixieExceptionChaosProvider.h

Instance Methods

chaosImplementationFor:environment:

The behaviour implementation

- (void)chaosImplementationFor:(id)victim environment:(id)environment

Parameters

victim

The class or instance of the class, that’s method should be changed

environment

A DixieCallEnvironment, that describes the arguments and return value

Discussion

The behaviour implementation

Declared In

DixieBaseChaosProvider.h
================================================ FILE: Documentation/html/Classes/DixieLogger.html ================================================ DixieLogger Class Reference
Inherits from NSObject
Declared in DixieLogger.h
DixieLogger.m

Overview

Base class for logging

Class Methods

defaultLogger

Returns default logger.

+ (instancetype)defaultLogger

Return Value

The logger.

Discussion

Returns default logger.

Declared In

DixieLogger.h

setDefaultLogger:

Changes the default logger.

+ (void)setDefaultLogger:(id)logger

Parameters

logger

The logger.

Discussion

Changes the default logger.

Declared In

DixieLogger.h

Instance Methods

log:

Logs a message.

- (void)log:(id)format, ...

Parameters

format

The format of the message. It can be followed by variadic arguments.

Discussion

Logs a message.

Declared In

DixieLogger.h
================================================ FILE: Documentation/html/Classes/DixieMethodInfo.html ================================================ DixieMethodInfo Class Reference
Inherits from NSObject
Declared in DixieMethodInfo.h
DixieMethodInfo.m

Overview

Describes a class and one of its method

Properties

isClassMethod

Indicates whether the method is a class method.

@property (readonly) BOOL isClassMethod

Discussion

Indicates whether the method is a class method.

Declared In

DixieMethodInfo.h

methodTypeEncoding

The string representation of the method encoding

@property (readonly) const char *methodTypeEncoding

Discussion

The string representation of the method encoding

Declared In

DixieMethodInfo.h

selector

Selector of the method.

@property (readonly) SEL selector

Discussion

Selector of the method.

Declared In

DixieMethodInfo.h

signature

Signature of the method.

@property (readonly) NSMethodSignature *signature

Discussion

Signature of the method.

Declared In

DixieMethodInfo.h

targetClass

Owner of the method.

@property (readonly) Class targetClass

Discussion

Owner of the method.

Declared In

DixieMethodInfo.h

Class Methods

infoWithClass:selector:

Creates a new MethodInfo instance.

+ (instancetype)infoWithClass:(id)targetClass selector:(id)selector

Parameters

targetClass

The owner of the method.

selector

The selector of the method.

Return Value

A MethodInfo instance.

Discussion

Creates a new MethodInfo instance.

Declared In

DixieMethodInfo.h
================================================ FILE: Documentation/html/Classes/DixieNilChaosProvider.html ================================================ DixieNilChaosProvider Class Reference
Inherits from DixieBaseChaosProvider : NSObject
Declared in DixieNilChaosProvider.h
DixieNilChaosProvider.m

Overview

Provides a behaviour, where the method’s implementation always returns nil;

Instance Methods

chaosImplementationFor:environment:

The behaviour implementation

- (void)chaosImplementationFor:(id)victim environment:(id)environment

Parameters

victim

The class or instance of the class, that’s method should be changed

environment

A DixieCallEnvironment, that describes the arguments and return value

Discussion

The behaviour implementation

Declared In

DixieBaseChaosProvider.h
================================================ FILE: Documentation/html/Classes/DixieNonChaosProvider.html ================================================ DixieNonChaosProvider Class Reference
Inherits from DixieBaseChaosProvider : NSObject
Declared in DixieNonChaosProvider.h
DixieNonChaosProvider.m

Overview

Provides the original behaviour

Tasks

Instance Methods

chaos

Returns a new behaviour implementation

- (IMP)chaos

Return Value

An implementation pointer

Discussion

Returns a new behaviour implementation

Declared In

DixieBaseChaosProvider.h
================================================ FILE: Documentation/html/Classes/DixieProfileEntry.html ================================================ DixieProfileEntry Class Reference
Inherits from NSObject
Declared in DixieProfileEntry.h
DixieProfileEntry.m

Overview

Describe the target class, selector and the desired behaviour

Properties

chaosProvider

The ChaosProvider which will provide the new implementation

@property (nonatomic, strong) DixieBaseChaosProvider *chaosProvider

Discussion

The ChaosProvider which will provide the new implementation

Declared In

DixieProfileEntry.h

entryID

Uniquely identifies the entry

@property (readonly) NSString *entryID

Discussion

Uniquely identifies the entry

Declared In

DixieProfileEntry.h

methodInfo

The DixieMethodInfo object, that describes the class and its method

@property (nonatomic, readonly) DixieMethodInfo *methodInfo

Discussion

The DixieMethodInfo object, that describes the class and its method

Declared In

DixieProfileEntry.h

Class Methods

entries:excludeSelectorsOfClass:chaosProvider:

Creates an array of DixieProfileEntry. The DixieProfileEntry array consists of all selectors on the victim EXCEPT those defined in the klass

+ (NSArray *)entries:(id)victim excludeSelectorsOfClass:(id)excludeClass chaosProvider:(id)chaosProvider

Parameters

victim

The victim whose method we wish to override

chaosProvider

The ChaosProvider which will provide the new implementation

klass

Tha class, whose selectors should not be added to the list of entries

Return Value

an array of DixieProfileEntries representing all available selectors on the victim EXCEPT those defined in the excludeClass

Discussion

Creates an array of DixieProfileEntry. The DixieProfileEntry array consists of all selectors on the victim EXCEPT those defined in the klass

Declared In

DixieProfileEntry.h

entries:excludes:chaosProvider:

Creates an array of DixieProfileEntries The DixieProfileEntries array consists of all selectors on the victim EXCEPT those specified in excludedSelectorNames

+ (NSArray *)entries:(id)victim excludes:(id)excludedSelectorNames chaosProvider:(id)chaosProvider

Parameters

victim

The victim whose method we wish to override

excludedSelectorNames

The selectors we do NOT wish to include in the return calue

chaosProvider

The ChaosProvider which will provide the new implementation

Return Value

an array of DixieProfileEntries representing all available selectors on the victim EXCEPT those specified

Discussion

Creates an array of DixieProfileEntries The DixieProfileEntries array consists of all selectors on the victim EXCEPT those specified in excludedSelectorNames

Declared In

DixieProfileEntry.h

entry:selector:chaosProvider:

Creates a DixieProfileEntry with the main properties set

+ (instancetype)entry:(id)victim selector:(id)selector chaosProvider:(id)chaosProvider

Parameters

victim

The victim whose method we wish to override

selector

The selector for the method we wish to override

chaosProvider

The ChaosProvider which will provide the new implementation

Return Value

a new DixieProfileEntry with the properties set

Discussion

Creates a DixieProfileEntry with the main properties set

Declared In

DixieProfileEntry.h
================================================ FILE: Documentation/html/Classes/DixieRandomChaosProvider.html ================================================ DixieRandomChaosProvider Class Reference
Inherits from DixieBaseChaosProvider : NSObject
Declared in DixieRandomChaosProvider.h
DixieRandomChaosProvider.m

Overview

Provides a behaviour, where the method’s implementation returns a random object, generated with a DixieRandomParamProvider

Class Methods

randomProvider:

Creates a DixieRandomChaosProvider

+ (instancetype)randomProvider:(id)paramProvider

Parameters

paramProvider

The DixieRandomParamProvider to use as the random object generator

Return Value

a DixieRandomChaosProvider

Discussion

Creates a DixieRandomChaosProvider

Declared In

DixieRandomChaosProvider.h

Instance Methods

chaosImplementationFor:environment:

The behaviour implementation

- (void)chaosImplementationFor:(id)victim environment:(id)environment

Parameters

victim

The class or instance of the class, that’s method should be changed

environment

A DixieCallEnvironment, that describes the arguments and return value

Discussion

The behaviour implementation

Declared In

DixieBaseChaosProvider.h
================================================ FILE: Documentation/html/Classes/DixieRandomParamProvider.html ================================================ DixieRandomParamProvider Class Reference
Inherits from DixieBaseParamProvider : NSObject
Declared in DixieRandomParamProvider.h
DixieRandomParamProvider.m

Overview

Provides a random number object

Tasks

Other Methods

Other Methods

Class Methods

providerWithUpperBound:

Creates a DixieRandomParamProvider with a given uppper bound

+ (instancetype)providerWithUpperBound:(id)upperBound

Parameters

upperBound

The upper limit to the random numbers, the numbers can be only lower than this

Return Value

a DixieRandomParamProvider

Discussion

Creates a DixieRandomParamProvider with a given uppper bound

Declared In

DixieRandomParamProvider.h

Instance Methods

parameter

Returns an object

- (id)parameter

Return Value

an object

Discussion

Returns an object

Declared In

DixieBaseParamProvider.h

setSeed:

Set the seed for the random generator

- (void)setSeed:(id)seed

Parameters

seed

A seed for deterministic behaviour

Discussion

Set the seed for the random generator

Declared In

DixieRandomParamProvider.h
================================================ FILE: Documentation/html/Classes/DixieRunTimeHelper.html ================================================ DixieRunTimeHelper Class Reference
Inherits from NSObject
Declared in DixieRunTimeHelper.h
DixieRunTimeHelper.m

Overview

Helper to generate behaviour implementation, transparently call implementations and provide Runtime informations

Class Methods

argumentsFor:originalArguments:

  • Parses a variadic list into array of objects
+ (NSArray *)argumentsFor:(id)signature originalArguments:(id)arguments

Discussion

  • Parses a variadic list into array of objects

Note: The current solution handles only object,selector,BOOL and char types. * * @param signature The signature to determine the type of parameters in the variadic list * @param arguments The variadic list * * @return Array of parsed objects

Declared In

DixieRunTimeHelper.m

blockForSignature:block:

Returns a block implementation for a given signature

+ (id)blockForSignature:(id)signature block:(id)block

Parameters

signature

The method signature

block

The body of the block implementation

Return Value

A block, that matches the signature and calls the block

Discussion

Returns a block implementation for a given signature

Declared In

DixieRunTimeHelper.m

callImplementation:on:chaosContext:environment:

Calls the implementation pointer

+ (void)callImplementation:(id)implementation on:(id)puppet chaosContext:(id)chaosContext environment:(id)environment

Parameters

implementation

The IMP pointer to call

puppet

The receiver of the ObjC message

chaosContext

The context of the behaviour

environment

The environment of the method’s implementation call

Discussion

Calls the implementation pointer

Declared In

DixieRunTimeHelper.h

classForMethodInfo:

Returns the class for the method described in the MethodInfo.

+ (Class)classForMethodInfo:(id)methodInfo

Parameters

methodInfo

Describes the target class and it’s method

Return Value

A Class object for instance methods and meta class object for class methods

Discussion

Returns the class for the method described in the MethodInfo.

Declared In

DixieRunTimeHelper.h

implementationWithChaosContext:environment:

Generates an implementation pointer that confirms to the chaosContext and block

+ (IMP)implementationWithChaosContext:(id)chaosContext environment:(id)block

Parameters

chaosContext

The context of the implementation

block

Block for the body of the implementation pointer

Return Value

the implementation pointer

Discussion

Generates an implementation pointer that confirms to the chaosContext and block

Declared In

DixieRunTimeHelper.h

methodForMethodInfo:

Returns the Method pointer for a given MethodInfo object

+ (Method)methodForMethodInfo:(id)methodInfo

Parameters

methodInfo

Describes the target class and it’s method

Return Value

The Method pointer

Discussion

Returns the Method pointer for a given MethodInfo object

Declared In

DixieRunTimeHelper.h

methodTypeEncodingForMethodInfo:

Returns the string representation of the method encoding describes by the MethodInfo object

+ (const char *)methodTypeEncodingForMethodInfo:(id)methodInfo

Parameters

methodInfo

Describes the target class and it’s method

Return Value

the string representation of the method encoding

Discussion

Returns the string representation of the method encoding describes by the MethodInfo object

Declared In

DixieRunTimeHelper.h

objectFromNext:type:

Converts the next item in the variadic arguments list into subclass of NSObjects

+ (id)objectFromNext:(id)arguments type:(id)argType

Parameters

arguments

The variadic list

argType

the expected type of the next item

Return Value

An NSObject subclass that represents the argument

Discussion

Converts the next item in the variadic arguments list into subclass of NSObjects

Note: We are using core foundation factories here, NSNumber, NSString might be swizzled

Declared In

DixieRunTimeHelper.m

selectorsForClass:

Collects the runtime public methodnames for a given class

+ (NSArray *)selectorsForClass:(id)targetClass

Parameters

targetClass

The class

Return Value

Array of public selector strings

Discussion

Collects the runtime public methodnames for a given class

Declared In

DixieRunTimeHelper.h
================================================ FILE: Documentation/html/Classes/DixieSequentialChaosProvider.html ================================================ DixieSequentialChaosProvider Class Reference
Inherits from DixieBaseChaosProvider : NSObject
Declared in DixieSequentialChaosProvider.h
DixieSequentialChaosProvider.m

Overview

Provides a behaviour, where the method’s implementation behaves differently for a new call. The different behaviours depend on the defined different DixieChaosProviders of the class

Tasks

Other Methods

Other Methods

Class Methods

sequence:

Creates a DixieSequentialChaosProvider

+ (instancetype)sequence:(id)sequenceOfChaosProviders

Parameters

sequenceOfChaosProviders

Array of DixieBaseChaosProvider, the order of the array defines, how the method’s implementation will behave for a new call.

Return Value

a DixieSequentialChaosProvider

Discussion

Creates a DixieSequentialChaosProvider

Declared In

DixieSequentialChaosProvider.h

Instance Methods

chaosImplementationFor:environment:

The behaviour implementation

- (void)chaosImplementationFor:(id)victim environment:(id)environment

Parameters

victim

The class or instance of the class, that’s method should be changed

environment

A DixieCallEnvironment, that describes the arguments and return value

Discussion

The behaviour implementation

Declared In

DixieBaseChaosProvider.h
================================================ FILE: Documentation/html/Classes/DixieSimpleLogger.html ================================================ DixieSimpleLogger Class Reference
Inherits from DixieLogger : NSObject
Declared in DixieSimpleLogger.h
DixieSimpleLogger.m

Overview

Default subclass of DixieLogger,that uses NSLog

Tasks

Instance Methods

log:

Logs a message.

- (void)log:(id)format, ...

Parameters

format

The format of the message. It can be followed by variadic arguments.

Discussion

Logs a message.

Declared In

DixieLogger.h
================================================ FILE: Documentation/html/Protocols/DixiePuppetMaking.html ================================================ DixiePuppetMaking Protocol Reference
Conforms to NSObject
Declared in DixiePuppetMaking.h

Overview

Interface to objects, that can change the behaviour of a class' method.

Tasks

Instance Methods

createPuppet:seed:

Creates puppet according to a given entry for the specified seed, by replacing the original behaviour with a new

- (void)createPuppet:(id)entry seed:(id)seed

Parameters

entry

The entry specifying the victim class, selector and behaviour

seed

An integer value to make the invocations on the puppets deterministic

Discussion

Creates puppet according to a given entry for the specified seed, by replacing the original behaviour with a new

Declared In

DixiePuppetMaking.h

dismissPuppet:

Dismisses the puppets for a given entry

- (void)dismissPuppet:(id)entry

Parameters

entry

The entry specifying the victim class, selector and behaviour

Discussion

Dismisses the puppets for a given entry

Declared In

DixiePuppetMaking.h
================================================ FILE: Documentation/html/css/styles.css ================================================ body { font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; font-size: 13px; } code { font-family: Courier, Consolas, monospace; font-size: 13px; color: #666; } pre { font-family: Courier, Consolas, monospace; font-size: 13px; line-height: 18px; tab-interval: 0.5em; border: 1px solid #C7CFD5; background-color: #F1F5F9; color: #666; padding: 0.3em 1em; } ul { list-style-type: square; } li { margin-bottom: 10px; } a, a code { text-decoration: none; color: #36C; } a:hover, a:hover code { text-decoration: underline; color: #36C; } h2 { border-bottom: 1px solid #8391A8; color: #3C4C6C; font-size: 187%; font-weight: normal; margin-top: 1.75em; padding-bottom: 2px; } table { margin-bottom: 4em; border-collapse:collapse; vertical-align: middle; } td { border: 1px solid #9BB3CD; padding: .667em; font-size: 100%; } th { border: 1px solid #9BB3CD; padding: .3em .667em .3em .667em; background: #93A5BB; font-size: 103%; font-weight: bold; color: white; text-align: left; } /* @group Common page elements */ #top_header { height: 91px; left: 0; min-width: 598px; position: absolute; right: 0; top: 0; z-index: 900; } #footer { clear: both; padding-top: 20px; text-align: center; } #contents, #overview_contents { -webkit-overflow-scrolling: touch; border-top: 1px solid #A9A9A9; position: absolute; top: 90px; left: 0; right: 0; bottom: 0; overflow-x: hidden; overflow-y: auto; padding-left: 2em; padding-right: 2em; padding-top: 1em; min-width: 550px; } #contents.isShowingTOC { left: 230px; min-width: 320px; } .copyright { font-size: 12px; } .generator { font-size: 11px; } .main-navigation ul li { display: inline; margin-left: 15px; list-style: none; } .navigation-top { clear: both; float: right; } .navigation-bottom { clear: both; float: right; margin-top: 20px; margin-bottom: -10px; } .open > .disclosure { background-image: url("../img/disclosure_open.png"); } .disclosure { background: url("../img/disclosure.png") no-repeat scroll 0 0; } .disclosure, .nodisclosure { display: inline-block; height: 8px; margin-right: 5px; position: relative; width: 9px; } /* @end */ /* @group Header */ #top_header #library { background: url("../img/library_background.png") repeat-x 0 0 #485E78; background-color: #ccc; height: 35px; font-size: 115%; } #top_header #library #libraryTitle { color: #FFFFFF; margin-left: 15px; text-shadow: 0 -1px 0 #485E78; top: 8px; position: absolute; } #libraryTitle { left: 0; } #top_header #library #developerHome { color: #92979E; right: 15px; top: 8px; position: absolute; } #top_header #library a:hover { text-decoration: none; } #top_header #title { background: url("../img/title_background.png") repeat-x 0 0 #8A98A9; border-bottom: 1px solid #757575; height: 25px; overflow: hidden; } #top_header h1 { font-size: 105%; font-weight: normal; margin: 0; padding: 3px 0 2px; text-align: center; /*text-shadow: 0 1px 0 #D5D5D5;*/ white-space: nowrap; } #headerButtons { background-color: #D8D8D8; background-image: url("../img/button_bar_background.png"); border-bottom: 0px solid #EDEDED; border-top: 0px solid #a8a8a8; font-size: 8pt; height: 28px; left: 0; list-style: none outside none; margin: 0; overflow: hidden; padding: 0; position: absolute; right: 0; top: 61px; } #headerButtons li { background-repeat: no-repeat; display: inline; margin-top: 0; margin-bottom: 0; padding: 0; } #toc_button button { background-color: #EBEEF1; border-color: #ACACAC; border-style: none solid none none; border-width: 0 1px 0 0; height: 28px; margin: 0; padding-left: 30px; text-align: left; width: 230px; } li#jumpto_button { left: 230px; margin-left: 0; position: absolute; } li#jumpto_button select { height: 22px; margin: 5px 2px 0 10px; max-width: 300px; } /* @end */ /* @group Table of contents */ #tocContainer.isShowingTOC { border-right: 1px solid #ACACAC; display: block; overflow-x: hidden; overflow-y: auto; padding: 0; } #tocContainer { background-color: #EBEEF1; border-top: 1px solid #ACACAC; bottom: 0; display: none; left: 0; overflow: hidden; position: absolute; top: 90px; width: 229px; } #tocContainer > ul#toc { font-size: 11px; margin: 0; padding: 12px 0 18px; width: 209px; -moz-user-select: none; -webkit-user-select: none; user-select: none; } #tocContainer > ul#toc > li { margin: 0; padding: 0 0 7px 30px; text-indent: -15px; } #tocContainer > ul#toc > li > .sectionName a { color: #000000; font-weight: bold; } #tocContainer > ul#toc > li > .sectionName a:hover { text-decoration: none; } #tocContainer > ul#toc li.children > ul { display: none; height: 0; } #tocContainer > ul#toc > li > ul { margin: 0; padding: 0; } #tocContainer > ul#toc > li > ul, ul#toc > li > ul > li { margin-left: 0; margin-bottom: 0; padding-left: 15px; } #tocContainer > ul#toc > li ul { list-style: none; margin-right: 0; padding-right: 0; } #tocContainer > ul#toc li.children.open > ul { display: block; height: auto; margin-left: -15px; padding-left: 0; } #tocContainer > ul#toc > li > ul, ul#toc > li > ul > li { margin-left: 0; padding-left: 15px; } #tocContainer li ul li { margin-top: 0.583em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } #tocContainer li ul li span.sectionName { white-space: normal; } #tocContainer > ul#toc > li > ul > li > .sectionName a { font-weight: bold; } #tocContainer > ul#toc > li > ul a { color: #4F4F4F; } /* @end */ /* @group Index formatting */ .index-title { font-size: 13px; font-weight: normal; } .index-column { float: left; width: 30%; min-width: 200px; font-size: 11px; } .index-column ul { margin: 8px 0 0 0; padding: 0; list-style: none; } .index-column ul li { margin: 0 0 3px 0; padding: 0; } .hierarchy-column { min-width: 400px; } .hierarchy-column ul { margin: 3px 0 0 15px; } .hierarchy-column ul li { list-style-type: square; } /* @end */ /* @group Common formatting elements */ .title { font-weight: normal; font-size: 215%; margin-top:0; } .subtitle { font-weight: normal; font-size: 180%; color: #3C4C6C; border-bottom: 1px solid #5088C5; } .subsubtitle { font-weight: normal; font-size: 145%; height: 0.7em; } .note { border: 1px solid #5088C5; background-color: white; margin: 1.667em 0 1.75em 0; padding: 0 .667em .083em .750em; } .warning { border: 1px solid #5088C5; background-color: #F0F3F7; margin-bottom: 0.5em; padding: 0.3em 0.8em; } .bug { border: 1px solid #000; background-color: #ffffcc; margin-bottom: 0.5em; padding: 0.3em 0.8em; } .deprecated { color: #F60425; } /* @end */ /* @group Common layout */ .section { margin-top: 3em; } /* @end */ /* @group Object specification section */ .section-specification { margin-left: 2.5em; margin-right: 2.5em; font-size: 12px; } .section-specification table { margin-bottom: 0em; border-top: 1px solid #d6e0e5; } .section-specification td { vertical-align: top; border-bottom: 1px solid #d6e0e5; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; padding: .6em; } .section-specification .specification-title { font-weight: bold; } /* @end */ /* @group Tasks section */ .task-list { list-style-type: none; padding-left: 0px; } .task-list li { margin-bottom: 3px; } .task-item-suffix { color: #996; font-size: 12px; font-style: italic; margin-left: 0.5em; } span.tooltip span.tooltip { font-size: 1.0em; display: none; padding: 0.3em; border: 1px solid #aaa; background-color: #fdfec8; color: #000; text-align: left; } span.tooltip:hover span.tooltip { display: block; position: absolute; margin-left: 2em; } /* @end */ /* @group Method section */ .section-method { margin-top: 2.3em; } .method-title { margin-bottom: 1.5em; } .method-subtitle { margin-top: 0.7em; margin-bottom: 0.2em; } .method-subsection p { margin-top: 0.4em; margin-bottom: 0.8em; } .method-declaration { margin-top:1.182em; margin-bottom:.909em; } .method-declaration code { font:14px Courier, Consolas, monospace; color:#000; } .declaration { color: #000; } .termdef { margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 0px; } .termdef dt { margin: 0; padding: 0; } .termdef dd { margin-bottom: 6px; margin-left: 16px; margin-right: 0px; margin-top: 1px; } .termdef dd p { margin-bottom: 6px; margin-left: 0px; margin-right: 0px; margin-top: -1px; } .argument-def { margin-top: 0.3em; margin-bottom: 0.3em; } .argument-def dd { margin-left: 1.25em; } .see-also-section ul { list-style-type: none; padding-left: 0px; margin-top: 0; } .see-also-section li { margin-bottom: 3px; } .declared-in-ref { color: #666; } #tocContainer.hideInXcode { display: none; border: 0px solid black; } #top_header.hideInXcode { display: none; } #contents.hideInXcode { border: 0px solid black; top: 0px; left: 0px; } /* @end */ ================================================ FILE: Documentation/html/css/stylesPrint.css ================================================ header { display: none; } div.main-navigation, div.navigation-top { display: none; } div#overview_contents, div#contents.isShowingTOC, div#contents { overflow: visible; position: relative; top: 0px; border: none; left: 0; } #tocContainer.isShowingTOC { display: none; } nav { display: none; } ================================================ FILE: Documentation/html/hierarchy.html ================================================ Dixie Hierarchy
================================================ FILE: Documentation/html/index.html ================================================ Dixie Reference
================================================ FILE: LICENSE ================================================ Apache License ============== _Version 2.0, January 2004_ _<>_ ### Terms and Conditions for use, reproduction, and distribution #### 1. Definitions “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means **(i)** the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or **(ii)** ownership of fifty percent (50%) or more of the outstanding shares, or **(iii)** beneficial ownership of such entity. “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License. “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.” “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. #### 2. Grant of Copyright License Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. #### 3. Grant of Patent License Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. #### 4. Redistribution You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: * **(a)** You must give any other recipients of the Work or Derivative Works a copy of this License; and * **(b)** You must cause any modified files to carry prominent notices stating that You changed the files; and * **(c)** You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and * **(d)** If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. #### 5. Submission of Contributions Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. #### 6. Trademarks This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. #### 7. Disclaimer of Warranty Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. #### 8. Limitation of Liability In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. #### 9. Accepting Warranty or Additional Liability While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. _END OF TERMS AND CONDITIONS_ ================================================ FILE: README.md ================================================ Dixie === Dixie Dixie is an open source Objective-C testing framework for altering object behaviours. Test your app through creating chaos in the inner systems. The primary goal of Dixie is to provide a set of tools, which the developers can test their code with. Behind the goal is the ideology of _"do not always expect the best"_. You can read more about this [here](https://medium.com/@Skyscanner/dixie-turning-chaos-to-your-advantage-4f3749e6d485). [![Build Status](https://travis-ci.org/Skyscanner/Dixie.svg)](https://travis-ci.org/Skyscanner/Dixie) ### How can you test your application with Dixie 1. Create a new target in your app’s project that runs your Dixie setup logic during app launch. With the separate target you can make sure all Dixie related code is separated and won’t be included in your production builds 2. Change the behaviour of some components with Dixie and deploy the test build to device or simulator to see how your app behaves 3. Once you got familiar with the library, it might be worth to create a list of behaviour changes that you can easily configure and combine from your debug build ### A few ideas what you can do * Hijack the localisation component of your app to simulate long strings or other unexpected text * Inject mocked network responses into the network layer (you can match the URLs with a regular expression so you can provide different responses for different requests) * Network mocking can also be utilised in automated UI tests, so you don’t have to rely on real network communication * You can easily mock GPS coordinates or even the current date, so you do not have to set the simulators location manually * Inject randomised properties to your data models to see how robust is your application handling the objects received from web ### In our projects we use Dixie in two ways 1. We just put the Dixie configuration code in the `AppDelegate` and remove if not needed (these are short testing sessions). `#ifdef`-ing is an option, also creating a separate target that has a category on the `AppDelegate`. 2. We use Dixie in the automated UI tests as a standard mocking framework. The tests rely on the final app target, and we found extremely hard to mock components on the low level (e.g. networking) in this scope. Either way we think Dixie comes handy in cases, where you have to mock libraries, that's less configurable or some components are not that easily injectable. ## Installation #### With CocoaPods [CocoaPods](https://cocoapods.org) is the recommended way to add Dixie to your project. - Add Dixie to your Podfile `pod 'Dixie'` - Install/update pod(s) `pod install` - Include DixieHeaders.h where you would like to use Dixie `#import ` #### Without CocoaPods You can add Dixie without CocoaPods to your project if you download the Dixie project and add it manually to your project. Don't forget to add the project path into the Header Search Path. You can see an example for this integration in the [Example app](https://github.com/Skyscanner/Dixie#example-app) ##Usage First define which method on which class the change should be applied to, and its new behaviour. You can do this by creating a `DixieProfileEntry`: ```objective-c //Tomorrow NSDate* testDate = [NSDate dateWithTimeIntervalSinceNow:24*60*60]; //A behaviour to always return tomorrow's date DixieChaosProvider* provider = [DixieConstantChaosProvider constant:testDate]; //Create the entry DixieProfileEntry* entry = [DixieProfileEntry entry:[NSDate class] selector:@selector(date) chaosProvider:provider] ``` Then create an instance of a `Dixie` configuration, set the profile and apply. ```objective-c //Create Dixie configuration Dixie* dixie = [Dixie new]; //Set and apply change dixie .Profile(entry) .Apply(); ``` After applying the profile, every call of `[NSDate date]` will return the date for tomorrow instead of today. This way you can test date issues without going to the device settings and changing the date manually. When you no longer need Dixie, revert your change: ```objective-c //Revert the change of the entry dixie .RevertIt(entry); ``` Full code: ```objective-c - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSDate* testDate = [NSDate dateWithTimeIntervalSinceNow:24*60*60]; DixieChaosProvider* provider = [DixieConstantChaosProvider constant:testDate]; DixieProfileEntry* entry = [DixieProfileEntry entry:[NSDate class] selector:@selector(date) chaosProvider:provider] Dixie* dixie = [Dixie new]; dixie .Profile(entry) .Apply(); return YES; } ``` You can set multiple profiles and also revert them all at once. You can also choose from some preset behaviours: ####DixieNonChaosProvider Provides the original behaviour. Good to use when you want to have a different behaviour in special cases only. ####DixieConstantChaosProvider Provides a behaviour that always returns a constant object. ####DixieNilChaosProvider Provides a behaviour that always returns `nil`. ####DixieBlockChaosProvider Provides a behaviour that is described by a block. Using this provider the method can be replaced with a full custom behaviour. For accessing method parameters and setting the return value you can use the `DixieCallEnvironment` object passed to the block. ####DixieRandomChaosProvider Provides a behaviour that returns a random object. The default implementation returns a random `NSNumber`. ####DixieExceptionChaosProvider Provides a behaviour that throws an exception. ####DixieSequentialChaosProvider For every call it returns the _ith_ chaosprovider's behaviour, where `i` is the number of the call. If the number of calls exceeds the number of predefined chaosprovider the last provider's behaviour will be used. ####DixieCompositeChaosProvider Checks the parameters of the method and if one matches the value of a given `DixieCompositeCondition`, then it returns the connected chaosprovider's behaviour. # Under the hood The idea of changing an object's behaviour is not new. It is usually used in unit testing, where a component's dependencies are mocked to have a controlled, reproducible environment. In these situations there is the requirement that the target project should be _easily injectable_. If you are depending on components that are not made by you, or that are not injectable, you have to turn to different methods. To implement the theory of creating chaos/altering component behaviour in Objective-C environment, Dixie uses the technique of _Method Swizzling_. Method swizzling relies on calling special runtime methods, that require knowing the target method and its environment. Dixie takes care of handling the runtime for you, and also hides the original method environment, so you only have to focus on defining the new behaviour and can apply it quickly and simply. __Note:__ * The current implementation is best at changing behaviours of methods on iOS simulator. Support for arm architectures will come in the next version. * Dixie is best for testing so, as with other similar libraries, its usage in production environments is strongly discouraged. # Example app You can find a [Dixie example app project](https://github.com/Skyscanner/Dixie/tree/master/DixieExampleApp) in the repository with some common use-cases of how to use Dixie. The project requires [CocoaPods](https://cocoapods.org) dependency manager, so you have to run the `pod install` command in the `DixieExampleApp` directory before you can run the project. The example app covers three use-cases: #### Location mocking Shows the actual location on a map using the [`CLLocationManager`](https://developer.apple.com/library/ios/documentation/CoreLocation/Reference/CLLocationManager_Class/index.html). Dixie changes the implementation of the [`locationManager:didUpdateLocations:`](https://developer.apple.com/library/ios/documentation/CoreLocation/Reference/CLLocationManagerDelegate_Protocol/#//apple_ref/occ/intfm/CLLocationManagerDelegate/locationManager:didUpdateLocations:) method, so any location can be mocked easily. The example app mocks a random city. With Dixie Revert function the device location is used. The whole logic can be found in the [`MapViewController.m`](https://github.com/Skyscanner/Dixie/blob/master/DixieExampleApp/DixieExampleApp/MapViewController.m). It uses a `DixieBlockChaosProvider` to be able to change the method implementation with a block. #### Date mocking A countdown timer to the next [Halley's Comet](http://en.wikipedia.org/wiki/Halley's_Comet) arrival. The countdown timer uses the actual date function ([`[NSDate date]`](https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/#//apple_ref/occ/clm/NSDate/date)) and Dixie changes the implementation of this method and mocks a random date between -10000 and +10000 days from the actual date. The whole logic can be found in the [`CountDownViewController.m`](https://github.com/Skyscanner/Dixie/blob/master/DixieExampleApp/DixieExampleApp/CountDownViewController.m). It uses a `DixieConstantChaosProvider` which provides a constant value mocking. #### Network mocking This example shows the weather at the actual location using [OpenWeatherMap API](http://openweathermap.org/api) as the data source and [AFNetworking](https://github.com/AFNetworking/AFNetworking) which is a popular iOS and OS X networking framework. Dixie changes the implementation of the `GET:parameters:success:failure:` method implementation of the [`AFHTTPRequestOperationManager`](https://github.com/AFNetworking/AFNetworking/blob/7f997ef99ae64e321b6747defcaae5b13a691119/AFNetworking/AFHTTPRequestOperationManager.h) class of the `AFNetworking` framework. The request is not going out to the network, Dixie creates the response object and calls the `success` callback which is the async callback coming from a successful network response. The whole logic can be found in the [`WeatherViewController.m`](https://github.com/Skyscanner/Dixie/blob/master/DixieExampleApp/DixieExampleApp/WeatherViewController.m), it uses a `DixieBlockChaosProvider`. #About The Dixie was born from the idea of Peter Adam Wiesner. The prototype was brought to life by Phillip Wheatley, Tamas Flamich, Zsolt Varnai and Peter Adam Wiesner within a research lab project in one week. The prototype was developed into this open source library by Zsolt Varnai, Csaba Szabo, Zsombor Fuszenecker and Peter Adam Wiesner. If you know a way to make Dixie better, please contribute! You can reach us: * [peter.wiesner@skyscanner.net](peter.wiesner@skyscanner.net) or [@Peteee24](https://twitter.com/peteee24) * [zsolt.varnai@skyscanner.net](zsolt.varnai@skyscanner.net) * [csaba.szabo@skyscanner.net](csaba.szabo@skyscanner.net) * [zsombor.fuszenecker@skyscanner.net](zsombor.fuszenecker@skyscanner.net) ================================================ FILE: deploy_docs.sh ================================================ #!/bin/bash echo "[DOCSCRIPT] Updating gh-pages branch..." git checkout master git branch -D gh-pages git branch gh-pages git checkout gh-pages find . -not -path './Documentation/*' -not -path './Documentation' -not -path './.git/*' -not -path './.git' -delete cp -R Documentation/html/* . git add -A git commit -m "[DOCSCRIPT] Deploying Documentation to gh-pages branch" echo "[DOCSCRIPT] Publishing documentation" git push origin gh-pages git checkout -f master ================================================ FILE: documentation.sh ================================================ /usr/local/bin/appledoc --project-name Dixie --project-company Skyscanner --output "./Documentation/" --logformat xcode --exit-threshold \"2\" --keep-intermediate --verbose 4 "./Dixie/Dixie"